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/src/uix/eidos/SHAPE_ENGINE_RFC.md

163 lines
11 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# RFC — Motor de forma (shape) de Eidos
> Hermano de `COLOR_ENGINE_RFC.md`, `TYPOGRAPHY_ENGINE_RFC.md` y `DEPTH_ENGINE_RFC.md`.
> Lleva el canal de **forma** (`shape` del libro *Diseñando lo que ocurre*) a reference-grade
> **rompiendo** el modelo de los referentes — con la **jaula abierta**. Es el **8º y último
> canal de expresión** del libro sin elevar (tiempo · movimiento · presencia · profundidad ·
> **forma** · color · sonido · háptica).
## 0. Tesis
> **La forma no es un número de redondeo que un elemento _tiene_; es una cualidad perceptual
> — continuidad, familia, tensión — que el sistema _compone_ y que, en su momento, _ocurre_.**
Todos reducen la forma a UN número: `border-radius`. Pero la esquina tiene más ejes que su
magnitud: **cuán continua** es (arco circular vs superelipse), a **qué familia** pertenece
(redondeada / continua / cortada / píldora), cómo se **relaciona** con las formas anidadas, y
**qué le ocurre** cuando el elemento es presionado o confirma. Eidos trata la forma como un
**canal de primera clase**: unificado (magnitud + continuidad + familia + armonía), y
**eventful** (la forma puede tensarse/relajarse), bajo la **jaula abierta**.
## 1. El estudio — cómo lo hacen los referentes y dónde topan
| Framework | Modelo | Límite estructural |
|---|---|---|
| **Tailwind / Bootstrap** | escala `rounded-sm…full`, arco circular | sin continuidad, sin armonía anidada, sin familia, estática; la esquina es un arco y punto |
| **Material 3** | shape scale + mapping por componente + (M3 Expressive) *morph* + familia `cut` | arco/cut; el morph es reciente y acotado; sistema **cerrado** (eliges de la escala) |
| **Apple / SwiftUI** | esquinas **continuas** (superelipse) `.continuous` | atado a plataforma, no es token portable; no eventful; anidado manual |
| **CSS hoy** | `border-radius` = arcos elípticos | sin superelipse nativa universal (`corner-shape` emergente); squircles vía SVG/clip-path hacks |
**Límite común**: forma = **un número de radio de arco**, propiedad **estática** que asignas,
**desligada** de los elementos vecinos/anidados, sin **continuidad** real, y **desconectada de
lo que ocurre**. SwiftUI es el único con continuidad — pero cerrada y por plataforma. Material
es el único con familia + morph — pero arco y cerrado. Nadie los **unifica** ni los hace
**abiertos**.
## 2. Dónde está Eidos hoy (coherente, pero no novedoso)
- **Escala de radius** en `--radius-{none·sm·md·lg·xl·xxl·full}` (4/6/10/16/20px + pill). ✓
- Asignada **por componente** vía el size primitive (`radius: 'md'`). ✓
- **PERO** el modelo es exactamente "un número de **arco circular**": sin continuidad
(squircle), sin **armonía** entre radios anidados, sin **familia** perceptual, y **estática**
(nunca ocurre). Estás ~a la par de Tailwind; por debajo de SwiftUI (continuidad) y de M3
(familia + morph).
## 3. El modelo novel — 4 piezas
1. **Continuidad (superelipse)** — un eje nuevo `--shape-smoothing` (0 = arco circular …
1 = superelipse tipo iOS). **Output progresivo** (estrategia idéntica al oklch del color):
se emite `border-radius` (universal, el fallback) **y** `corner-shape: superellipse(…)` donde
se soporta. Resuelve de raíz la esquina-de-arco que todos arrastran, sin romper a nadie.
2. **Armonía de radios anidados** — radio interior **derivado** del exterior:
`interior = max(0, exterior − gap)` (concéntrico), computado en `calc()`. Una convención
`--shape-nest` para que tarjeta-dentro-de-tarjeta (o input-dentro-de-panel) nunca desencaje.
3. **Familia de forma** — `rounded · continuous · cut · pill` (+ `sharp`). Eje **perceptual**,
no de magnitud. Canon del eidos (como roles/variants): valores themeables, set canon.
4. **Forma _eventful_ (lo genuinamente nuevo)** — la forma se **tensa/relaja** al ocurrir algo:
`contact`→aprieta esquinas (squeeze), `commit`→las redondea, vía la **misma firma** que ya
dirige motion/depth. Forma-como-suceso, coordinada desde **un solo evento sema**.
## 3.bis Los dos momentos de la forma
La forma respeta el **modelo de dos momentos** del framework (motion F1) — no lo reinventa:
| Momento | Atributo (eje) | Para shape | Fase |
|---|---|---|---|
| **estado** | `data-state` (persistente) | la **forma en reposo** — magnitud (`--radius-*`) + familia + continuidad: cómo *es* el elemento | 1 |
| **evento** | `data-event-*` (transitorio, durante el `hold`) | el **morph** — apretar/redondear al `contact`/`commit`: lo que *ocurre*. Ordenado por `sequence`, junto a las firmas de motion/depth | 3 |
Un control **tiene** una forma (estado) **y la tensa** al pulsarse (evento) — los dos momentos,
nunca colapsados. Mismo rigor del libro (evento ≠ estado) llevado a la forma.
## 4. Doctrina — _default fuerte, jaula abierta_
| Pieza | Default fuerte | Puerta abierta |
|---|---|---|
| **escala** | `--radius-*` canónica | config-driven (`EidosConfig` size/radius); el `border-radius` crudo siempre a un paso |
| **continuidad** | `--shape-smoothing` por defecto (sutil) | override global/por-componente/por-elemento; `0` vuelve al arco puro |
| **familia** | set canónico (rounded/continuous/cut/pill/sharp) | el set es **canon** pero themeable; un wrapper compone una propia sin inventar familia |
| **anidado** | convención `--shape-nest` (concéntrico) | opt-in; el cálculo es transparente (`calc()`), anulable |
| **eventful** | `contact`↓apretar / `commit`↑redondear | **opt-in/opt-out** (como sound/haptic/depth); registro abierto de sema; **degrada con `prefers-reduced-motion`**; la forma estática funciona sin el canal |
| **sistema entero** | tema canónico | **`applyShape(seed)`** runtime (hermano de `applyColorScheme`/`applyTypeScale`/`applyDepth`) |
Es exactamente cómo ya operan color/tipografía/profundidad: canon retintable + builders
runtime + primitivos siempre accesibles. Forma hereda el mismo contrato de apertura.
## 5. Contrato de tokens (añadidos, congelados)
Bare-prefixed por sistema (`--shape-…`). La **magnitud** sigue en `--radius-*` (no se renombra
nada → cero rotura):
```
--radius-{key} magnitud (escala existente — se mantiene)
--shape-smoothing factor de superelipse 0..1 (Fase 1) → corner-shape: superellipse(k)
--shape-nest-gap gap por defecto del radio anidado (Fase 2)
```
- **Continuidad**: `[style] { border-radius: var(--radius-md) }` (universal) + donde se soporte
`corner-shape: superellipse(var(--shape-smoothing-k))` (progresivo, degrada al arco).
- **Familia**: atributo `data-shape='cut'|'continuous'|…` o recipe del componente (no un token
global) — selecciona el `corner-shape` / clip apropiado.
- **Anidado**: `border-radius: max(0px, calc(var(--_outer-radius) - var(--shape-nest-gap)))` —
convención en `calc()`, sin token de salida nuevo.
> **El anidado de 4 esquinas requiere radios FINITOS — a `full` es solo el _top_.** A `full`
> (`--radius-full` = 9999px) el radio se **recorta a la mitad de la dimensión menor de cada
> elemento**. Un hijo ancho (p. ej. 16:10) **no puede** ser concéntrico en sus 4 esquinas: su altura
> cap­ea las cuatro a ~½-altura, distinto del padre. Pero sus **esquinas superiores SÍ pueden** valer
> `radio_card − gap` si las **inferiores se quedan rectas** (la restricción de altura deja de morder).
> Esa es la geometría del reproductor iOS: carátula con top redondeado concéntrico + base recta que
> encuentra los metadatos.
>
> La regla CSS `[data-shape-nest]` no sirve aquí porque el valor *computado* del radio del padre
> sigue siendo `9999px` (el cap es un valor *usado*, no legible en CSS). El demo `/temas/forma` lo
> **mide** (`min(w,h)/2 − gap` vía `ResizeObserver`) y lo aplica a las esquinas superiores de la
> carátula; las inferiores quedan a `0`. El toggle "radios concéntricos" se inhabilita a `full`
> («auto: solo top») porque ahí el anidado es automático y parcial por geometría, no opcional.
## 6. Fases (la flexibilidad va horneada en cada una)
1. ✅ **Continuidad + escala + familias** — `--shape-smoothing` + `data-shape` →
`corner-shape` con las 4 familias (`rounded`/`continuous`/`cut`/`scoop`). Emisión
progresiva: `border-radius` universal (la magnitud, `--radius-*` intactos) + `corner-shape`
donde se soporte (degrada al arco). Config-driven + validación + test + regen. (Las familias
se adelantaron aquí — son la misma mecánica `corner-shape`.)
2. ✅ **Armonía anidada** — `--shape-nest-gap` + regla `[data-shape-nest]`:
`border-radius: max(0, var(--shape-outer-radius) − gap)` (concéntrico).
3. ✅ **Forma _eventful_ (momento-evento)** — el morph de esquina **plegado en la firma
`press-squeeze`** (cross-modal: un press = escala + sombra + esquina) + `@property
--shape-smoothing` para que interpole. Sobre el sistema de `signatures` existente; degrada con
reduced-motion. No un sistema paralelo.
4. ✅ **Builder runtime `applyShape(seed)`** — dial de `smoothing`/`nestGap` + override de
familias, bloque gestionado (hermano de `applyColorScheme`/`applyTypeScale`/`applyDepth`).
5. ✅ **Showcase + docs** — `/temas/forma` (continuidad con dial + familias + anidado +
eventful en vivo) + THEMING §30.
## 7. Composición con lo existente
- **Escala `--radius-*`** → la magnitud de cada forma (se reusa, no se duplica).
- **Sistema de `signatures`** (motion/depth) → el morph eventful (Fase 3), no un motor nuevo.
- **Dos momentos de motion** → el morph es un movimiento de la forma, no un salto.
- **Bus de eventos sema** → el disparo eventful (Fase 3), como sound/haptic/depth.
- **Espaciado** → el gap del radio anidado (Fase 2).
No se reinventa nada: se **unifica + se hace continuo, armónico y eventful** lo que hoy es un
número suelto, bajo la doctrina del libro.
## 8. Doctrina (paralela a color / tipografía / profundidad)
- **Escala + familias = canon del eidos** (como roles/variants y planos): valores themeables,
pero el *set* es canon.
- **Continuidad = cualidad por defecto**, retuneable; `0` = arco puro (jaula abierta).
- **Forma eventful = capacidad del motor**, opt-in con degradación (como sound/haptic/depth).
- **Theme = retintar/retunear lo perceptualmente fijo**: cambia CUÁNTO redondea `md` o cuánta
continuidad lleva, no QUÉ significa `cut`.
- **Jaula abierta**: opinión fuerte que nunca atrapa — `border-radius` crudo siempre accesible.
## 9. Fuera de alcance
- Blobs / formas orgánicas aleatorias y morphing de `path` arbitrario (la forma es perceptual,
no un motor de geometría libre).
- Recortes complejos por geometría (clip-path a medida por componente queda en cada recipe).
- Esquinas por-lado asimétricas como sistema (el `border-radius` por-esquina crudo ya las cubre).

Powered by TurnKey Linux.