/* ==========================================================================
   vx-components.css — Vistaria × PostHog grammar: every vx- component recipe
   SPEC.md §4.0–§4.26, §4.32–§4.46 (§4.27–§4.31 shell lives in vx-shell.css).

   Reads tokens from vx-tokens.css (both themes) and icon/keyframe tokens from
   vx-base.css (--vx-i-*, @keyframes vx-*). Components NEVER branch on theme:
   anything that differs between light and dark is a token (§2.2).

   Hue hook: [data-hue]/[data-status] set --vx-h / --vx-h-solid / --vx-h-ink /
   --vx-h-on in vx-tokens.css; recipes here only read them.

   Bare elements (input, select, textarea, table, fieldset) get :where()
   bases (0 specificity) so un-classed markup (article HTML, simple forms)
   still renders in the grammar and any class rule wins. The legacy CLASS
   mappings of the migration (.btn, .card, .panel, .chip …, spec §9.4) were
   retired on 2026-10-03 once every page was on vx- names; the three legacy
   names that still have users are marked "legacy:" below.

   Logical properties only (§7). Physical left/right appear only on the
   always-LTR allow-list (.vx-code, [dir="ltr"] inputs, the .vx-select chevron).
   ========================================================================== */


/* ── §4.1 Button: the 3D keycap ─────────────────────────────────────────── */
.vx-btn{
  --vx-btn-face:var(--vx-neutral-face); --vx-btn-ledge:var(--vx-neutral-ledge);
  --vx-btn-edge:var(--vx-neutral-edge); --vx-btn-edge-hover:var(--vx-neutral-edge-hover);
  --vx-btn-fg:var(--vx-ink);
  --vx-btn-depth:3px; --vx-btn-h:34px; --vx-btn-px:14px; --vx-btn-py:4px; --vx-btn-fs:.875rem; --vx-btn-r:var(--vx-r-md);
  --vx-btn-d:var(--vx-btn-depth); --vx-btn-e:var(--vx-bw-btn);
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:8px;
  box-sizing:border-box; min-block-size:var(--vx-btn-h); padding-block:var(--vx-btn-py); padding-inline:var(--vx-btn-px);   /* the block padding only shows when a label wraps to two lines */
  margin-block-start:0; margin-block-end:calc(var(--vx-btn-depth) + var(--vx-bw-btn));   /* reserve the ledge in block flow (a row of keycaps absorbs it: .vx-actions / .vx-row below) */
  font:600 var(--vx-btn-fs)/1.2 var(--vx-font); letter-spacing:0; text-transform:none; color:var(--vx-btn-fg);
  /* A label WRAPS rather than run past a phone screen (WCAG 1.4.10: de/ru at
     320px ran 9–44px off-screen). The face keeps its height for one line and
     grows for two; a word longer than the keycap breaks rather than overflows.
     No max-inline-size:100%: an inline keycap already shrinks to the room it
     has, and a % cap made a keycap with a negative margin (a summary pulled
     to the gutter) wrap inside its own shrink-to-fit parent at full width.
     Short toolbar/icon keycaps opt out with .vx-btn--nowrap. */
  text-decoration:none; text-align:center; white-space:normal; text-wrap:balance; overflow-wrap:break-word;
  cursor:pointer; user-select:none; -webkit-tap-highlight-color:transparent;
  background:var(--vx-btn-face); border:var(--vx-bw-btn) solid var(--vx-btn-edge); border-radius:var(--vx-btn-r);
  box-shadow:0 var(--vx-btn-d) 0 0 var(--vx-btn-ledge), 0 calc(var(--vx-btn-d) + var(--vx-btn-e)) 0 0 var(--vx-btn-edge);
  translate:0 0;
  transition:translate var(--vx-dur-fast) var(--vx-ease-standard), box-shadow var(--vx-dur-fast) var(--vx-ease-standard),
             border-color var(--vx-dur-fast) var(--vx-ease-standard), background-color var(--vx-dur-fast) var(--vx-ease-standard),
             color var(--vx-dur-fast) var(--vx-ease-standard);
}
.vx-btn:hover{
  --vx-btn-d:calc(var(--vx-btn-depth) + 1px); translate:0 -1px; border-color:var(--vx-btn-edge-hover); color:var(--vx-btn-fg); transition:none; }
.vx-btn:active{
  --vx-btn-d:0px; --vx-btn-e:0px; translate:0 calc(var(--vx-btn-depth) + var(--vx-bw-btn));
  transition:translate var(--vx-dur-press) var(--vx-ease-standard), box-shadow var(--vx-dur-press) var(--vx-ease-standard); }
.vx-btn:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; }
.vx-btn svg{ inline-size:16px; block-size:16px; flex:none; opacity:.85; }
.vx-btn--lg svg{ inline-size:20px; block-size:20px; }

/* variants */
.vx-btn--primary{
  --vx-btn-face:var(--vx-action-face); --vx-btn-ledge:var(--vx-action-ledge); --vx-btn-edge:var(--vx-action-edge);
  --vx-btn-edge-hover:var(--vx-action-edge-hover); --vx-btn-fg:var(--vx-on-action); font-weight:700; }
.vx-btn--secondary{
  --vx-btn-face:var(--vx-secondary-face); --vx-btn-ledge:var(--vx-secondary-ledge); --vx-btn-edge:var(--vx-secondary-edge);
  --vx-btn-edge-hover:var(--vx-action-edge-hover); --vx-btn-fg:var(--vx-ink); font-weight:700; }
.vx-btn--danger{
  --vx-btn-fg:var(--vx-danger); --vx-btn-edge:color-mix(in srgb,var(--vx-danger) 65%,transparent);
  --vx-btn-edge-hover:var(--vx-danger); --vx-btn-ledge:color-mix(in srgb,var(--vx-red) 30%,var(--vx-neutral-face)); }
.vx-btn--danger-solid{
  --vx-btn-face:var(--vx-red-solid); --vx-btn-fg:var(--vx-on-solid); --vx-btn-edge:color-mix(in srgb,var(--vx-red-solid) 70%,var(--vx-on-bright));
  --vx-btn-edge-hover:color-mix(in srgb,var(--vx-red-solid) 55%,var(--vx-on-bright)); --vx-btn-ledge:color-mix(in srgb,var(--vx-red-solid) 75%,var(--vx-on-bright)); font-weight:700; }   /* darkened with the theme-invariant ink (--vx-on-bright), not a literal */

/* tertiary = flat (PostHog app tertiary); ghost = flat + border on hover (PostHog OS default button) */
.vx-btn:is(.vx-btn--tertiary,.vx-btn--ghost){
  --vx-btn-face:transparent; --vx-btn-edge:transparent; --vx-btn-edge-hover:transparent;
  --vx-btn-fg:var(--vx-text); border-width:1px; box-shadow:none; margin-block-end:0; font-weight:600; }
.vx-btn--ghost{ --vx-btn-edge-hover:var(--vx-line-strong); }
.vx-btn:is(.vx-btn--tertiary,.vx-btn--ghost):hover{
  background:var(--vx-hover); color:var(--vx-ink); translate:0 -.5px; }
.vx-btn:is(.vx-btn--tertiary,.vx-btn--ghost):active{
  background:var(--vx-press); translate:0 .5px; }
.vx-btn:is(.vx-btn--tertiary,.vx-btn--ghost)[aria-pressed="true"]{
  background:var(--vx-sunken); color:var(--vx-ink); }
/* a ghost/tertiary that is also danger keeps the flat shape but the danger ink */
.vx-btn:is(.vx-btn--tertiary,.vx-btn--ghost).vx-btn--danger{ --vx-btn-fg:var(--vx-danger); --vx-btn-edge-hover:color-mix(in srgb,var(--vx-danger) 65%,transparent); }

/* sizes (face height excludes the ledge) */
.vx-btn--xs{
  --vx-btn-h:24px; --vx-btn-px:8px;  --vx-btn-py:2px; --vx-btn-fs:.75rem;    --vx-btn-depth:2px; --vx-btn-r:var(--vx-r-sm); gap:4px; }
.vx-btn--sm{ --vx-btn-h:28px; --vx-btn-px:10px; --vx-btn-py:3px; --vx-btn-fs:.8125rem;  --vx-btn-depth:2px; gap:6px; }
/* md is the default: 34px / 14px / 14px / 3px */
.vx-btn--lg{ --vx-btn-h:42px; --vx-btn-px:20px; --vx-btn-py:6px; --vx-btn-fs:.9375rem;  --vx-btn-depth:4px; --vx-btn-r:8px; }
.vx-btn--block{ display:flex; inline-size:100%; }
.vx-btn--icon{ padding:0; inline-size:var(--vx-btn-h); }
/* one line, never wrapped: icon keycaps and the short keycaps of a bar or toolbar
   (they sit in a fixed-height strip). A keycap in a table cell keeps one line
   too: the table scrolls sideways instead of squeezing its row actions. */
.vx-btn:is(.vx-btn--nowrap,.vx-btn--icon), :where(td,th) .vx-btn{ white-space:nowrap; overflow-wrap:normal; }
.vx-btn:is(.vx-btn--nowrap,.vx-btn--icon){ flex-shrink:0; }

/* states */
.vx-btn:is([disabled],[aria-disabled="true"]){ opacity:.5; cursor:not-allowed; }
.vx-btn:is([disabled],[aria-disabled="true"]):is(:hover,:active){
  --vx-btn-d:var(--vx-btn-depth); --vx-btn-e:var(--vx-bw-btn);
  translate:0 0; border-color:var(--vx-btn-edge); background:var(--vx-btn-face); }
.vx-btn.is-loading{ color:transparent; pointer-events:none; }
.vx-btn.is-loading::after{
  content:""; position:absolute; inset:0; margin:auto; inline-size:16px; block-size:16px; border-radius:50%;
  border:2px solid color-mix(in srgb,var(--vx-btn-fg) 30%,transparent); border-block-start-color:var(--vx-btn-fg);
  animation:vx-spin .8s linear infinite; }


/* keycap rows: where the ledge goes (F8). In block flow a keycap reserves its
   ledge with margin-block-end (above). In a ROW (flex/grid) that margin moved
   the face ~2px off the centre line of its neighbours and added height, so 17
   pages undid it 28 times. A row absorbs the ledge instead: its keycaps drop
   the margin, and the row keeps the room under itself (.vx-actions,
   .vx-form__actions) or already has padding for it (feet, heads, bars).
     .vx-actions   a row of keycaps (and links/tags): wraps, 8px gap, centred,
                   keeps --vx-ledge-room under itself. --end: at the inline-end.
     .vx-row       any inline row (label + tag + keycap …): wraps, 8×12 gap,
                   centred; no room kept (it sits in a padded box or a gap). */
.vx-actions{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding-block-end:var(--vx-ledge-room); min-inline-size:0; }
.vx-actions--end{ justify-content:flex-end; }
.vx-row{ display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; min-inline-size:0; }
:is(.vx-actions,.vx-row,.vx-form__actions,.vx-panel__head,.vx-panel__actions,.vx-panel__foot,.vx-modal__head,.vx-modal__foot,
    .vx-banner,.vx-banner__actions,.vx-composer__row,.vx-toolbar,.vx-toolbar__end,.vx-code__head,.vx-scene__actions,.vx-window__actions) > .vx-btn{ margin-block-end:0; }
/* a keycap in a row may shrink (its label wraps) instead of pushing the row past a phone screen */
:is(.vx-actions,.vx-row,.vx-form__actions,.vx-panel__actions,.vx-panel__foot,.vx-modal__foot,.vx-banner__actions,.vx-toolbar__end,.vx-scene__actions) > *{ min-inline-size:0; }


/* ── §4.2 Icon button ───────────────────────────────────────────────────── */
.vx-iconbtn{
  box-sizing:border-box; inline-size:32px; block-size:32px; display:inline-grid; place-items:center; flex:none; padding:0; margin:0;
  color:var(--vx-text-2); background:transparent; border:1px solid transparent; border-radius:var(--vx-r-md); cursor:pointer;
  text-decoration:none; -webkit-tap-highlight-color:transparent;
  transition:background-color var(--vx-dur-fast) var(--vx-ease-standard), color var(--vx-dur-fast), translate var(--vx-dur-fast); }
.vx-iconbtn:hover{ background:var(--vx-hover); color:var(--vx-ink); translate:0 -.5px; transition:none; }
.vx-iconbtn:active{ background:var(--vx-press); translate:0 .5px; }
.vx-iconbtn:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:1px; }
.vx-iconbtn svg{ inline-size:16px; block-size:16px; }
.vx-iconbtn--sm{ inline-size:26px; block-size:26px; border-radius:var(--vx-r-full); }   /* window-bar controls */
.vx-iconbtn--sm svg{ inline-size:14px; block-size:14px; }
.vx-iconbtn[aria-pressed="true"]{ background:var(--vx-sunken); color:var(--vx-ink); }


/* ── §4.3 Window: a card with a title bar (no OS controls) ──────────────── */
.vx-window{ background:var(--vx-sheet); border:1px solid var(--vx-line); border-radius:var(--vx-r-xl);
  box-shadow:var(--vx-shadow-sheet); overflow:clip; container:window / inline-size; min-inline-size:0; }
.vx-window__bar{ display:flex; align-items:center; gap:8px; min-block-size:40px; padding-inline:14px 8px;
  background:color-mix(in srgb,var(--vx-sunken) 55%,var(--vx-sheet)); border-block-end:1px solid var(--vx-line-soft); }
