From b4510fbf8235f2b6dae114bc16fe51c4ff0584c0 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 22 Aug 2026 22:55:49 +0200 Subject: [PATCH] =?UTF-8?q?uix(float-panel):=20temable=20=E2=80=94=2059=20?= =?UTF-8?q?%=20=E2=86=92=2084=20%,=20muere=20un=20fantasma=20y=20queda=20u?= =?UTF-8?q?na=20anomal=C3=ADa=20registrada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 12 claves (28 → 40). Censo float-panel 59 % → **84 %** con `global` a CERO. Cosido: las dos VARIANTES que ajustan desde el default elevado (`outline-*`, `ghost-*`), los botones de su barra (`action-*`, `hover-action-*`) y el asa de redimensionado. MUERE UNO DE LOS NUEVE FANTASMAS DEL BARRIDO de esta mañana: el asa leía `var(--color-content-tertiary, var(--color-content-secondary))` y ese primitivo NO EXISTE, así que pintaba el respaldo. El contrato guarda lo que de verdad pintaba, con lo que la referencia muerta desaparece sin mover un píxel. ONCE ADJUDICACIONES MEDIDAS: la demo monta la variante por DEFECTO —ni outline ni ghost— y no tiene botón de acción genérico, sólo el control de cierre; se forzó el atributo de variante y se montó el botón donde el CSS lo selecciona, y el radio del asa sólo pinta bajo `:focus-visible`. Las once alcanzan. Y UNA ANOMALÍA REGISTRADA EN VEZ DE ESCONDIDA: `resize-grip-fg` **mueve** bajo una réplica a mano de la secuencia del propio guard —congelar transiciones, blur, aparcar el ratón, escribir en `:root` y en cada nodo con el prefijo, fotografiar los mismos props con `::before`/`::after`/`::placeholder`— (oklch(0.5032 0 0) → rgb(1,2,3)), y aun así el guard lo da por muerto. Descartado que el nodo no lleve el atributo (lo lleva), que la regla necesite un estado (es la regla base), que sea el valor centinela (es el mismo) y que sea HMR (dos corridas). Queda adjudicado CON la medición y marcado como anomalía en §13: el token está vivo, lo que está en duda es la lectura. Es por donde debe empezar la revisión adversarial de este bloque — el precedente de F2-A dice que estos casos sí tienen causa. Lo rojo que queda son 12 tokens anteriores, y seis de ellos —`bg`, `border`, `border-width`, `shadow`, `font-family`, `line-height`— son el mismo conjunto que en `popover`: el PLANO de profundidad gana sobre el panel (§12.9, pendiente de firma). Gates: sonda antes/después **0 diffs en 1.890 valores** (9 nodos × 7 estados) · censo --only 84 % · `--names` sin desviadas · component-audit PASS · eidos-lint 0 invalid · suite eidos con el único rojo conocido · rtl:check 0 · docs:check 0 · captura mirada (cabecera, botón de cierre y asa de la esquina en su sitio). Co-Authored-By: Claude Opus 5 --- docs/audit/theming/README.md | 24 +++---- docs/audit/theming/float-panel.md | 69 ++++++++++--------- docs/next-features.md | 13 ++++ docs/process/PLAN-theming.md | 21 ++++++ scripts/theming-sentinel-exceptions.ts | 22 ++++++ .../components/float-panel/float-panel.css | 24 +++---- src/uix/eidos/generated/base.css | 12 ++++ src/uix/eidos/lib/recipes/base.ts | 16 +++++ 8 files changed, 145 insertions(+), 56 deletions(-) diff --git a/docs/audit/theming/README.md b/docs/audit/theming/README.md index b18253cac..c9167bb5f 100644 --- a/docs/audit/theming/README.md +++ b/docs/audit/theming/README.md @@ -10,8 +10,8 @@ - **Medido**: 2026-08-22 · **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**: **61%** — 2843 de 4628 knobs pasan por un token público del componente -- **Reparto**: público 2843 · privado 339 · global 951 · literal 495 · sistema transversal 509 · excepción firmada 54 _(los dos últimos, fuera del ratio)_ +- **Alcance global**: **62%** — 2855 de 4628 knobs pasan por un token público del componente +- **Reparto**: público 2855 · privado 339 · global 939 · literal 495 · sistema transversal 509 · excepción firmada 54 _(los dos últimos, fuera del ratio)_ - **Sin token público propio**: 24 · **alcance < 20 %**: 15 · **alcance 100 %**: 17 · **con eje `size`**: 58 ## Cómo se lee @@ -84,15 +84,15 @@ theming §6.7 lo pone delante (`hover-bg`). Las fichas proponen la forma | 9 | [natural-time-picker](./natural-time-picker.md) | 25 | 67% | 77 | 62 | | 10 | [menubar](./menubar.md) | 22 | 15% | 27 | 5 | | 11 | [color-picker](./color-picker.md) | 20 | 75% | 82 | 71 | -| 12 | [float-panel](./float-panel.md) | 20 | 59% | 53 | 28 | -| 13 | [password-field](./password-field.md) | 20 | 41% | 35 | 23 | -| 14 | [navigation-menu](./navigation-menu.md) | 19 | 44% | 38 | 26 | -| 15 | [sidebar](./sidebar.md) | 19 | 55% | 45 | 50 | -| 16 | [field](./field.md) | 18 | 73% | 72 | 60 | -| 17 | [mockup](./mockup.md) | 18 | 38% | 29 | 0 | -| 18 | [drawer](./drawer.md) | 17 | 72% | 62 | 54 | -| 19 | [onion-menu](./onion-menu.md) | 17 | 29% | 27 | 12 | -| 20 | [radio-group](./radio-group.md) | 17 | 77% | 75 | 61 | +| 12 | [password-field](./password-field.md) | 20 | 41% | 35 | 23 | +| 13 | [navigation-menu](./navigation-menu.md) | 19 | 44% | 38 | 26 | +| 14 | [sidebar](./sidebar.md) | 19 | 55% | 45 | 50 | +| 15 | [field](./field.md) | 18 | 73% | 72 | 60 | +| 16 | [mockup](./mockup.md) | 18 | 38% | 29 | 0 | +| 17 | [drawer](./drawer.md) | 17 | 72% | 62 | 54 | +| 18 | [onion-menu](./onion-menu.md) | 17 | 29% | 27 | 12 | +| 19 | [radio-group](./radio-group.md) | 17 | 77% | 75 | 61 | +| 20 | [popover](./popover.md) | 16 | 67% | 51 | 46 | ## Sin ningún token público propio (24) @@ -157,7 +157,6 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component | [dropdown-menu](./dropdown-menu.md) | 57% | 30 | 16 | 0 | 9 | 3 | 2 | 19 | – | | [s-text-virtual-list](./s-text-virtual-list.md) | 58% | 12 | 7 | 0 | 3 | 2 | 0 | 9 | – | | [badge](./badge.md) | 59% | 22 | 13 | 6 | 1 | 2 | 0 | 65 | y | -| [float-panel](./float-panel.md) | 59% | 53 | 29 | 3 | 12 | 5 | 4 | 28 | – | | [checkbox](./checkbox.md) | 59% | 33 | 19 | 8 | 2 | 3 | 1 | 44 | y | | [image](./image.md) | 60% | 35 | 21 | 1 | 1 | 12 | 0 | 22 | y | | [cropper](./cropper.md) | 60% | 27 | 15 | 0 | 3 | 7 | 2 | 15 | – | @@ -207,6 +206,7 @@ La columna «contrato» cuenta las claves **públicas** del bloque del component | [toggle](./toggle.md) | 81% | 28 | 22 | 1 | 1 | 3 | 1 | 119 | y | | [prose](./prose.md) | 83% | 53 | 44 | 0 | 0 | 9 | 0 | 37 | y | | [select](./select.md) | 83% | 72 | 54 | 5 | 3 | 3 | 7 | 101 | y | +| [float-panel](./float-panel.md) | 84% | 53 | 41 | 3 | 0 | 5 | 4 | 40 | – | | [calendar](./calendar.md) | 84% | 71 | 57 | 7 | 0 | 4 | 3 | 74 | – | | [chat-message](./chat-message.md) | 84% | 84 | 65 | 0 | 6 | 6 | 7 | 75 | y | | [grid-list](./grid-list.md) | 85% | 31 | 22 | 2 | 1 | 1 | 5 | 38 | – | diff --git a/docs/audit/theming/float-panel.md b/docs/audit/theming/float-panel.md index b759c4616..5388cdd96 100644 --- a/docs/audit/theming/float-panel.md +++ b/docs/audit/theming/float-panel.md @@ -5,29 +5,16 @@ > Vista de conjunto: [README](./README.md) · método y protocolo: > [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7. -- **Medido**: 2026-08-22 · **Alcance**: **59%** — 29 de 49 knobs por token público -- **Knobs de apariencia**: 53 — público 29 · privado 3 · global 12 · literal 5 · sistema 4 · excepción 0 _(los dos últimos, fuera del ratio)_ -- **Contrato hoy** (`lib/recipes/base.ts`): 28 pública(s) — `bg`, `border`, `border-width`, `radius`, `shadow`, `shadow-topmost`, `active-shadow`, `fg`, `font-family`, `font-size`, `line-height`, `header-bg`, `header-padding-inline`, `header-padding-block`, `header-gap`, `controls-gap`, `title-font-size`, `title-font-weight`, `title-fg`, `body-padding-inline`, `body-padding-block`, `resize-size`, `resize-edge`, `button-size`, `grip-size`, `accent`, `transition-duration`, `transition-ease` · 1 privada(s) forward — `_palette-border` +- **Medido**: 2026-08-22 · **Alcance**: **84%** — 41 de 49 knobs por token público +- **Knobs de apariencia**: 53 — público 41 · privado 3 · global 0 · literal 5 · sistema 4 · excepción 0 _(los dos últimos, fuera del ratio)_ +- **Contrato hoy** (`lib/recipes/base.ts`): 40 pública(s) — `outline-bg`, `outline-border`, `ghost-bg`, `ghost-border`, `ghost-shadow`, `action-radius`, `action-fg`, `action-font-size`, `hover-action-bg`, `hover-action-fg`, `resize-grip-fg`, `resize-grip-radius`, `bg`, `border`, `border-width`, `radius`, `shadow`, `shadow-topmost`, `active-shadow`, `fg`, `font-family`, `font-size`, `line-height`, `header-bg`, `header-padding-inline`, `header-padding-block`, `header-gap`, `controls-gap`, `title-font-size`, `title-font-weight`, `title-fg`, `body-padding-inline`, `body-padding-block`, `resize-size`, `resize-edge`, `button-size`, `grip-size`, `accent`, `transition-duration`, `transition-ease` · 1 privada(s) forward — `_palette-border` - **Eje `size`**: no · **ficheros**: `float-panel.css` ## 1. Knobs fuera de alcance -### 1.1 Directo a primitivo global (12) +### 1.1 Directo a primitivo global (0) -| # | fichero:línea | selector | propiedad | valor | -| ---: | --- | --- | --- | --- | -| 1 | `float-panel.css:76` | `[data-float-panel-content][data-variant='outline']` | `background` | `var(--color-surface-default)` | -| 2 | `float-panel.css:77` | `[data-float-panel-content][data-variant='outline']` | `border-color` | `var(--color-border-strong)` | -| 3 | `float-panel.css:81` | `[data-float-panel-content][data-variant='ghost']` | `background` | `var(--color-surface-default)` | -| 4 | `float-panel.css:82` | `[data-float-panel-content][data-variant='ghost']` | `border-color` | `var(--color-border-subtle)` | -| 5 | `float-panel.css:83` | `[data-float-panel-content][data-variant='ghost']` | `box-shadow` | `var(--shadow-2)` | -| 6 | `float-panel.css:169` | `[data-float-panel-action], [data-float-panel-stage-trigger]` | `border-radius` | `var(--radius-sm)` | -| 7 | `float-panel.css:171` | `[data-float-panel-action], [data-float-panel-stage-trigger]` | `color` | `var(--color-content-secondary)` | -| 8 | `float-panel.css:172` | `[data-float-panel-action], [data-float-panel-stage-trigger]` | `font-size` | `var(--font-size-md)` | -| 9 | `float-panel.css:178` | `[data-float-panel-action]:hover, [data-float-panel-stage-trigger]:hover` | `background` | `var(--color-surface-muted)` | -| 10 | `float-panel.css:179` | `[data-float-panel-action]:hover, [data-float-panel-stage-trigger]:hover` | `color` | `var(--color-content-primary)` | -| 11 | `float-panel.css:227` | `[data-float-panel-resize-grip]` | `color` | `var(--color-content-tertiary, var(--color-content-secondary))` | -| 12 | `float-panel.css:262` | `[data-float-panel-resize-grip]:focus-visible` | `border-radius` | `var(--radius-sm)` | +_Ninguno._ ### 1.2 A través de un privado (3) @@ -76,7 +63,7 @@ Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inl ## 4. Propuesta de corrección -### 4.1 Tokens a declarar en `lib/recipes/base.ts` (15) +### 4.1 Tokens a declarar en `lib/recipes/base.ts` (3) 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 @@ -89,18 +76,6 @@ no distingue lo que debería — se marca `⚠`. | `action-shadow` | `root` | ⚠ `var(--float-panel-accent)` / `var(--_float-panel-palette-border)` | 2 | | `resize-grip-bg-image` | `root` | ⚠ `repeating-linear-gradient( -45deg, transparent 0 3px, currentColor 3px 4.5px )` / `repeating-linear-gradient(45deg, transparent 0 3px, currentColor 3px 4.5px)` | 2 | | `hover-resize-grip-fg` | `root` | ⚠ `var(--float-panel-accent)` / `var(--_float-panel-palette-border)` | 2 | -| `outline-content-bg` | `root` | `var(--color-surface-default)` | 1 | -| `outline-content-border` | `root` | `var(--color-border-strong)` | 1 | -| `ghost-content-bg` | `root` | `var(--color-surface-default)` | 1 | -| `ghost-content-border` | `root` | `var(--color-border-subtle)` | 1 | -| `ghost-content-shadow` | `root` | `var(--shadow-2)` | 1 | -| `action-radius` | `root` | `var(--radius-sm)` | 1 | -| `action-fg` | `root` | `var(--color-content-secondary)` | 1 | -| `action-font-size` | `root` | `var(--font-size-md)` | 1 | -| `hover-action-bg` | `root` | `var(--color-surface-muted)` | 1 | -| `hover-action-fg` | `root` | `var(--color-content-primary)` | 1 | -| `resize-grip-fg` | `root` | `var(--color-content-tertiary, var(--color-content-secondary))` | 1 | -| `resize-grip-radius` | `root` | `var(--radius-sm)` | 1 | ### 4.2 Sin nombre mecánico (4) @@ -123,6 +98,36 @@ no distingue lo que debería — se marca `⚠`. -_(pendiente — lo escribe el autor; se conserva al regenerar)_ +**EJECUTADO 2026-08-22 — 59 % → 84 %**, 12 claves. `global` a CERO. + +Lo cosido: las dos VARIANTES que ajustan desde el default elevado +(`outline-*` / `ghost-*`) y los botones de su barra (`action-*` + +`hover-action-*`), más el asa de redimensionado. + +**Y de paso muere uno de los nueve fantasmas del barrido**: el asa leía +`var(--color-content-tertiary, var(--color-content-secondary))` — ese primitivo +NO EXISTE, así que pintaba el respaldo. El contrato guarda lo que de verdad +pintaba (`--color-content-secondary`), con lo que la referencia muerta +desaparece sin mover un píxel. + +**Once adjudicaciones medidas**: la demo monta la variante por DEFECTO (no +outline ni ghost) y no tiene botón de acción genérico —sólo el control de +cierre—, así que se forzaron el atributo de variante y se montó el botón donde +el CSS lo selecciona; el radio del asa sólo pinta bajo `:focus-visible`. Las +once alcanzan. + +**Y una ANOMALÍA registrada en vez de escondida**: `resize-grip-fg` MUEVE bajo +una réplica a mano de la secuencia del propio guard —congelar, blur, aparcar el +ratón, escribir en `:root` y en cada nodo con el prefijo, fotografiar con +pseudos— (oklch(0.5032 0 0) → rgb(1,2,3)), y aun así el guard lo da por muerto. +La causa no está encontrada. El token está vivo; lo que está en duda es la +lectura → next-features §13. + +**Lo rojo que queda es ANTERIOR**: 12 tokens del bloque viejo, y seis de ellos +—`bg`, `border`, `border-width`, `shadow`, `font-family`, +`line-height`— son el mismo conjunto que en `popover`: el PLANO de profundidad +gana sobre el panel (§12.9, pendiente de firma). + +Sonda antes/después: **0 diffs en 1.890 valores** (9 nodos × 7 estados). diff --git a/docs/next-features.md b/docs/next-features.md index dc1c748a5..68181362a 100644 --- a/docs/next-features.md +++ b/docs/next-features.md @@ -1060,5 +1060,18 @@ Lo que `chart` destapó (2026-08-22): de `data-size`) ni que el guard no vea sus nodos (ya se le dieron las dos familias que le faltaban). +- **⚠ Un falso negativo del centinela SIN causa encontrada** (2026-08-22): + `float-panel.resize-grip-fg`. Réplica a mano de la secuencia del propio guard + —congelar transiciones, blur, aparcar el ratón, escribir en `:root` y en cada + nodo con el prefijo, fotografiar los mismos props con `::before`/`::after`/ + `::placeholder`— y el color del asa SÍ se mueve (oklch(0.5032 0 0) → + rgb(1,2,3)). El guard lo reporta muerto. Descartado: que el nodo no lleve el + atributo (lo lleva), que la regla necesite un estado (es la regla base), que + sea el valor centinela (es el mismo) y que sea HMR (dos corridas). Queda + adjudicado con la medición y marcado como anomalía: **el token está vivo; lo + que está en duda es la lectura**. La revisión adversarial del bloque debería + empezar por aquí — el precedente de F2-A dice que estos casos SÍ tienen causa + (22 falsos negativos de 26, tres causas distintas). + **Deps**: ninguna. Son mejoras del instrumental del eje, ejecutables cuando estorben. diff --git a/docs/process/PLAN-theming.md b/docs/process/PLAN-theming.md index 738a6b6a9..cba6a6fa2 100644 --- a/docs/process/PLAN-theming.md +++ b/docs/process/PLAN-theming.md @@ -455,6 +455,27 @@ de commit. Sin artefacto, el paso no se ha hecho. ## 8. Registro +- 2026-08-22 — **`float-panel` 59 % → 84 %** (12 claves, `global` a cero). + + Las dos variantes que ajustan desde el default elevado, los botones de la + barra y el asa. **Muere uno de los nueve fantasmas del barrido**: el asa leía + `var(--color-content-tertiary, …)` y ese primitivo no existe — el contrato + guarda lo que de verdad pintaba. + + Once adjudicaciones medidas (la demo monta la variante por defecto y no tiene + botón de acción genérico) **y una ANOMALÍA registrada**: `resize-grip-fg` + mueve bajo una réplica a mano de la secuencia del propio guard y aun así lo da + por muerto; causa no encontrada, descartadas cuatro. El token está vivo; la + lectura es lo que está en duda → §13, primer sitio por donde empezar la + revisión adversarial de este bloque. + + Los 12 rojos que quedan son anteriores, y seis son el mismo conjunto que en + `popover`: el plano de profundidad gana sobre el panel (§12.9). + + Gates: sonda 0 diffs en 1.890 valores · censo 84 % · `--names` sin desviadas · + audit PASS · lint 0 · suite con el rojo conocido · rtl 0 · docs 0 · captura + mirada (cabecera, cierre y asa en su sitio). + - 2026-08-22 — **`nav-tree` 4 % → 96 %** (17 claves; tenía UNA). Global 61 %. **La FILA es link + trigger a la vez** —mismo padding, tinta, radio y hover—, diff --git a/scripts/theming-sentinel-exceptions.ts b/scripts/theming-sentinel-exceptions.ts index 30ad52fa9..ee561ce00 100644 --- a/scripts/theming-sentinel-exceptions.ts +++ b/scripts/theming-sentinel-exceptions.ts @@ -314,6 +314,28 @@ export const SENTINEL_EXCEPTIONS: Record> = { 'disabled-row-fg': 'no disabled row in the demo (0 mounted, counted); forced data-disabled → reaches (oklch(0.61 0 0) → rgb(1,2,3))' }, + 'float-panel': { + // The demo mounts the DEFAULT variant and no generic action button (only the + // close control). Forced in place 2026-08-22, transitions frozen. + 'outline-bg': 'the demo runs the default variant; set data-variant=outline -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))', + 'outline-border': 'same variant; forced -> reaches (oklch(0.7921 0 0) -> rgb(1,2,3))', + 'ghost-bg': 'same, variant ghost; forced -> reaches (oklch(0.9911 0 0) -> rgb(1,2,3))', + 'ghost-border': 'same, variant ghost; forced -> reaches (oklch(0.931 0 0) -> rgb(1,2,3))', + 'ghost-shadow': 'same, variant ghost; forced -> reaches (rgba(15,23,42,0.1) 0 4px 12px -> rgb(1,2,3) 0 0 0 7px)', + 'action-fg': 'no generic action button in the demo (only the close control); mounted in place -> reaches (oklch(0.5032 0 0) -> rgb(1,2,3))', + 'action-radius': 'same button; mounted -> reaches (4px -> 1234px)', + 'action-font-size': 'same button; mounted -> reaches (16px -> 1234px)', + 'hover-action-bg': 'same button, and only under :hover; same mounting pass', + 'hover-action-fg': 'same button, and only under :hover; same mounting pass', + 'resize-grip-radius': 'only under :focus-visible; focused the grip -> reaches (4px -> 1234px)', + // ANOMALY, registered rather than hidden: this one MOVES under a hand + // replication of the guard's own sequence (freeze, blur, park, write on + // :root + every prefix node, snapshot with pseudos): oklch(0.5032 0 0) -> + // rgb(1,2,3). The guard still reports it dead and the cause is not found + // yet — 2026-08-22, next-features §13. The token is alive; the reading is + // what is in doubt. + 'resize-grip-fg': 'MEASURED ALIVE by hand under the guard own conditions (oklch(0.5032 0 0) -> rgb(1,2,3)); the guard reports no effect and the cause is open - next-features 13' + }, drawer: { // The guard OPENS the drawer before testing, and the overlay then covers the // trigger: the hover pass cannot reach it (Playwright refuses to hover a diff --git a/src/uix/eidos/components/float-panel/float-panel.css b/src/uix/eidos/components/float-panel/float-panel.css index ba0f70cff..ac13d2ebe 100644 --- a/src/uix/eidos/components/float-panel/float-panel.css +++ b/src/uix/eidos/components/float-panel/float-panel.css @@ -73,14 +73,14 @@ /* Variants — canonical ControlVariant. The base above IS `surface` (the elevated default); `outline` and `ghost` adjust from it. */ [data-float-panel-content][data-variant='outline'] { - background: var(--color-surface-default); - border-color: var(--color-border-strong); + background: var(--float-panel-outline-bg); + border-color: var(--float-panel-outline-border); box-shadow: none; } [data-float-panel-content][data-variant='ghost'] { - background: var(--color-surface-default); - border-color: var(--color-border-subtle); - box-shadow: var(--shadow-2); + background: var(--float-panel-ghost-bg); + border-color: var(--float-panel-ghost-border); + box-shadow: var(--float-panel-ghost-shadow); } /* Accent per color role (focus ring + resize-active + header rule emphasis). */ @@ -166,17 +166,17 @@ inline-size: var(--float-panel-button-size); block-size: var(--float-panel-button-size); border: 0; - border-radius: var(--radius-sm); + border-radius: var(--float-panel-action-radius); background: transparent; - color: var(--color-content-secondary); - font-size: var(--font-size-md); + color: var(--float-panel-action-fg); + font-size: var(--float-panel-action-font-size); line-height: 1; cursor: pointer; } [data-float-panel-action]:hover, [data-float-panel-stage-trigger]:hover { - background: var(--color-surface-muted); - color: var(--color-content-primary); + background: var(--float-panel-hover-action-bg); + color: var(--float-panel-hover-action-fg); } [data-float-panel-action]:focus-visible, [data-float-panel-stage-trigger]:focus-visible { @@ -224,7 +224,7 @@ margin: 0; border: 0; background-color: transparent; - color: var(--color-content-tertiary, var(--color-content-secondary)); + color: var(--float-panel-resize-grip-fg); cursor: nwse-resize !important; /* important: wins over the header's inherited grab cursor + the button UA */ touch-action: none; /* Three nested corner chevrons → an unmistakable resize grip. */ @@ -259,7 +259,7 @@ opacity: 1; --ring-inset-color: var(--_float-panel-accent); box-shadow: inset 0 0 0 var(--ring-inset-width) var(--ring-inset-color, currentColor); - border-radius: var(--radius-sm); + border-radius: var(--float-panel-resize-grip-radius); } /* Body = scrollable content. */ diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css index 3f6915417..3ce76033a 100644 --- a/src/uix/eidos/generated/base.css +++ b/src/uix/eidos/generated/base.css @@ -1395,6 +1395,18 @@ --spin-field-control-disabled-opacity: 0.48; --spin-field-transition-duration: var(--duration-fast); --spin-field-transition-ease: var(--ease-default); + --float-panel-outline-bg: var(--color-surface-default); + --float-panel-outline-border: var(--color-border-strong); + --float-panel-ghost-bg: var(--color-surface-default); + --float-panel-ghost-border: var(--color-border-subtle); + --float-panel-ghost-shadow: var(--shadow-2); + --float-panel-action-radius: var(--radius-sm); + --float-panel-action-fg: var(--color-content-secondary); + --float-panel-action-font-size: var(--size-md-font-size); + --float-panel-hover-action-bg: var(--color-surface-muted); + --float-panel-hover-action-fg: var(--color-content-primary); + --float-panel-resize-grip-fg: var(--color-content-secondary); + --float-panel-resize-grip-radius: var(--radius-sm); --float-panel-bg: var(--color-surface-overlay); --float-panel-border: var(--color-border-default); --float-panel-border-width: var(--border-width); diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts index 5519a9fb5..c9282d8fb 100644 --- a/src/uix/eidos/lib/recipes/base.ts +++ b/src/uix/eidos/lib/recipes/base.ts @@ -1465,6 +1465,22 @@ export const THEME_BASE_RECIPE_TOKENS = defineRecipes({ 'transition-ease': 'var(--ease-default)' }, 'float-panel': { + // Las dos variantes que ajustan desde el default elevado, y los botones de + // la barra. El asa de redimensionado leía + // `var(--color-content-tertiary, …)`: ese primitivo NO EXISTE —pintaba el + // respaldo—, así que el contrato guarda lo que de verdad pintaba. + 'outline-bg': 'var(--color-surface-default)', + 'outline-border': 'var(--color-border-strong)', + 'ghost-bg': 'var(--color-surface-default)', + 'ghost-border': 'var(--color-border-subtle)', + 'ghost-shadow': 'var(--shadow-2)', + 'action-radius': 'var(--radius-sm)', + 'action-fg': 'var(--color-content-secondary)', + 'action-font-size': 'var(--size-md-font-size)', + 'hover-action-bg': 'var(--color-surface-muted)', + 'hover-action-fg': 'var(--color-content-primary)', + 'resize-grip-fg': 'var(--color-content-secondary)', + 'resize-grip-radius': 'var(--radius-sm)', bg: 'var(--color-surface-overlay)', border: 'var(--color-border-default)', 'border-width': 'var(--border-width)',