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/time-picker.md

21 KiB

time-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-24 · Alcance: 18% — 10 de 57 knobs por token público
  • Knobs de apariencia: 59 — público 10 · privado 12 · global 24 · literal 11 · sistema 2 · excepción 0 (los dos últimos, fuera del ratio)
  • Contrato hoy (lib/recipes/base.ts): 16 pública(s) — accent-border, accent-track, accent-text, gap, clock-gap, clock-width, clock-fg, clock-font-family, clock-font-size, clock-line-height, clock-hand-hour, clock-hand-minute, clock-hand-second, clock-thumb-shadow, clock-thumb-ring, trigger-radius
  • Eje size: sí · ficheros: time-picker.css

1. Knobs fuera de alcance

1.1 Directo a primitivo global (24)

# fichero:línea selector propiedad valor
1 time-picker.css:19 [data-time-picker] color var(--field-control-fg) ⤴ prestado de field
2 time-picker.css:20 [data-time-picker] font-family var(--field-font-family) ⤴ prestado de field
3 time-picker.css:22 [data-time-picker] line-height var(--field-control-line-height) ⤴ prestado de field
4 time-picker.css:86 [data-time-picker-trigger] border var(--field-control-border-width) solid var(--field-control-border) ⤴ prestado de field
5 time-picker.css:87 [data-time-picker-trigger] border-radius var(--field-control-radius) ⤴ prestado de field
6 time-picker.css:88 [data-time-picker-trigger] background var(--field-control-bg) ⤴ prestado de field
7 time-picker.css:114 [data-time-picker-trigger][data-disabled], [data-time-picker-trigger]:disabled opacity var(--field-disabled-opacity) ⤴ prestado de field
8 time-picker.css:123 [data-time-field-input] [data-time-picker-trigger] inline-size var(--field-segment-height) ⤴ prestado de field
9 time-picker.css:124 [data-time-field-input] [data-time-picker-trigger] block-size var(--field-segment-height) ⤴ prestado de field
10 time-picker.css:130 [data-time-field-input] [data-time-picker-trigger] color var(--field-control-fg) ⤴ prestado de field
11 time-picker.css:144 [data-time-field-input] [data-time-picker-trigger]:focus-visible background var(--field-segment-active-bg) ⤴ prestado de field
12 time-picker.css:145 [data-time-field-input] [data-time-picker-trigger]:focus-visible color var(--field-segment-active-text) ⤴ prestado de field
13 time-picker.css:160 [data-time-picker-clock] padding var(--space-2-5)
14 time-picker.css:204 [data-time-picker-clock] [data-time-picker-day-period-toggle] [data-toggle-group-item][data-state='on']:hover background var(--toggle-palette-solid) ⤴ prestado de toggle
15 time-picker.css:205 [data-time-picker-clock] [data-time-picker-day-period-toggle] [data-toggle-group-item][data-state='on']:hover border-color var(--toggle-palette-solid) ⤴ prestado de toggle
16 time-picker.css:222 .time-picker-slider-label color var(--color-content-subtle)
17 time-picker.css:223 .time-picker-slider-label font-family var(--style-label-font-family)
18 time-picker.css:225 .time-picker-slider-label font-weight var(--font-weight-medium)
19 time-picker.css:226 .time-picker-slider-label letter-spacing var(--tracking-caps)
20 time-picker.css:237 .time-picker-scale padding-inline calc(var(--_slider-thumb-size, 1rem) / 2)
21 time-picker.css:249 .time-picker-scale-tick color var(--color-content-muted)
22 time-picker.css:250 .time-picker-scale-tick font-family var(--font-family-mono, var(--style-label-font-family))
23 time-picker.css:253 .time-picker-scale-tick font-size var(--font-size-xxs)
24 time-picker.css:262 .time-picker-scale-mark background var(--color-border-default)

1.2 A través de un privado (12)