.vx-window__title{ margin:0; font:600 .8125rem/1.2 var(--vx-font); color:var(--vx-ink); letter-spacing:0; min-inline-size:0;
  flex:0 1 auto; max-inline-size:70%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* the title wins on a narrow bar: the path gives way first */
.vx-window__path{ flex:1 1 0; font:500 .75rem/1 var(--vx-font); color:var(--vx-text-3); min-inline-size:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vx-window__bar:not(:has(.vx-window__path)) > .vx-window__title{ max-inline-size:none; }   /* no path shares the bar: the title may use all of it */
.vx-window__actions{ margin-inline-start:auto; display:flex; align-items:center; gap:2px; }
.vx-window__actions > .vx-iconbtn{ opacity:.7; transition:opacity 100ms; }   /* only icon utilities dim: dimmed TEXT would fall under 4.5:1 */
.vx-window__actions > :is(:hover,:focus-visible,:focus-within){ opacity:1; }
.vx-window__body{ padding:clamp(16px, 4cqi, 40px); }
.vx-window--flush > .vx-window__body{ padding:0; }
.vx-window--pop{ animation:vx-pop-in var(--vx-dur-open) var(--vx-ease-back) both; }
@media (max-width:640px){ .vx-window{ border-radius:var(--vx-r-lg); } }


/* ── §4.4 Card (marketing) ──────────────────────────────────────────────── */
.vx-card{
  box-sizing:border-box; background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-lg);
  padding:var(--vx-5); color:var(--vx-text); min-inline-size:0; box-shadow:none; }
.vx-card > :is(h2,h3,.vx-h3):first-child{ margin-block-end:6px; }
.vx-card--sheet{ background:var(--vx-sheet); }
.vx-card--float{ box-shadow:var(--vx-shadow-float); }                         /* the hero scan card */
.vx-card--dashed{ background:var(--vx-sunken); border:2px dashed var(--vx-line-strong); }   /* optional / later / add-on */
.vx-card--desk{ border-radius:var(--vx-r-xl); padding:clamp(20px,5cqi,48px);
  background-color:var(--vx-desk);
  background-image:radial-gradient(72% 72% at 50% 38%, var(--vx-desk-glow), transparent 70%), radial-gradient(var(--vx-desk-dot) 1.4px, transparent 0);
  background-repeat:no-repeat, repeat; background-size:auto, var(--vx-desk-pitch) var(--vx-desk-pitch); background-attachment:scroll, scroll; }
.vx-card--recommended{ border-color:var(--vx-action-edge); box-shadow:0 3px 0 var(--vx-gold); margin-block-end:3px;   /* a gold ledge, the keycap's own depth language — not a stripe */
  padding-block-end:calc(var(--vx-5) - 3px); }   /* the ledge's 3px margin comes off the padding: in a stretched grid its bottom-pinned keycap stays level with its neighbours' */
.vx-card--link{ display:block; color:inherit; text-decoration:none;
  transition:translate var(--vx-dur-open) var(--vx-ease-standard), box-shadow var(--vx-dur-open) var(--vx-ease-standard), border-color var(--vx-dur-fast); }
.vx-card--link:hover{ translate:0 -2px; box-shadow:var(--vx-shadow-lift); border-color:var(--vx-line-strong); }
.vx-card--link:active{ translate:0 0; transition-duration:var(--vx-dur-press); }
.vx-card--link:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; }
/* a card whose parts stack (blog cards: cover, title, excerpt, meta); __foot sits on the bottom edge */
.vx-card--stack, .vx-card--link.vx-card--stack{ display:flex; flex-direction:column; gap:10px; }
.vx-card__foot{ margin-block-start:auto; padding-block-start:4px; color:var(--vx-text-3); }   /* meta line or a go-arrow */
.vx-card__cover{ display:block; inline-size:100%; block-size:auto; aspect-ratio:1200 / 630; object-fit:cover; margin-block-end:4px;
  border:1px solid var(--vx-line); border-radius:var(--vx-r-sm); box-shadow:var(--vx-shadow-photo); }   /* §6.5 card cover */
.vx-card__excerpt{ margin:0; font:500 .9375rem/1.55 var(--vx-font); color:var(--vx-text-2); }
/* the call-to-action card (a desk card closing a page): title, line, one keycap, start-aligned */
.vx-card--cta{ display:grid; gap:12px; justify-items:start; }
.vx-card--cta > .vx-btn{ margin-block-start:8px; }
/* a grid of marketing cards (blog index, hub, related posts) */
.vx-cards{ display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,17rem),1fr)); gap:16px; }


/* ── §4.5 Panel (app and cockpit) ───────────────────────────────────────── */
.vx-panel{
  box-sizing:border-box; background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); min-inline-size:0; }
.vx-panel__head{
  display:flex; flex-wrap:wrap; align-items:center; gap:8px; min-block-size:44px; padding-block:8px; padding-inline:16px 12px;
  border-block-end:1px solid var(--vx-line-soft); }
.vx-panel__title{ margin:0; flex:1 1 0; min-inline-size:0; font:600 1rem/1.35 var(--vx-font); letter-spacing:0; color:var(--vx-ink); }
.vx-panel__meta{
  font:600 .6875rem/1 var(--vx-font); letter-spacing:var(--vx-track-label); text-transform:var(--vx-case-label); color:var(--vx-text-3);
  border:0; background:none; padding:0; min-block-size:0; }
.vx-panel__actions{ margin-inline-start:auto; display:flex; align-items:center; gap:4px; }
.vx-panel__body{ padding:16px; }
.vx-panel__foot{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding-block:10px; padding-inline:16px; border-block-start:1px solid var(--vx-line-soft);
  background:color-mix(in srgb,var(--vx-sunken) 35%,var(--vx-card)); }
/* a save bar that stays on screen while its long panel scrolls; on a phone it rides above the tab bar (--vx-tabbar-h, vx-shell) */
.vx-panel__foot--sticky{ position:sticky; inset-block-end:var(--vx-tabbar-h, 0px); }
/* on a landscape phone (≤500px tall) a save bar stays put only while it has
   something to save: while its warning ("Unsaved") tag shows, or .is-dirty */
@media (max-height:500px){
  .vx-panel__foot--sticky:not(.is-dirty):not(:has(.vx-tag[data-status="warning"]:not([hidden]))){ position:static; }
}
.vx-panel--flush > .vx-panel__body{ padding:0; }                              /* a table fills it edge to edge */
/* the description keeps a small-text measure (34rem ≈ 85 characters at 13px;
   rem, never ch): in a wide panel it ran ~160 a line. The end margin fills the
   rest of the row, so it still starts a line of its own under the title. */
.vx-panel__head .vx-panel__desc{ flex-basis:100%; max-inline-size:34rem; margin:0; margin-inline-end:max(0px, 100% - 34rem);
  font:500 .8125rem/1.4 var(--vx-font); color:var(--vx-text-2); }
/* opt-in: the title keeps its own width, so a tag after it sits beside it (actions still go to the end) */
.vx-panel__head--inline > .vx-panel__title{ flex:0 1 auto; }
/* a panel stretched by its grid row grows its body, so a __foot stays on the bottom edge */
.vx-panel--fill{ display:flex; flex-direction:column; }
.vx-panel--fill > .vx-panel__body{ flex:1 1 auto; }


/* ── §4.6 Tile (dashboard insight tile) ─────────────────────────────────── */
.vx-tile{ display:flex; flex-direction:column; min-inline-size:0; background:var(--vx-card); border:1px solid var(--vx-line);
  border-radius:var(--vx-r-md); transition:border-color var(--vx-dur-open) ease, box-shadow var(--vx-dur-open) ease; }
.vx-tile__head{ display:flex; gap:10px; padding-block:14px 10px; padding-inline:14px 12px; }
.vx-tile__ribbon{ inline-size:6px; align-self:stretch; flex:none; border-radius:var(--vx-r-md); background:var(--vx-h, var(--vx-line-strong)); }
.vx-tile__titles{ min-inline-size:0; display:grid; gap:2px; }
.vx-tile__title{ margin:0; font:600 1rem/1.5 var(--vx-font); letter-spacing:0; color:var(--vx-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* (meta, actions: no product page uses them yet; kept as the spec's tile anatomy, §4.6, shown in the harness specimen) */
.vx-tile__meta{ font:600 .6875rem/1rem var(--vx-font); letter-spacing:var(--vx-track-label); text-transform:var(--vx-case-label); color:var(--vx-text-3); }
.vx-tile__actions{ margin-inline-start:auto; display:flex; align-items:flex-start; gap:2px; opacity:0; transition:opacity var(--vx-dur-fast); }
.vx-tile:is(:hover,:focus-within) .vx-tile__actions{ opacity:1; }
@media (hover:none){ .vx-tile__actions{ opacity:1; } }
.vx-tile__body{ flex:1; min-block-size:0; padding-block:0 16px; padding-inline:16px; }
.vx-tile:hover{ box-shadow:var(--vx-elev); }
.vx-tile.is-highlighted{ border-color:var(--vx-accent); outline:1px solid var(--vx-accent); }


/* ── §4.7 Stat / KPI ────────────────────────────────────────────────────── */
.vx-stats{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,10rem),1fr)); gap:12px; }
.vx-stat{
  box-sizing:border-box; position:relative; display:flex; flex-direction:column; gap:4px; min-inline-size:0; padding-block:14px; padding-inline:16px;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); }
.vx-stat:is([data-hue],[data-status])::before{
  content:""; position:absolute; inset-block:12px; inset-inline-start:-1px;
  inline-size:3px; border-start-end-radius:3px; border-end-end-radius:3px; background:var(--vx-h); }   /* logical: no RTL override needed */
.vx-stat__label{ font:500 .8125rem/1.3 var(--vx-font); color:var(--vx-text-2); display:flex; align-items:center; gap:6px; }
.vx-stat__value{ font:700 clamp(1.5rem,1rem + 1.4vw,2.25rem)/1.1 var(--vx-font-figures); font-variant-numeric:tabular-nums;
  letter-spacing:var(--vx-track-tight); color:var(--vx-ink); white-space:nowrap; }
.vx-stat__unit{ font-size:.5em; font-weight:600; color:var(--vx-text-3); margin-inline-start:.15em; letter-spacing:0; }
.vx-stat__delta{ display:inline-flex; align-items:center; gap:4px; font:600 .8125rem/1.2 var(--vx-font-figures); font-variant-numeric:tabular-nums; color:var(--vx-text-3); }
.vx-stat__delta--up{ color:var(--vx-success); }
.vx-stat__delta--down{ color:var(--vx-danger); }
.vx-stat__delta svg{ inline-size:12px; block-size:12px; }     /* ▲ ▼ are vertical: never mirrored */
.vx-stat__spark{ display:block; inline-size:100%; margin-block-start:6px; block-size:28px; overflow:visible; }   /* §4.7 (the specimen's; rooms still draw their own) */
.vx-stat__spark :is(polyline,path){ fill:none; stroke:var(--vx-s, var(--vx-series-1)); stroke-width:1.5; stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }


/* ── §4.8 Callouts, the sticky note and the hand-note ───────────────────── */
.vx-callout{ --bg:var(--vx-sunken); --ln:var(--vx-line); --ic:var(--vx-text-2);
  display:grid; grid-template-columns:20px minmax(0,1fr); gap:2px 10px; padding-block:14px; padding-inline:16px; margin-block:16px 24px;
  background:var(--bg); border:1px solid var(--ln); border-radius:var(--vx-r-md); color:var(--vx-text); }
.vx-callout__icon{ grid-row:span 2; inline-size:20px; block-size:20px; margin-block-start:2px; color:var(--ic); opacity:.85; }
.vx-callout__title{ margin:0; font:700 1rem/1.4 var(--vx-font); color:var(--vx-ink); }
.vx-callout__body{ grid-column:2; margin:0; font:500 .9375rem/1.6 var(--vx-font); }
.vx-callout--action { --bg:color-mix(in srgb,var(--vx-gold) 15%,var(--vx-card)); --ln:var(--vx-gold);  --ic:var(--vx-gold-ink); }
.vx-callout--fyi    { --bg:var(--vx-sunken); }
.vx-callout--caution{ --bg:color-mix(in srgb,var(--vx-red) 10%,var(--vx-card)); --ln:color-mix(in srgb,var(--vx-red) 60%,transparent); --ic:var(--vx-red-ink); }
.vx-callout--tip    { --bg:color-mix(in srgb,var(--vx-teal) 10%,var(--vx-card)); --ln:color-mix(in srgb,var(--vx-teal) 50%,transparent); --ic:var(--vx-teal-ink); }
/* On a tinted status/callout ground text-3 falls under 4.5:1 in dark (3.79–4.45):
   meta text there is set in text-2. scripts/design_qa.py --only contrast checks
   text-2 and the link colour on every one of these grounds. */
:is(.vx-callout--action,.vx-callout--caution,.vx-callout--tip,.vx-banner--success,.vx-banner--warning,.vx-banner--danger,.admin-err){ --vx-text-3:var(--vx-text-2); }

/* sticky note: a scrapbook card with masking tape; max one per page */
.vx-note{ --vx-text-3:var(--vx-text-2);   /* on the note's gold tint text-3 falls to 3.9:1 in dark */
  position:relative; padding-block:20px 16px; padding-inline:18px; color:var(--vx-text);
  background:color-mix(in srgb,var(--vx-gold) 14%,var(--vx-card)); border:1px solid color-mix(in srgb,var(--vx-gold) 40%,var(--vx-line));
  border-radius:var(--vx-r-sm); box-shadow:var(--vx-shadow-photo); rotate:calc(-1deg * var(--vx-dir)); }
.vx-note::before{ content:""; position:absolute; inset-block-start:-11px; inline-size:86px; block-size:24px;
  background:var(--vx-tape); border:1px solid color-mix(in srgb,var(--vx-ink) 6%,transparent);
  clip-path:polygon(4% 0,96% 0,100% 18%,97% 36%,100% 54%,97% 72%,100% 90%,95% 100%,4% 100%,0 82%,3% 62%,0 44%,3% 26%,0 10%); }
.vx-note::before{ inset-inline-start:24px; rotate:calc(-4deg * var(--vx-dir)); }

/* hand-note label ("Fresh", "Start here"): bold italic blue, tilted */
.vx-handnote{ display:inline-block; font:700 1.125rem/1.2 var(--vx-font); font-style:italic; color:var(--vx-blue-ink);
  rotate:calc(-2deg * var(--vx-dir)); }
