uix(date-range-field): temable — 29 % → 100 %, y una clave que giraba OTRA cosa

4 claves nuevas (3 → 7), una RENOMBRADA porque mentía y un literal anotado.
Centinela 7/7.

`row-gap` ALIMENTABA EL `column-gap`. La clave pública se llamaba `row-gap` y lo
que movía era el hueco ENTRE los dos campos y su separador; el hueco de fila de
verdad —etiqueta ↔ campos— leía `--space-1-5` a pelo. Ahora hay dos, cada una con
el nombre de lo que alimenta, y NINGÚN computado se mueve: la nueva `column-gap`
hereda el valor que tenía `row-gap` (`--space-3`) y `row-gap` recupera el suyo
(`--space-1-5`). Un nombre equivocado no es un detalle: es una perilla que gira
otra cosa.

La etiqueta se acuña aquí a propósito y CON FECHA DE CADUCIDAD. La receta ya lo
explica: la raíz del rango NO es un `[data-field]`, así que no puede heredar la
etiqueta de `field.css` —sus tokens viven en ese ámbito— y repetía los valores de
la fundación a pelo. Los mismos valores, ahora nombrados (`label-fg`,
`label-font-size` leyendo el bundle, `label-font-weight`). Cuando el mandato de
composición de Field (§5.3-3) convierta esa raíz en un campo, las tres
desaparecen y la etiqueta hereda: queda escrito en el contrato para que quien lo
ejecute las borre sin dudar.

Gates: sonda 0 diffs en 992 valores × 8 estados · centinela 7/7 · censo 100 % ·
`component:audit` PASS · suite eidos con el rojo conocido ajeno · `rtl:check` 0 ·
`docs:check` 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-background
dev 2 months ago
parent 694fcb99dc
commit 0e7dbf2d6f

@ -10,9 +10,9 @@
- **Medido**: 2026-08-23 · **162 recetas** con CSS + **8 componentes sin receta** = 170 fichas, el árbol entero de `eidos/components/`
- **La pregunta**: ¿cuánto de la apariencia de cada componente puede cambiar un tema **sin tocar el sistema ni la receta**?
- **Alcance global**: **64%** — 2980 de 4621 knobs pasan por un token público del componente
- **Reparto**: público 2980 · privado 321 · global 869 · literal 451 · sistema transversal 509 · excepción firmada 91 _(los dos últimos, fuera del ratio)_
- **Sin token público propio**: 24 · **alcance < 20 %**: 14 · **alcance 100 %**: 20 · **con eje `size`**: 58
- **Alcance global**: **65%** — 2984 de 4620 knobs pasan por un token público del componente
- **Reparto**: público 2984 · privado 321 · global 865 · literal 450 · sistema transversal 509 · excepción firmada 92 _(los dos últimos, fuera del ratio)_
- **Sin token público propio**: 24 · **alcance < 20 %**: 14 · **alcance 100 %**: 21 · **con eje `size`**: 58
## Cómo se lee
@ -125,7 +125,6 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
| [skin-media-player](./skin-media-player.md) | 22% | 11 | 2 | 0 | 1 | 6 | 2 | 10 | y |
| [palabras](./palabras.md) | 22% | 468 | 103 | 1 | 272 | 87 | 5 | 0 | – |
| [surface](./surface.md) | 25% | 4 | 1 | 3 | 0 | 0 | 0 | 25 | – |
| [date-range-field](./date-range-field.md) | 29% | 8 | 2 | 0 | 4 | 1 | 1 | 3 | – |
| [time-range-field](./time-range-field.md) | 29% | 8 | 2 | 0 | 4 | 1 | 1 | 3 | – |
| [scroll-frames](./scroll-frames.md) | 33% | 9 | 3 | 1 | 1 | 4 | 0 | 4 | – |
| [toggle-group](./toggle-group.md) | 33% | 3 | 1 | 0 | 1 | 1 | 0 | 1 | – |
@ -252,6 +251,7 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component
| [box](./box.md) | 100% | 9 | 9 | 0 | 0 | 0 | 0 | 43 | – |
| [label](./label.md) | 100% | 8 | 2 | 0 | 0 | 0 | 6 | 2 | – |
| [text-focus](./text-focus.md) | 100% | 8 | 8 | 0 | 0 | 0 | 0 | 8 | – |
| [date-range-field](./date-range-field.md) | 100% | 7 | 6 | 0 | 0 | 0 | 1 | 7 | – |
| [display](./display.md) | — | 6 | 0 | 0 | 0 | 0 | 6 | 0 | – |
| [text-circular](./text-circular.md) | 100% | 6 | 6 | 0 | 0 | 0 | 0 | 6 | – |
| [barcode](./barcode.md) | 100% | 5 | 5 | 0 | 0 | 0 | 0 | 7 | – |