# fichero:línea selector propiedad valor
1 time-picker.css:21 [data-time-picker] font-size var(--_time-picker-font-size)
2 time-picker.css:83 [data-time-picker-trigger] inline-size var(--_time-picker-height)
3 time-picker.css:84 [data-time-picker-trigger] block-size var(--_time-picker-height)
4 time-picker.css:99 [data-time-picker-trigger]:hover border-color var(--_time-picker-accent-border)
5 time-picker.css:100 [data-time-picker-trigger]:hover background var(--_time-picker-accent-track)
6 time-picker.css:101 [data-time-picker-trigger]:hover color var(--_time-picker-accent-text)
7 time-picker.css:105 [data-time-picker-trigger]:focus-visible border-color var(--_time-picker-accent-border)
8 time-picker.css:137 [data-time-field-input] [data-time-picker-trigger]:hover background var(--_time-picker-accent-track)
9 time-picker.css:138 [data-time-field-input] [data-time-picker-trigger]:hover color var(--_time-picker-accent-text)
10 time-picker.css:224 .time-picker-slider-label font-size var(--_time-picker-label-font, var(--font-size-xxs))
11 time-picker.css:308 [data-time-picker-clock] [data-slider-thumb] border-color var(--_time-picker-slider-accent, var(--_time-picker-accent-border))
12 time-picker.css:323 [data-time-picker-clock] [data-slider-range] background var(--_time-picker-slider-accent, var(--_time-picker-accent-border))

1.3 Literales (11)

# fichero:línea selector propiedad valor
1 time-picker.css:17 [data-time-picker] inline-size 100%
2 time-picker.css:185 [data-time-picker-clock] [data-slider] inline-size 100%
3 time-picker.css:213 .time-picker-slider gap 2px
4 time-picker.css:214 .time-picker-slider inline-size 100%
5 time-picker.css:227 .time-picker-slider-label line-height 1
6 time-picker.css:233 .time-picker-scale block-size 0.875rem
7 time-picker.css:234 .time-picker-scale inline-size 100%
8 time-picker.css:248 .time-picker-scale-tick gap 1px
9 time-picker.css:254 .time-picker-scale-tick line-height 1
10 time-picker.css:260 .time-picker-scale-mark inline-size 1px
11 time-picker.css:261 .time-picker-scale-mark block-size 4px

1.4 Excepciones firmadas (0) — 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.

Ninguno.

2. Sistema transversal (2) — 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 time-picker.css:107 [data-time-picker-trigger]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)
2 time-picker.css:318 [data-time-picker-clock] [data-slider-thumb]:focus-visible outline var(--focus-ring-width) solid var(--focus-ring-color)

3. Privados de la receta — ¿de dónde sale su valor?

privado declaraciones valor(es) origen ¿deriva de un público?
--_time-picker-height 4 var(--field-control-height-md), var(--field-control-height-xs), var(--field-control-height-sm), var(--field-control-height-lg) global no
--_time-picker-font-size 4 var(--field-control-font-size-md), var(--field-control-font-size-xs), var(--field-control-font-size-sm), var(--field-control-font-size-lg) global no
--_time-picker-accent-border 8 var(--time-picker-accent-border), var(--color-secondary-border), var(--color-neutral-border), var(--color-affirm-border), var(--color-fulfill-border), var(--color-risk-border) …(+2) global, public no
--_time-picker-accent-track 8 var(--time-picker-accent-track), var(--color-secondary-track), var(--color-neutral-track), var(--color-affirm-track), var(--color-fulfill-track), var(--color-risk-track) …(+2) global, public no
--_time-picker-accent-text 8 var(--time-picker-accent-text), var(--color-secondary-text), var(--color-neutral-text), var(--color-affirm-text), var(--color-fulfill-text), var(--color-risk-text) …(+2) global, public no
--_time-picker-label-font 4 var(--font-size-sm), var(--font-size-xxs), var(--font-size-xs), var(--font-size-md) global no
--_time-picker-slider-accent 3 var(--time-picker-clock-hand-hour), var(--time-picker-clock-hand-minute), var(--time-picker-clock-hand-second) public sí
--_time-picker-slider-track 3 var(--time-picker-accent-track), var(--color-secondary-track), var(--color-neutral-track) global, public no

4. Propuesta de corrección

  • Consume la capa compartida picker-shell. Un eje que la capa posee se consume como var(--_x, var(--x)); el consumidor no acuña --time-picker-{eje} para él — sería un vocabulario paralelo (README de eidos/components, «Capas compartidas» regla 2).
  • Consume tokens públicos de field, toggle. Un token prestado importa la semántica de su dueño: la corrección no es duplicarlo con prefijo propio, sino la decisión de familia que la auditoría de fase 1 dejó registrada (theming-audit.md §B, familia calendar).
  • Tiene eje size: los tokens dimensionales van por talla ({part}-{eje}-{k}) apuntando al bundle --size-{k}-*, nunca al primitivo crudo (theming §5; el guard recipe-css-contract prohíbe el primitivo).