.vx-handnote:is(:lang(fa),:lang(ar),:lang(ur),:lang(ja),:lang(zh),:lang(ko),:lang(hi)){ font-style:normal; font-weight:800; }


/* ── §4.9 Tags and badges: outlined, not filled ─────────────────────────── */
.vx-tag{
  box-sizing:border-box; display:inline-flex; align-items:center; gap:3px; min-block-size:20px; padding-block:1px; padding-inline:6px;
  font:500 .6875rem/1rem var(--vx-font); letter-spacing:0; text-transform:none; color:var(--vx-h-ink, var(--vx-text-2));
  border:1px solid color-mix(in srgb, var(--vx-h-ink, var(--vx-text-3)) 55%, transparent); border-radius:var(--vx-r-sm);
  background:transparent; white-space:nowrap; vertical-align:middle; text-decoration:none; }
.vx-tag:is(:lang(fa),:lang(ar),:lang(ur)){ font-size:.75rem; }
.vx-tag svg{ inline-size:12px; block-size:12px; opacity:.85; }
.vx-tag--tint{
  background:color-mix(in srgb,var(--vx-h, var(--vx-text-3)) 12%,transparent); border-color:transparent; }
.vx-tag--solid{ background:var(--vx-h-solid, var(--vx-slate-solid)); color:var(--vx-h-on, var(--vx-on-solid)); border-color:transparent; font-weight:600; }
.vx-tag--muted{ color:var(--vx-text-2); background:var(--vx-card); border-color:var(--vx-line); }
a.vx-tag:hover{ border-color:var(--vx-h-ink, var(--vx-line-strong)); transition:none; }   /* hovered text chips change border, never fill (§2.3) */
a.vx-tag:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; }

/* §4.46 lamp tag */
.vx-tag--dot::before{ content:""; inline-size:6px; block-size:6px; flex:none; border-radius:50%; background:currentColor; }


/* ── §4.10 Pills / filter chips ─────────────────────────────────────────── */
.vx-pills{ display:flex; flex-wrap:wrap; gap:6px; }
.vx-pill{
  box-sizing:border-box; display:inline-flex; align-items:center; gap:6px; min-block-size:28px; padding-block:4px; padding-inline:11px; cursor:pointer;
  font:500 .8125rem/1.2 var(--vx-font); letter-spacing:0; color:var(--vx-text-2); text-decoration:none; background:transparent;
  border:1px solid transparent; border-radius:var(--vx-r-full);
  transition:color var(--vx-dur-fast) var(--vx-ease-standard), border-color var(--vx-dur-fast), background-color var(--vx-dur-fast); }
.vx-pill:hover{ border-color:var(--vx-line-strong); color:var(--vx-ink); transition:none; }
.vx-pill:is([aria-pressed="true"],[aria-current],.is-active){
  background:var(--vx-blue-solid); border-color:var(--vx-blue-solid); color:var(--vx-on-solid); }
.vx-pill:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; }
.vx-pill--outline{ border-color:var(--vx-line); }
.vx-pill--outline:is([aria-pressed="true"],[aria-current],.is-active){ border-color:var(--vx-blue-solid); }


/* ── §4.11 Count badge, kbd and avatar ──────────────────────────────────── */
.vx-count{ box-sizing:border-box; display:inline-grid; place-items:center; min-inline-size:20px; block-size:20px; padding-block:0; padding-inline:5px;
  font:700 .75rem/1 var(--vx-font-figures); font-variant-numeric:tabular-nums;
  color:var(--vx-h-on, var(--vx-on-accent)); background:var(--vx-h-solid, var(--vx-accent));
  border:2px solid var(--vx-sheet); border-radius:var(--vx-r-full); }
.vx-count[hidden]{ display:none; }
kbd{ box-sizing:border-box; display:inline-grid; place-items:center; min-inline-size:20px; block-size:20px; padding-block:0; padding-inline:4px;
  font:500 .75rem/1 var(--vx-mono); color:var(--vx-text-2); background:var(--vx-card);
  border:1px solid var(--vx-line-strong); border-block-end-width:2px; border-radius:var(--vx-r-sm); }
.vx-avatar{ inline-size:28px; block-size:28px; display:inline-grid; place-items:center; flex:none; border-radius:var(--vx-r-md);
  font:600 .8125rem/1 var(--vx-font); color:var(--vx-h-ink, var(--vx-teal-ink));
  background:color-mix(in srgb,var(--vx-h, var(--vx-teal)) 18%,var(--vx-card)); }


/* ── §4.12 Highlights in copy ───────────────────────────────────────────── */
.vx-hl{ color:var(--vx-h-ink, var(--vx-blue-ink)); background:color-mix(in srgb,var(--vx-h, var(--vx-blue)) var(--vx-hl-mix),transparent);
  border-radius:var(--vx-r-md); padding-inline:.18em; -webkit-box-decoration-break:clone; box-decoration-break:clone; }
:is(.vx-display,.vx-h1,.vx-h2) .vx-hl{ line-height:1.3; }   /* the tint box stops short of the previous line's descenders */
.vx-hl--free{ color:var(--vx-lime-ink); background:color-mix(in srgb,var(--vx-lime) var(--vx-free-mix),transparent); border-radius:var(--vx-r-sm); padding-inline:.22em; }
/* marker: drawn once when scrolled into view (JS arms it; without JS it is simply shown) */
.vx-mark{ background-image:linear-gradient(var(--vx-mark),var(--vx-mark)); background-repeat:no-repeat;
  background-position:0 90%; background-size:100% 70%; padding-inline:.06em;
  border-start-start-radius:.3em; border-start-end-radius:.55em; border-end-end-radius:.35em; border-end-start-radius:.6em;
  -webkit-box-decoration-break:clone; box-decoration-break:clone; color:inherit; }
[dir="rtl"] .vx-mark{ background-position:100% 90%; }
html.js .vx-mark.is-armed{ background-size:0% 70%; }
html.js .vx-mark.is-armed.is-in{ background-size:100% 70%; transition:background-size var(--vx-dur-draw) var(--vx-ease-out-quint); }


/* ── §4.13 Product glyph tile ───────────────────────────────────────────── */
.vx-glyph{ --s:28px; inline-size:var(--s); block-size:var(--s); flex:none; display:inline-grid; place-items:center;
  border-radius:var(--vx-r-md); color:var(--vx-h-ink, var(--vx-text-2));
  background:color-mix(in srgb,var(--vx-h, var(--vx-text-3)) 12%,transparent); transition:background-color var(--vx-dur-fast); }
.vx-glyph svg{ inline-size:calc(var(--s) * .58); block-size:calc(var(--s) * .58); }
.vx-glyph--sm{ --s:20px; border-radius:var(--vx-r-sm); }
.vx-glyph--lg{ --s:40px; }
.vx-glyph--xl{ --s:56px; border-radius:var(--vx-r-lg); }
:is(a,button,[role="tab"]):hover > .vx-glyph, .vx-glyph:is(a,button):hover{ background:color-mix(in srgb,var(--vx-h, var(--vx-text-3)) 22%,transparent); transition:none; }
:is([aria-current="page"],[aria-current="location"],[aria-selected="true"],.is-active) > .vx-glyph, .vx-glyph.is-active{ background:var(--vx-h-solid, var(--vx-slate-solid)); color:var(--vx-h-on, var(--vx-on-solid)); }


/* ── §4.14 Segmented control ────────────────────────────────────────────── */
.vx-seg{
  display:inline-flex; gap:2px; padding:3px; background:var(--vx-sheet); border:1px solid var(--vx-line-control); border-radius:8px; }
.vx-seg > :is(a,button,label){ position:relative; display:inline-flex; align-items:center; gap:6px; min-block-size:28px; padding-block:0; padding-inline:12px; cursor:pointer;
  font:500 .8125rem/1 var(--vx-font); letter-spacing:0; color:var(--vx-text-2); text-decoration:none; background:transparent;
  border:0; border-radius:var(--vx-r-sm); transition:background-color var(--vx-dur-fast), color var(--vx-dur-fast); }
.vx-seg > :hover{ background:var(--vx-hover); color:var(--vx-ink); transition:none; }
.vx-seg > :is([aria-pressed="true"],[aria-checked="true"],[aria-current]:not([aria-current="false"]),.is-on,:has(input:checked)){
  background:var(--vx-sunken); color:var(--vx-ink); font-weight:600; }
.vx-seg input{ position:absolute; opacity:0; pointer-events:none; }
.vx-seg > :focus-visible, .vx-seg > :has(input:focus-visible){ outline:2px solid var(--vx-focus); outline-offset:1px; }


/* ── §4.15 Tabs: underline (app) and folder (marketing) ─────────────────── */
.vx-tabs{
  display:flex; gap:24px; border-block-end:1px solid var(--vx-line); overflow-x:auto; scrollbar-width:none;
  padding-inline:4px; margin-inline:-4px; }   /* room for the first/last tab's focus ring inside the scroller */
@media (max-width:767px){ .vx-tabs{ gap:16px; } }
.vx-tab{
  position:relative; flex:none; padding-block:10px 11px; padding-inline:4px; margin-inline:-4px;   /* the inset focus ring clears the glyphs; net position unchanged */
  font:600 .875rem/1.2 var(--vx-font); letter-spacing:0; color:var(--vx-text-3);
  background:none; border:0; text-decoration:none; white-space:nowrap; cursor:pointer; transition:color var(--vx-dur-fast); }
.vx-tab:hover{ color:var(--vx-ink); transition:none; }
.vx-tab::after{ content:""; position:absolute; inset-inline:4px; inset-block-end:-1px; block-size:2px;
  border-start-start-radius:2px; border-start-end-radius:2px;
  background:var(--vx-accent); scale:0 1; transition:scale var(--vx-dur-fast) var(--vx-ease-standard); }
.vx-tab:is([aria-selected="true"],[aria-current="page"],[aria-current="true"],.is-active){ color:var(--vx-accent-ink); }
.vx-tab:is([aria-selected="true"],[aria-current="page"],[aria-current="true"],.is-active)::after{ scale:1 1; }
.vx-tab:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:-2px; border-radius:var(--vx-r-sm); }
.vx-tab .vx-count{ margin-inline-start:6px; }
/* A strip that scrolls sideways (tabs, folder tabs, the app bar's links) has
   no scrollbar: its edge fades while more tabs hide that way (R10). ui.js §16
   sets data-vx-more="start|end|start end" from the scroll position, in the
   reading direction. */
[data-vx-more]{ --vx-fade:28px; }   /* the mask only reads alpha: any opaque token draws it */
[data-vx-more="end"]{ -webkit-mask-image:linear-gradient(to right,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); mask-image:linear-gradient(to right,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); }
[data-vx-more="start"]{ -webkit-mask-image:linear-gradient(to left,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); mask-image:linear-gradient(to left,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); }
[dir="rtl"] [data-vx-more="end"]{ -webkit-mask-image:linear-gradient(to left,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); mask-image:linear-gradient(to left,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); }
[dir="rtl"] [data-vx-more="start"]{ -webkit-mask-image:linear-gradient(to right,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); mask-image:linear-gradient(to right,var(--vx-ink) calc(100% - var(--vx-fade)),transparent); }
[data-vx-more="start end"]{ -webkit-mask-image:linear-gradient(to right,transparent,var(--vx-ink) var(--vx-fade),var(--vx-ink) calc(100% - var(--vx-fade)),transparent); mask-image:linear-gradient(to right,transparent,var(--vx-ink) var(--vx-fade),var(--vx-ink) calc(100% - var(--vx-fade)),transparent); }

/* folder tabs: each tab has its product colour; the active tab joins an 8px frame of the same colour */
.vx-folder{ min-inline-size:0; }
.vx-folder__tabs{ display:flex; gap:4px; overflow-x:auto; scrollbar-width:none; }
.vx-folder__tab{ display:inline-flex; align-items:center; gap:8px; flex:none; padding-block:10px; padding-inline:14px; cursor:pointer;
  font:600 .875rem/1.2 var(--vx-font); letter-spacing:0; color:var(--vx-text-2); background:transparent; border:0;
  border-start-start-radius:var(--vx-r-md); border-start-end-radius:var(--vx-r-md); border-end-start-radius:0; border-end-end-radius:0;
  transition:background-color var(--vx-dur-fast), color var(--vx-dur-fast); }
.vx-folder__tab:hover{ background:var(--vx-hover); color:var(--vx-ink); transition:none; }
.vx-folder__tab[aria-selected="true"]{ background:var(--vx-h-solid); color:var(--vx-h-on); }
.vx-folder__tab:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:-2px; }
.vx-folder__tab[aria-selected="true"] .vx-glyph{ background:color-mix(in srgb,var(--vx-h-on) 18%,transparent); color:var(--vx-h-on); }
.vx-folder__panel{ border:8px solid var(--vx-h-solid, var(--vx-slate-solid)); border-radius:var(--vx-r-lg); background:var(--vx-h-solid, var(--vx-slate-solid)); }
.vx-folder:has(.vx-folder__tab:first-child[aria-selected="true"]) .vx-folder__panel{ border-start-start-radius:0; }  /* square only under the FIRST tab, while it is active */
.vx-folder__inner{ background:var(--vx-card); color:var(--vx-text); border-radius:4px; padding:clamp(16px,3cqi,28px);
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.1fr); gap:24px; align-items:center; }
@container window (max-width:760px){ .vx-folder__inner{ grid-template-columns:1fr; } .vx-folder__panel{ border-width:4px; } }
@media (max-width:760px){ .vx-folder__inner{ grid-template-columns:1fr; } .vx-folder__panel{ border-width:4px; } }
.vx-folder__panel[hidden]{ display:none; }
.vx-folder__panel:not([hidden]){ animation:vx-fade-in var(--vx-dur-panel) ease-out both; }


