docs(words): visual audit + homogenization plan

Soma is clean (95/100, headless). The mess is words.css drifting from its
own token contract: ~117 tokens declared, ~42 used, 41 orphaned, the same
concept expressed 3-4 ways (radius, mix%, focus ring, sizes, durations,
padding), 3 duplicated color palettes, rail hardcoded over orphaned tokens.
Phased plan A-E; pilot = inspector. Working doc, updated per phase.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent 138ea2a162
commit 317cb5b297

@ -0,0 +1,65 @@
# Words — auditoría visual + plan de homogeneización
> Estado: **auditado 2026-06-06**. La capa soma está limpia; el trabajo es 100 % en
> la recipe `words.css` (eidos). Documento de trabajo — se actualiza por fase.
## Diagnóstico
**Soma (`src/uix/soma/components/words/`) está limpia (95/100):** headless, emite
`data-words-*`, sin estilos inline / `<style>` / valores visuales. Único pecadillo:
`engine/blocks/built-ins.ts:975` hardcodea `margin-left: ${indent*1.5}em` en el
*serializador HTML* (export, no render) — baja prioridad. **NO tocar soma por estética.**
**El problema es `words.css` (recipe, ~55 KB): se desincronizó de su propio contrato
de tokens.** La recipe (`lib/recipes/base.ts`, bloque words) declara ~117 tokens; el CSS
usa ~42 + decenas de valores hardcodeados y deja **41 tokens huérfanos**. El mismo concepto
se expresa de 3-4 formas según la superficie → incoherencia visible.
## Patrones de incoherencia (lo accionable)
| Patrón | Síntoma | Canon objetivo |
|---|---|---|
| **Radius** | `4px` literal · `var(--words-command-radius)` · `var(--radius-2,4px)` · `2px`/`3px` | una sola escala `--words-radius-{sm,md,lg}` |
| **Tints (mix%)** | hardcoded 4/8/12/14/16/22/30/40/45/50 % | escala `--words-wash-{faint,subtle,soft,strong}` (= % aplicados al color base de cada superficie) |
| **Focus ring** | 2px unificado pero mix dispersa (30/40/45 %) | un token `--words-focus-ring` (spec completa) |
| **Tamaños bespoke** | swatch 1.15rem · checkbox 1.1em · intent 0.625rem · control widths 6.75/7.5/15rem · sidebar/drawer 16rem (×3) | tokens `--words-swatch-size`, `--words-field-width`, `--words-panel-width`… |
| **Unidades** | `em` vs `rem` vs `px` vs token en font-size/spacing | `rem`/tokens; reservar `em` solo para lo relativo-al-texto intencional |
| **Durations** | `120ms`/`140ms` inline | `--words-transition-duration` siempre |
| **Padding** | `--space-*` vs `4px 8px` vs `1px 5px` | siempre `--space-*` |
| **Paletas color** | 3 arrays de hex DISTINTOS (bubble / block-panel / inspector) | una fuente única |
| **Rail** | `--words-rail-bg/border` huérfanos; rail hardcodea `#f5f5f5`/`#e3e3e3` | cablear los tokens (fixed-tone está bien, pero vía token) |
## Deuda de contrato (los 3 tests rojos)
- **Usados sin declarar (2):** `--words-font-size-xs`, `--words-swatch` (este último es var
inline por-swatch → documentar como excepción o declararlo con default).
- **Huérfanos (41):** `gap-*`, `toolbar-*`, `button-size-*`, `command-{px,*-hover}`, `status-*`,
`rail-*`, `selection-color`, `heading-font-size`, `_accent-*`, etc. → triar: *cablear* o *podar*.
- **API (`component-api-contract.test.ts`):** `words-inspector.svelte` tiene un `<style>` vacío;
`words.svelte` usa `onMount` (→ `$effect`).
## Plan por fases
- **A — Vocabulario canónico (fuente de verdad).** Triar los 41 huérfanos (cablear/podar) +
añadir las escalas que matan la sopa (`--words-wash-*`, `--words-focus-ring`, tokens de tamaño) +
declarar los 2 que faltan. → 2 tests de recipe verdes.
- **B — Homogeneizar `words.css`** superficie por superficie consumiendo el vocabulario (radius,
wash, focus, durations, sizes, padding). El grueso.
- **C — Centralizar las 3 paletas** de color en una sola fuente.
- **D — Fixes de API** (quitar `<style>` del inspector, `onMount→$effect`). → 3er test verde.
- **E — Verificar + README** (3 tests verdes · `check` · regresión visual en `/uix/components/words`
· README que fije vocabulario + look para que no vuelva a derivar).
## Arranque: piloto = **inspector**
La superficie más cargada de sopa. Introducir ahí los tokens de escala, reescribirla token-limpia,
verificar en navegador, y con el enfoque validado → generalizar tokens + barrer el resto.
## Tracker
- [ ] Piloto inspector (tokens de escala + reescritura + verificación)
- [ ] A — vocabulario (triar huérfanos + escalas + declarar faltantes)
- [ ] B — barrido de superficies
- [ ] C — paletas centralizadas
- [ ] D — fixes API (3er test)
- [ ] E — verificación + README
Loading…
Cancel
Save

Powered by TurnKey Linux.