feat(eidos): F4-D foundation — themed selection, caret, scrollbars

Add a "Foundation globals" section to eidos/archetypes.css (document-wide,
not archetype-keyed) closing the two zero-coverage systemic gaps + the
scrollbar item from the F4-D GAP menu:

- ::selection — translucent accent wash (background only, text keeps its
  colour so it stays legible in light and dark)
- caret-color — accent identity on input/textarea/contenteditable, in
  :where() so a field recipe can override (invalid -> threat)
- native scrollbars — themed + thin via the STANDARD properties on :root
  (Firefox + Chromium >= 121). Heavy ::-webkit-scrollbar deliberately
  skipped: ScrollArea draws overlay bars and hides the native one inline
  (scrollbar-width: none on its viewport, which wins). Thumb colour matches
  ScrollArea's thumb.

Cursors were already archetype-wired (trigger/close/action/item/option =
pointer, thumb = grab/grabbing, disabled = not-allowed, text zones = native
input + explicit cursor:text in date-field/editable) — no change needed.

All values read role tokens (--color-primary-solid, --color-content-muted),
lowest specificity so any component recipe still wins.

Verified live (tags-input demo, base-dark): input caret = --color-primary-solid
exactly; scrollbar-width thin applied; ::selection rule present + token
resolves; docs-harness :root override wins (app > foundation). npm run check
src/ = 9-error baseline, 0 new.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
menubar-v4-safe
dev 3 months ago
parent 1c7b4e7f51
commit 58c798b195

