|
|
|
|
/* ── Content (variant-shared base) ──────────────────────────────────────── */
|
|
|
|
|
|
|
|
|
|
[data-floating-wrapper]:has(> [data-tooltip-content]) {
|
|
|
|
|
z-index: var(--tooltip-content-z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tooltip-content] {
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
--_tooltip-padding-block: var(--tooltip-padding-block-md);
|
|
|
|
|
--_tooltip-padding-inline: var(--tooltip-padding-inline-md);
|
|
|
|
|
--_tooltip-font-size: var(--tooltip-font-size-md);
|
|
|
|
|
--_tooltip-bg: var(--tooltip-bg);
|
|
|
|
|
--_tooltip-border: var(--tooltip-border);
|
|
|
|
|
--_tooltip-shadow: var(--tooltip-shadow);
|
|
|
|
|
--_tooltip-width: var(--_tooltip-content-width-override, var(--_tooltip-match-anchor-width, auto));
|
|
|
|
|
--_tooltip-max-width: var(--_tooltip-content-max-width-override, var(--tooltip-max-width));
|
|
|
|
|
--_tooltip-max-height: var(
|
|
|
|
|
--_tooltip-content-max-height-override,
|
|
|
|
|
var(--floating-available-height, calc(100dvh - var(--space-4)))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
display: block;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
inline-size: var(--_tooltip-width);
|
|
|
|
|
min-inline-size: var(--_tooltip-content-min-width-override, auto);
|
|
|
|
|
max-inline-size: min(var(--_tooltip-max-width), calc(100vw - var(--space-4)));
|
|
|
|
|
block-size: var(--_tooltip-content-height-override, auto);
|
|
|
|
|
min-block-size: var(--_tooltip-content-min-height-override, auto);
|
|
|
|
|
max-block-size: var(--_tooltip-max-height);
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
padding-block: var(--_tooltip-padding-block);
|
|
|
|
|
padding-inline: var(--_tooltip-padding-inline);
|
|
|
|
|
/* `visible` so the absolutely-positioned caret (containing block = this relative
|
|
|
|
|
* content) is NOT clipped where it pokes past the panel edge — the same reason
|
|
|
|
|
* the popover content is `overflow: visible`. Without this the arrow was clipped
|
|
|
|
|
* away entirely. Tooltips are short, so no inner scroll viewport is needed. */
|
|
|
|
|
overflow: visible;
|
|
|
|
|
border: var(--tooltip-border-width) solid var(--_tooltip-border);
|
|
|
|
|
border-radius: var(--tooltip-radius);
|
|
|
|
|
background: var(--_tooltip-bg);
|
refactor(eidos): el catálogo habla un idioma — 269 claves al vocabulario firmado
D-TH.6, ejecutada. El slot de tinta pasa a `fg` y el modificador interactivo
se pone delante, que es lo que theming §6.7 r7 documentaba sin guard desde
que se escribió. Value-preserving: renombra la clave en `recipes/base.ts` y
sus 793 referencias en 101 ficheros; no toca un solo valor.
claves renombradas 269 en 66 componentes
referencias 793 en 101 ficheros
censo antes/después 162 recetas · 5.203 knobs · 1.841 públicos (37 %) · 56
sin contrato — IDÉNTICO, como debe ser un rename
--names antes/después 269 desviadas → 0
Qué NO entra, y por qué:
47 `{rol}-{slot-de-rol}` canónicas: COLOR_ROLE_SLOTS pone el modificador
detrás POR CONSTRUCCIÓN (`primary-solid-hover`)
13 exentas firmadas `--focus-ring-*` es familia del sistema; el color
de `aura` es un sustantivo; `stop-color` ES una
parte de gradient-builder
47 hovers neutros por VALOR: migran a la capa de estado
(§38 + R-4.3), no se renombran — firma 3
6 ocurrencias en historia changelog, errores-toxico, PLAN-affix/background:
reescribir un registro fechado lo vuelve mentira
El clasificador vive en el censo (`--names`), no en un script suelto, para que
el guard R-5.3 consuma la MISMA gramática que el codemod. Su muta-prueba
(`__names-mutatest.ts`, 27 casos) es lo que hizo el trabajo: cazó que yo
promovía al frente CUALQUIER valor declarado por el morfo, y así
`--sidebar-width-icon` (la anchura del raíl colapsado) se convertía en
`--sidebar-icon-width` (la anchura de un icono), que es otra cosa. La firma
dice «delante lo interactivo, detrás lo dimensional y contextual»: ahora sólo
promociona el vocabulario interactivo cerrado, y lo contextual —`below`,
`loaded`, `vertical`, `icon`— se queda donde estaba. Los cinco casos de
regresión están en la muta-prueba.
También cazó que `dropdown-menu.item-bg-hover` lee `var(--color-primary-element)`:
es un hover CON VALENCIA (el palette swap de recipe-contract §2), no el hover
bespoke que §38 deprecó. Clasificar por el nombre lo habría metido en una
migración que no le toca; se clasifica por el VALOR.
Verificación (§7.4, artefacto por paso):
diff de generated/ 269 renombres 1:1 · 0 cambios de valor · 22 privados
reapuntados a los nombres nuevos (`__names-verify-diff`)
computed tag-group · field · tabs: 6.467 valores en 23 estados,
0 diffs — y comprobado en el navegador que sirve el CSS
nuevo, para que ese 0 no sea el de una copia cacheada
huérfanos 0 en código
suite eidos 434 pasan · 1 rojo, el conocido (`skin-media-player`).
`recipe-css-contract` verde: es el guard que caza el
`var()` sin fallback a un nombre que ya no se emite,
o sea el fallo exacto de un rename a medias
component:audit 163 PASS · 3 NEEDS-WORK, los tres SIN TOCAR por esto
check 0 errores en ficheros tocados (los 73 globales son de
otras sesiones de la rama; se atribuye por fichero)
rtl:check 0 · docs:check 0
formato el renombrado no alarga ninguna línea: ningún fichero
tiene más líneas de 100 chars que antes, así que no se
pasa prettier — hacerlo reformateaba 300 ficheros de
deriva ajena
Entra aquí la corrección del repaso de los 7 ya hechos:
`gradient-builder.checker-color` → `checker-fg` (el damero de transparencia;
ahí `color` era slot). Sus `stop-color-*` no se tocan.
Queda para el paso siguiente: R-5.3 no puede graduar a `error` directo
mientras los 47 hovers neutros sigan hablando el idioma viejo — o migran
antes (firma 3, ya firmada), o el guard necesita una exención greppable.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
color: var(--tooltip-fg);
|
|
|
|
|
box-shadow: var(--_tooltip-shadow);
|
|
|
|
|
transform-origin: var(--floating-transform-origin, center);
|
|
|
|
|
font-family: var(--tooltip-font-family);
|
|
|
|
|
font-size: var(--_tooltip-font-size);
|
|
|
|
|
font-weight: var(--tooltip-font-weight);
|
|
|
|
|
line-height: var(--tooltip-line-height);
|
|
|
|
|
text-wrap: pretty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ── Sizes ──────────────────────────────────────────────────────────────── */
|
|
|
|
|
|
|
|
|
|
[data-tooltip-content][data-size='sm'] {
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
--_tooltip-padding-block: var(--tooltip-padding-block-sm);
|
|
|
|
|
--_tooltip-padding-inline: var(--tooltip-padding-inline-sm);
|
|
|
|
|
--_tooltip-font-size: var(--tooltip-font-size-sm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tooltip-content][data-size='lg'] {
|
feat(audit): component re-audit + fixes P0–P5 (P4 complete, P5 in progress)
Re-audit of the whole component catalog at pilot depth (91 fichas + the
checkpoint verdicts in docs/audit/components/) and the executed fix packages.
- P0–P3: doctrine (sema participation, CANON §3 intent, component-guide §5 +
API naming, §32 outline), guards (morfo-vocabulary-check S10/S11d,
component-audit A-3.1/A-1.4/S9, eidos-lint classHooks), morfo contracts
(role=application removed ×4, aria-selected off the Day, drp translationRef,
field data-state prune, pin-input commit-set, media-player renames), 13 new
sema packs + 12 morfos family-default → pack.
- P4 (N1–N10) COMPLETE: selectionMode (select/combobox/toggle-group/calendar);
onValueCommit terminal-callback norm (pin-input/search/password/textarea +
date/time/color-field add); typed validation reason + onInvalid (tags-input,
css-field); index/onIndexChange (carousel); deselectable; openDelay/
groupSkipDelay; allowCustomValue; defaultValue prune.
- P5 (in progress): S1 class-hooks codemod (22 hooks → data-attrs across
cropper/button/image-picker/toggle/image-adjustments); S5 outline remnant in
field.css; depth pass (data-depth=overlay on tooltip/toast/float-panel);
touch-rows (--touch-target token, decoupled ::before hit-slop, area-not-visual,
44 AAA). S6 (Field composition) + S8 (calendar-surface) pending.
Verification: errors-outside-(alpha|words|palabras|chronos) == 59 (baseline);
morfo-vocabulary-check exit 0; eidos-lint class-hooks/invalid 0 on touched
components; per-component vitest suites green.
Handoff + remaining plan: docs/process/continue-audit-fixes-2026-07.md
Excluded (broken by the N1 rename, left broken per user decision, not staged):
words/**, palabras/**, chronos, web/routes/alpha/**.
Reconciliation pending: the touch-rows ::before for checkbox/switch reverses
changelog §37's earlier pseudo-element rejection (WCAG-overlap) that had routed
markers to a labeled-row/Field task — flagged for the user in the handoff.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
--_tooltip-padding-block: var(--tooltip-padding-block-lg);
|
|
|
|
|
--_tooltip-padding-inline: var(--tooltip-padding-inline-lg);
|
|
|
|
|
--_tooltip-font-size: var(--tooltip-font-size-lg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ── Variants ───────────────────────────────────────────────────────────── */
|
|
|
|
|
|
|
|
|
|
/* `solid` is the default surface — the base block already paints it. */
|
|
|
|
|
|
|
|
|
|
[data-tooltip-content][data-variant='outline'] {
|
|
|
|
|
--_tooltip-bg: transparent;
|
|
|
|
|
--_tooltip-border: var(--color-border-strong);
|
|
|
|
|
--_tooltip-shadow: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tooltip-content][data-variant='ghost'] {
|
|
|
|
|
--_tooltip-bg: color-mix(in srgb, var(--color-surface-overlay) 70%, transparent);
|
|
|
|
|
--_tooltip-border: transparent;
|
|
|
|
|
--_tooltip-shadow: none;
|
feat(eidos): canonize theming scales + tokenize magic numbers
Audit-driven canonization of the eidos theming layer: a canonical scale that
components bypass with literals drifts into N variants. Every axis is now
retunable-by-theme AND consumed via token, never a bare literal.
Bloque A/B (scales): --blur-* (Tailwind-aligned, depth planes consume it);
inner-shadow --shadow-inset-* (mode-aware) for the recessed plane; gradient
angle/named tokens; --breakpoint-* sourced from ActiveDom (runtime, dev-settable)
+ container queries; opacity dual numeric+semantic scale; border-width
none/thin/medium/thick/heavy (adds real 3px); tracking caps/widest. Fase 7:
3 size archetypes documented + coherence guard (no px/rem in recipe
font-size/icon-size).
Bloque C (magic numbers): z-index 80/50/99 (combobox/nav-menu/drag-drop) ->
recipe content-z/preview-z tokens (overlay micro-band soma mirrors); on-scale
durations -> var(--duration-*) (dialog fast/slow, card slow); 12 single
border/ring widths -> var(--border-width-*), value-preserving. Off-scale kept
only as justified recipe tokens (continuous spinner/loading periods, sub-fast
press). Self-contained dimensional scales (avatar ring, ring-thickness) left whole.
Docs: THEMING.md SS35 + SS6 + SS29, THEMING_NOTES, README, TSC. Excludes
words/palabras/chronos (active dev tracks).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 months ago
|
|
|
backdrop-filter: blur(var(--blur-md));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ── Arrow ──────────────────────────────────────────────────────────────── */
|
|
|
|
|
|
|
|
|
|
/* `display: block` keeps the SVG off the text baseline — inline added ~21px of
|
|
|
|
|
* phantom height that both misaligned the caret AND pushed the panel too far from
|
|
|
|
|
* the trigger (the positioner adds the measured arrow height to the gap). */
|
|
|
|
|
[data-tooltip-arrow] svg {
|
|
|
|
|
display: block;
|
|
|
|
|
overflow: visible;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Colour the SVG shapes directly — the polygon/path carry `fill`/`stroke =
|
|
|
|
|
* "currentColor"` presentation attributes that a `fill`/`stroke` on the wrapping
|
|
|
|
|
* <span> can't override. The body matches the panel bg (a seamless caret, not a
|
|
|
|
|
* dark blob) and the two exposed edges take the panel border. Now that the content
|
|
|
|
|
* is `overflow: visible` (the caret is no longer clipped), that border outline is
|
|
|
|
|
* what makes the matched caret read against the page — same as the popover. */
|
|
|
|
|
[data-tooltip-arrow] polygon {
|
|
|
|
|
fill: var(--_tooltip-bg, var(--tooltip-bg));
|
|
|
|
|
stroke: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tooltip-arrow] path {
|
|
|
|
|
stroke: var(--_tooltip-border, var(--tooltip-border));
|
|
|
|
|
stroke-width: var(--tooltip-border-width);
|
|
|
|
|
vector-effect: non-scaling-stroke;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Pull the caret base into the panel by the border width (per side) so the fill
|
|
|
|
|
* covers the panel's border there and the side strokes continue the outline —
|
|
|
|
|
* otherwise the panel border draws a line across the caret base. Mirrors the
|
|
|
|
|
* popover recipe. */
|
|
|
|
|
[data-tooltip-arrow][data-side='bottom'] {
|
|
|
|
|
margin-block-start: var(--tooltip-border-width);
|
|
|
|
|
}
|
|
|
|
|
[data-tooltip-arrow][data-side='top'] {
|
|
|
|
|
margin-block-end: var(--tooltip-border-width);
|
|
|
|
|
}
|
|
|
|
|
[data-tooltip-arrow][data-side='left'] {
|
|
|
|
|
margin-inline-end: var(--tooltip-border-width);
|
|
|
|
|
}
|
|
|
|
|
[data-tooltip-arrow][data-side='right'] {
|
|
|
|
|
margin-inline-start: var(--tooltip-border-width);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Outline variant: transparent bg → fill with the surface, stroke the edges. */
|
|
|
|
|
[data-tooltip-content][data-variant='outline'] ~ [data-tooltip-arrow] polygon,
|
|
|
|
|
[data-tooltip-content][data-variant='outline'] [data-tooltip-arrow] polygon {
|
|
|
|
|
fill: var(--color-surface-default);
|
|
|
|
|
}
|
|
|
|
|
[data-tooltip-content][data-variant='outline'] ~ [data-tooltip-arrow] path,
|
|
|
|
|
[data-tooltip-content][data-variant='outline'] [data-tooltip-arrow] path {
|
|
|
|
|
stroke: var(--color-border-strong);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ── Entrance / exit ─────────────────────────────────────────────────────────
|
feat(motion): tooltip entrance is now a bounce (rebote)
Replaces the tooltip's per-side 2px slide-in with a scale BOUNCE: grow from 0.7,
overshoot to 1.06, dip to 0.97 (the undershoot — the "rebote"), settle to 1, over
`--duration-moderate`. It scales from `transform-origin` (the floating origin,
toward the anchor), so it keeps a directional feel without per-side keyframes —
8 keyframes collapse to 2.
Bespoke recipe keyframe, NOT a registered `motion` preset: the tooltip's state is
3-valued (`delayed-open` / `instant-open` / `closed`), not the generic `open` /
`closed` the shared presets key on — so a registered preset wouldn't fire here.
This also confirms the architecture boundary: components whose state shape doesn't
match open/closed use a bespoke recipe animation, not the `motion` selector.
`instant-open` (keyboard focus) keeps no entrance; the reduced-motion block (kills
the animation) already covers the new rules — verified the bounce curve in-browser
(scale 0.7 → 1.06 → 0.97 → 1). Recipe-only change, no generator/base.css touched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 months ago
|
|
|
* Tooltip morfo's data-state values: 'closed' | 'delayed-open' | 'instant-open'.
|
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions
Fable audit follow-through (fable_audit.md + fable-eidos-audit.md):
- RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must
consume, enforced by component-audit R-4.1-4.6 (all at error; escape
valves /* literal */ + /* functional */; WIP tracks excluded). Stale
audit rules fixed against the current architecture (E-2.2 wrapper
imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant
mirror) - verdicts went 0/117/15 -> 75/50/5.
- Motion migration 15/15: recipes off local @keyframes onto the channel -
preset stamps (dropdown/context/select/combobox/tooltip/link-preview/
clipboard), new expand/collapse + value-flash signatures, shared-axis
reverse pair, delayed-open open-alias in the preset trigger
(PRESET_STATE_ALIASES), materials pattern for irreducible triggers
(card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every
recipe's tuned values.
- buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 -
stale alphas after applyColorScheme), intentSeeds so temper starts from
the ACTIVE theme's intent mapping (risk stays orange), alpha background
self-derived from the scheme's own neutral step 1 (was hardcoded
#fff/#111); mode now forces the donor variant.
- Inventory decisions (fase D): semanticTracking axis removed (all-zero),
border-hover slot dropped (0 consumers), separator slot adopted across
line dividers (step 6, Radix divider tone), size-bundle consumption
pilot on toggle (canonical coordinates consumed, deliberate deviations
kept visible).
- Docs: building-a-component.md (the one door, 9-phase route + known
traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh
session), THEMING wiring updates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
* The panel runs the canonical `scale-fade` preset (its original look: subtle
|
|
|
|
|
* scale from the floating transform-origin + fade), stamped by the wrapper as
|
|
|
|
|
* `data-animation-style`. The generator's open-state ALIAS (`delayed-open` ≡
|
|
|
|
|
* open — PRESET_STATE_ALIASES, render-css.ts) is what lets the tri-state
|
|
|
|
|
* machine drive the preset; `instant-open` is deliberately NOT an alias, so a
|
|
|
|
|
* keyboard-focus open appears with no entrance (its semantics). The recipe
|
|
|
|
|
* keeps its tuned durations via the preset's per-element hooks. Reduced motion
|
|
|
|
|
* is the preset's policy (`opacity-only` → quick fade). */
|
|
|
|
|
|
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions
Fable audit follow-through (fable_audit.md + fable-eidos-audit.md):
- RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must
consume, enforced by component-audit R-4.1-4.6 (all at error; escape
valves /* literal */ + /* functional */; WIP tracks excluded). Stale
audit rules fixed against the current architecture (E-2.2 wrapper
imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant
mirror) - verdicts went 0/117/15 -> 75/50/5.
- Motion migration 15/15: recipes off local @keyframes onto the channel -
preset stamps (dropdown/context/select/combobox/tooltip/link-preview/
clipboard), new expand/collapse + value-flash signatures, shared-axis
reverse pair, delayed-open open-alias in the preset trigger
(PRESET_STATE_ALIASES), materials pattern for irreducible triggers
(card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every
recipe's tuned values.
- buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 -
stale alphas after applyColorScheme), intentSeeds so temper starts from
the ACTIVE theme's intent mapping (risk stays orange), alpha background
self-derived from the scheme's own neutral step 1 (was hardcoded
#fff/#111); mode now forces the donor variant.
- Inventory decisions (fase D): semanticTracking axis removed (all-zero),
border-hover slot dropped (0 consumers), separator slot adopted across
line dividers (step 6, Radix divider tone), size-bundle consumption
pilot on toggle (canonical coordinates consumed, deliberate deviations
kept visible).
- Docs: building-a-component.md (the one door, 9-phase route + known
traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh
session), THEMING wiring updates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
[data-tooltip-content] {
|
|
|
|
|
--motion-duration-enter: var(--duration-normal);
|
|
|
|
|
--motion-duration-exit: var(--duration-fast);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* instant-open: no entrance — element appears at final position. */
|
|
|
|
|
[data-tooltip-content][data-state='instant-open'] {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
transform: none;
|
|
|
|
|
}
|
|
|
|
|
|
feat(soma,morfo,eidos): M1(ii) tooltip — los tres eventos existen por fin, y el silencio queda donde estaba firmado
El morfo declaraba emerge-present / emerge-dismiss / emerge-dismiss-escape y
nadie los emitia: el SILENT del pack nunca casaba, la puerta de temas que su
propio docblock documenta no podia funcionar, y el preset present-rise que
declara `event: ['emerge-present',...]` jamas pintaba. La excepcion del censo
lo decia desde agosto: «Today's silence is accidental, not the declared
design».
El re-analisis pedido por el autor cazo lo que la primera propuesta no vio:
la firma present-rise es GLOBAL (base.css:6520), la entrada por data-state es
el workaround de la emision ausente (el comentario del provider lo dice
literal), y la semantica autorizada distingue hover (entrada) de focus
(instant-open, «appears with no entrance — its semantics») — cosa que el
evento no distingue. De ahi la opcion B firmada: el estado conserva la
entrada; la emision añade la superficie que faltaba.
Cableado con la receta F4: `present` pre→post — y SIN su `commits` (fijaba
'delayed-open' y pisaria el 'instant-open' del camino focus; los overlays
binarios conservan el suyo porque su valor es total, desviacion declarada);
dismiss ×2 ganan `targetFallback: [trigger]` (Presence sostiene el content por
la salida; el fallback cubre la carrera). Provider: emision SOLO en
transiciones reales — un open-timer cancelado no presenta nada que retirar, un
re-hover abierto no re-emite — y `handleClose` lleva la causa para distinguir
el Escape.
MEDIDO en navegador, los tres caminos y la fuga exacta:
hover present CONTENT · entrada autorizada corriendo (scale-in+fade-in),
present-rise NO — el preset gana la cascada; miedo al doble
movimiento REFUTADO en el camino delayed
focus present CONTENT con instant-open y present-rise CORRIENDO — la fuga
predicha, confirmada → silencio visual MINIMO en la receta, scoped a
[data-state='instant-open'][data-event-phase='active'];
re-medido: anims [] y la entrada delayed intacta
leave dismiss CONTENT via Presence · salida autorizada (scale-out+
fade-out), dismiss-fade no
Escape dismiss-escape CONTENT · desestampado del hold a ~240ms
Deudas limpiadas en el mismo commit (el guard lo exige): 3 ids de
INERT_EVENT_DEBT + 3 excepciones de EMISSION_EXCEPTIONS. Quedan 4 de la parte
(ii): virtual-list/grid ×3 y gradient-picker commit-reset (S-14).
Verificado: soma navegador 1278✓/1 (el timeout ajeno) · tooltip 4/4 ·
sema+morfo+contracts 552✓/6 ajenos · check 69 = base aislada, diff VACIO ·
prettier: morfo/tooltip.ts limpio en HEAD queda limpio; los 3 avisos ya
fallaban en HEAD.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
|
|
|
/* The emerge firma must not add the entrance this state deliberately lacks.
|
|
|
|
|
* On the delayed path the preset entrance wins the cascade over the global
|
|
|
|
|
* `present-rise` signature (measured 2026-08-13); on instant-open there is no
|
|
|
|
|
* state-keyed animation competing, so the signature would animate a focus /
|
|
|
|
|
* skip-delay appearance — against its semantics. Visual silence, scoped to
|
|
|
|
|
* exactly that path: the same doctrine the sema pack signs for sound
|
|
|
|
|
* («una señal … sabe cuándo permanecer mínima o incluso silenciosa»). */
|
|
|
|
|
[data-tooltip-content][data-state='instant-open'][data-event-phase='active'] {
|
|
|
|
|
animation: none;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ── Trigger states ─────────────────────────────────────────────────────────
|
|
|
|
|
* Trigger is the wrapper around any focusable element (button, link, …).
|
|
|
|
|
* The audit (R-1.2 / R-1.5) requires the recipe to acknowledge `data-disabled`
|
|
|
|
|
* and `:focus-visible`. The wrapped element keeps its own styling; the rules
|
|
|
|
|
* here suppress the tooltip behavior cleanly when the trigger is disabled. */
|
|
|
|
|
|
|
|
|
|
[data-tooltip-trigger][data-disabled] {
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[data-tooltip-trigger]:focus-visible {
|
|
|
|
|
/* Defer the focus ring to the wrapped element — but ensure the outline
|
|
|
|
|
is at least visible if the trigger is rendered as a focusable shell. */
|
|
|
|
|
outline: var(--focus-ring-width) solid var(--focus-ring-color);
|
|
|
|
|
outline-offset: var(--focus-ring-offset);
|
|
|
|
|
}
|
|
|
|
|
|
feat(eidos): recipe contract R-4.x + motion-channel migration 15/15 + theme-builder fixes + inventory decisions
Fable audit follow-through (fable_audit.md + fable-eidos-audit.md):
- RECIPE_CONTRACT.md (E2 canon): the transversal systems every recipe must
consume, enforced by component-audit R-4.1-4.6 (all at error; escape
valves /* literal */ + /* functional */; WIP tracks excluded). Stale
audit rules fixed against the current architecture (E-2.2 wrapper
imports, D-1.2 v2 9-tab union, D-3.1 single snippet, TabsVariant
mirror) - verdicts went 0/117/15 -> 75/50/5.
- Motion migration 15/15: recipes off local @keyframes onto the channel -
preset stamps (dropdown/context/select/combobox/tooltip/link-preview/
clipboard), new expand/collapse + value-flash signatures, shared-axis
reverse pair, delayed-open open-alias in the preset trigger
(PRESET_STATE_ALIASES), materials pattern for irreducible triggers
(card/timeline/tabs/nav-menu/metrics). Duration/scale hooks keep every
recipe's tuned values.
- buildScheme (fase C): full a1..a12 alpha ramp per role (was a2/a3 -
stale alphas after applyColorScheme), intentSeeds so temper starts from
the ACTIVE theme's intent mapping (risk stays orange), alpha background
self-derived from the scheme's own neutral step 1 (was hardcoded
#fff/#111); mode now forces the donor variant.
- Inventory decisions (fase D): semanticTracking axis removed (all-zero),
border-hover slot dropped (0 consumers), separator slot adopted across
line dividers (step 6, Radix divider tone), size-bundle consumption
pilot on toggle (canonical coordinates consumed, deliberate deviations
kept visible).
- Docs: building-a-component.md (the one door, 9-phase route + known
traps), PLAN-docs-reconciliation.md (fase 6 kickoff for a fresh
session), THEMING wiring updates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3 months ago
|
|
|
/* Reduced motion is owned by the preset's policy (`scale-fade` → opacity-only:
|
|
|
|
|
* a brief fade, transforms dropped) — emitted by the generator under both
|
|
|
|
|
* `[data-motion='reduce']` and the media query. No local override needed. */
|