uix(result): la COSTURA del texto — 23 % → 86 %, y `global` a cero

Quince claves. Misma corrección que en `chart`: el valor sigue siendo el del
canon —bundle de talla, ranuras de contenido, escalas de peso e interlineado,
familia mono— pero el knob pasa a ser del componente, que es lo que PLAN §2-A
exige y lo que permite retocar esta superficie sin mover el sistema entero.

POR PARTE, NO POR ROL — y es la diferencia con `chart`:

    title-{font-size,font-weight,line-height,fg}
    description-{font-size,line-height,fg}
    extra-{font-size,fg}
    code-{font-family,font-weight,letter-spacing,fg}
    media-{font-size,fg}

Cinco partes con tipografía distinta y ningún estilo con nombre que juegue
«estado terminal de página» (`h2` está en el tamaño del título pero significa
otra cosa). Es la forma dominante del catálogo — `description-fg` ×8,
`title-font-size`… — mientras que en chart dos roles se repetían sobre 19 nodos
y por eso allí la costura fue por rol.

El `calc(var(--size-xl-font-size) * 3)` del glifo entra en su costura con el
multiplicador DENTRO del valor: el 3× es identidad documentada, y así el glifo
sigue a la escala en vez de congelarse.

DOCE ADJUDICACIONES, TODAS SOBRE NODOS REALES (la lección de `drag-drop`): con
los controles de la propia demo, no fabricando nodos. Los tres acentos de estado
sólo pintan bajo su `data-status` —chip—; el bloque `extra` es opcional
—casilla—; el código grande sólo existe en los estados http —chip `not-found`:
Azeret Mono → Zapfino, 600 → 123, 3,36px → 4,5px—; y la tinta POR DEFECTO del
glifo sólo gana SIN `data-status`, porque cada estado re-apunta el privado a su
acento por diseño —se quitó el atributo: oklch(0.61 0 0) → rgb(1,2,3)—.

Con la costura, `global` cae a CERO y el alcance a 86 %: los tres knobs que
faltan para el 100 % son literales de identidad (el `1em` del código grande, que
hereda la escala del glifo; el `line-height: 1` del glifo; el `100%` del extra).

Gates: sonda antes/después **0 diffs en 990 valores** (5 nodos × 7 estados) ·
centinela 15/27 con las doce adjudicadas y medidas · censo --only **86 %** con
`global` 13 → 0 · --names 27/27 conformes · component-audit PASS · eidos-lint 0
invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0.

Global del eje tras las dos costuras: **57 % → 58 %** (2.677 → 2.727 públicos).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent 643179de0f
commit 5fdef91fb9

