test(eidos): elevation-plane anti-drift guard + mark §13 surface axis LIVE

The B2 rollout is complete, so the ARCHETYPE_COHERENCE_AUDIT §13 "Superficie /
elevación" axis flips A1 → LIVE. Per the audit's update rule (row → LIVE +
guard), add `elevation-plane.test.ts`: every floating overlay's eidos Content
wrapper must stamp `data-depth` so the plane paints its elevation. 13 wrappers
pass (dropdown/context-menu + their sub-contents, menubar, navigation-menu,
popover, link-preview, command, select, combobox, dialog, drawer). tooltip +
listbox are excluded by design (variant-as-material / inline list).

Catches the menubar-class regression — a panel that reuses a shared content
selector but forgets data-depth silently loses its elevation when the donor
recipe is pruned.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
active-uix
dev 4 months ago
parent d578f83281
commit 5f14793b62

@ -31,6 +31,35 @@ consuman por defecto**.
---
## ESTADO DE IMPLEMENTACIÓN — hand-off 2026-06-22
**B2 COMPLETO — el plano de elevación adoptado por TODOS los overlays.** 4 commits (pusheados a
`gita active-uix`): dropdown (`f80f2225`) · context-menu+menubar+navigation-menu (`009f5367`) ·
link-preview+command (`be5396ce`) · select+combobox (`d578f832`). Patrón por overlay: el wrapper
eidos del `Content` estampa `data-depth="overlay"`, se podan border/bg/shadow del CSS (+ tokens del
recipe en dropdown/context-menu/select) y el arrow apunta a `--depth-overlay-surface`/`-border`.
dialog/drawer ya en plano `modal` (2026-06-20).
- **FUERA por diseño** (no son targets del plano): `tooltip` (el variant ES el material — solid
relleno / outline transparente / ghost con blur —, no énfasis sobre un trigger) · `listbox` (lista
inline `surface-default` sin sombra, no overlay flotante). Falsos positivos descartados:
carousel/grid-list/tree-view (bg de item) · color-picker/date-range-picker (contenido dentro de un
popover, que ya tiene el plano).
- **select+combobox a plano-constante** (decisión del usuario): el variant tiñe solo el
trigger/control, ya NO la elevación del popup (se quitaron los overrides outline=raised /
ghost=transparent). Los 3 variants comparten la misma elevación overlay.
- **Regresión propia** (pusheada en f80f2225, arreglada en 009f5367): menubar reusa
`[data-dropdown-menu-content]` → el prune del dropdown lo dejó sin elevación; arreglado estampando
`data-depth` en su wrapper eidos. Lección: al podar un selector/recipe compartido, grepear los
reusadores.
- **Fila "Superficie / elevación" de §13 → `LIVE ✓`** + **lint anti-deriva** `elevation-plane.test.ts`
(cada `Content` de overlay debe estampar `data-depth`; tooltip/listbox excluidos por diseño).
**Siguiente:** A2 (radio: `--radius-default`=sm + factor Radix + responder a `--scaling`) → A3 (estado
hover/active + foco unificado).
---
## ESTADO DE IMPLEMENTACIÓN — hand-off 2026-06-20
**Hecho hoy (sobre el A1 de ayer):**
@ -779,7 +808,7 @@ cada una — no son faltas per-componente, son los arquetipos que faltan):
| eje | canon — QUÉ consumir | NO hacer (deriva) | estado |
|---|---|---|---|
| **Superficie / elevación** | `data-depth='overlay'\|'modal'\|…` → **bundle completo** (surface·shadow·halo·border·blur·z) | `surface-raised`/`-default` a dedo; `--{c}-overlay-z` propio; frost arbitrario | **A1** |
| **Superficie / elevación** | `data-depth='overlay'\|'modal'\|…` → **bundle completo** (surface·shadow·halo·border·blur·z) | `surface-raised`/`-default` a dedo; `--{c}-overlay-z` propio; frost arbitrario | **LIVE ✓** (B2, 2026-06-22; guard `elevation-plane.test.ts`) |
| **Radio** | `--radius-default`(=sm) / factor global + `[data-shape-nest]` concéntrico | `calc(--radius-md − space)` a mano; px fijo | **A2** |
| **Estado (hover/active)** | `--state-{variant}-hover/active` (ghost = state-layer `currentColor`) | `color-mix` ad-hoc; 9 familias sueltas | **A3** |
| **Foco** | `--focus-ring-*` + `--focus-ring-surface` + `outline` (HCM-safe); intent vía `data-intent` | tokens de foco propios; box-shadow que muere en HCM | **A3** |

@ -0,0 +1,57 @@
import { describe, it, expect } from 'vitest';
import { existsSync, readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const COMPONENTS = join(dirname(fileURLToPath(import.meta.url)), 'components');
/**
* Anti-drift guard for the elevation plane.
*
* ARCHETYPE_COHERENCE_AUDIT §13, axis "Superficie / elevación" → LIVE (B2 rollout,
* 2026-06-22). Every FLOATING OVERLAY takes its elevation (surface · border ·
* shadow · halo) from the `data-depth` plane — it does NOT paint its own
* surface/shadow. So each overlay's eidos `Content` wrapper MUST stamp
* `data-depth` for the plane to apply.
*
* This catches the menubar-class regression: a panel that reuses another part's
* content selector (`[data-dropdown-menu-content]`) but forgets `data-depth`
* silently loses its elevation the moment the donor recipe is pruned.
*
* EXCLUDED by design (NOT plane targets — see §13 / the 2026-06-22 hand-off):
* tooltip — the variant IS the material (solid / outline / ghost), not emphasis;
* the plane would flatten it.
* listbox — an inline list (`surface-default`, no shadow), not a floating overlay.
*/
const OVERLAY_CONTENT_WRAPPERS: Record<string, readonly string[]> = {
'dropdown-menu': ['dropdown-menu-content.svelte', 'dropdown-menu-sub-content.svelte'],
'context-menu': ['context-menu-content.svelte', 'context-menu-sub-content.svelte'],
menubar: ['menubar-content.svelte'],
'navigation-menu': ['navigation-menu-content.svelte'],
popover: ['popover-content.svelte'],
'link-preview': ['link-preview-content.svelte'],
command: ['command.svelte'],
select: ['select-content.svelte'],
combobox: ['combobox-content.svelte'],
dialog: ['dialog-content.svelte'],
drawer: ['drawer-content.svelte']
};
describe('elevation plane adoption (B2 anti-drift guard)', () => {
for (const [component, files] of Object.entries(OVERLAY_CONTENT_WRAPPERS)) {
for (const file of files) {
it(`${component} · ${file} stamps data-depth (consumes the elevation plane)`, () => {
const path = join(COMPONENTS, component, file);
expect(
existsSync(path),
`${file} not found — wrapper renamed? Update OVERLAY_CONTENT_WRAPPERS.`
).toBe(true);
const src = readFileSync(path, 'utf8');
expect(
/data-depth=/.test(src),
`${file} must stamp data-depth="overlay|modal" so the elevation plane paints the panel.`
).toBe(true);
});
}
}
});
Loading…
Cancel
Save

Powered by TurnKey Linux.