/* ── §4.16 Tables and the comparison table ──────────────────────────────── */
/* bare <table> is a :where() base (0 specificity) so page CSS still wins */
.vx-table-wrap{
  position:relative; border:1px solid var(--vx-line); border-radius:var(--vx-r-md);
  overflow:auto; -webkit-overflow-scrolling:touch;
  /* Edge shade while more of the table hides sideways (R8): two shades fixed
     to the box's edges, two covers in the card colour riding on the content's
     own edges. At the scroll start the start cover hides the start shade and
     only the far edge shows a shade; scrolled to the end, the reverse. The
     content edges ARE the reading edges, so this is right in RTL with no
     direction rule. ui.js makes an overflowing wrap a named, focusable region. */
  background:
    linear-gradient(to right, var(--vx-card) 40%, transparent) left center / 28px 100% no-repeat local,
    linear-gradient(to left, var(--vx-card) 40%, transparent) right center / 28px 100% no-repeat local,
    linear-gradient(to right, var(--vx-scroll-shadow), transparent) left center / 12px 100% no-repeat scroll,
    linear-gradient(to left, var(--vx-scroll-shadow), transparent) right center / 12px 100% no-repeat scroll,
    var(--vx-card); }
/* header cells let the shade through (a sticky header keeps its card ground: rows scroll under it) */
.vx-table-wrap > :is(table,.vx-table):not(.vx-table--sticky) th{ background:transparent; }
/* A row-action column stays on screen on a phone (R8): `.vx-col-act` on its th/td
   pins it to the table's visible end edge while the other columns scroll under
   it, with a shade on its inner edge; a focused cell scrolls clear of it (2.4.11). */
@container sheet (max-width:640px){
  .vx-table-wrap .vx-table :is(th,td).vx-col-act{ position:sticky; inset-inline-end:0; z-index:1; background:var(--vx-card);
    border-inline-start:1px solid var(--vx-line-soft); box-shadow:calc(-4px * var(--vx-dir)) 0 6px -4px var(--vx-scroll-shadow); }
  .vx-table-wrap .vx-table th.vx-col-act{ z-index:2; }
  .vx-table-wrap:has(.vx-col-act){ scroll-padding-inline-end:8rem; }
}
/* a table that fills a flush panel loses its own frame: the panel is the frame */
.vx-panel--flush > .vx-panel__body > .vx-table-wrap{ border:0; border-radius:0; }
.vx-table,
:where(table:not([role="presentation"])){        /* bare table: article HTML */
  inline-size:100%; border-collapse:separate; border-spacing:0; font:500 .8125rem/1.4 var(--vx-font); color:var(--vx-text-2); }
.vx-table caption, :where(table caption){ caption-side:top; text-align:start; padding-block:12px 0; padding-inline:16px; font:600 .9375rem/1.3 var(--vx-font); color:var(--vx-ink); }
.vx-table th, :where(table:not([role="presentation"]) th){
  padding:8px; text-align:start; white-space:nowrap; background:var(--vx-card);
  font:700 .75rem/1rem var(--vx-font); letter-spacing:calc(var(--vx-track-label) * .66); text-transform:var(--vx-case-label); color:var(--vx-text-3);
  border-block-end:1px solid var(--vx-line); }
.vx-table th:is(:lang(fa),:lang(ar),:lang(ur)), :where(table:not([role="presentation"]) th:is(:lang(fa),:lang(ar),:lang(ur))){ font-size:.8125rem; }
.vx-table td, :where(table:not([role="presentation"]) td){ padding-block:7px; padding-inline:8px; vertical-align:middle; border-block-start:1px solid var(--vx-line-soft); }
.vx-table tbody tr:first-child td, :where(table:not([role="presentation"]) tbody tr:first-child td){ border-block-start:0; }
.vx-table thead + tbody tr:first-child td{ border-block-start:0; }
.vx-table :is(th,td):first-child, :where(table:not([role="presentation"]) :is(th,td):first-child){ padding-inline-start:16px; }
.vx-table :is(th,td):last-child, :where(table:not([role="presentation"]) :is(th,td):last-child){ padding-inline-end:16px; }
.vx-table :is(td,th) :is(b,strong), .vx-table .is-primary, :where(table td :is(b,strong)){ color:var(--vx-ink); font-weight:600; }
:is(.vx-table,table) .vx-num{ text-align:end; font-family:var(--vx-font-figures); font-variant-numeric:tabular-nums; white-space:nowrap; }
.vx-table tr:is(.is-clickable,[data-href]):hover td{ background:var(--vx-accent-tint); cursor:pointer; }
.vx-table tr.is-selected td{ background:var(--vx-accent-tint); color:var(--vx-ink); font-weight:600; }
.vx-table tr.is-new td{ animation:vx-row-new 1.5s ease-out; }
.vx-table tr:is([data-hue],[data-status]) td:first-child{ box-shadow:inset calc(3px * var(--vx-dir)) 0 0 var(--vx-h); }
.vx-table--lg{ font-size:.9375rem; }
.vx-table--lg td{ padding-block:10px; padding-inline:12px; }
.vx-table--lg th{ padding-block:10px; padding-inline:12px; }
.vx-table--sticky thead th{ position:sticky; inset-block-start:0; z-index:1; }
/* a box that scrolls a sticky-header table keeps a focused row clear of that header (WCAG 2.4.11) */
:is(.vx-table-wrap, .ck-scroll):has(> .vx-table--sticky, > .vx-table-wrap > .vx-table--sticky){ scroll-padding-block-start:44px; }
.vx-table th button, :where(table th button){ all:unset; cursor:pointer; display:inline-flex; gap:4px; align-items:center; }
.vx-table th button:hover, :where(table th button:hover){ color:var(--vx-ink); }
.vx-table th button:focus-visible, :where(table th button:focus-visible){ outline:2px solid var(--vx-focus); outline-offset:2px; border-radius:var(--vx-r-sm); }
.vx-table th[aria-sort] button::after{ content:""; inline-size:10px; block-size:10px; background:currentColor;
  -webkit-mask:var(--vx-i-chevron) center/contain no-repeat; mask:var(--vx-i-chevron) center/contain no-repeat; }
.vx-table th[aria-sort="ascending"] button::after{ rotate:180deg; }   /* ascending = up; vertical, never mirrored */
.vx-table th[aria-sort="none"] button::after{ opacity:.35; }
.vx-table-wrap.is-loading::before{ content:""; position:absolute; inset-block-start:0; inset-inline-start:0; block-size:2px; inline-size:33%;
  background:var(--vx-accent); animation:vx-loadbar 1.5s linear infinite; z-index:2; }   /* vx-loadbar translates the strip (transform only) */
.vx-table-foot{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding-block:8px; padding-inline:16px; border-block-start:1px solid var(--vx-line-soft);
  font:500 .8125rem/1.3 var(--vx-font); color:var(--vx-text-2); }

/* comparison table (✓ / ✗), marketing: use as .vx-table.vx-table--lg.vx-compare */
.vx-compare{ table-layout:fixed; }
.vx-compare th[scope="col"]{ text-align:center; font:600 .9375rem/1.3 var(--vx-font); text-transform:none; letter-spacing:0; color:var(--vx-ink); white-space:normal; }
.vx-compare th[scope="row"]{ text-align:start; font:700 .9375rem/1.35 var(--vx-font); color:var(--vx-ink); text-transform:none; letter-spacing:0; white-space:normal; border-block-end:0;
  border-block-start:1px solid var(--vx-line-soft); background:transparent; }
.vx-compare tbody tr:first-child th[scope="row"]{ border-block-start:0; }
.vx-compare th[scope="row"] small{ display:block; margin-block-start:2px; font:500 .875rem/1.4 var(--vx-font); color:var(--vx-text-2); }
.vx-compare td, .vx-compare :is(td,th).vx-num{ text-align:center; }
.vx-compare :is(td,th)+:is(td,th){ border-inline-start:1px solid var(--vx-line-soft); }
.vx-compare .is-us{ background:color-mix(in srgb,var(--vx-gold) 10%,var(--vx-card)); }
.vx-compare thead .is-us{ color:var(--vx-ink); font-weight:700; }   /* the tinted column carries the emphasis; no stripe */
.vx-yes,.vx-no{ display:inline-block; inline-size:18px; block-size:18px; vertical-align:middle; }
.vx-yes{ color:var(--vx-success); }
.vx-no{ color:var(--vx-danger); }   /* SVG, stroke 2.25, + visually hidden translated "Yes"/"No" */


/* ── §4.17 Forms ────────────────────────────────────────────────────────── */
.vx-field{
  display:grid; gap:6px; min-inline-size:0; }
.vx-field__label{
  font:600 .875rem/1.3 var(--vx-font); letter-spacing:0; text-transform:none; color:var(--vx-ink); }
.vx-field__label .vx-req{ color:var(--vx-danger); margin-inline-start:2px; }
.vx-field__help{
  font:500 .8125rem/1.45 var(--vx-font); color:var(--vx-text-2); }
.vx-field__error{ display:flex; gap:6px; align-items:flex-start; font:600 .8125rem/1.4 var(--vx-font); color:var(--vx-danger); }
.vx-field__error svg{ inline-size:16px; block-size:16px; flex:none; margin-block-start:1px; }

/* inputs. Bare input/select/textarea are :where() bases (0 specificity). */
.vx-input, .vx-select, .vx-textarea,
:where(input:not([type="checkbox"],[type="radio"],[type="range"],[type="hidden"],[type="submit"],[type="button"],[type="reset"],[type="file"],[type="image"],[type="color"]), select, textarea){
  box-sizing:border-box; inline-size:100%; min-block-size:38px; padding-block:7px; padding-inline:11px; margin:0; appearance:none;
  font:500 .9375rem/1.4 var(--vx-font); color:var(--vx-ink); background-color:var(--vx-card);
  border:1px solid var(--vx-line-control); border-radius:var(--vx-r-md);
  transition:border-color var(--vx-dur-press) ease-in-out, box-shadow var(--vx-dur-press) ease-in-out; }
.vx-app :is(.vx-input,.vx-select), :where(.vx-app :is(input:not([type="checkbox"],[type="radio"],[type="range"],[type="hidden"],[type="submit"],[type="button"],[type="file"]), select)){
  min-block-size:34px; font-size:.875rem; padding-block:6px; }
:is(.vx-input,.vx-select,.vx-textarea):hover, :where(input:not([type="checkbox"],[type="radio"],[type="range"],[type="hidden"],[type="submit"],[type="button"],[type="file"]):hover, select:hover, textarea:hover){
  border-color:var(--vx-neutral-edge-hover); }
:is(.vx-input,.vx-select,.vx-textarea):focus-visible, :is(.vx-input,.vx-textarea):focus,
:where(input:not([type="checkbox"],[type="radio"],[type="range"],[type="hidden"],[type="submit"],[type="button"],[type="file"]):focus, select:focus-visible, textarea:focus){
  outline:none; border-color:var(--vx-accent); box-shadow:0 0 0 3px color-mix(in srgb,var(--vx-accent) 22%,transparent); }
:is(.vx-input,.vx-select,.vx-textarea)[aria-invalid="true"], :where(input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"]){ border-color:var(--vx-danger); }
:is(.vx-input,.vx-select,.vx-textarea)[aria-invalid="true"]:focus, :where(input[aria-invalid="true"]:focus, select[aria-invalid="true"]:focus, textarea[aria-invalid="true"]:focus){
  box-shadow:0 0 0 3px color-mix(in srgb,var(--vx-red) 22%,transparent); }
:is(.vx-input,.vx-select,.vx-textarea):disabled, :where(input:disabled:not([type="checkbox"],[type="radio"],[type="range"]), select:disabled, textarea:disabled){
  background-color:var(--vx-sunken); color:var(--vx-text-disabled); border-color:var(--vx-line); cursor:not-allowed; }
:is(.vx-input,.vx-textarea)::placeholder, :where(input::placeholder, textarea::placeholder){ color:var(--vx-text-3); opacity:1; }
.vx-input:is([type="number"],.vx-num), :where(input[type="number"]){ font-family:var(--vx-font-figures); font-variant-numeric:tabular-nums; }
/* the one-time code (§4.17): one field, figures, tracked out; always Latin + dir=ltr, so the literal tracking is allowed */
.vx-input--otp{ padding-block:10px; font:600 1.5rem/1 var(--vx-font-figures); font-variant-numeric:tabular-nums; letter-spacing:.3em; }
.vx-input[dir="ltr"], :where(input[dir="ltr"]){ direction:ltr; text-align:left; }   /* [dir="ltr"] url, email, code: always LTR, even in RTL pages */
.vx-textarea, :where(textarea){ min-block-size:96px; padding-block:9px; line-height:1.5; resize:vertical; }
.vx-select, :where(select){ padding-inline-end:32px; cursor:pointer; background-image:var(--vx-i-select); background-repeat:no-repeat; background-size:16px; background-position:right 10px center; }  /* vx-select chevron */
[dir="rtl"] .vx-select, :where([dir="rtl"] select){ background-position:left 10px center; }  /* vx-select chevron, RTL */
[dir="ltr"] .vx-select:dir(ltr), :where([dir="ltr"] select:dir(ltr)){ background-position:right 10px center; }  /* vx-select chevron: an LTR island in an RTL page */
:where(select[multiple], select[size]:not([size="1"])){ background-image:none; padding-inline-end:11px; }  /* vx-select: list boxes have no chevron */
.vx-select option, :where(select option){ color:var(--vx-ink); background-color:var(--vx-card); }

/* checkbox + radio */
.vx-check, .vx-radio,
:where(input[type="checkbox"]:not(.vx-switch,[role="switch"]), input[type="radio"]){
  appearance:none; flex:none; box-sizing:border-box; inline-size:16px; block-size:16px; margin:0; display:inline-grid; place-content:center; cursor:pointer;
  vertical-align:middle; background:var(--vx-card); border:1.5px solid var(--vx-line-control);
  transition:background-color var(--vx-dur-open) ease, border-color var(--vx-dur-open) ease; }
.vx-check, :where(input[type="checkbox"]:not(.vx-switch,[role="switch"])){ border-radius:var(--vx-r-sm); }
.vx-radio, :where(input[type="radio"]){ border-radius:50%; }
.vx-check::before, :where(input[type="checkbox"]:not(.vx-switch,[role="switch"]))::before{
  content:""; inline-size:10px; block-size:10px; background:var(--vx-on-accent); scale:0;
  clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%); transition:scale var(--vx-dur-open) var(--vx-ease-back); }