4.1 Tokens a declarar en lib/recipes/base.ts (35)

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 (--time-picker-…) scope TSC valor propuesto usos
hover-trigger-bg root ⚠ var(--time-picker-accent-track) / var(--color-secondary-track) / var(--color-neutral-track) / var(--color-affirm-track) / var(--color-fulfill-track) / var(--color-risk-track) / var(--color-threat-track) / var(--color-loss-track) 16
hover-trigger-fg root ⚠ var(--time-picker-accent-text) / var(--color-secondary-text) / var(--color-neutral-text) / var(--color-affirm-text) / var(--color-fulfill-text) / var(--color-risk-text) / var(--color-threat-text) / var(--color-loss-text) 16
hover-trigger-border root ⚠ var(--time-picker-accent-border) / var(--color-secondary-border) / var(--color-neutral-border) / var(--color-affirm-border) / var(--color-fulfill-border) / var(--color-risk-border) / var(--color-threat-border) / var(--color-loss-border) 8
trigger-border root ⚠ var(--time-picker-accent-border) / var(--color-secondary-border) / var(--color-neutral-border) / var(--color-affirm-border) / var(--color-fulfill-border) / var(--color-risk-border) / var(--color-threat-border) / var(--color-loss-border) 8
fg root ⚠ var(--field-control-fg) / var(--color-content-subtle) / var(--color-content-muted) 3
font-family root ⚠ var(--field-font-family) / var(--style-label-font-family) / var(--font-family-mono, var(--style-label-font-family)) 3
font-size-md size:md ⚠ var(--field-control-font-size-md) / var(--font-size-sm) 2
font-size-xs size:xs ⚠ var(--field-control-font-size-xs) / var(--font-size-xxs) 2
font-size-sm size:sm ⚠ var(--field-control-font-size-sm) / var(--font-size-xs) 2
font-size-lg size:lg ⚠ var(--field-control-font-size-lg) / var(--font-size-md) 2
trigger-bg root ⚠ var(--field-control-bg) / var(--field-segment-active-bg) 2
trigger-fg root ⚠ var(--field-control-fg) / var(--field-segment-active-text) 2
gap (ya existe) root ⚠ 2px / 1px 2
height root ⚠ 0.875rem / 4px 2
line-height root var(--field-control-line-height) 1
trigger-width-md size:md var(--field-control-height-md) 1
trigger-width-xs size:xs var(--field-control-height-xs) 1
trigger-width-sm size:sm var(--field-control-height-sm) 1
trigger-width-lg size:lg var(--field-control-height-lg) 1
trigger-height-md size:md var(--field-control-height-md) 1
trigger-height-xs size:xs var(--field-control-height-xs) 1
trigger-height-sm size:sm var(--field-control-height-sm) 1
trigger-height-lg size:lg var(--field-control-height-lg) 1
trigger-radius (ya existe) root var(--field-control-radius) 1
disabled-trigger-opacity root var(--field-disabled-opacity) 1
trigger-width root var(--field-segment-height) 1
trigger-height root var(--field-segment-height) 1
hover-clock-bg host var(--toggle-palette-solid) 1
hover-clock-border host var(--toggle-palette-solid) 1
font-weight root var(--font-weight-medium) 1
letter-spacing root var(--tracking-caps) 1
padding-inline root calc(var(--_slider-thumb-size, 1rem) / 2) 1
font-size root var(--font-size-xxs) 1
width root 1px 1
bg root var(--color-border-default) 1

4.2 Sin nombre mecánico (10)

  • ⚠ 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 — 4: inline-size.
  • ⚠ decisión: border es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4) — 1: border.
  • ⚠ decisión: padding es shorthand o eje físico — hay que partirlo en ejes lógicos antes de nombrarlo (recipe-contract §1, R-4.4) — 1: padding.
  • ⚠ 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.
  • ya alcanzable: el privado --_time-picker-slider-accent deriva de un público (var(--time-picker-clock-hand-hour), var(--time-picker-clock-hand-minute), var(--time-picker-clock-hand-second)) — sin acción; el censo lo cuenta como no alcanzable por el límite del regex — 2: border-color, background.

