From 3219a19c3c0799073d4a4d37dfa244d1ad53f596 Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 20 Aug 2026 20:41:05 +0200 Subject: [PATCH] fix(switch): el velo para el off, el swap de paleta para el checked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Firma 3, tercer componente, y el primero donde la regla servía DOS hovers a la vez: `--_switch-track-bg-hover` resolvía al color neutro cuando el switch está off y al `palette-solid-hover` cuando está checked. recipe-contract §2 los separa —el neutro es la capa del sistema, el con valencia es el swap de la receta— así que la regla se parte en dos: `[data-switch]:hover` sólo el borde; el fondo lo pone el velo de archetypes.css `[data-switch][data-state=checked]:hover` `background-color: var(--_switch-palette-solid-hover)` Y la regla base pasa a `background-color:` por lo mismo de siempre: el atajo fijaba `background-image: none` y ganaba al `:where()` del sistema. Medido (377 valores, 7 estados): 2 diffs, los dos en el hover del track off — el velo aparece y el fondo vuelve a su base. Verificado además en el navegador que las DOS reglas viven y que el swap del checked sigue en pie. `track-bg-off-hover` sale del contrato, y con él el privado que lo reenviaba. censo switch 57 % · audit PASS · suite 434 (1 rojo conocido) Nota de método: borrar la clave por línea partió una declaración multilínea (clave y valor en líneas distintas) y dejó el valor huérfano — esbuild lo cazó al regenerar. Un rename en sitio es seguro; un borrado necesita mirar si el valor va debajo. Co-Authored-By: Claude Opus 5 --- src/uix/eidos/components/switch/switch.css | 16 ++++++++++++---- src/uix/eidos/generated/base.css | 2 -- src/uix/eidos/lib/recipes/base.ts | 3 --- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/uix/eidos/components/switch/switch.css b/src/uix/eidos/components/switch/switch.css index a30573e67..39b7e0b27 100644 --- a/src/uix/eidos/components/switch/switch.css +++ b/src/uix/eidos/components/switch/switch.css @@ -8,7 +8,6 @@ * Per-color cascade is config-owned via `declarations[]`. */ --_switch-track-bg: var(--switch-track-bg-off); --_switch-track-border: var(--switch-track-border-off); - --_switch-track-bg-hover: var(--switch-track-bg-off-hover); --_switch-track-border-hover: var(--switch-hover-track-border-off); --_switch-thumb-offset: 0px; @@ -21,7 +20,10 @@ padding: 0; border: var(--switch-track-border-width) solid var(--_switch-track-border); border-radius: var(--switch-track-radius); - background: var(--_switch-track-bg); + /* LONGHAND: `background:` resets `background-image`, and this rule (0,1,0) + * outweighs the `:where()` (0,0,0) of `archetypes.css` — the state-layer + * veil would never paint on the track. */ + background-color: var(--_switch-track-bg); box-shadow: none; cursor: pointer; outline: none; @@ -60,15 +62,21 @@ --_switch-thumb-translate: var(--switch-size-xl-thumb-translate); } +/* Two hovers live here, and recipe-contract §2 splits them: the OFF track is + * NEUTRAL feedback, so it is the system's veil (§38) and the recipe declares + * nothing; the CHECKED track is a VALENCED hover, so it is the palette swap + * and stays. The border follows the private in both states. */ [data-switch]:hover:not([data-disabled]):not([data-readonly]) { - background: var(--_switch-track-bg-hover); border-color: var(--_switch-track-border-hover); } +[data-switch][data-state='checked']:hover:not([data-disabled]):not([data-readonly]) { + background-color: var(--_switch-palette-solid-hover); +} + [data-switch][data-state='checked'] { --_switch-track-bg: var(--_switch-palette-solid); --_switch-track-border: var(--_switch-palette-solid); - --_switch-track-bg-hover: var(--_switch-palette-solid-hover); --_switch-track-border-hover: var(--_switch-palette-solid-hover); --_switch-thumb-offset: var(--_switch-thumb-translate); } diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css index 9d602c938..1a717ff02 100644 --- a/src/uix/eidos/generated/base.css +++ b/src/uix/eidos/generated/base.css @@ -3061,7 +3061,6 @@ --switch-transition-duration: var(--duration-fast); --switch-transition-ease: var(--ease-default); --switch-track-bg-off: var(--color-surface-overlay); - --switch-track-bg-off-hover: color-mix( in srgb, var(--color-surface-overlay) 82%, var(--color-surface-raised) ); --switch-track-border-off: var(--color-border-default); --switch-hover-track-border-off: var(--color-border-strong); --switch-disabled-track-bg: color-mix( in srgb, var(--color-surface-overlay) 70%, var(--color-surface-default) ); @@ -3634,7 +3633,6 @@ --splitter-panel-bg: transparent; --splitter-handle-size: var(--space-2); --splitter-handle-bg: var(--color-border-subtle); - --splitter-handle-bg-hover: var(--color-border-default); --splitter-active-handle-bg: var(--color-primary-solid); --splitter-grip-radius: var(--radius-full); --splitter-grip-bg: var(--color-content-muted); diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts index 9d5ad4ddb..7c9e3602c 100644 --- a/src/uix/eidos/lib/recipes/base.ts +++ b/src/uix/eidos/lib/recipes/base.ts @@ -4299,8 +4299,6 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({ 'transition-duration': 'var(--duration-fast)', 'transition-ease': 'var(--ease-default)', 'track-bg-off': 'var(--color-surface-overlay)', - 'track-bg-off-hover': - 'color-mix( in srgb, var(--color-surface-overlay) 82%, var(--color-surface-raised) )', 'track-border-off': 'var(--color-border-default)', 'hover-track-border-off': 'var(--color-border-strong)', 'disabled-track-bg': @@ -5399,7 +5397,6 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({ 'panel-bg': 'transparent', 'handle-size': 'var(--space-2)', 'handle-bg': 'var(--color-border-subtle)', - 'handle-bg-hover': 'var(--color-border-default)', 'active-handle-bg': 'var(--color-primary-solid)', 'grip-radius': 'var(--radius-full)', 'grip-bg': 'var(--color-content-muted)',