.vx-radio::before, :where(input[type="radio"])::before{ content:""; inline-size:6px; block-size:6px; border-radius:50%; background:var(--vx-on-accent); scale:0; transition:scale var(--vx-dur-fast) var(--vx-ease-back); }
:is(.vx-check,.vx-radio):hover:not(:checked), :where(input[type="checkbox"]:not(.vx-switch,[role="switch"]):hover:not(:checked), input[type="radio"]:hover:not(:checked)){ border-color:var(--vx-accent); }
:is(.vx-check,.vx-radio):checked, .vx-check:indeterminate,
:where(input[type="checkbox"]:not(.vx-switch,[role="switch"]):checked, input[type="checkbox"]:not(.vx-switch,[role="switch"]):indeterminate, input[type="radio"]:checked){
  background:var(--vx-accent); border-color:var(--vx-accent); }
:is(.vx-check,.vx-radio):checked::before, :where(input[type="checkbox"]:not(.vx-switch,[role="switch"]):checked, input[type="radio"]:checked)::before{ scale:1; }
.vx-check:indeterminate::before, :where(input[type="checkbox"]:not(.vx-switch,[role="switch"]):indeterminate)::before{ clip-path:inset(40% 8%); scale:1; }
:is(.vx-check,.vx-radio):focus-visible, :where(input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible){ outline:2px solid var(--vx-focus); outline-offset:2px; }
:is(.vx-check,.vx-radio):disabled, :where(input[type="checkbox"]:disabled, input[type="radio"]:disabled){ opacity:.5; cursor:not-allowed; }
.vx-choice{ display:flex; align-items:flex-start; gap:8px; min-block-size:24px; font:500 .9375rem/1.45 var(--vx-font); color:var(--vx-text); cursor:pointer; }
.vx-choice > :is(.vx-check,.vx-radio,input[type="checkbox"],input[type="radio"]){ margin-block-start:.2em; }

/* switch: <input type=checkbox role=switch class="vx-switch"> or <button role=switch aria-checked> */
.vx-switch{
  appearance:none; position:relative; flex:none; box-sizing:border-box; inline-size:30px; block-size:18px; margin:0; padding:0; cursor:pointer;
  font-size:0; color:transparent; overflow:visible; vertical-align:middle;
  background:var(--vx-line-control); border:0; border-radius:var(--vx-r-full); transition:background-color var(--vx-dur-press) ease; }
/* the track is 30×18; an invisible outset makes the hit target 38×32 (≥24, WCAG 2.5.8) */
.vx-switch::after{ content:""; position:absolute; inset-block:-7px; inset-inline:-4px; }
.vx-switch::before{ content:""; position:absolute; inset-block-start:3px; inset-inline-start:3px; inline-size:12px; block-size:12px;
  border-radius:50%; background:var(--vx-on-solid); translate:0 0; transition:translate var(--vx-dur-press) ease, background-color var(--vx-dur-press) ease; }
.vx-switch:is(:checked,[aria-checked="true"]){ background:var(--vx-accent); }
.vx-switch:is(:checked,[aria-checked="true"])::before{ translate:calc(12px * var(--vx-dir)) 0; background:var(--vx-on-accent); }
.vx-switch:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; }
.vx-switch:is(:disabled,[aria-busy="true"]){ opacity:.5; cursor:not-allowed; }
.vx-toggle{ display:flex; align-items:center; gap:10px; min-block-size:32px; cursor:pointer; }   /* label row, keeps a 32px target */
/* ⚠️ A switch that ACTS on change (POSTs at once: kill switches, sales lines,
   stop rules) must not sit in a <label>: a click on the row's words would flip
   it in production. Such a row is <div class="vx-toggle vx-toggle--static">
   with the switch named by aria-labelledby. Only a switch saved by a separate
   Save button may use the <label class="vx-toggle"> row. */
.vx-toggle--static{ cursor:auto; }

.vx-fieldset, :where(fieldset){ border:1px solid var(--vx-line); border-radius:var(--vx-r-md); padding-block:10px 16px; padding-inline:16px; margin:0; min-inline-size:0; }
:is(.vx-fieldset) > legend, :where(fieldset > legend){ padding-inline:4px; font:600 .8125rem/1 var(--vx-font); color:var(--vx-text-2); }
.vx-inputgroup{ display:flex; flex-wrap:wrap; gap:8px; align-items:flex-start; container-type:inline-size; }   /* wraps only when the 12rem field + keycap don't fit */
.vx-inputgroup > :is(.vx-input,input){ flex:1 1 12rem; min-inline-size:0; inline-size:auto; }
@container (max-width:22rem){ .vx-inputgroup > .vx-btn{ flex:1 1 100%; } }   /* a full-width keycap only when field + keycap cannot share the row */
@media (max-width:480px){ .vx-inputgroup{ flex-wrap:wrap; } .vx-inputgroup > .vx-btn{ flex:1 1 100%; } }
.vx-form{ display:grid; gap:16px; }
.vx-form__actions{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding-block-end:var(--vx-ledge-room); }   /* = .vx-actions */


/* ── §4.18 Banner / alert ───────────────────────────────────────────────── */
.vx-banner,
.admin-err{                                      /* legacy: .admin-err, the cockpit's error strip (admin_base showErr) */
  --bg:var(--vx-info-bg); --ln:var(--vx-info-line); --ic:var(--vx-info);
  box-sizing:border-box; display:flex; align-items:flex-start; gap:10px; min-block-size:48px; padding-block:10px; padding-inline:12px;
  font:500 .875rem/1.5 var(--vx-font); color:var(--vx-ink); text-align:start; background:var(--bg); border:1px solid var(--ln); border-radius:var(--vx-r-md); }
.vx-banner__icon{ inline-size:20px; block-size:20px; flex:none; margin-block-start:1px; color:var(--ic); }
.vx-banner__title{ font-weight:700; }
.vx-banner__actions{ margin-inline-start:auto; display:flex; flex-wrap:wrap; gap:8px; align-self:center; }
/* with actions the banner wraps: the actions drop under the words on a phone instead of pushing past it */
.vx-banner:has(> .vx-banner__actions){ flex-wrap:wrap; }
.vx-banner:has(> .vx-banner__actions) > :not(svg,.vx-banner__icon,.vx-banner__actions,.vx-btn,.vx-spinner){ flex:1 1 14rem; min-inline-size:0; }
.vx-banner .vx-btn:not(.vx-btn--primary):not(.vx-btn--danger-solid){ --vx-btn-face:var(--vx-card); }   /* a primary keeps its gold inside a banner */
.vx-banner--success{ --bg:var(--vx-success-bg); --ln:var(--vx-success-line); --ic:var(--vx-success); }
.vx-banner--warning{ --bg:var(--vx-warning-bg); --ln:var(--vx-warning-line); --ic:var(--vx-warning); }
.vx-banner--danger { --bg:var(--vx-danger-bg);  --ln:var(--vx-danger-line);  --ic:var(--vx-danger); }
.vx-banner--strip{ border-radius:0; border-inline:0; border-block-start:0; }   /* full-width at the top of a sheet */


/* ── §4.19 Toast ────────────────────────────────────────────────────────── */
.vx-toasts{
  position:fixed; z-index:var(--vx-z-toast); inset-block-end:calc(16px + env(safe-area-inset-bottom)); inset-inline-end:16px;
  display:grid; gap:8px; inline-size:min(26rem,calc(100vw - 32px)); pointer-events:none; }
.vx-toast{
  box-sizing:border-box; pointer-events:auto; display:flex; align-items:flex-start; gap:10px; padding-block:12px; padding-inline:14px 12px;
  font:500 .875rem/1.4 var(--vx-font); color:var(--vx-ink); background:var(--vx-card);
  border:1px solid var(--vx-line-control); border-radius:var(--vx-r-md); box-shadow:var(--vx-elev), var(--vx-shadow-menu);
  animation:vx-toast-in var(--vx-dur-fast) var(--vx-ease-out-expo) both; }
.vx-toast.is-leaving{ animation:vx-toast-out 100ms ease-in both; }
.vx-toast__icon{ inline-size:20px; block-size:20px; flex:none; color:var(--vx-h-ink, var(--vx-info)); }
.vx-toast__title{ font-weight:600; }
.vx-toast__body{ color:var(--vx-text-2); }
.vx-toast__close{ margin-inline-start:auto; }
@media (max-width:480px){ .vx-toasts{ inset-inline:12px; inline-size:auto; } }


/* ── §4.20 Modal and drawer (native <dialog>) ───────────────────────────── */
dialog.vx-modal{
  box-sizing:border-box; inline-size:min(34rem,calc(100vw - 32px)); max-inline-size:none; max-block-size:calc(100dvh - 64px);
  margin-block:max(8vh,32px) auto; margin-inline:auto; padding:0;
  color:var(--vx-text); background:var(--vx-card); border:1px solid color-mix(in srgb,var(--vx-ink) 22%,transparent);
  border-radius:var(--vx-r-lg); box-shadow:var(--vx-shadow-modal); overflow:hidden; }
dialog.vx-modal[open]{ display:flex; flex-direction:column; animation:vx-pop-in var(--vx-dur-open) var(--vx-ease-back) both; }
dialog.vx-modal.is-closing{ animation:vx-pop-out var(--vx-dur-fast) var(--vx-ease-in-sharp) both; }
dialog.vx-modal::backdrop{ background:var(--vx-scrim); -webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px); animation:vx-fade-in var(--vx-dur-open) ease-out both; }
.vx-modal--wide{ inline-size:min(52rem,calc(100vw - 32px)); }
.vx-modal__head{ display:flex; align-items:center; gap:12px; padding-block:14px; padding-inline:16px 12px; border-block-end:1px solid var(--vx-line-soft); }
.vx-modal__title{ margin:0; font:700 1.125rem/1.4 var(--vx-font); color:var(--vx-ink); }
.vx-modal__close{ margin-inline-start:auto; }
.vx-modal__close.is-shaking{ animation:vx-tilt-shake 400ms ease both; }
.vx-modal__body{ padding:16px; overflow:auto; overscroll-behavior:contain; }
.vx-modal__foot{ display:flex; justify-content:flex-end; flex-wrap:wrap; gap:8px; padding-block:12px 10px; padding-inline:16px;
  border-block-start:1px solid var(--vx-line-soft); background:color-mix(in srgb,var(--vx-sunken) 35%,var(--vx-card)); }
@media (max-width:520px){
  dialog.vx-modal{ inline-size:100%; max-inline-size:100%; margin-block:auto 0; margin-inline:0;
    border-start-start-radius:var(--vx-r-lg); border-start-end-radius:var(--vx-r-lg); border-end-start-radius:0; border-end-end-radius:0; border-block-end:0; }
  dialog.vx-modal[open]{ animation:vx-sheet-up 250ms var(--vx-ease-out-expo) both; }
}

dialog.vx-drawer{ box-sizing:border-box; margin:0; margin-inline-start:auto; block-size:100dvh; max-block-size:100dvh; inline-size:min(30rem,94vw); max-inline-size:none; padding:0;
  background:var(--vx-sheet); color:var(--vx-text); border:0; border-inline-start:1px solid var(--vx-line); box-shadow:var(--vx-shadow-float); }
dialog.vx-drawer[open]{ display:flex; flex-direction:column; animation:vx-drawer-in 280ms var(--vx-ease-out-expo) both; }
dialog.vx-drawer::backdrop{ background:var(--vx-scrim); -webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px); }


/* ── §4.21 Tooltip and menu / popover ───────────────────────────────────── */
.vx-tip{ position:absolute; z-index:var(--vx-z-tooltip); inline-size:max-content; max-inline-size:min(24rem,calc(100vw - 24px)); padding-block:6px; padding-inline:8px; pointer-events:none;
  font:500 .8125rem/1.35 var(--vx-font); color:var(--vx-on-inverse); background:var(--vx-inverse);
  border-radius:var(--vx-r-md); box-shadow:var(--vx-shadow-modal); opacity:0; translate:0 3px;
  transition:opacity 50ms ease-in, translate 50ms ease-in; }
.vx-tip.is-open{ opacity:1; translate:0 0; transition:opacity 100ms ease-out, translate 100ms ease-out; }
.vx-tip kbd{ color:var(--vx-on-inverse); background:transparent; border-color:color-mix(in srgb,var(--vx-on-inverse) 40%,transparent); }
/* CSS-only text tooltip for icon buttons and verdict badges */
[data-vx-tip]{ position:relative; }
[data-vx-tip]::after{ content:attr(data-vx-tip); position:absolute; inset-block-end:calc(100% + 6px); inset-inline-start:50%; translate:calc(-50% * var(--vx-dir)) 3px;
  inline-size:max-content; max-inline-size:18rem; padding-block:6px; padding-inline:8px; font:500 .8125rem/1.35 var(--vx-font); letter-spacing:0; text-transform:none;
  white-space:normal; text-align:start; color:var(--vx-on-inverse);
  background:var(--vx-inverse); border-radius:var(--vx-r-md); opacity:0; pointer-events:none; transition:opacity 50ms, translate 50ms; z-index:var(--vx-z-tooltip); }
[data-vx-tip]:is(:hover,:focus-visible)::after{ opacity:1; translate:calc(-50% * var(--vx-dir)) 0; transition-duration:100ms; }
@media (hover:none){ [data-vx-tip]::after{ display:none; } }

