From 08f2d82d94d026869d9edf2b1bf29473566a3b06 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 6 Jun 2026 15:47:31 +0200 Subject: [PATCH] =?UTF-8?q?fix(words):=20one=20sans=20across=20all=20chrom?= =?UTF-8?q?e=20=E2=80=94=20kill=20the=20mixed-typeface=20inspector?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inspector mixed THREE fonts: labels in Lora (serif!), titles in system-ui, inputs in Instrument Sans. Root cause: eidos's "content" archetype (Accordion content) maps to the reading serif, and the inspector's `[scope] *` rule is only (0,1,0) — equal to the component's `[data-x]` font rule — so the Phase 3 code-split flipped the load order and the serif won. Fix: a `--words-chrome-font` token (= --font-ui, independent of the content `font-family` a theme may set to serif) + a rule forcing it across EVERY chrome surface (toolbar·bubble·slash·drawer·inspector·gutter menus) with a DOUBLED scope attribute (0,2,0) that beats any single-attribute component font regardless of code-split order. Verified in browser: all chrome = Instrument Sans (was Lora/system-ui/Instrument). Content keeps its reading font. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/uix/eidos/components/words/AUDIT.md | 12 ++++- src/uix/eidos/components/words/words.css | 57 ++++++++++++------------ src/uix/eidos/generated/base.css | 1 + src/uix/eidos/lib/recipes/base.ts | 4 ++ 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/src/uix/eidos/components/words/AUDIT.md b/src/uix/eidos/components/words/AUDIT.md index a7e2f0cf0..7efc0a86f 100644 --- a/src/uix/eidos/components/words/AUDIT.md +++ b/src/uix/eidos/components/words/AUDIT.md @@ -81,5 +81,15 @@ verificar en navegador, y con el enfoque validado → generalizar tokens + barre sin consumidor, `::selection` ya usa `wash-soft`). **Eidos suite 197/197 verde** — el contrato del recipe ya coincide con el uso real. Poda visualmente inerte (el test "declares" garantiza que words.css no referenciaba ninguno). -- [ ] B (resto) — tamaños bespoke (swatch/checkbox/anchos/sidebar 16rem×3)→tokens, padding `--space-*` +- [x] **Tipografía del chrome — UNA sola sans** (2026-06-06): el inspector mezclaba 3 fuentes + (label **Lora**/serif, title **system-ui**, input Instrument Sans) — la "content" archetype de + eidos (Accordion content) mapea a la serif de lectura y se colaba; `[scope] *` es solo (0,1,0), + empata con el `[data-x]` del componente → el code-split de la Fase 3 invirtió el orden y ganaba + la serif. Fix: token `--words-chrome-font` (= `--font-ui`, independiente del `font-family` de + contenido que el tema puede poner serif) + regla que fuerza esa sans en TODO el chrome + (toolbar·bubble·slash·drawer·inspector·menús) con atributo doblado **(0,2,0)** que gana a + cualquier fuente de componente sin importar el orden de carga. Verificado: todo el chrome = + Instrument Sans. +- [ ] B (resto) — tamaños bespoke (swatch/checkbox/anchos/sidebar 16rem×3)→tokens, padding `--space-*`; + **escala de font-size del chrome armónica** (hoy xs/sm/md ≈ 11/12/13px, casi sin jerarquía) - [ ] E — verificación final (build + navegador) + README diff --git a/src/uix/eidos/components/words/words.css b/src/uix/eidos/components/words/words.css index 44388a7e6..92578e28d 100644 --- a/src/uix/eidos/components/words/words.css +++ b/src/uix/eidos/components/words/words.css @@ -370,35 +370,34 @@ /* Tightened from space-4 → space-2 (16px → 8px) — the sidebar is narrow and the previous padding ate ~20% of the usable inline width. */ padding: var(--space-2); - /* Force the system sans stack on EVERY descendant of the inspector - (labels, values, subsection titles, NumberField inputs, ToggleGroup - chips, accordion triggers, table cell counters, etc.). The editor's - content font can be serif when the surface is themed for reading - (`Words` body inherits `--words-font-family`); the inspector chrome - must stay sans regardless or the controls render with mixed - typography. - - The container declaration alone is NOT enough — eidos primitives - (Accordion.Trigger, Button, NumberField.Input, ToggleGroup.Item, - …) set their own `font-family` in their recipe CSS, breaking the - cascade. The `* { font-family: inherit }` rule forces every - descendant to inherit from the container regardless of recipe - overrides. This is the standard pattern when you want a subtree - to share one typeface against shipped components that ship their - own font choices. */ - font-family: - system-ui, - -apple-system, - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif; -} -[data-words-inspector] *, -[data-words-inspector] *::before, -[data-words-inspector] *::after { - font-family: inherit; +} + +/* ── Chrome typeface — ONE sans across every panel ───────────────────────── + The editor CONTENT may be themed serif (`--words-font-family`), but every + piece of CHROME (toolbar · bubble · slash · drawer · inspector · gutter + menus) must render in a single UI sans (`--words-chrome-font`) or controls + show mixed faces. Shipped components impose their own `font-family`, and the + "content" archetype (Accordion content, etc.) maps to the READING serif — + which leaked into the inspector labels (Lora). `[scope] *` is only (0,1,0), + EQUAL to a component's `[data-x]` font rule, so post-code-split LOAD ORDER + decided the winner. DOUBLING the scope attribute → (0,2,0) beats any + single-attribute component font regardless of order, on the root AND every + descendant. */ +[data-words-menubar][data-words-menubar], +[data-words-menubar][data-words-menubar] *, +[data-words-bubble-menu][data-words-bubble-menu], +[data-words-bubble-menu][data-words-bubble-menu] *, +[data-words-slash-menu][data-words-slash-menu], +[data-words-slash-menu][data-words-slash-menu] *, +[data-words-drawer][data-words-drawer], +[data-words-drawer][data-words-drawer] *, +[data-words-inspector][data-words-inspector], +[data-words-inspector][data-words-inspector] *, +[data-words-block-handle-menu][data-words-block-handle-menu], +[data-words-block-handle-menu][data-words-block-handle-menu] *, +[data-words-block-inserter-menu][data-words-block-inserter-menu], +[data-words-block-inserter-menu][data-words-block-inserter-menu] * { + font-family: var(--words-chrome-font); } /* Depth accent — the active node's nesting level (1 = top-level block, 2 = column, 3 = block-inside-a-column, …) is stamped on the inspector diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css index fdb4c0966..9e81f6986 100644 --- a/src/uix/eidos/generated/base.css +++ b/src/uix/eidos/generated/base.css @@ -2405,6 +2405,7 @@ --words-wash-soft: 30%; --words-wash-strong: 44%; --words-swatch: var(--words-bg); + --words-chrome-font: var(--font-ui); --words-command-gap: var(--space-1); --words-command-radius: var(--radius-md); --words-command-color: var(--color-content-secondary); diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts index ae0f1553e..5bc61d426 100644 --- a/src/uix/eidos/lib/recipes/base.ts +++ b/src/uix/eidos/lib/recipes/base.ts @@ -2688,6 +2688,10 @@ export const THEME_BASE_RECIPE_TOKENS = { // Per-swatch hue, set inline by the bubble/inspector color grids; the // declared default is the surface bg (an unset swatch reads as empty). swatch: 'var(--words-bg)', + // The CHROME typeface (toolbar · bubble · drawer · inspector · menus). Always a + // UI sans, INDEPENDENT of `font-family` (the content/reading font, which a theme + // may set to serif). Keeps every control + label in one face. + 'chrome-font': 'var(--font-ui)', 'command-gap': 'var(--space-1)', 'command-radius': 'var(--radius-md)', 'command-color': 'var(--color-content-secondary)',