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/SCALING_RFC.md

93 lines
4.9 KiB

# RFC — Eje `scaling` (zoom global), separado de la densidad
> **Estado: ✅ IMPLEMENTADO.** (diseño 2026-06-01 · implementado 2026-06-02)
> Surge de P1-2: la tipografía-por-densidad (`content-scale`) estaba mal planteada.
> Densidad y zoom son cosas distintas; este RFC introduce el zoom como su propio eje.
>
> **Código**: `lib/config-types.ts` (`SCALING_KEYS` / `ScalingKey` / `DEFAULT_SCALING`),
> `lib/primitives/static.ts` (`STATIC_SCALING`), `lib/render-css.ts`
> (`appendScalingDeclarations` / `appendScaledMetricDeclarations` / `renderScalingBlocks`),
> `active-eidos.svelte.ts` (`scaling` / `scalingSource` / `getScaling()` / `data-scaling`).
> Doc consolidada en THEMING.md §23. `--density-scale` y `--density-content-scale`
> fueron eliminados en este sprint.
## 0. Motivación
`scaling` en Radix Themes (90/95/100/105/110%) es un **zoom global** que escala
espacio, tipografía, alturas y line-box con UN factor — accesibilidad/zoom, no
densidad. Eidos tenía un `--density-content-scale` (±4%) muerto que intentaba
escalar tipografía bajo el eje de densidad, lo cual **confunde densidad con zoom**:
- **Densidad** (`compact` / `comfortable` / `spacious`): aprieta layout (espacio +
altura de control), **texto estable** (legibilidad — Material/Carbon). Ya hecho.
- **Scaling** (este RFC): zoom — escala las métricas px **incluida la tipografía**.
Los dos ejes son **ortogonales** y **componen** (puedes tener `compact` + `110%`).
## 1. Decisiones
- **Discreto**, paridad Radix: `90 / 95 / 100 / 105 / 110` (%). Default `100`.
Se proyecta como `[data-scaling='90']` (bloques, cacheable) + `--scaling`.
- **Escala** (px): `font-size`, `space`, `control-height`, `icon-size`.
- **NO escala**:
- `line-height` → es **ratio unitless** (1.45…); ya escala vía el font-size
escalado. Multiplicarlo lo **duplicaría** (bug). Excluir.
- `border-width` (1px nítido), `radius` (independiente — como en Radix),
`shadow`, `z-index`, `opacity`, `motion`. Excluir.
- **Composición con densidad** (multiplicativa) en las 2 métricas compartidas:
`--space-N: calc(base × var(--density-space-scale) × var(--scaling))`,
`--control-height-N: calc(base × var(--density-control-scale) × var(--scaling))`.
- **Poda** `--density-scale` (maestro) + `--density-content-scale`: eran el intento
a-medias de lo que este eje hace bien. Reconcilia §20.1 (densidad = texto estable;
scaling = zoom incluye texto).
## 2. Diseño
**Primitiva** (`lib/primitives/static.ts`):
```ts
export const STATIC_SCALING = { '90': 0.9, '95': 0.95, '100': 1, '105': 1.05, '110': 1.1 }
```
Default activo: `100`.
**Tipos** (`config-types.ts`): `SCALING_KEYS = ['90','95','100','105','110']`,
`ScalingKey`. La primitiva de densidad pierde `scale` + `contentScale`.
**Emisión** (`render-css.ts`):
- `:root` declara `--scaling-90: 0.9 … --scaling-110: 1.1` (constantes) y
`--scaling: var(--scaling-100)` (activo).
- Bloques `[data-scaling='90'] { --scaling: var(--scaling-90); }` … (los ≠100).
- `font-size` + `icon-size` pasan de verbatim a `calc(value × var(--scaling))`.
- `space` + `control-height` añaden `× var(--scaling)` al `calc` que ya tienen.
- `line-height`, `radius`, `border`, `shadow`, etc.: **sin cambios**.
**Runtime** (`active-eidos.svelte.ts`): nueva `scalingSource` (get/onChange,
espejo de `densitySource`); `apply()` escribe `data-scaling` en el host (junto a
`data-mode` / `data-density`); `dispose()` lo limpia. `EIDOS_SCALING_ATTR`.
**Contrato** (`contract.ts`): emite `--scaling` + las constantes como knobs.
## 3. Conflictos (resueltos)
| Punto | Resolución |
|---|---|
| Densidad × scaling en space/control-height | Composición multiplicativa en el `calc`. Ortogonales en intención. |
| line-height (ratio) | NO escalar — escala vía font-size. |
| radius/border/shadow/z/opacity/motion | NO escalar (paridad Radix + corrección). |
| `--density-scale` + `content-scale` muertos | Podados — superados por este eje. |
| `size` prop | Ortogonal — `size` elige tier, scaling multiplica el valor del tier. Compone. |
| Zoom de navegador | Compone multiplicativamente (ambos px). Es app-level, distinto. |
| §20.1 (tipografía no escala con densidad) | Sigue cierto — densidad no la escala; **scaling sí**. Dos ejes. |
## 4. Plan de implementación
1. `STATIC_SCALING` + quitar `scale`/`contentScale` de `STATIC_DENSITY`.
2. Tipos (`SCALING_KEYS`/`ScalingKey`; ajustar `DensityPrimitiveSet`).
3. `render-css`: emisión scaling + bloques + `× var(--scaling)` en las 4 familias;
podar emisión de density scale/content-scale.
4. `ActiveEidos`: `scalingSource` + `data-scaling` + cleanup.
5. `contract`: tokens scaling; quitar density scale/content-scale.
6. Regenerar `generated/base.css`.
7. Tests: actualizar forma de `--space-4`/`--control-height` (× scaling); test de
font-size escalado; bloque `[data-scaling]`; test de `scalingSource`.
8. Verificar (`check` + `vitest src/uix/eidos` + navegador) + doc en THEMING.md.

Powered by TurnKey Linux.