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/components/tooltip/tooltip.css

195 lines
9.4 KiB

/* ── Content (variant-shared base) ──────────────────────────────────────── */
[data-floating-wrapper]:has(> [data-tooltip-content]) {
z-index: var(--tooltip-content-z);
}
[data-tooltip-content] {
--_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);
/* private: per-instance VALUE CHANNEL — `--_tooltip-content-width-override`
and `--_tooltip-match-anchor-width` are written per instance and nobody
declares them; `auto` is the identity when neither is set. A theme pinning
one would break `matchAnchorWidth`. Same class `drawer` §5 signed. */
--_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);
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);
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'] {
--_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'] {
--_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; /* literal: the outline variant IS transparent — identity, not a knob */
--_tooltip-border: var(--color-border-strong);
--_tooltip-shadow: none; /* literal: this variant IS shadowless — identity, not a knob */
}
[data-tooltip-content][data-variant='ghost'] {
/* El plano `overlay` pinta la superficie y gana a esta declaración: se deja
con su valor literal porque acuñar un token aquí sería acuñar una mentira
(medido 2026-08-23; §12.9). */
--_tooltip-bg: color-mix(in srgb, var(--color-surface-overlay) 70%, transparent);
--_tooltip-border: transparent;
--_tooltip-shadow: none; /* literal: this variant IS shadowless — identity, not a knob */
backdrop-filter: blur(var(--tooltip-ghost-blur));
}
/* ── 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(--tooltip-outline-arrow-bg);
}
[data-tooltip-content][data-variant='outline'] ~ [data-tooltip-arrow] path,
[data-tooltip-content][data-variant='outline'] [data-tooltip-arrow] path {
stroke: var(--tooltip-outline-arrow-border);
}
/* ── Entrance / exit ─────────────────────────────────────────────────────────
* Tooltip morfo's data-state values: 'closed' | 'delayed-open' | 'instant-open'.
* 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). */
[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; /* literal: an open tooltip is fully visible — identity, not a knob */
transform: none;
}
/* 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);
}
/* 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. */

Powered by TurnKey Linux.