|
|
|
|
@ -0,0 +1,144 @@
|
|
|
|
|
# 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.
|
|
|
|
|
|
|
|
|
|
## 6. Fases (la flexibilidad va horneada en cada una)
|
|
|
|
|
|
|
|
|
|
1. **Continuidad + escala** — `--shape-smoothing` + emisión progresiva (`border-radius` +
|
|
|
|
|
`corner-shape` donde se soporte) + validación + test + regen. Puertas: smoothing
|
|
|
|
|
config-driven/override, `--radius-*` intactos, escape al `border-radius` crudo.
|
|
|
|
|
2. **Armonía anidada** — convención/helper de radio anidado computado (`--shape-nest-gap`).
|
|
|
|
|
3. **Forma _eventful_ (momento-evento)** — firma `shape-morph` (squeeze/round) **sobre el
|
|
|
|
|
sistema de `signatures` existente**, coordinada con motion/depth desde un evento, degradando
|
|
|
|
|
con reduced-motion. Anulable (sobreescribe keyframes/signatures). No un sistema paralelo.
|
|
|
|
|
4. **Familias** — `rounded/continuous/cut/pill/sharp` como atributo + recipe + builder
|
|
|
|
|
`applyShape(seed)`.
|
|
|
|
|
5. **Showcase + docs** — `/temas/forma` (continuidad/anidado/familias/eventful en vivo) +
|
|
|
|
|
THEMING §shape.
|
|
|
|
|
|
|
|
|
|
## 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).
|