# RFC — Motor de profundidad (depth) de Eidos > Hermano de `COLOR_ENGINE_RFC.md` y `TYPOGRAPHY_ENGINE_RFC.md`. Lleva el canal de > **profundidad** (`depth/presence` del libro *Diseñando lo que ocurre*) a reference-grade > **rompiendo** el modelo de los referentes, no copiándolo — con la **jaula abierta**. ## 0. Tesis > **La profundidad no es algo que un elemento _tiene_; es algo que _ocurre_.** Un overlay no "tiene elevación 4": **enuncia una emergencia** — asciende a un plano delantero al aparecer, recede al irse — gobernado por el **mismo evento sema** que ya dirige su motion/sound/haptic. La profundidad pasa a ser un **canal de expresión de primera clase** (uno de los 8 del libro), **unificado** (una sola noción cohere superficie + sombra + z + atmósfera), **eventful** (lo dispara el motor sema) y con **jaula abierta** (default fuerte, puertas en cada capa). ## 1. El estudio — cómo lo hacen los referentes y dónde topan | Framework | Modelo | Límite estructural | |---|---|---| | **Material 3** | elevación = tinte tonal + sombra, escala `dp` 0–5 | `dp` = altura física con 1 foco de luz; la elevación es **propiedad** del componente, no expresión de un suceso; escala fija | | **Tailwind** | `shadow-sm…2xl` presets planos | sin modo (la sombra en dark *miente*), sin superficie, sin semántica | | **Apple / SwiftUI** | materiales (blur/vibrancy) + sombra sutil | atado a plataforma (backdrop), no es sistema de tokens portable | | **Polaris / Carbon / Radix** | escala de sombra por rol o numérica | estática; rol fijo, desligada de eventos | **Límite común** (incluso M3, el más fino): profundidad = **propiedad estática que asignas** + **modelo de luz skeuomórfico** + **desconectada** de lo que ocurre y de sus propias señales entre sí. Nadie trata la profundidad como **expresión de un suceso**. Y todos eligen un bando: Tailwind = flexible **sin opinión**; Material = **opinión fuerte pero jaula cerrada**. ## 2. Dónde está Eidos hoy (ya por encima de la media, pero no novedoso) - **z-index** en bandas semánticas: `base · raised · sticky · dropdown · popover · tooltip · modal · toast`. ✓ - **Escalera de superficie tonal y mode-aware**: `surface-default→raised→overlay` = `neutral-1→2→4` (en dark, "más arriba" = más claro — el tonal-overlay de M3, ya presente). ✓ - **Sombras nombradas por rol**: `shadow-subtle/raised/overlay` (→ `shadow-1/3/5`), set propio por tema (`THEME_BASE_DARK_SHADOW`). ✓ (por encima de Tailwind) - **PERO** son **3 sistemas separados** (eliges sombra + superficie + z a mano), la profundidad es **estática** (un prop) y el modelo sigue siendo el de sombra-skeuomórfica. Estás ~a la par de M3. ## 3. El modelo novel — 4 piezas 1. **Plano semántico unificado** — `flush · raised · overlay · modal · recessed`. Un nivel cohere superficie + sombra + z + (blur/scrim) de una vez. Nombra por **rol en la jerarquía de atención**, no por milímetros. 2. **Mezcla multi-señal adaptada al modo, _computada_** — light se apoya en sombra; dark en tinte de superficie + halo (la sombra en dark miente). Sombras derivadas del **color de la superficie en OKLCH** (no negro-alpha plano), reusando el motor de color. Resuelve el problema sombra-en-dark de raíz. 3. **Profundidad _eventful_ (lo genuinamente nuevo)** — un canal que el motor **sema** dispara, como sound/haptic: `emerge`→sube, `contact`→hunde, `signal/threat`→empuja al frente; coordinado con el modelo de **dos momentos** de motion. 4. **Atmósfera / presencia** — backdrop-blur (frost) + scrim: lo que está al frente desenfoca/dimma lo que recede (solapamiento con el canal *presence*). ## 3.bis Los dos momentos de la profundidad La profundidad respeta el **modelo de dos momentos** del framework (motion F1) — no lo reinventa. Eidos ya lee los dos ejes; depth añade su capa a cada uno: | Momento | Atributo (eje) | Para depth | Fase | |---|---|---|---| | **estado** | `data-state` (persistente · soma/morfo) | el **plano en reposo** — `data-depth='{plane}'`: dónde *está* el elemento. Eidos lo aplica como un *preset* de estado. | 1 ✅ | | **evento** | `data-event-*` (transitorio · sema, durante el `hold`) | el **ascenso / recesión** — una *signature de profundidad* al `emerge`/`contact`: lo que *ocurre*. Ordenada por `sequence`, junto a las signatures de motion. | 3 | Por eso un overlay **tiene** un plano (estado) **y asciende** a él (evento) — los dos momentos, nunca colapsados en uno. El canal depth es un canal nuevo **expresado por el mismo modelo** que ya usa motion: rigor del libro (evento ≠ estado) llevado a la profundidad. ## 4. Doctrina — _default fuerte, jaula abierta_ > La capa semántica es **aditiva** sobre primitivos que **nunca desaparecen**; el set, la > mezcla y el canal son **extensibles/anulables** por config + el registro abierto de sema. | Pieza | Default fuerte | Puerta abierta | |---|---|---| | **planos** | set canónico (5) | el **set es config-driven** (`EidosConfig.depth.planes`); añade `sheet`/`peek`, renombra — no un enum cerrado | | **mezcla** | mezcla computada por plano | **retunear la mezcla por plano** en config; **override por componente** de cualquier señal; los **primitivos siguen ahí** (`--shadow-N`, `z-index`, `box-shadow` crudo a un paso) | | **canal eventful** | `emerge↑ / contact↓` | **opt-in/opt-out** (como sound+haptic); reglas en el **registro abierto de sema** (declaration merging + cascada appendable → la app añade/anula el mapa evento→profundidad); **degrada con `prefers-reduced-motion`**; la profundidad **estática funciona sin el canal** (eventful es aditivo, nunca un muro) | | **atmósfera** | frost+scrim en overlays | amount/opacidad en config; **opt-out** por overlay (coste/preferencia) | | **sistema entero** | tema canónico | **`applyDepth(seed)`** runtime (hermano de `applyColorScheme`/`applyTypeScale`) | Esto **no es nuevo en el framework**: es exactamente cómo ya operan sema (registro abierto), eidos (config + `setCssVariables` + overrides de recipe) y color/tipografía (canon retintable + builders runtime). Depth hereda el mismo contrato de apertura. ## 5. Contrato de tokens (añadidos, congelados) Bare-prefixed por sistema (`--depth-…`). El plano es un **bundle nombrado** que **compone los primitivos existentes** — no los reemplaza: ``` --depth-{plane}-surface → var(--color-surface-{…}) (tinte tonal, mode-aware) --depth-{plane}-shadow → var(--shadow-{…}) (gota, mode-aware vía tema) --depth-{plane}-halo → oklab rim-light (lift en dark · Fase 2) --depth-{plane}-z → var(--z-index-{…}) (banda) --depth-{plane}-blur → frost backdrop-blur (Fase 4 ✅ · opt-in vía data-frost) --depth-{plane}-scrim → atmósfera (token disponible; sin regla — backdrop por componente) ``` Consumo: `[data-depth='{plane}']` aplica las señales **aditivas seguras** (sombra + z + blur); la **superficie** es un token opt-in (`background: var(--depth-{plane}-surface)`) para no pisar fondos de componente. Sin renombrar nada existente → **cero rotura de componentes**. ## 6. Fases (la flexibilidad va horneada en cada una) 1. ✅ **Plano unificado** — `EidosConfig.depth` + planos canónicos + emisión `--depth-{plane}-*` (componen surface/shadow/z) + regla `[data-depth]` (sombra+z) + validación + test + regen. Puertas: set config-driven, mezcla por plano, primitivos intactos, escape a raw. 2. ✅ **Mezcla computada mode-adaptive** — la sombra de gota mantiene la escala themed (slate sutil en light / negro más opaco en dark — ya un tinte, no negro plano); Fase 2 añade el cue **`halo`**: un rim-light de borde superior **computado en oklab** (`color-mix(in oklab, white N%, transparent)`, escalado por plano: 5/7/8% en raised/overlay/ modal). Es invisible sobre superficies claras (manda la gota) y se vuelve la señal de elevación sobre superficies oscuras (donde la gota apenas se ve) — resuelve "la sombra miente en dark" **sin tocar las sombras globales**: vive solo en el canal depth, compuesto en el `box-shadow` de `[data-depth]` (`shadow, halo`). El halo derivado de la superficie + el frost atmosférico quedan para Fase 4. 3. ✅ **Canal `depth` eventful (momento-evento)** — la dimensión de ELEVACIÓN vive en la *firma*: `present-rise` (emerge) hace crecer la sombra desde plano → la de reposo del elemento (sube); `press-squeeze` (contact) la aplana a la superficie (recede). Generic (flush = no-op), coordinado con posición/escala y con sound+haptic desde **un solo evento**, degradando con reduced-motion (cap global). Anulable: un tema sobreescribe los keyframes/signatures. Monta sobre el sistema de `signatures` existente, **no** un sistema paralelo. 4. ✅ **Atmósfera (frost)** — cue `blur` por plano (overlay/modal) + regla **opt-in** `[data-depth='{plane}'][data-frost]` (superficie translúcida `color-mix` 80% + `backdrop-filter: blur`), gated para no volver translúcido un overlay opaco por defecto. + builder runtime **`applyDepth(planes)`** / `clearDepth()` (+ `buildDepth` puro) que retune cualquier cue de plano en vivo — hermano de `applyColorScheme` / `applyTypeScale`. (El cue `scrim` queda disponible como token; el backdrop dim de modales lo siguen gestionando los componentes, así que no se cabló a una regla.) 5. ✅ **Showcase + docs** — `/temas/profundidad` a profundidad de referencia: reacciona · estados (dynamic elevation) · asciende (firma) · escalera de planos · catálogo en reposo · luz vs sombra (el halo) · jaula abierta · a11y. Supera la amplitud de la referencia de *elevation* de Material añadiendo los dos ejes que le faltan (eventful + jaula abierta). + THEMING §29. ## 7. Composición con lo existente - **Escalera de superficie** (color) → la señal `surface` del plano (mode-aware gratis). - **Motor de color OKLCH** → sombras computadas (Fase 2) y halos. - **Dos momentos de motion** → la transición de ascenso/recesión (Fase 3) es un movimiento, no un salto. - **Bus de eventos sema** → el disparo eventful (Fase 3), como sound/haptic. - **z-index bands** → la señal `z` del plano. No se reinventa nada: se **unifica + se hace eventful** lo disperso, bajo la doctrina del libro. ## 8. Doctrina (paralela a color / tipografía) - **Planos + canal = canon del eidos** (como roles/variants y estilos nombrados): valores themeables, pero el *set* es canon. - **Profundidad eventful = capacidad del motor**, opt-in con degradación (como sound/haptic). - **Theme = retintar/retunear lo perceptualmente fijo**: cambia CUÁNTA sombra es `overlay`, no QUÉ significa `overlay`. - **Jaula abierta**: opinión fuerte que nunca atrapa — primitivos siempre accesibles. ## 9. Fuera de alcance - 3D real / perspectiva / parallax con giroscopio (la profundidad es perceptual, no un motor 3D). - Ray-tracing de sombras por geometría (se computa el tinte/halo, no la oclusión física).