.vx-dropdown{ position:relative; }
.vx-dropdown > summary{ list-style:none; }
.vx-dropdown > summary::-webkit-details-marker{ display:none; }
.vx-dropdown > .vx-menu{ position:absolute; z-index:var(--vx-z-modal); inset-block-start:calc(100% + 6px); inset-inline-end:0; }
.vx-dropdown.vx-dropdown--up > .vx-menu{ inset-block-start:auto; inset-block-end:calc(100% + 6px); transform-origin:bottom; }   /* opens upward (footer/side-nav foot) */
.vx-dropdown--start > .vx-menu{ inset-inline-end:auto; inset-inline-start:0; }
.vx-menu{ box-sizing:border-box; min-inline-size:220px; max-inline-size:min(20rem,calc(100vw - 24px)); max-block-size:min(70vh,32rem); overflow:auto; padding:5px; margin:0;
  list-style:none; background:var(--vx-sheet); border:1px solid var(--vx-line); border-radius:var(--vx-r-lg); box-shadow:var(--vx-shadow-menu);
  transform-origin:top; animation:vx-menu-in 160ms var(--vx-ease-out-expo) both; }
.vx-menu__label{ padding-block:8px 4px; padding-inline:10px; font:600 .6875rem/1 var(--vx-font); letter-spacing:var(--vx-track-label); text-transform:var(--vx-case-label); color:var(--vx-text-3); }
.vx-menu__item{ box-sizing:border-box; display:flex; align-items:center; gap:8px; inline-size:100%; min-block-size:32px; padding-block:0; padding-inline:10px; cursor:pointer;
  font:500 .8125rem/1.2 var(--vx-font); color:var(--vx-ink); text-align:start; text-decoration:none; background:none; border:0; border-radius:var(--vx-r-sm); }
.vx-menu__item:is(:hover,:focus-visible){ background:var(--vx-sunken); outline:none; }
.vx-menu__item:focus-visible{ box-shadow:inset 0 0 0 2px var(--vx-focus); }
.vx-menu__item:is([aria-current],[aria-checked="true"]){ font-weight:600; }
.vx-menu__item :is(kbd,.vx-menu__hint){ margin-inline-start:auto; color:var(--vx-text-3); }
.vx-menu__item--danger{ color:var(--vx-danger); }
.vx-menu__sep{ block-size:1px; margin:5px; background:var(--vx-line-soft); border:0; }


/* ── §4.22 Empty state ──────────────────────────────────────────────────── */
.vx-empty{
  box-sizing:border-box; display:grid; justify-items:start; gap:10px; padding:32px; border:2px dashed var(--vx-line); border-radius:var(--vx-r-lg);
  text-align:start; color:var(--vx-text-2);
  background:color-mix(in srgb,var(--vx-sunken) 40%,transparent); }
.vx-empty__title{ margin:0; font:700 1.125rem/1.35 var(--vx-font); color:var(--vx-ink); }
.vx-empty__text{ margin:0; max-inline-size:36rem; color:var(--vx-text-2); }
.vx-empty--compact{ padding-block:16px; padding-inline:20px; gap:6px; border-width:1px; }


/* ── §4.23 Skeleton and spinner ─────────────────────────────────────────── */
.vx-skel{
  position:relative; overflow:hidden; display:block; block-size:14px; border-radius:var(--vx-r-md);
  background:color-mix(in srgb,var(--vx-ink) 7%,transparent); }
/* the sweep is a translated highlight (compositor), not an animated background-position (a repaint per frame) */
.vx-skel::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--vx-ink) 6%,transparent) 50%,transparent);
  animation:vx-shimmer 2s ease infinite; }
.vx-skel--title{ block-size:22px; inline-size:40%; }
.vx-skel--row{ block-size:40px; }
.vx-skel-list{ display:grid; gap:8px; }
.vx-skel-list > :nth-child(2){ opacity:.8; }
.vx-skel-list > :nth-child(3){ opacity:.6; }
.vx-skel-list > :nth-child(4){ opacity:.4; }
.vx-skel-list > :nth-child(n+5){ opacity:.2; }
.vx-spinner{ box-sizing:border-box; display:inline-block; inline-size:20px; block-size:20px; flex:none; border-radius:50%;
  border:2.5px solid color-mix(in srgb,var(--vx-accent) 25%,transparent); border-block-start-color:var(--vx-accent);
  animation:vx-spin .8s linear infinite; }
.vx-spinner--lg{ inline-size:32px; block-size:32px; border-width:3.5px; }


/* ── §4.24 Progress, meter and score ────────────────────────────────────── */
.vx-meter{
  --v:0%; position:relative; display:block; box-sizing:border-box; block-size:6px; overflow:hidden; border:0; border-radius:var(--vx-r-full); background:var(--vx-sunken); }
.vx-meter > :is(i,span){
  position:absolute; inset-block:0; inset-inline-start:0; inline-size:var(--v);
  background:var(--vx-h, var(--vx-accent)); border-radius:inherit; transition:inline-size var(--vx-dur-panel) var(--vx-ease-out-quint); }
.vx-meter--lg{ block-size:12px; }
/* stacked meter: several fills in one track, each <i data-status style="--v:N%"> CUMULATIVE and widest first
   (later fills paint over earlier ones): e.g. done ⊂ done+partial ⊂ done+partial+missing */
.vx-meter--stack > i{ border-radius:inherit; }
.vx-meter-row{ display:grid; grid-template-columns:minmax(6rem,11rem) minmax(0,1fr) auto; gap:10px; align-items:center; font-size:.8125rem; }
/* stacked rows share one set of columns, so every track has the same length */
.vx-meter-rows{ display:grid; grid-template-columns:minmax(6rem,11rem) minmax(0,1fr) auto; gap:8px 10px; align-items:center; }
.vx-meter-rows > .vx-meter-row{ grid-column:1 / -1; grid-template-columns:subgrid; }
.vx-meter-row > :first-child{ color:var(--vx-text-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vx-meter-row > :last-child{ color:var(--vx-ink); font:600 .8125rem/1 var(--vx-font-figures); font-variant-numeric:tabular-nums; }
progress.vx-meter{ appearance:none; border:0; inline-size:100%; }
progress.vx-meter::-webkit-progress-bar{ background:var(--vx-sunken); border-radius:var(--vx-r-full); }
progress.vx-meter::-webkit-progress-value{ background:var(--vx-h, var(--vx-accent)); border-radius:var(--vx-r-full); }
progress.vx-meter::-moz-progress-bar{ background:var(--vx-h, var(--vx-accent)); border-radius:var(--vx-r-full); }

/* headline score = PostHog's BoldNumber: a big 700 number, a unit, one comparison line and a meter. Start-aligned, flat. */
.vx-score{ display:grid; gap:6px; justify-items:start; min-inline-size:0; }
.vx-score__value{ display:flex; align-items:baseline; gap:.2em; font:700 clamp(2.5rem,1.5rem + 3vw,4rem)/1 var(--vx-font-figures);
  font-variant-numeric:tabular-nums; letter-spacing:var(--vx-track-tight); color:var(--vx-ink); }
.vx-score__of{ font:600 .35em/1 var(--vx-font-figures); color:var(--vx-text-3); letter-spacing:0; }     /* "/100" */
.vx-score__meta{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; font:500 .8125rem/1.4 var(--vx-font); color:var(--vx-text-2); }
.vx-score > .vx-meter{ inline-size:min(100%,18rem); }


/* ── §4.25 Accordion / FAQ ──────────────────────────────────────────────── */
.vx-accs{ border-block:1px solid var(--vx-line); }
.vx-acc + .vx-acc{ border-block-start:1px solid var(--vx-line); }
.vx-acc{ interpolate-size:allow-keywords; }
.vx-acc > summary{ list-style:none; display:flex; align-items:center; justify-content:space-between; gap:16px; padding-block:14px; padding-inline:2px; cursor:pointer;
  font:600 1rem/1.4 var(--vx-font); letter-spacing:calc(var(--vx-track-head) * 1.5); color:var(--vx-ink); }
.vx-acc > summary::-webkit-details-marker{ display:none; }
.vx-acc > summary::after{ content:""; flex:none; inline-size:16px; block-size:16px; background:currentColor;
  -webkit-mask:var(--vx-i-plus) center/contain no-repeat; mask:var(--vx-i-plus) center/contain no-repeat; }
.vx-acc[open] > summary::after{ -webkit-mask-image:var(--vx-i-minus); mask-image:var(--vx-i-minus); }
.vx-acc > summary:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:2px; border-radius:var(--vx-r-sm); }
.vx-acc__body{ padding-block:0 16px; padding-inline:2px; max-inline-size:var(--vx-w-prose); color:var(--vx-text-2); }
.vx-acc::details-content{ block-size:0; overflow:clip;
  transition:block-size var(--vx-dur-panel) var(--vx-ease-accordion), content-visibility var(--vx-dur-panel) allow-discrete; }
.vx-acc[open]::details-content{ block-size:auto; }
/* compact: a disclosure inside a panel or a table cell (the marker follows the label) */
.vx-acc--compact > summary{ justify-content:flex-start; gap:8px; padding-block:6px; }
/* a whole panel as a disclosure: <details class="vx-panel vx-acc vx-acc--compact"> <summary> title … </summary> <div class="vx-panel__body"> */
.vx-panel.vx-acc > summary{ padding-block:10px; padding-inline:16px 12px; }
.vx-panel.vx-acc > summary > .vx-panel__title{ flex:1 1 auto; }
.vx-panel.vx-acc > .vx-panel__body{ border-block-start:1px solid var(--vx-line-soft); }


/* ── §4.26 Steps / journey and check list ───────────────────────────────── */
.vx-steps{ list-style:none; margin:0; padding:0; display:grid; gap:16px; grid-template-columns:repeat(auto-fit,minmax(min(100%,15rem),1fr)); }
.vx-step{ position:relative; display:grid; align-content:start; gap:8px; padding:20px;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-lg); }
.vx-step--later{ background:var(--vx-sunken); border:2px dashed var(--vx-line-strong); }
.vx-step__head{ display:flex; align-items:center; gap:8px; }
.vx-step__badge{ inline-size:24px; block-size:24px; flex:none; display:inline-grid; place-items:center; border-radius:50%;
  font:700 .8125rem/1 var(--vx-font-figures); background:var(--vx-gold); color:var(--vx-on-bright); }
.vx-step--later .vx-step__badge{ box-sizing:border-box; background:transparent; border:1.5px solid var(--vx-line-control); color:var(--vx-text-2); }
.vx-step__eyebrow{ font:600 .8125rem/1.2 var(--vx-font); letter-spacing:0; text-transform:none; color:var(--vx-gold-ink); }  /* sits in .vx-step__head beside the badge */
@media (min-width:900px){
  .vx-steps--arrows{ column-gap:28px; }
  .vx-steps--arrows > .vx-step:not(:last-child)::after{ content:""; position:absolute; inset-block-start:50%; inset-inline-end:-22px;
    inline-size:16px; block-size:16px; background:var(--vx-text-3); -webkit-mask:var(--vx-i-arrow) center/contain no-repeat; mask:var(--vx-i-arrow) center/contain no-repeat;
    scale:var(--vx-dir) 1; translate:0 -50%; }
}
.vx-checks{ list-style:none; margin:0; padding:0; display:grid; gap:8px; }
.vx-checks > li{ display:grid; grid-template-columns:16px minmax(0,1fr); gap:8px; font:500 .9375rem/1.45 var(--vx-font); color:var(--vx-text); }
.vx-checks > li::before{ content:""; inline-size:16px; block-size:16px; margin-block-start:.15em; background:var(--vx-success);
  -webkit-mask:var(--vx-i-check) center/contain no-repeat; mask:var(--vx-i-check) center/contain no-repeat; }
.vx-checks--no > li::before{ background:var(--vx-danger); -webkit-mask-image:var(--vx-i-x); mask-image:var(--vx-i-x); }
.vx-checks--opt > li::before{ background:var(--vx-text-3); -webkit-mask-image:var(--vx-i-minus); mask-image:var(--vx-i-minus); }   /* an add-on or a separate agreement: neither included nor excluded */


/* ── §4.32 Breadcrumbs ──────────────────────────────────────────────────── */
.vx-crumbs{
  display:flex; flex-wrap:wrap; align-items:center; gap:4px; min-inline-size:0; overflow-wrap:anywhere; font:500 .8125rem/1.3 var(--vx-font); letter-spacing:0; text-transform:none; color:var(--vx-text-2); }
.vx-crumbs > *{ min-inline-size:0; }
.vx-crumbs a{ padding-block:2px; padding-inline:4px; border-radius:var(--vx-r-sm); color:inherit; text-decoration:none; }
.vx-crumbs a:hover{ background:var(--vx-hover); color:var(--vx-ink); }
.vx-crumbs a:focus-visible{ outline:2px solid var(--vx-focus); outline-offset:1px; }
.vx-crumbs [aria-current="page"]{ color:var(--vx-ink); font-weight:600; }
.vx-crumbs__sep{ color:var(--vx-text-3); }  /* the character "/", bidi-neutral: no flipping */


/* ── §4.34 Code block and inline code ───────────────────────────────────── */
.vx-code{ margin-block:8px 16px; direction:ltr; text-align:left; background:var(--vx-sunken); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); overflow:hidden; }  /* vx-code: always LTR */
.vx-code__head{ display:flex; align-items:center; gap:8px; min-block-size:34px; padding-inline:12px 6px;
  font:600 .8125rem/1 var(--vx-font); color:var(--vx-text-2); border-block-end:1px solid var(--vx-line);
  background:color-mix(in srgb,var(--vx-sunken-2) 45%,var(--vx-sunken)); }
.vx-code__head > .vx-btn{ margin-inline-start:auto; margin-block-end:0; }
.vx-code pre{ margin:0; padding-block:14px; padding-inline:16px; overflow:auto; font:500 .8125rem/1.6 var(--vx-mono); color:var(--vx-ink); tab-size:2;
  background:   /* the table wrap's scroll shades, on the code's sunken ground */
    linear-gradient(to right, var(--vx-sunken) 40%, transparent) left center / 28px 100% no-repeat local,
    linear-gradient(to left, var(--vx-sunken) 40%, transparent) right center / 28px 100% no-repeat local,
    linear-gradient(to right, var(--vx-scroll-shadow), transparent) left center / 12px 100% no-repeat scroll,
    linear-gradient(to left, var(--vx-scroll-shadow), transparent) right center / 12px 100% no-repeat scroll; }