@ -21,10 +21,11 @@ el **componente real + control real del demo**, nunca DOM fabricado
(`feedback_verify_with_real_components_not_synthetic_dom`).
**Queda de la §9 / cola lateral (arranque próxima sesión):**
- **F4-D · GAP-\*** (§7 del audit + §F4-D abajo): menú de personalización
(selection/caret/cursor · scrollbar global · layer-4 · jaulas abiertas ·
assets variables · límites a registrar). **Requiere SCOPING del usuario** (qué
se arranca vs qué se registra como límite deliberado).
- **F4-D · GAP-\*** (§7 del audit + §F4-D abajo): menú de personalización.
**✅ selection/caret/cursor + scrollbar global EJECUTADOS 07-12** (bloque
«EJECUTADO 07-12» abajo). **Quedan 4, requieren SCOPING del usuario** (qué se
arranca vs qué se registra como límite deliberado): layer-4 · jaulas abiertas
· assets variables · límites a registrar.
- **cascada-vs-firmas** (motion, cola lateral): las reglas generadas
`[data-stagger][data-state='open'] > [data-animation-style]` (0,3,0) retienen
`animation` y sombrean firmas de evento (0,2,0). Diseño de motion — adjudicar.
@ -748,13 +749,48 @@ Deuda "sin urgencia" desde 2026-05/06 — ponerle fecha (**DECISIÓN #5**):
| Iniciativa | Contenido | Tamaño |
| --- | --- | --- |
| Selection/caret/cursor | La fundación no emite `::selection`, `caret-color` ni tokens de cursor (cableados por arquetipo) — los 3 huecos sistémicos visibles. | M |
| Scrollbar global | `scrollbar-color`/webkit sistémico fuera de scroll-area. | S–M |
| ✅ **Selection/caret/cursor** | **EJECUTADO 07-12** (bloque abajo). Los cursores YA estaban cableados por arquetipo; los huecos reales eran `::selection` + `caret-color` (0 en catálogo). | M |
| ✅ **Scrollbar global** | **EJECUTADO 07-12** (mismo pase). `scrollbar-color`/`scrollbar-width` estándar en `:root`; webkit descartado (ScrollArea oculta la nativa inline). | S–M |
| Layer 4 | `--{c}-{role}-{slot}` sin consumidores; la FAQ la marca candidata a colapso "si en 6 meses nadie la usa" → decidir: consumir o colapsar. | decisión |
| Jaulas abiertas | `scrim` sin regla consumidora · `--depth-{plane}-z` 0 consumidores · container queries 0 consumidores — fecha de consume-o-poda para que no fosilicen. | decisión |
| Assets variables | Motor de fuentes variables listo, assets aún TTF estáticos (rfc-typography §5). | M |
| Límites a registrar (sin código) | Sonido por tema = app/dev (D.7) · icon-set no temable · touch-target constante (§37) · `ThemeDefinition` sin `recipes` (§19). Registrarlos como decisiones en el gap-log y cerrar. | S |
#### ✅ EJECUTADO 07-12 — selection/caret/cursor + scrollbar global
Sección **«Foundation globals»** en `src/uix/eidos/archetypes.css` (no
archetype-keyed: tematizan el DOCUMENTO, no una parte), a especificidad mínima
(bare `::selection`, `:root`, `:where(...)`) para que cualquier recipe gane:
```css
::selection { background-color: color-mix(in srgb, var(--color-primary-solid) 24%, transparent); }
:where(input, textarea, [contenteditable]) { caret-color: var(--color-primary-solid); }
:root { scrollbar-color: var(--color-content-muted) transparent; scrollbar-width: thin; }
```
- **Selección** = lavado accent translúcido 24 %, solo `background-color` (el
texto conserva su color → legible en claro y oscuro).
- **Caret** = identidad accent; en `:where()` para que un recipe de campo lo
pueda cambiar (inválido → threat).
- **Scrollbars** = estándar (Firefox + Chromium ≥ 121). Descartado
`::-webkit-scrollbar`: ScrollArea dibuja overlay y oculta la nativa inline
(`scrollbar-width: none` en su viewport, gana). Thumb = `content-muted` para
casar con el thumb de ScrollArea.
- **Cursores** = NO era hueco: ya cableados (trigger/close/action/item/option →
pointer · thumb → grab/grabbing · disabled → not-allowed · text zones →
input nativo + `cursor: text` en date-field/editable · field-trigger →
pointer). Confirmado con grep; sin cambio.
**Verificado real** (demo tags-input, `data-theme=base-dark`): caret del
`<input>` = `oklch(0.5556 0.1829 305.86)` = `--color-primary-solid` exacto ·
`scrollbar-width: thin` aplicado · regla `::selection` presente y token
resuelve. Precedencia probada: el harness de docs sobre-escribe el default
`:root` con su `--uix-line` (app > fundación). `npm run check` src/ = 9 baseline,
0 nuevos.
**Queda de F4-D** (4 ítems, requieren SCOPING): Layer 4 · jaulas abiertas ·
assets variables · límites a registrar.
---
## Tabla de cobertura (toda ID de §9 → fase)

@ -21,6 +21,41 @@
* property recipes tune — must lose to any component rule.
*/
/* ── Foundation globals (document-wide, NOT archetype-keyed) ─────────────────
* Three catalog-wide affordances the foundation owns directly. They are not
* keyed to a `data-archetype` because they theme the DOCUMENT, not a part —
* selection, caret and native scrollbars have no host element to hang off. All
* three read the same role tokens the rest of eidos uses, so a theme retunes
* them through the config's `--color-*`, never by shadowing this file. Kept at
* the lowest specificity (bare `::selection`, `:root`, `:where(...)`) so any
* component recipe still wins.
*/
/* Text selection — a translucent accent wash. ONLY the background is set: the
* selected text keeps its own colour, so it stays legible on any surface in
* both light and dark (overriding `color` would blow out light-on-dark text). */
::selection {
background-color: color-mix(in srgb, var(--color-primary-solid) 24%, transparent);
}
/* Caret — the accent identity on every free-text control. `:where()` keeps it
* at (0,0,0) so a field recipe can still override it (e.g. invalid → threat). */
:where(input, textarea, [contenteditable]) {
caret-color: var(--color-primary-solid);
}
/* Native scrollbars — themed + thin, catalog-wide, via the STANDARD properties
* (Firefox + Chromium ≥ 121 + Edge). The heavy `::-webkit-scrollbar` pseudo
* tree is deliberately NOT used: ScrollArea draws its own overlay bars and hides
* the native one inline (`scrollbar-width: none` on its viewport, which outranks
* this), so these globals only reach the plain overflow containers (page body,
* ad-hoc scroll regions). Thumb colour matches ScrollArea's thumb so native and
* custom bars read alike when both appear on a page. */
:root {
scrollbar-color: var(--color-content-muted) transparent;
scrollbar-width: thin;
}
/* ── State layer (MD3) — canonical hover / press / selected feedback ─────────
* A translucent `currentColor` overlay: the single source for NEUTRAL interaction
* feedback, collapsing the per-component hover idioms (each recipe was hand-rolling

Loading…
Cancel
Save

Powered by TurnKey Linux.