4.3 Avisos sobre los tokens propuestos (7)

  • el privado --_time-picker-font-size debe pasar a leer este público (o desaparecer) — --time-picker-font-size-md, --time-picker-font-size-xs, --time-picker-font-size-sm, --time-picker-font-size-lg
  • el privado --_time-picker-height debe pasar a leer este público (o desaparecer) — --time-picker-trigger-width-md, --time-picker-trigger-width-xs, --time-picker-trigger-width-sm, --time-picker-trigger-width-lg, --time-picker-trigger-height-md, --time-picker-trigger-height-xs, --time-picker-trigger-height-sm, --time-picker-trigger-height-lg
  • el privado --_time-picker-accent-border debe pasar a leer este público (o desaparecer) — --time-picker-hover-trigger-border, --time-picker-trigger-border
  • el privado --_time-picker-accent-track debe pasar a leer este público (o desaparecer) — --time-picker-hover-trigger-bg
  • el privado --_time-picker-accent-text debe pasar a leer este público (o desaparecer) — --time-picker-hover-trigger-fg
  • el privado --_time-picker-label-font debe pasar a leer este público (o desaparecer) — --time-picker-font-size-md, --time-picker-font-size-xs, --time-picker-font-size-sm, --time-picker-font-size-lg
  • ⚠ decisión: el valor es una expresión — el token puede llevar la expresión entera o sólo su término variable — --time-picker-padding-inline

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

Revisión 2026-08-20 — verificación previa a implementación (Opus). Gemelo de time-range-picker — misma familia, mismos defectos; su ficha lleva el detalle y ésta las diferencias.

Análisis (§1–§3): CORRECTO en cifras (59 · 0 · 3 · 42 · 12 · 2), con el mismo hallazgo: los «ajenos» --_time-field-* los declara este CSS con prefijo equivocado (time-picker.css:8-12) — renombrar a --_time-picker-* (mecánico, git ls-files antes) es el paso previo a todo.

Propuesta (§4.1): NO APTA tal cual, por las mismas tres causas verificadas: colisiones por estado sin parsear (clock-bg/border mezclan manecillas y ticks primary/secondary/neutral; gap/height colapsan pistas y separadores), composición (Field + Slider + Toggle + picker-shell: lo que lee --field-*/--slider-* públicos se tema en la ficha del dueño; padding-inline: calc(var(--_slider-thumb-size,…)/2) consume un privado DE SLIDER → decisión del dueño), y hover-clock-bg/border = var(--toggle-palette-solid) con scope host inválido (paleta ajena ⇒ bloque composition: o nada). Diferencia con TRP: aquí el trigger además monta sobre --field-segment-height (la vía segmento), que refuerza el mandato field-composition de theming-audit.md §5.3-3.

Lo acuñable aquí: la cara del reloj (clock-gap/width/fg/font-*/shadow), los acentos accent-border/track/text promovidos a públicos (los privados renombrados los leen), y los font-size-{k} del HUD separados por parte (dos escalas conviven: campo y HUD xxs); patrón Sidebar (coordenadas root

  • resuelto host/size:{k}; el root estampa data-size ✓, el clock también la estampa — si el popup del clock viaja por portal, sus declarations por talla llevan parts: ['clock']). Los 12 literales: anotar o tokenizar uno a uno.

Bloqueos de firma: los mismos de TRP (field-composition · eje del thumb de slider · D-TH.4 orden B7).


EJECUTADO 2026-08-20 (parcial: lo que no depende de otra firma). Alcance 0 % → 18 % · contrato 0 → 15 claves públicas.

Hecho: renombrados los 44 privados con prefijo AJENO — declaraba --_time-field-* dentro de su propio CSS, que el censo contaba como global y que se cruzaría con un TimeField anidado — a --_time-picker-*; el acento pasa a público (accent-border / -track / -text); y a contrato la cara del reloj (clock-gap, clock-width, clock-fg, clock-font-*), las tres manecillas (clock-hand-{hour,minute,second}), el refuerzo del pulgar y el radio del trigger en línea.

No hecho, y por qué: la mitad con forma de campo sigue leyendo --field-* porque compone Field. La corrección de fondo es el mandato de composición de Field (theming-audit.md §5.3-3), que sigue sin ejecutar — así que ese 82 % no es deriva, es préstamo con dueño.

Verificación: diff de computed = 0 sobre 580 valores en 8 estados · component:audit PASS · suite eidos sin rojos nuevos · rtl:check 0 · docs:check 0.

El guard de huérfanos cazó 12 tokens que declaré de más: copié day-period-* y tick-* del range-picker, que este componente no tiene. Retirados, salvo trigger-radius, que sí tenía consumidor y se cableó.

Powered by TurnKey Linux.