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.
svelte-kit-vice/docs/audit/theming/emoji-picker.md

8.8 KiB

emoji-picker — 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 · método y protocolo: PLAN-theming.md §1, §2, §7.

  • Medido: 2026-08-25 · Alcance: 100% — 22 de 22 knobs por token público
  • Knobs de apariencia: 26 — público 22 · privado 0 · global 0 · literal 0 · sistema 4 · excepción 3 · estructural 0 · puente 0 · canal 0 (los cinco últimos, fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 21 pública(s) — trigger-size, open-trigger-fg, panel-width, panel-gap, header-gap, grid-gap, grid-max-block-size, grid-padding-inline, grid-padding-block-end, option-radius, option-font-size, tone-marker-size, tone-marker-radius, tone-marker-bg, footer-gap, footer-border-fg, preview-gap, preview-glyph-size, preview-name-font-size, preview-name-fg, preview-min-block-size
  • Eje size: no · ficheros: emoji-picker.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (0)

Ninguno.

1.2 A través de un privado (0)

Ninguno.

1.3 Literales (0)

Ninguno.

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
1 emoji-picker.css:72 [data-emoji-picker-content] inline-size 100%
2 emoji-picker.css:119 [data-emoji-picker-content] [data-emoji-picker-option] line-height 1
3 emoji-picker.css:163 [data-emoji-picker-preview] > :first-child line-height 1

2. Sistema transversal (4) — 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 emoji-picker.css:46 [data-emoji-picker-trigger]:hover:not([data-disabled]) background-image linear-gradient(var(--state-hover), var(--state-hover))
2 emoji-picker.css:50 [data-emoji-picker-trigger]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
3 emoji-picker.css:56 [data-emoji-picker-trigger][data-state='open'] background-image linear-gradient(var(--state-hover), var(--state-hover))
4 emoji-picker.css:61 [data-emoji-picker-trigger][data-disabled] opacity var(--opacity-disabled)

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 Tokens a declarar en lib/recipes/base.ts (0)

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 al final) y theming §6.7 (slots de color, modificador delante). Un token con DOS valores distintos es una colisión de nombre: son dos knobs, o el nombre no distingue lo que debería — se marca ⚠.

token (--emoji-picker-…) scope TSC valor propuesto usos

4.2 Sin nombre mecánico (3)

  • ⚠ 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.
  • ⚠ 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 — 2: line-height.

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

EJECUTADO 2026-08-23 — 61 % → 100 %. Siete claves nuevas, tres retiradas por muertas, tres literales firmados y cinco adjudicaciones medidas. Contrato 17 → 21. Diff de computed 0 sobre 6.080 valores en 8 estados (176 nodos con el panel abierto), capturas 2× antes/después idénticas.

Las siete, con el nombre que dio el catálogo: open-trigger-fg (accordion lo nombra igual), grid-padding-inline + grid-padding-block-end (el eje lógico completo, como en card-group / combobox / command) y las tres del marcador de tono, la familia timeline.marker-{size,radius,bg}. Se llama tone-marker-* y no marker-* porque el pie lleva además un selector de TONO: marker a secas sería ambiguo dentro del propio componente.

TRES CLAVES RETIRADAS — el cromo de reposo del trigger no es suyo. El trigger lleva también data-popover-trigger, y [data-popover-trigger]:not([data-archetype='field-trigger']) es (0,2,0) contra el (0,1,0) de esta receta: el radio, la tinta y el tamaño de letra los pinta popover.css. Medido: mover --emoji-picker-trigger-{fg,radius,font-size} no cambiaba NADA. Retiradas con sus declaraciones, 0 diffs, que es la prueba de que estaban muertas. Es el defecto que gradient-picker documentó (36 de sus 45 tokens) y la misma respuesta. Sobreviven dos, y por razones distintas: trigger-size porque popover dimensiona con height y no con el par lógico, y open-trigger-fg porque su selector añade [data-state='open'] y gana por orden. trigger-fg no llegó a existir: se acuñó y se midió muerta en el mismo pase.

NOTA 2026-08-25 — la PREMISA de ese párrafo caducó; la retirada sigue siendo correcta. El sobre de trigger ya no es (0,2,0): la firma §55 «el sobre de trigger de popover es el SUELO» lo emite desde :where(...), (0,0,0), así que hoy PIERDE contra el (0,1,0) de esta receta. Las tres claves siguen retiradas y no hay defecto visual —la receta calla y el suelo pinta, que es su trabajo—, pero si volvieran ganarían: la razón por la que estaban muertas ya no es la que dice arriba. Se anota en vez de reescribirse porque la medida de entonces fue correcta con la cascada de entonces.

Cinco adjudicaciones, todas medidas forzando sobre nodos reales: las tres del marcador de tono (la demo monta cero celdas data-tone-capable; forzado el atributo sobre una celda real, el ::after alcanza — 4px → 37px, 9999px → 37px, y el fondo), preview-name-fg (los hijos de la vista previa son <span> desnudos, sin atributo del componente, así que quedan fuera del conjunto medido) y open-trigger-fg, que es el caso interesante.

⚠ open-trigger-fg OSCILA entre corridas: 17/21, 16/21, 16/21 con el mismo código. Medido vivo cuatro veces —la última replicando paso a paso el staticPass del propio guard, que movió a la primera talla—, así que el token no miente: lo que falla es el instrumento. La causa: el panel se cierra en algún punto de la pasada y, durante la animación de SALIDA, el content sigue en el DOM mientras el trigger ya perdió data-state='open' — que es lo que la regla selecciona; reopen() mira el CONTENT, cree que está abierto y no reabre. Probé un openMarker sobre el trigger y no basta (el clic de reapertura cae en esa misma ventana), así que lo retiré en vez de dejar un override que no arregla. El arreglo real es que reopen() espere a la CONDICIÓN en vez de dormir un número fijo — §13. Su entrada de ledger saldrá STALE en las corridas donde alcanza, y eso está escrito en la propia razón para que nadie la borre por ello.

Y el instrumento de captura estaba roto desde siempre: __shot.ts tenía el puerto 5173 cableado, así que cualquier sesión en otro puerto moría con ERR_EMPTY_RESPONSE. Es probablemente por lo que los pasos 6 y 13 del protocolo se saltaron en 33 componentes. Ahora toma la URL como argumento y un --open opcional para los componentes cuya superficie sólo existe abierta.

Verificación: sonda antes/después 0 diffs (6.080 valores · 8 estados) · R-5.4 17/21 con las cinco adjudicadas, exit 0 · component:audit PASS · censo 100 % · eidos-lint 17 morfo-backed / 0 invalid, 0 class-hooks · rtl:check 0 · docs:check 0 · capturas 2× antes y después, miradas.

Powered by TurnKey Linux.