.vx-code .tok-comment{ color:var(--vx-text-3); }
.vx-code .tok-keyword{ color:var(--vx-blue-ink); }
.vx-code .tok-string{ color:var(--vx-pink-ink); }
.vx-code .tok-number{ color:var(--vx-teal-ink); }
.vx-code .tok-function{ color:var(--vx-purple-ink); }
.vx-code .tok-attr{ color:var(--vx-sky-ink); }
.vx-code .tok-punct{ color:var(--vx-text-2); }
:not(pre) > code, .vx-codechip{ padding-block:.12em; padding-inline:.35em; font:500 .875em/1.2 var(--vx-mono); color:var(--vx-ink); direction:ltr; unicode-bidi:isolate;
  background:var(--vx-sunken); border:1px solid var(--vx-line); border-radius:var(--vx-r-sm); overflow-wrap:anywhere; }
.vx-codechip--nowrap{ white-space:nowrap; overflow-wrap:normal; }
.vx-codechip--param{ color:var(--vx-teal-ink); background:color-mix(in srgb,var(--vx-teal) 10%,transparent); border-color:color-mix(in srgb,var(--vx-teal-ink) 50%,transparent); }
a > code{ color:var(--vx-blue-ink); background:color-mix(in srgb,var(--vx-blue) 10%,transparent); border-color:color-mix(in srgb,var(--vx-blue) 50%,transparent); }


/* ── §4.36 Misc ─────────────────────────────────────────────────────────── */
/* .vx-divider, .vx-scroll, .vx-vh, .vx-flip-rtl and .vx-latin live in vx-base.css (E1) */
.vx-num,
.n{                                              /* legacy: .n (_admin_charts bar values) */
  font-family:var(--vx-font-figures); font-variant-numeric:tabular-nums; letter-spacing:0; }
.n{ direction:ltr; unicode-bidi:isolate; }      /* a Latin figure run inside an RTL table cell */
.vx-icon{ inline-size:16px; block-size:16px; flex:none; stroke-width:1.5; }


/* ── §4.37 Chart frame, legend and chart tooltip ────────────────────────── */
/* legacy: svg.svgchart (_admin_charts.html line2) is the chart's own <svg> */
.vx-chart{ position:relative; min-inline-size:0; block-size:var(--vx-chart-h,220px); }
.vx-chart svg, svg.svgchart{ display:block; inline-size:100%; block-size:100%; overflow:visible; font:500 12px/1 var(--vx-font-figures); font-variant-numeric:tabular-nums; }
:is(.vx-chart,.svgchart) .grid line{ stroke:var(--vx-chart-grid); stroke-width:1; stroke-dasharray:3 3; vector-effect:non-scaling-stroke; }
:is(.vx-chart,.svgchart) .axis :is(line,path){ stroke:var(--vx-chart-axis); vector-effect:non-scaling-stroke; }
:is(.vx-chart,.svgchart) .tick text{ fill:var(--vx-chart-label); }
:is(.vx-chart,.svgchart) .crosshair{ stroke:var(--vx-chart-crosshair); stroke-dasharray:3 3; }
:is(.vx-chart,.svgchart) .line{ fill:none; stroke:var(--vx-s, var(--vx-series-1)); stroke-width:2; stroke-linejoin:round; stroke-linecap:round; vector-effect:non-scaling-stroke; }
:is(.vx-chart,.svgchart) .area{ fill:color-mix(in srgb,var(--vx-s, var(--vx-series-1)) 18%,transparent); stroke:none; }
:is(.vx-chart,.svgchart) .bar{ fill:var(--vx-s, var(--vx-series-1)); }
:is(.vx-chart,.svgchart) .dot{ fill:var(--vx-card); stroke:var(--vx-s, var(--vx-series-1)); stroke-width:2; }
[class~="vx-s1"]{ --vx-s:var(--vx-series-1); }
[class~="vx-s2"]{ --vx-s:var(--vx-series-2); }
[class~="vx-s3"]{ --vx-s:var(--vx-series-3); }
[class~="vx-s4"]{ --vx-s:var(--vx-series-4); }
[class~="vx-s5"]{ --vx-s:var(--vx-series-5); }
[class~="vx-s6"]{ --vx-s:var(--vx-series-6); }
[class~="vx-s7"]{ --vx-s:var(--vx-series-7); }
[class~="vx-s8"]{ --vx-s:var(--vx-series-8); }
[class~="vx-s9"]{ --vx-s:var(--vx-series-9); }
[class~="vx-s10"]{ --vx-s:var(--vx-series-10); }
[class~="vx-s-danger"]{ --vx-s:var(--vx-red-ink); }   /* a sparkline whose trend is bad (legacy .spark.rd) */

.vx-legend{ display:flex; flex-wrap:wrap; align-items:center; gap:4px 12px; margin-block:0 8px; margin-inline:0; padding:0; list-style:none; font:500 .8125rem/1.3 var(--vx-font); color:var(--vx-text-2); }
.vx-chart + .vx-legend, .svgchart + .vx-legend{ margin-block:8px 0; }
.vx-legend > :is(li,span), .vx-legend li{ display:inline-flex; align-items:center; gap:6px; }
.vx-legend i{ display:inline-block; inline-size:10px; block-size:10px; flex:none; border-radius:var(--vx-r-xs); background:var(--vx-s, var(--vx-series-1)); }
.vx-legend__end{ margin-inline-start:auto; color:var(--vx-chart-label); font-family:var(--vx-font-figures); font-variant-numeric:tabular-nums; }   /* axis range ("first – last") */

.vx-chart__tip{ box-sizing:border-box; position:absolute; z-index:var(--vx-z-tooltip); pointer-events:none; min-inline-size:10rem; max-inline-size:30rem; padding-block:8px; padding-inline:10px;
  font:500 .8125rem/1.35 var(--vx-font); color:var(--vx-text); background:var(--vx-card); border:1px solid var(--vx-line);
  border-radius:var(--vx-r-md); box-shadow:var(--vx-elev); transition:inset-inline-start 50ms linear, inset-block-start 50ms linear, opacity 200ms; }
.vx-chart__tip table{ border-collapse:collapse; inline-size:100%; font-size:.75rem; }
.vx-chart__tip th{ padding:0; padding-inline-end:12px; text-align:start; font-weight:700; letter-spacing:0; text-transform:none; color:var(--vx-ink); background:none; border:0; }
.vx-chart__tip td{ padding:0; text-align:end; font:700 .75rem/1.4 var(--vx-font-figures); font-variant-numeric:tabular-nums; color:var(--vx-ink); border:0; }
.vx-chart.is-empty{ display:grid; place-items:center start; } /* holds a .vx-empty--compact: "Measuring – first numbers on {date}" */
/* a frame holding the chart's own <svg> plus its legend (or its empty state): the SVG takes what the legend leaves */
.vx-chart--legend{ display:flex; flex-direction:column; }
.vx-chart--legend > svg{ flex:1 1 0; min-block-size:0; block-size:auto; }
.vx-chart--legend > .vx-legend{ margin-block:8px 0; }
.vx-chart--legend > .vx-empty{ flex:1; align-content:center; }   /* start-aligned, vertically centred (§4.22) */
.vx-chart.is-loading > .vx-skel{ block-size:100%; }


/* ── §4.38 Bar list: the breakdown row ──────────────────────────────────── */
.vx-barlist{ display:grid; gap:2px; margin:0; padding:0; list-style:none; }
.vx-barlist__head{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:12px; padding-block:0 4px; padding-inline:8px;
  font:700 .75rem/1rem var(--vx-font); letter-spacing:calc(var(--vx-track-label) * .66); text-transform:var(--vx-case-label); color:var(--vx-text-3); }
.vx-barlist > li{ position:relative; isolation:isolate; display:grid; grid-template-columns:minmax(0,1fr) auto; gap:12px; align-items:center;
  min-block-size:30px; padding-inline:8px; border-radius:var(--vx-r-sm); font:500 .8125rem/1.3 var(--vx-font); color:var(--vx-text); }
.vx-barlist > li::before{ content:""; position:absolute; z-index:-1; inset-block:2px; inset-inline-start:0; inline-size:var(--v,0%);
  border-radius:var(--vx-r-sm); background:color-mix(in srgb,var(--vx-h,var(--vx-series-1)) 12%,transparent);   /* the Tint Rule: ≤12% under text */
  transition:inline-size var(--vx-dur-panel) var(--vx-ease-out-quint); }
.vx-barlist > li:not(.vx-barlist__head):is(:hover,:focus-within){ background:var(--vx-hover); --vx-text-2:var(--vx-text); --vx-text-3:var(--vx-text); }   /* hover stacks on the bar: its small text steps up a tone (dark 4.10 → 7+) */
.vx-barlist > li.vx-barlist__head{ min-block-size:0; font:700 .75rem/1rem var(--vx-font); color:var(--vx-text-3); }
.vx-barlist > li.vx-barlist__head::before{ content:none; }
.vx-barlist__label{ min-inline-size:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.vx-barlist__label a{ color:inherit; text-decoration:none; }
.vx-barlist__label a:hover{ text-decoration:underline; }
.vx-barlist__value{ font:600 .8125rem/1 var(--vx-font-figures); font-variant-numeric:tabular-nums; color:var(--vx-ink); }
.vx-barlist__value small{ margin-inline-start:6px; font-weight:500; color:var(--vx-text-2); }   /* share, e.g. "18%" */


/* ── §4.40 Toolbar: filters above a table or chart ──────────────────────── */
.vx-toolbar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding-block:8px; padding-inline:12px; border-block-end:1px solid var(--vx-line-soft); }
.vx-toolbar__search{ position:relative; flex:1 1 14rem; max-inline-size:22rem; }
.vx-toolbar__search .vx-input{ padding-inline-start:32px; min-block-size:32px; font-size:.8125rem; }
.vx-toolbar__search svg{ position:absolute; inset-inline-start:10px; inset-block-start:50%; translate:0 -50%; inline-size:14px; block-size:14px; color:var(--vx-text-3); pointer-events:none; }
.vx-toolbar__end{ margin-inline-start:auto; display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.vx-toolbar__count{ font:500 .8125rem/1 var(--vx-font); color:var(--vx-text-2); }   /* "142 customers" */
.vx-toolbar > .vx-panel__title{ flex:1 0 auto; max-inline-size:100%; }   /* a toolbar's title keeps its width; the search wraps under it on a phone */
.vx-panel > .vx-toolbar:first-child{ border-start-start-radius:var(--vx-r-md); border-start-end-radius:var(--vx-r-md); }


/* ── §4.41 Key–value list ───────────────────────────────────────────────── */
.vx-kv{ display:grid; grid-template-columns:minmax(8rem,max-content) minmax(0,1fr); margin:0; font:500 .8125rem/1.45 var(--vx-font); }
.vx-kv > :is(dt,dd){ margin:0; padding-block:8px; border-block-start:1px solid var(--vx-line-soft); }
.vx-kv > :is(dt,dd):nth-child(-n+2){ border-block-start:0; }
.vx-kv > dt{ padding-inline-end:16px; color:var(--vx-text-2); }
.vx-kv > dd{ color:var(--vx-ink); min-inline-size:0; overflow-wrap:anywhere; }
.vx-kv > dd.vx-num{ font-weight:600; }
@container (max-width:28rem){ .vx-kv{ grid-template-columns:1fr; } .vx-kv > dd{ padding-block-start:0; border-block-start:0; } }


/* ── §4.42 Activity feed ────────────────────────────────────────────────── */
.vx-feed{ display:grid; margin:0; padding:0; list-style:none; }
/* the time column is fit-content(40%): its own width while it fits, and it WRAPS
   rather than squeezing the text column to nothing (R6: a nowrap time in an
   auto column overprinted the text in a 320–360px cockpit panel) */
.vx-feed > li{ display:grid; grid-template-columns:28px minmax(0,1fr) fit-content(40%); gap:10px; align-items:start; padding-block:10px; padding-inline:16px;
  border-block-start:1px solid var(--vx-line-soft); font:500 .8125rem/1.45 var(--vx-font); color:var(--vx-text); }
.vx-feed > li:first-child{ border-block-start:0; }
.vx-feed > li > .vx-dot{ justify-self:center; margin-block-start:.45em; }
.vx-feed__text b{ color:var(--vx-ink); font-weight:600; }
.vx-feed__time{ font:500 .75rem/1.45 var(--vx-font-figures); color:var(--vx-text-3); text-align:end; }
.vx-feed > li.is-new{ animation:vx-row-new 1.5s ease-out; }
.vx-feed--compact > li{ padding-block:7px; grid-template-columns:20px minmax(0,1fr) fit-content(40%); }


/* ── §4.43 Message thread: support threads and the manager chat ─────────── */
.vx-thread{ display:grid; gap:12px; }
.vx-msg{ box-sizing:border-box; display:grid; gap:6px; min-inline-size:0; overflow-wrap:anywhere; max-inline-size:min(44rem,92%); padding-block:12px; padding-inline:14px; background:var(--vx-card); border:1px solid var(--vx-line);
  border-radius:var(--vx-r-lg); font:500 .9375rem/1.55 var(--vx-font); color:var(--vx-text); }
.vx-msg__meta{ display:flex; flex-wrap:wrap; align-items:center; gap:2px 8px; min-inline-size:0; font:500 .75rem/1.2 var(--vx-font); color:var(--vx-text-3); overflow-wrap:anywhere; }
.vx-msg__meta b{ color:var(--vx-ink); font-weight:600; }
.vx-msg--us{ box-shadow:inset calc(3px * var(--vx-dir)) 0 0 var(--vx-teal); }           /* our reply: teal ribbon at the inline-start */
.vx-msg--me{ justify-self:end; background:var(--vx-sheet); border-color:var(--vx-line-soft); }   /* the viewer's own message, at the inline-end */
.vx-msg--system{ justify-self:stretch; max-inline-size:none; background:transparent; border:1px dashed var(--vx-line); font-size:.8125rem; color:var(--vx-text-2); }
.vx-msg.is-pending{ border-style:dashed; }   /* sending: dashed = "not yet" + a "Sending" word in the meta row. Never opacity */
.vx-composer{ display:grid; gap:8px; padding:12px; border-block-start:1px solid var(--vx-line-soft); background:var(--vx-sheet); position:sticky; inset-block-end:0; }
.vx-composer__row{ display:flex; gap:8px; align-items:flex-end; }
.vx-composer__row > :is(.vx-textarea,.vx-input){ flex:1; min-inline-size:0; }
.vx-composer__row > .vx-textarea{ min-block-size:44px; }
.vx-composer__row > .vx-btn{ flex:none; }
/* a short screen (a phone, or any landscape phone): the reply box scrolls with
   the thread instead of covering a third of the screen above the keyboard (R3) */
@media (max-width:640px), (max-height:500px){ .vx-composer{ position:static; } }


/* ── §4.44 File drop (_raw_uploader.html) ───────────────────────────────── */
.vx-drop{ box-sizing:border-box; position:relative; display:grid; justify-items:start; gap:6px; padding:20px; cursor:pointer;
  background:color-mix(in srgb,var(--vx-sunken) 40%,var(--vx-card)); border:2px dashed var(--vx-line-control); border-radius:var(--vx-r-lg);
  transition:border-color var(--vx-dur-fast), background-color var(--vx-dur-fast); }
.vx-drop:hover{ border-color:var(--vx-neutral-edge-hover); transition:none; }
.vx-drop.is-over{ border-color:var(--vx-accent); background:var(--vx-accent-tint); }
.vx-drop:focus-within{ outline:2px solid var(--vx-focus); outline-offset:2px; }
.vx-drop input[type=file]{ position:absolute; inset:0; inline-size:100%; block-size:100%; opacity:0; cursor:pointer; }
.vx-drop__title{ font:600 .9375rem/1.3 var(--vx-font); color:var(--vx-ink); }
.vx-drop__hint{ font:500 .8125rem/1.4 var(--vx-font); color:var(--vx-text-2); }
.vx-files{ display:grid; gap:6px; margin-block:8px 0; margin-inline:0; padding:0; list-style:none; }
.vx-files > li{ display:grid; grid-template-columns:20px minmax(0,1fr) auto; gap:8px; align-items:center; padding-block:8px; padding-inline:10px;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); font:500 .8125rem/1.3 var(--vx-font); color:var(--vx-text); }
.vx-files > li > svg{ inline-size:16px; block-size:16px; color:var(--vx-text-2); }
.vx-files .vx-meter{ grid-column:2 / -1; }