@ -5,33 +5,26 @@
> Vista de conjunto: [README](./README.md) · método y protocolo:
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
- **Medido**: 2026-08-23 · **Alcance**: **29%** — 2 de 7 knobs por token público
- **Knobs de apariencia**: 8 — público 2 · privado 0 · global 4 · literal 1 · sistema 1 · excepción 1 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 3 pública(s) — `row-gap`, `separator-fg`, `separator-glyph`
- **Medido**: 2026-08-23 · **Alcance**: **100%** — 6 de 6 knobs por token público
- **Knobs de apariencia**: 7 — público 6 · privado 0 · global 0 · literal 0 · sistema 1 · excepción 2 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 7 pública(s) — `column-gap`, `row-gap`, `label-fg`, `label-font-size`, `label-font-weight`, `separator-fg`, `separator-glyph`
- **Eje `size`**: no · **ficheros**: `date-range-field.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (4)
### 1.1 Directo a primitivo global (0)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `date-range-field.css:22` | `[data-date-range-field]` | `row-gap` | `var(--space-1-5)` |
| 2 | `date-range-field.css:34` | `[data-date-range-field-label]` | `color` | `var(--color-content-primary)` |
| 3 | `date-range-field.css:35` | `[data-date-range-field-label]` | `font-size` | `var(--font-size-sm)` |
| 4 | `date-range-field.css:36` | `[data-date-range-field-label]` | `font-weight` | `var(--font-weight-regular)` |
_Ninguno._
### 1.2 A través de un privado (0)
_Ninguno._
### 1.3 Literales (1)
### 1.3 Literales (0)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `date-range-field.css:24` | `[data-date-range-field]` | `inline-size` | `100%` |
_Ninguno._
### 1.4 Excepciones firmadas (1) — fuera del ratio
### 1.4 Excepciones firmadas (2) — fuera del ratio
Literales que llevan su anotación `/* literal: <razón> */` en la propia
declaración: la válvula de recipe-contract §3, la misma que honra
@ -40,7 +33,8 @@ razón se lea, no para acuñarlas.
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `date-range-field.css:61` | `[data-date-range-field]:has( [data-date-range-field-input][data-endpoint='start'] ):has([data-date-range-field-input][data-endpoint='end'])::before` | `font-size` | `0.9em` |
| 1 | `date-range-field.css:24` | `[data-date-range-field]` | `inline-size` | `100%` |
| 2 | `date-range-field.css:61` | `[data-date-range-field]:has( [data-date-range-field-input][data-endpoint='start'] ):has([data-date-range-field-input][data-endpoint='end'])::before` | `font-size` | `0.9em` |
## 2. Sistema transversal (1) — informativo, fuera del ratio
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
@ -55,7 +49,7 @@ _La receta no declara privados propios en su CSS._
## 4. Propuesta de corrección
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (5)
### 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
@ -65,10 +59,6 @@ no distingue lo que debería — se marca `⚠`.
| token (`--date-range-field-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `row-gap` _(ya existe)_ | `root` | `var(--space-1-5)` | 1 |
| `label-fg` | `root` | `var(--color-content-primary)` | 1 |
| `label-font-size` | `root` | `var(--font-size-sm)` | 1 |
| `label-font-weight` | `root` | `var(--font-weight-regular)` | 1 |
| `input-font-size` | `root` | `0.9em` | 1 |
### 4.2 Sin nombre mecánico (1)
@ -87,6 +77,28 @@ no distingue lo que debería — se marca `⚠`.
<!-- veredicto:start -->
_(pendiente — lo escribe el autor; se conserva al regenerar)_
**EJECUTADO 2026-08-23 — 29 % → 100 %**, 4 claves nuevas (3 → 7), **una
RENOMBRADA porque mentía** y un literal anotado. Centinela 7/7.
**`row-gap` alimentaba el `column-gap`.** La clave pública se llamaba `row-gap`
y lo que movía era el hueco ENTRE los dos campos y su separador; el hueco de
fila de verdad —etiqueta ↔ campos— leía `--space-1-5` a pelo. Ahora hay dos, cada
una con el nombre de lo que alimenta, **y ningún computado se mueve**: la nueva
`column-gap` hereda el valor que tenía `row-gap` (`--space-3`) y la `row-gap`
recupera el suyo (`--space-1-5`). Un nombre equivocado no es un detalle: es una
perilla que gira otra cosa.
**La etiqueta se acuña aquí a propósito, y con fecha de caducidad.** La receta ya
lo explica: la raíz del rango **NO es un `[data-field]`**, así que no puede
heredar la etiqueta de `field.css` —sus tokens viven en ese ámbito— y repetía los
valores de la fundación a pelo. Los mismos valores, ahora nombrados (`label-fg`,
`label-font-size` leyendo el bundle, `label-font-weight`). **Cuando el mandato de
composición de Field (§5.3-3) convierta esa raíz en un campo, las tres
desaparecen** y la etiqueta hereda: queda escrito en el contrato para que quien
lo ejecute las borre sin dudar.
Verificación: **diff de computed = 0** sobre 992 valores en 8 estados ·
centinela **7/7** · censo 100 % · `component:audit` PASS · suite eidos con el
rojo conocido ajeno · `rtl:check` 0 · `docs:check` 0.
<!-- veredicto:end -->

