You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
8.0 KiB
140 lines
8.0 KiB
# chat-log — alcance de tema: análisis y propuesta
|
|
|
|
> Generado por `node --import tsx/esm scripts/theming-census.ts --report`.
|
|
> Lo **medido** y la **propuesta** se regeneran; el **Veredicto** (§5) se conserva.
|
|
> Vista de conjunto: [README](./README.md) · método y protocolo:
|
|
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
|
|
|
|
- **Medido**: 2026-08-23 (tras el commit) · **Alcance**: **100%** — 34 de 34 knobs por token público
|
|
- **Knobs de apariencia**: 37 — público 34 · privado 0 · global 0 · literal 0 · sistema 3 · excepción 3 _(los dos últimos, fuera del ratio)_
|
|
- **Contrato hoy** (`lib/recipes/base.ts`): 35 pública(s) — `bg`, `padding-inline`, `padding-block`, `separator-gap`, `separator-font-size`, `separator-fg`, `separator-bg`, `separator-padding-inline`, `separator-padding-block`, `separator-radius`, `divider-fg`, `divider-line`, `divider-font-size`, `divider-gap`, `divider-padding-block`, `event-font-size`, `event-fg`, `event-padding-block`, `event-radius`, `pill-bg`, `pill-fg`, `pill-font-size`, `pill-padding-inline`, `pill-height`, `pill-radius`, `pill-shadow`, `pill-offset`, `pill-gap`, `to-latest-size`, `to-latest-bg`, `to-latest-fg`, `to-latest-border`, `to-latest-shadow`, `to-latest-offset`, `to-latest-radius`
|
|
- **Eje `size`**: no · **ficheros**: `chat-log.css`
|
|
|
|
## 1. Knobs fuera de alcance
|
|
|
|
### 1.1 Directo a primitivo global (0)
|
|
|
|
_Ninguno_ — los cuatro que había (el `padding-block` del divisor, el radio de
|
|
foco de la fila de evento, el `gap` de la pill y el radio del to-latest) están
|
|
cosidos: la clave es del componente, el valor sigue siendo el del sistema.
|
|
|
|
### 1.2 A través de un privado (0)
|
|
|
|
_Ninguno._
|
|
|
|
### 1.3 Literales (0)
|
|
|
|
_Ninguno sin firmar._
|
|
|
|
### 1.4 Excepciones firmadas (3) — 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
|
|
`component-audit`. **Una desviación firmada no es deuda** — se listan para que la
|
|
razón se lea, no para acuñarlas.
|
|
|
|
| # | fichero:línea | selector | propiedad | valor | razón |
|
|
| ---: | --- | --- | --- | --- | --- |
|
|
| 1 | `chat-log.css:10` | `[data-chat-log]` | `block-size` | `100%` | el log ocupa la caja que la app le da — identidad |
|
|
| 2 | `chat-log.css:18` | `[data-chat-log] [data-virtual-list-viewport]` | `block-size` | `100%` | el viewport ocupa el log — identidad |
|
|
| 3 | `chat-log.css:119` | `[data-chat-log-pill-new]` | `inline-size` | `fit-content` | la pill la dimensiona su contenido — identidad |
|
|
|
|
**Y dos declaraciones RETIRADAS por muertas** (no son excepción: dejaron de
|
|
existir): `[data-chat-log-to-latest] svg { block-size: 1em; inline-size: 1em }`.
|
|
El `Icon` compuesto escribe `style="width: var(--icon-size-sm)"` EN LÍNEA y
|
|
ningún selector gana a un estilo en línea — el glifo medía 16 px, nunca los
|
|
14 px que la regla creía pintar. Retirarla da **0 diffs**.
|
|
|
|
## 2. Sistema transversal (3) — informativo, fuera del ratio
|
|
|
|
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
|
|
|
|
| # | fichero:línea | selector | propiedad | valor |
|
|
| ---: | --- | --- | --- | --- |
|
|
| 1 | `chat-log.css:92` | `[data-chat-log-event]:focus-visible` | `outline` | `var(--focus-ring-width) solid var(--focus-ring-color)` |
|
|
| 2 | `chat-log.css:158` | `[data-chat-log-pill-new]:hover, [data-chat-log-to-latest]:hover` | `background-image` | `linear-gradient(var(--state-hover), var(--state-hover))` |
|
|
| 3 | `chat-log.css:163` | `[data-chat-log-pill-new]:focus-visible, [data-chat-log-to-latest]:focus-visible` | `outline` | `var(--focus-ring-width) solid var(--focus-ring-color)` |
|
|
|
|
## 3. Privados de la receta — ¿de dónde sale su valor?
|
|
|
|
_La receta no declara privados propios en su CSS._
|
|
|
|
## 4. Propuesta de corrección
|
|
|
|
### 4.1 EJECUTADA (2026-08-23) — 4 claves acuñadas, 2 declaraciones retiradas
|
|
|
|
La propuesta generada pedía 7 claves. Entraron **4**, con los nombres del
|
|
CATÁLOGO y no los del generador:
|
|
|
|
| propuesto | acuñado | por qué |
|
|
| --- | --- | --- |
|
|
| `divider-unread-padding-block` | **`divider-padding-block`** | la familia del contrato ya dice `divider-fg` / `-line` / `-font-size` / `-gap`; el generador nombra por el atributo de la parte, el catálogo por el grupo |
|
|
| `event-radius` | **`event-radius`** | correcto |
|
|
| `pill-new-gap` | **`pill-gap`** | misma razón: la familia es `pill-*` |
|
|
| `to-latest-radius` | **`to-latest-radius`** | correcto |
|
|
| `pill-new-width` (`fit-content`) | — | identidad: la pill la dimensiona su contenido; firmada `literal:` |
|
|
| `to-latest-height` / `-width` (`1em`) | — | la regla estaba MUERTA (el `Icon` compuesto escribe su tamaño en línea): retirada |
|
|
|
|
### 4.2 Sin nombre mecánico (2)
|
|
|
|
- Los dos `block-size: 100%` son identidad (§1.4), firmados con su anotación.
|
|
|
|
### 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.
|
|
- [ ] **Velo o acento en el nodo equivocado** (`archetype: 'item'` en un envoltorio, un `background` en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
|
|
- [ ] **Doble animación** al mover un sello a una superficie con animación propia — registro de `animationstart`/`animationend`.
|
|
- [ ] **Diff de computed = 0** en reposo · hover · abierto · disabled · foco, por talla, antes y después.
|
|
- [ ] **Centinela por token nuevo**: valor imposible en el root → el nodo lo sigue. Si no, el token miente.
|
|
|
|
## 5. Veredicto
|
|
|
|
<!-- veredicto:start -->
|
|
|
|
**EJECUTADO 2026-08-23 — 77 % → 100 %.** Contrato 31 → **35** claves; censo
|
|
`público 34 · global 0 · literal 0 · sistema 3 · excepción 3`. Diff de computed
|
|
**VACÍO** (1.920 valores, 7 estados, 9 nodos). Centinela **34/35**, una
|
|
adjudicada. `component-audit` PASS · `eidos-lint` 0 invalid · `rtl:check` 0 ·
|
|
`docs:check` 0 · `check` sin errores del componente.
|
|
|
|
**Lo caro no fue acuñar: fue VER.** El centinela daba 15/31 antes de tocar una
|
|
línea, y las 16 «muertas» estaban las 16 VIVAS. Tres cegueras, ninguna del
|
|
código:
|
|
|
|
1. **El viewport que scrollea es del componente COMPUESTO.** El log pinta su
|
|
`padding-inline` / `padding-block` sobre `[data-virtual-list-viewport]`, un
|
|
nodo sin un solo `data-chat-log-*`: fuera del filtro de sonda y guard. Es la
|
|
cuarta forma del mismo punto ciego (prose, navigation-menu, waveform).
|
|
2. **Tres de las seis partes no las montaba la demo** — separador de día y
|
|
divisor de no-leídos no existían en el escenario, y la fila de evento vivía
|
|
en el índice 0 de una lista virtualizada anclada al FINAL, o sea fuera de la
|
|
ventana. Once claves sin nodo que pintar. La demo las monta ya, cerca del
|
|
final (instrumento, §3.bis del CONTINUE).
|
|
3. **La pastilla del separador es un `> span` sin atributo** — seis claves más
|
|
sin nodo.
|
|
|
|
Con las tres arregladas: **31/31 antes de tocar el código**. La lección es la
|
|
de siempre con un número pequeño: 9 nodos son pocos para seis partes; contarlos
|
|
es lo que destapó las tres.
|
|
|
|
**El hallazgo real: una regla que no ha pintado nunca.**
|
|
`[data-chat-log-to-latest] svg { block-size: 1em; inline-size: 1em }` no puede
|
|
ganar: el `Icon` compuesto emite `style="width: var(--icon-size-sm); height: …"`
|
|
INLINE, y un estilo en línea gana a todo selector. El glifo mide 16 px (paso
|
|
`sm` del icono), no los 14 px que `1em` daría sobre la fuente heredada del
|
|
botón. **Retirada, 0 diffs** — que es la prueba de que estaba muerta. Es la
|
|
clase `carousel.item-gap` / `drag-drop.preview-z`, pero con el estilo en línea
|
|
puesto por un COMPONENTE COMPUESTO, no por soma: lo que otro componente escribe
|
|
inline tampoco es tema.
|
|
|
|
**Adjudicada (1)**: `event-radius` — sólo pinta bajo `:focus-visible` y el
|
|
guard hace blur tras abrir. Medido enfocando con teclado la fila REAL con
|
|
`transition` congelada: 0 px en reposo, 4 px enfocada, **1234 px** con el
|
|
centinela.
|
|
|
|
**Lo que queda fuera y por qué**: tres identidades firmadas (§1.4) y tres knobs
|
|
de sistema transversal (§2). No hay deuda: el componente está CERRADO en su
|
|
número.
|
|
|
|
<!-- veredicto:end -->
|