/* ── §4.45 Stages: a job in progress (the free scan, a publish run) ─────── */
.vx-stages{ display:grid; gap:2px; margin:0; padding:0; list-style:none; }
.vx-stages > li{ display:grid; grid-template-columns:20px minmax(0,1fr) auto; gap:10px; align-items:center; min-block-size:32px;
  font:500 .875rem/1.35 var(--vx-font); color:var(--vx-text-2); }
.vx-stages > li::before{ content:""; box-sizing:border-box; inline-size:16px; block-size:16px; justify-self:center; border-radius:50%; border:1.5px solid var(--vx-line-control); }
.vx-stages > li[aria-current="step"]{ color:var(--vx-ink); font-weight:600; }
.vx-stages > li[aria-current="step"]::before{ border-color:color-mix(in srgb,var(--vx-accent) 25%,transparent); border-block-start-color:var(--vx-accent); border-width:2px; animation:vx-spin .8s linear infinite; }
.vx-stages > li.is-done{ color:var(--vx-text); }
.vx-stages > li.is-done::before{ border:0; border-radius:0; background:var(--vx-success); -webkit-mask:var(--vx-i-check) center/contain no-repeat; mask:var(--vx-i-check) center/contain no-repeat; }
.vx-stages > li.is-failed{ color:var(--vx-danger); }
.vx-stages > li.is-failed::before{ border:0; border-radius:0; background:var(--vx-danger); -webkit-mask:var(--vx-i-x) center/contain no-repeat; mask:var(--vx-i-x) center/contain no-repeat; }


/* ── §4.46 Status dot and lamp tags ─────────────────────────────────────── */
.vx-dot{
  display:inline-block; inline-size:8px; block-size:8px; flex:none; border-radius:50%; background:var(--vx-h, var(--vx-text-3)); vertical-align:middle; }
.vx-dot.is-live{ box-shadow:0 0 0 3px color-mix(in srgb,var(--vx-h, var(--vx-success)) 25%,transparent); }

/* ── §6.5 Reader: article rhythm, docs flavour, contents list, reader grid ─ */
/* .vx-prose (vx-base) sets the 17/28 article body; these give it rhythm.
   Raw-element rules skip component markup (a .vx-code's <pre>, a .vx-table). */
.vx-prose > * + *{ margin-block-start:1em; }
.vx-prose > h2{ margin-block-start:2em; padding-block-start:1em; border-block-start:1px solid var(--vx-line-soft); }
.vx-prose > h3{ margin-block-start:1.5em; }
.vx-prose > :is(h2,h3) + *{ margin-block-start:.5em; }
.vx-prose > :first-child{ margin-block-start:0; padding-block-start:0; border-block-start:0; }
.vx-prose > .vx-accs + h2{ padding-block-start:0; border-block-start:0; }   /* the FAQ list already ends on a hairline */
.vx-prose :is(h2,h3){ scroll-margin-block-start:16px; }   /* <html>'s scroll-padding already clears the taskbar (vx-base, ui.js §10): a heading lands 16px under it */
.vx-prose :is(ul,ol):not([class]){ padding-inline-start:1.4em; }
.vx-prose :is(ul,ol):not([class]) > li + li{ margin-block-start:.4em; }
.vx-prose li::marker{ color:var(--vx-text-3); }
.vx-prose blockquote{ padding-block:14px; padding-inline:16px; background:var(--vx-sunken); border:1px solid var(--vx-line); border-radius:var(--vx-r-sm);
  letter-spacing:calc(var(--vx-track-head) * .75); }   /* the callout--fyi look (§6.5) */
.vx-prose img{ display:block; block-size:auto; border:1px solid var(--vx-line); border-radius:var(--vx-r-md); box-shadow:var(--vx-shadow-photo); }
.vx-prose pre:not(.vx-code > pre){ padding-block:14px; padding-inline:16px; overflow:auto; direction:ltr; text-align:start;
  background:var(--vx-sunken); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); }
.vx-prose table:not(.vx-table, .vx-table-wrap > table){ display:block; inline-size:fit-content; max-inline-size:100%; overflow-x:auto;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-r-md); }   /* hugs a small table, scrolls a wide one */
/* docs and legal: the same reader at 15/24 (§6.5) */
.vx-prose--docs{ font-size:.9375rem; line-height:1.6; }

/* contents list ("Jump to", docs/legal sections). ui.js [data-vx-spy] marks the current link */
.vx-toc ol{ display:grid; gap:2px; margin-block-start:8px; }
.vx-toc li{ break-inside:avoid; }
.vx-toc a{ display:block; padding-block:4px; padding-inline:8px; border-radius:var(--vx-r-sm); font-size:.875rem; line-height:1.35;
  color:var(--vx-text-2); text-decoration:none; }
.vx-toc a:hover{ background:var(--vx-hover); color:var(--vx-ink); }
.vx-toc a[aria-current]{ color:var(--vx-ink); font-weight:600; }
@container window (min-width:640px) and (max-width:1083px){ .vx-toc--cols ol{ display:block; columns:2; column-gap:24px; } }   /* stacked above a wide column */

/* reader grid: head, contents, body. --article: contents at the inline-end from a
   1084px window (hidden below); --docs: contents at the inline-start, stacked above
   the body below 1084px. The body column is minmax(0,…): a wide code block or table
   scrolls inside it instead of widening it. */
.vx-reader{ display:grid; grid-template-columns:minmax(0,1fr); grid-template-areas:"head" "body"; row-gap:28px; }
.vx-reader__head{ grid-area:head; display:grid; gap:12px; justify-items:start; min-inline-size:0; max-inline-size:var(--vx-w-prose); }
.vx-reader__toc{ grid-area:toc; min-inline-size:0; }
.vx-reader__body{ grid-area:body; display:grid; grid-template-columns:minmax(0,1fr); gap:28px; align-content:start; min-inline-size:0; max-inline-size:var(--vx-w-prose); }
.vx-reader--article > .vx-reader__body{ gap:40px; }   /* article, FAQ, call to action: bigger blocks */
.vx-reader__body > .vx-callout{ margin-block:0; }      /* the body's gap spaces its blocks */
.vx-reader--article > .vx-reader__toc{ display:none; }
.vx-reader--docs:has(> .vx-reader__toc){ grid-template-areas:"head" "toc" "body"; }
@container window (min-width:1084px){
  .vx-reader--article{ grid-template-columns:minmax(0,var(--vx-w-prose)) 14rem; grid-template-areas:"head ." "body toc"; justify-content:space-between; column-gap:48px; }
  .vx-reader--article > .vx-reader__toc{ display:block; }
  .vx-reader--docs:has(> .vx-reader__toc){ grid-template-columns:15rem minmax(0,var(--vx-w-prose)); grid-template-areas:"toc head" "toc body"; column-gap:56px; }
  .vx-reader > .vx-reader__toc{ position:sticky; inset-block-start:calc(var(--vx-bar-h) + var(--vx-gutter) + 24px); align-self:start;
    max-block-size:calc(100dvh - var(--vx-bar-h) - 64px); overflow:auto; }
}


/* Big Persian/Arabic numerals: tabular Vazirmatn figures sit too far apart at
   display size (۵ ۹). Alignment only matters in columns, so KPI values, prices
   and the report score set proportional figures in RTL. Tables keep tnum. */
[dir="rtl"] :is(.vx-stat__value,.vx-bignum,.vx-score__value){ font-variant-numeric:normal; }


/* ── Windows High Contrast / forced colours (T-02) ────────────────────────── */
/* Icons painted as a MASK over a background colour vanish when the system
   forces backgrounds to Canvas: the ✓ of a check list, the +/− of an
   accordion, the done/failed stage marks, the sort chevrons, the step arrows.
   They are painted in CanvasText instead. Custom checkboxes, radios and
   selects fall back to the system's own controls; a switch and a meter draw
   their state in system colours. */
@media (forced-colors:active){
  :is(.vx-checks > li, .vx-acc > summary, .vx-stages > li, .vx-steps--arrows > .vx-step)::before,
  :is(.vx-acc > summary, .vx-table th[aria-sort] button, .vx-steps--arrows > .vx-step:not(:last-child))::after,
  .vx-tag--dot::before, .vx-dot{ forced-color-adjust:none; background:CanvasText; }
  .vx-stages > li:not(.is-done,.is-failed)::before{ background:transparent; border-color:CanvasText; }
  .vx-check, .vx-radio, :where(input[type="checkbox"]:not(.vx-switch,[role="switch"]), input[type="radio"]){ appearance:auto; }
  .vx-select, :where(select){ appearance:auto; background-image:none; padding-inline-end:11px; }
  .vx-switch{ forced-color-adjust:none; background:Canvas; border:1px solid CanvasText; }
  .vx-switch::before{ background:CanvasText; }
  .vx-switch:is(:checked,[aria-checked="true"]){ background:Highlight; border-color:Highlight; }
  .vx-switch:is(:checked,[aria-checked="true"])::before{ background:HighlightText; }
  .vx-meter{ forced-color-adjust:none; background:Canvas; border:1px solid CanvasText; }
  .vx-meter > :is(i,span){ background:CanvasText; }
  .vx-tab:is([aria-selected="true"],[aria-current="page"],[aria-current="true"],.is-active)::after{ forced-color-adjust:none; background:Highlight; }
  .vx-btn{ border-color:ButtonText; }
}


/* ── print (T-01): what a fill MEANS survives the printer ─────────────────── */
/* Printers drop backgrounds by default: white text on a solid chip, an active
   tab's indicator, a meter's fill or a keycap face would print as nothing.
   These keep their fills (the dark tokens never reach print: vx-tokens). */
@media print{
  :is(.vx-tag--solid,.vx-tag--tint,.vx-count,.vx-pill,.vx-folder__tab,.vx-folder__panel,.vx-glyph,.vx-avatar,.vx-step__badge,
      .vx-meter,.vx-barlist > li,.vx-switch,.vx-dot,.vx-hl,.vx-mark,.vx-tab,.vx-btn,.vx-stat,.vx-tile__ribbon,.vx-table tr,.vx-callout,.vx-banner,.vx-code){
    -webkit-print-color-adjust:exact; print-color-adjust:exact; }
  .vx-table-wrap, .vx-code pre{ background:none; overflow:visible; }   /* no scroll shades on paper; the whole table prints */
}


/* ── touch: bigger targets where the pointer is a finger (R7) ─────────────── */
/* Every control already clears WCAG 2.5.8 (24px); on a coarse pointer the
   day's action and block keycaps reach 44px and icon buttons 40px (2.5.5).
   The shells' own fixed-height strips (taskbar, scene actions) keep theirs. */
@media (pointer:coarse){
  .vx-btn:is(.vx-btn--primary,.vx-btn--block):not(.vx-taskbar *, .vx-scene__actions *, td *, .vx-btn--xs){ min-block-size:44px; }
  .vx-iconbtn:not(.vx-iconbtn--sm){ inline-size:40px; block-size:40px; }
  .vx-iconbtn--sm{ inline-size:32px; block-size:32px; }
}