@ -5,43 +5,28 @@
> Vista de conjunto: [README](./README.md) · método y protocolo:
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
- **Medido**: 2026-08-22 · **Alcance**: **23%** — 5 de 22 knobs por token público
- **Knobs de apariencia**: 22 — público 5 · privado 0 · global 13 · literal 4 · sistema 0 _(fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 12 pública(s) — `gap`, `padding-block`, `padding-inline`, `actions-gap`, `actions-margin-block-start`, `extra-margin-block-start`, `description-measure`, `extra-measure`, `success-fg`, `error-fg`, `warning-fg`, `info-fg`
- **Medido**: 2026-08-22 · **Alcance**: **86%** — 19 de 22 knobs por token público
- **Knobs de apariencia**: 22 — público 19 · privado 0 · global 0 · literal 3 · sistema 0 _(fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 27 pública(s) — `gap`, `padding-block`, `padding-inline`, `actions-gap`, `actions-margin-block-start`, `extra-margin-block-start`, `title-font-size`, `title-font-weight`, `title-line-height`, `title-fg`, `description-font-size`, `description-line-height`, `description-fg`, `extra-font-size`, `extra-fg`, `media-font-size`, `media-fg`, `code-font-family`, `code-font-weight`, `code-letter-spacing`, `code-fg`, `description-measure`, `extra-measure`, `success-fg`, `error-fg`, `warning-fg`, `info-fg`
- **Eje `size`**: no · **ficheros**: `result.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (13)
### 1.1 Directo a primitivo global (0)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `result.css:39` | `[data-result-media]` | `font-size` | `calc(var(--size-xl-font-size) * 3)` |
| 2 | `result.css:59` | `[data-result-code]` | `font-family` | `var(--font-family-mono, monospace)` |
| 3 | `result.css:61` | `[data-result-code]` | `font-weight` | `var(--font-weight-semibold)` |
| 4 | `result.css:63` | `[data-result-code]` | `color` | `var(--color-content-muted)` |
| 5 | `result.css:70` | `[data-result-title]` | `font-size` | `var(--size-xl-font-size)` |
| 6 | `result.css:71` | `[data-result-title]` | `font-weight` | `var(--font-weight-semibold)` |
| 7 | `result.css:72` | `[data-result-title]` | `line-height` | `var(--font-line-height-sm, 1.4)` |
| 8 | `result.css:73` | `[data-result-title]` | `color` | `var(--color-content-primary)` |
| 9 | `result.css:80` | `[data-result-description]` | `font-size` | `var(--size-md-font-size)` |
| 10 | `result.css:81` | `[data-result-description]` | `line-height` | `var(--font-line-height-md, 1.5)` |
| 11 | `result.css:82` | `[data-result-description]` | `color` | `var(--color-content-muted)` |
| 12 | `result.css:105` | `[data-result-extra]` | `font-size` | `var(--size-sm-font-size)` |
| 13 | `result.css:106` | `[data-result-extra]` | `color` | `var(--color-content-secondary)` |
_Ninguno._
### 1.2 A través de un privado (0)
_Ninguno._
### 1.3 Literales (4)
### 1.3 Literales (3)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `result.css:40` | `[data-result-media]` | `line-height` | `1` |
| 2 | `result.css:60` | `[data-result-code]` | `font-size` | `1em` |
| 3 | `result.css:62` | `[data-result-code]` | `letter-spacing` | `0.04em` |
| 4 | `result.css:103` | `[data-result-extra]` | `inline-size` | `100%` |
| 1 | `result.css:41` | `[data-result-media]` | `line-height` | `1` |
| 2 | `result.css:61` | `[data-result-code]` | `font-size` | `1em` |
| 3 | `result.css:104` | `[data-result-extra]` | `inline-size` | `100%` |
## 2. Sistema transversal (0) — informativo, fuera del ratio
@ -57,7 +42,7 @@ _Ninguno._
## 4. Propuesta de corrección
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (15)
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (1)
Valor **verbatim** del CSS de hoy: el default no se mueve, sólo cambia quién
puede moverlo. Nombres derivados de recipe-contract §1 (ejes lógicos, talla
@ -67,31 +52,13 @@ no distingue lo que debería — se marca `⚠`.
| token (`--result-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `media-font-size` | `root` | `calc(var(--size-xl-font-size) * 3)` | 1 |
| `code-font-family` | `root` | `var(--font-family-mono, monospace)` | 1 |
| `code-font-size` | `root` | `1em` | 1 |
| `code-font-weight` | `root` | `var(--font-weight-semibold)` | 1 |
| `code-letter-spacing` | `root` | `0.04em` | 1 |
| `code-fg` | `root` | `var(--color-content-muted)` | 1 |
| `title-font-size` | `root` | `var(--size-xl-font-size)` | 1 |
| `title-font-weight` | `root` | `var(--font-weight-semibold)` | 1 |
| `title-line-height` | `root` | `var(--font-line-height-sm, 1.4)` | 1 |
| `title-fg` | `root` | `var(--color-content-primary)` | 1 |
| `description-font-size` | `root` | `var(--size-md-font-size)` | 1 |
| `description-line-height` | `root` | `var(--font-line-height-md, 1.5)` | 1 |
| `description-fg` | `root` | `var(--color-content-muted)` | 1 |
| `extra-font-size` | `root` | `var(--size-sm-font-size)` | 1 |
| `extra-fg` | `root` | `var(--color-content-secondary)` | 1 |
### 4.2 Sin nombre mecánico (2)
- **⚠ decisión: `1` es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar** — 1: `line-height`.
- **⚠ decisión: `100%` es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar** — 1: `inline-size`.
### 4.3 Avisos sobre los tokens propuestos (1)
- **⚠ decisión: el valor es una expresión — el token puede llevar la expresión entera o sólo su término variable** — `--result-media-font-size`
### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)
- [ ] **Privado que no deriva de un público** — §3 lo marca; el privado debe leer el público o desaparecer.
@ -104,38 +71,48 @@ no distingue lo que debería — se marca `⚠`.
<!-- veredicto:start -->
**EJECUTADO 2026-08-22 — 14 % → 23 %**, cuatro claves nuevas (8 → 12). El 23 %
es el techo de este componente y no es deuda: **lo que queda fuera lee el CANON
directamente**, que es lo que la doctrina manda.
**EJECUTADO 2026-08-22 — 14 % → 23 % → 86 %**, en dos pasadas: cuatro claves
de caja y luego **15 de COSTURA** para el tipo y la tinta (8 → 27). `global`
queda a CERO; los tres knobs restantes son literales de identidad.
**Lo que la receta posee es su CAJA**: el inset de página
(`padding-block`/`-inline`), el ritmo entre bloques
(`actions-margin-block-start`, `extra-margin-block-start`) y los cuatro acentos
de estado que ya tenía. Cuatro claves nuevas, ni una más.
**Lo que NO se acuña, y por qué**: el tipo lee el BUNDLE DE TALLA
(`var(--size-{xl,md,sm}-font-size)`) —que es literalmente lo que
recipe-contract §1 prescribe para el texto de un componente—, la tinta lee las
ranuras de contenido (`--color-content-{primary,muted,secondary}`), el peso la
escala (`--font-weight-semibold`), el interlineado la suya
(`--font-line-height-{sm,md}`) y el código grande la familia mono del tema.
Acuñar `--result-title-font-size` sería tipografía por componente, prohibida el
2026-08-22. El censo cuenta esas trece lecturas como `global`; es la misma nota
de `listbox` y `chart` (§13), no deuda de este componente.
**Los cuatro literales**: el `calc(var(--size-xl-font-size) * 3)` del glifo de
estado —identidad documentada: el display es TRES veces el paso xl—, el `1em`
del código grande (hereda esa escala a propósito), su `0.04em` de tracking
óptico y el `100%` del extra. Ninguno es tema.
**El tipo y la tinta se COSEN, no se inventan** (firmado 2026-08-22). Los
valores siguen siendo los del canon —bundle de talla, ranuras de contenido,
escalas de peso e interlineado, familia mono del tema— pero el knob es de
`result`, que es lo que PLAN §2-A exige y lo que permite retocar esta superficie
sin mover el sistema. Mi primera lectura («no se acuña nada») era media
doctrina: el valor es del sistema, el knob es del componente.
**Aquí la costura va por PARTE, no por rol** —al contrario que en `chart`—
porque son cinco partes con tipografía distinta y ningún estilo con nombre juega
«estado terminal de página»: `title-{font-size,font-weight,line-height,fg}` ·
`description-{font-size,line-height,fg}` · `extra-{font-size,fg}` ·
`code-{font-family,font-weight,letter-spacing,fg}` · `media-{font-size,fg}`.
Es la forma dominante del catálogo (`description-fg` ×8, `title-font-size`…).
El `calc(var(--size-xl-font-size) * 3)` del glifo entra en su costura con el
multiplicador DENTRO del valor: el 3× es identidad, pero así el glifo sigue a la
escala.
**Los tres literales que quedan**: el `1em` del código grande (hereda la
escala del glifo a propósito), el `line-height: 1` del glifo y el `100%` del
extra. Ninguno es tema.
**Un renombrado de higiene**: el privado `--_result-media-color` pasa a
`--_result-media-fg` — la gramática firmada (D-TH.6) dice `fg`, y R-5.3 no mira
los privados, así que se corrige a mano al pasar por aquí.
**Guard R-5.4**: 7/12 en vivo, y **las cinco que callan están medidas sobre
nodos REALES**, no sintéticos (la lección de `drag-drop`): los tres acentos de
estado sólo pintan bajo su `data-status` —se pulsó su chip— y el bloque
`extra` es opcional —se marcó su casilla—. Las cinco alcanzan.
**Guard R-5.4**: 15/27 en vivo, y **las doce que callan están medidas sobre
nodos REALES**, no sintéticos (la lección de `drag-drop`), con los controles de
la propia demo: los tres acentos de estado sólo pintan bajo su `data-status`
—se pulsó su chip—, el bloque `extra` es opcional —se marcó su casilla—, el
código grande sólo existe en los estados http —se pulsó `not-found`— y la tinta
por defecto del glifo sólo gana SIN `data-status`, porque cada estado re-apunta
el privado a su acento por diseño —se quitó el atributo—. Las doce alcanzan.
Sonda antes/después: **0 diffs en 990 valores** (5 nodos × 7 estados).

@ -327,7 +327,19 @@ export const SENTINEL_EXCEPTIONS: Record<string, Record<string, string>> = {
'warning-fg':
'only paints under [data-status=warning]; clicked its chip 2026-08-22 -> reaches (oklch(0.6908 0.1909 45.02) -> rgb(1,2,3))',
'info-fg':
'only paints under [data-status=info]; clicked its chip 2026-08-22 -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3))'
'only paints under [data-status=info]; clicked its chip 2026-08-22 -> reaches (oklch(0.5556 0.1829 305.86) -> rgb(1,2,3))',
'extra-font-size':
'same optional block; ticked its checkbox 2026-08-22 -> reaches (14px -> 1234px)',
'extra-fg': 'same optional block; ticked 2026-08-22 -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))',
'media-fg':
'the DEFAULT glyph ink: with a [data-status] the private wins by design (each status re-points --_result-media-fg to its accent) and the demo always sets one. Removed the attribute 2026-08-22 -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))',
'code-font-family':
'the big HTTP code only renders for the http statuses and the demo boots on success; clicked the not-found chip 2026-08-22 -> reaches (Azeret Mono -> Zapfino)',
'code-font-weight': 'same http-only node; clicked not-found 2026-08-22 -> reaches (600 -> 123)',
'code-letter-spacing':
'same http-only node; clicked not-found 2026-08-22 -> reaches (3.36px -> 4.5px)',
'code-fg':
'same http-only node; clicked not-found 2026-08-22 -> reaches (oklch(0.61 0 0) -> rgb(1,2,3))'
},
chart: {
'transition-duration':

@ -73,29 +73,37 @@ justified empty state.
## Talla y tema
Contrato en `lib/recipes/base.ts > result` — **12 claves** (8 + 4 el
2026-08-22). Alcance del censo: **23 %** (era 14 %). Sin eje `size`: Result es
de página (paridad AntD). **Guard R-5.4**: 7/12 en vivo; las cinco que callan
están medidas sobre nodos REALES (los tres acentos de estado pulsando su chip,
el bloque `extra` marcando su casilla) y alcanzan.
Contrato en `lib/recipes/base.ts > result` — **27 claves** (8 + 4 + 15 el
2026-08-22). Alcance del censo: **86 %** (era 14 %), con `global` a CERO. Sin
eje `size`: Result es de página (paridad AntD). **Guard R-5.4**: 15/27 en vivo;
las doce que callan están medidas sobre nodos REALES con los controles de la
demo (chip de estado, chip `not-found` para el código http, casilla del
`extra`, y quitar `data-status` para la tinta por defecto del glifo).
```
--result-gap · padding-block · padding-inline
--result-actions-gap · actions-margin-block-start
--result-extra-margin-block-start · extra-measure · description-measure
--result-{success,error,warning,info}-fg
caja gap · padding-block · padding-inline · actions-gap
actions-margin-block-start · extra-margin-block-start
medida description-measure · extra-measure
acentos {success,error,warning,info}-fg
tipo title-{font-size,font-weight,line-height,fg}
description-{font-size,line-height,fg} · extra-{font-size,fg}
code-{font-family,font-weight,letter-spacing,fg}
media-{font-size,fg}
```
**La receta posee su CAJA, no su tipografía.** El tipo lee el bundle de talla
(`--size-{xl,md,sm}-font-size`, lo que recipe-contract §1 prescribe), la tinta
las ranuras de contenido, el peso y el interlineado sus escalas, y el código
grande la familia mono del tema. Acuñar `--result-title-font-size` sería
tipografía por componente. El censo cuenta esas trece lecturas como `global`:
es la nota de `listbox` / `chart` (next-features §13), no deuda de aquí.
**El valor es del canon; el knob es del componente.** El tipo y la tinta siguen
tomando sus valores del bundle de talla, las ranuras de contenido y las escalas
de peso e interlineado — pero a través de una COSTURA (`--result-title-*`…), que
es lo que PLAN §2-A exige y lo que permite retocar esta superficie sin mover el
sistema entero. Aquí la costura va **por parte** —cinco partes con tipografía
distinta y ningún estilo con nombre que juegue «estado terminal de página»—, al
contrario que en `chart`, donde dos roles se repiten sobre 19 nodos.
Fuera de contrato por identidad: el `calc(var(--size-xl-font-size) * 3)` del
glifo —el display es TRES veces el paso xl—, el `1em` del código grande y su
`0.04em` de tracking óptico.
El `calc(var(--size-xl-font-size) * 3)` del glifo vive dentro de su costura: el
3× es identidad, y así el glifo sigue a la escala.
Fuera de contrato por identidad: el `1em` del código grande (hereda la escala
del glifo), el `line-height: 1` del glifo y el `100%` del extra.
## Gaps

@ -11,10 +11,11 @@
*
* `--result-*` tokens are public overrides; `--_result-*` internal.
*
* TYPE and INK read the canon directly and mint nothing: the size bundle
* (`--size-{k}-font-size`, what recipe-contract §1 prescribes), the content
* slots and the weight scale. What the recipe owns is its BOX — the page
* inset, the rhythm between blocks and the status accents.
* TYPE and INK come from the canon — the size bundle, the content slots, the
* weight and leading scales — but through a SEAM per part: `--result-title-*`,
* `-description-*`, `-extra-*`, `-code-*`, `-media-*` carry those values so a
* theme can retune THIS surface without moving the system (PLAN §2-A). Five
* parts with distinct typography, so the seam is per part, not per role.
*/
[data-result] {
@ -36,9 +37,9 @@
display: flex;
align-items: center;
justify-content: center;
font-size: calc(var(--size-xl-font-size) * 3); /* literal: display glyph 3× */
font-size: var(--result-media-font-size);
line-height: 1;
color: var(--_result-media-fg, var(--color-content-muted));
color: var(--_result-media-fg, var(--result-media-fg));
}
[data-result][data-status='success'] {
@ -56,30 +57,30 @@
/* The big HTTP code (forbidden / not-found / server-error) — neutral. */
[data-result-code] {
font-family: var(--font-family-mono, monospace);
font-family: var(--result-code-font-family);
font-size: 1em; /* literal: identity — inherits the media display scale */
font-weight: var(--font-weight-semibold);
letter-spacing: 0.04em; /* literal: optical tracking for the big mono code */
color: var(--color-content-muted);
font-weight: var(--result-code-font-weight);
letter-spacing: var(--result-code-letter-spacing);
color: var(--result-code-fg);
}
/* ── Title ─────────────────────────────────────────────────────────── */
[data-result-title] {
margin: 0;
font-size: var(--size-xl-font-size);
font-weight: var(--font-weight-semibold);
line-height: var(--font-line-height-sm, 1.4);
color: var(--color-content-primary);
font-size: var(--result-title-font-size);
font-weight: var(--result-title-font-weight);
line-height: var(--result-title-line-height);
color: var(--result-title-fg);
}
/* ── Description ───────────────────────────────────────────────────── */
[data-result-description] {
margin: 0;
font-size: var(--size-md-font-size);
line-height: var(--font-line-height-md, 1.5);
color: var(--color-content-muted);
font-size: var(--result-description-font-size);
line-height: var(--result-description-line-height);
color: var(--result-description-fg);
max-inline-size: var(--result-description-measure);
text-wrap: pretty;
}
@ -102,6 +103,6 @@
max-inline-size: var(--result-extra-measure);
inline-size: 100%;
text-align: start;
font-size: var(--size-sm-font-size);
color: var(--color-content-secondary);
font-size: var(--result-extra-font-size);
color: var(--result-extra-fg);
}

@ -4009,6 +4009,21 @@
--result-actions-gap: var(--space-2);
--result-actions-margin-block-start: var(--space-1);
--result-extra-margin-block-start: var(--space-4);
--result-title-font-size: var(--size-xl-font-size);
--result-title-font-weight: var(--font-weight-semibold);
--result-title-line-height: var(--font-line-height-sm);
--result-title-fg: var(--color-content-primary);
--result-description-font-size: var(--size-md-font-size);
--result-description-line-height: var(--font-line-height-md);
--result-description-fg: var(--color-content-muted);
--result-extra-font-size: var(--size-sm-font-size);
--result-extra-fg: var(--color-content-secondary);
--result-media-font-size: calc(var(--size-xl-font-size) * 3);
--result-media-fg: var(--color-content-muted);
--result-code-font-family: var(--font-family-mono);
--result-code-font-weight: var(--font-weight-semibold);
--result-code-letter-spacing: 0.04em;
--result-code-fg: var(--color-content-muted);
--result-description-measure: 45ch;
--result-extra-measure: 60ch;
--result-success-fg: var(--color-fulfill-solid);

@ -6424,6 +6424,31 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({
'actions-gap': 'var(--space-2)',
'actions-margin-block-start': 'var(--space-1)',
'extra-margin-block-start': 'var(--space-4)',
// ── The seam for type + ink (2026-08-22, firmado) ────────────────────
// The values are the canon's — size bundle, content slots, weight and
// leading scales — but the KNOB is the component's: PLAN §2-A. Five parts
// with distinct typography, so it is per PART (the catalogue's dominant
// shape) and not per role as in `chart`, whose two roles repeat over 19
// nodes. No named style plays "page terminal state", so nothing is bound
// wholesale to one.
'title-font-size': 'var(--size-xl-font-size)',
'title-font-weight': 'var(--font-weight-semibold)',
'title-line-height': 'var(--font-line-height-sm)',
'title-fg': 'var(--color-content-primary)',
'description-font-size': 'var(--size-md-font-size)',
'description-line-height': 'var(--font-line-height-md)',
'description-fg': 'var(--color-content-muted)',
'extra-font-size': 'var(--size-sm-font-size)',
'extra-fg': 'var(--color-content-secondary)',
// The status glyph: THREE times the xl step is its identity, and the
// multiplier stays in the value so the glyph keeps following the scale.
'media-font-size': 'calc(var(--size-xl-font-size) * 3)',
'media-fg': 'var(--color-content-muted)',
// The big HTTP code — neutral by design (AntD never paints 404 red).
'code-font-family': 'var(--font-family-mono)',
'code-font-weight': 'var(--font-weight-semibold)',
'code-letter-spacing': '0.04em',
'code-fg': 'var(--color-content-muted)',
'description-measure': '45ch',
'extra-measure': '60ch',
'success-fg': 'var(--color-fulfill-solid)',

Loading…
Cancel
Save

Powered by TurnKey Linux.