@ -455,6 +455,19 @@ de commit. Sin artefacto, el paso no se ha hecho.
## 8. Registro
- 2026-08-23 — **`date-range-field` 29 % → 100 %** (4 claves, una RENOMBRADA
porque mentía). Centinela 7/7.
**`row-gap` alimentaba el `column-gap`**: la clave pública movía el hueco entre
los dos campos, y el de fila —etiqueta ↔ campos— leía `--space-1-5` a pelo.
Dos claves ahora, cada una con el nombre de lo que alimenta, y **ningún
computado se mueve**. Un nombre equivocado es una perilla que gira otra cosa.
**La etiqueta se acuña con fecha de caducidad**: la raíz del rango NO es un
`[data-field]` —lo dice la propia receta— así que no puede heredar la etiqueta
de field.css y repetía los valores de la fundación. Nombrados aquí, y escrito
en el contrato que el mandato §5.3-3 los borra cuando la raíz sea un campo.
- 2026-08-23 — **`surface` ADJUDICADO: el 25 % es su techo**, cero claves nuevas.
Es la cara de PINTURA de Box y lo que pinta no es suyo: `bg` y `fg` salen del
puente de paleta (THM-2) y el acabado es canal de valor del generador (§39).

@ -18,10 +18,10 @@
display: grid;
grid-template-columns: 1fr auto 1fr;
grid-template-rows: auto auto;
column-gap: var(--date-range-field-row-gap, var(--space-3));
row-gap: var(--space-1-5);
column-gap: var(--date-range-field-column-gap);
row-gap: var(--date-range-field-row-gap);
align-items: center;
inline-size: 100%;
inline-size: 100%; /* literal: the range fills its row — identity, not a knob */
min-inline-size: 0;
}
@ -31,9 +31,9 @@
[data-date-range-field-label] {
grid-column: 1 / -1;
grid-row: 1;
color: var(--color-content-primary);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-regular);
color: var(--date-range-field-label-fg);
font-size: var(--date-range-field-label-font-size);
font-weight: var(--date-range-field-label-font-weight);
}
[data-date-range-field-input] {

@ -4763,7 +4763,11 @@
--context-menu-heading-font-size: var(--size-xs-font-size);
--context-menu-separator-bg: var(--color-neutral-separator);
--context-menu-separator-margin-block: var(--space-1);
--date-range-field-row-gap: var(--space-3);
--date-range-field-column-gap: var(--space-3);
--date-range-field-row-gap: var(--space-1-5);
--date-range-field-label-fg: var(--color-content-primary);
--date-range-field-label-font-size: var(--size-sm-font-size);
--date-range-field-label-font-weight: var(--font-weight-regular);
--date-range-field-separator-fg: var(--color-content-muted);
--date-range-field-separator-glyph: '—';
--time-range-field-row-gap: var(--space-3);

@ -7988,7 +7988,18 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({
// DateRangeField — layout only; chrome inherits from date-field.
// ─────────────────────────────────────────────────────────────────────
'date-range-field': {
'row-gap': 'var(--space-3)',
// El hueco ENTRE los dos campos y su separador. La clave se llamaba
// `row-gap` y alimentaba el `column-gap`: nombre corregido, valor idéntico.
'column-gap': 'var(--space-3)',
// Y el de VERDAD: etiqueta ↔ fila de campos, que leía `--space-1-5` a pelo.
'row-gap': 'var(--space-1-5)',
// La raíz del rango NO es un `[data-field]`, así que no puede heredar la
// etiqueta de field.css (sus tokens de etiqueta viven en ese ámbito). Los
// mismos valores, nombrados aquí. Cuando el mandato de composición de Field
// (§5.3-3) convierta la raíz en un campo, estas tres desaparecen.
'label-fg': 'var(--color-content-primary)',
'label-font-size': 'var(--size-sm-font-size)',
'label-font-weight': 'var(--font-weight-regular)',
'separator-fg': 'var(--color-content-muted)',
'separator-glyph': "'—'"
},

Loading…
Cancel
Save

Powered by TurnKey Linux.