/* StellarAdmin.TagHelpers. Built from Client/css by scripts/build-css.mjs. */
@layer theme, base, sa.reset, sa.tokens, sa.components, components, sa.theme, sa.overrides, utilities;

/* reset.css */
/* StellarAdmin reset, in place of Tailwind's preflight (whose rules it follows, with the token colours
   and fonts). sa.reset sits below the components, so any component or author rule beats it. An app
   that also loads Tailwind's preflight gets both; the two agree. */

@layer sa.reset {
  *, ::after, ::before, ::backdrop, ::file-selector-button {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: 0 solid var(--sa-color-line);
  }
  * { outline-color: color-mix(in oklab, var(--sa-color-accent) 50%, transparent); }
  html, :host {
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
    tab-size: 4;
    font-family: var(--sa-font-sans);
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
  }
  body {
    background: var(--sa-color-canvas);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-body);
  }
  hr { height: 0; color: inherit; border-top-width: 1px; }
  abbr:where([title]) { text-decoration: underline dotted; }
  h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; }
  a { color: inherit; text-decoration: inherit; }
  b, strong { font-weight: bolder; }
  code, kbd, samp, pre { font-family: var(--sa-font-mono); font-size: 1em; }
  small { font-size: 80%; }
  sub, sup { position: relative; font-size: 75%; line-height: 0; vertical-align: baseline; }
  sub { bottom: -0.25em; }
  sup { top: -0.5em; }
  table { text-indent: 0; border-color: inherit; border-collapse: collapse; }
  :-moz-focusring { outline: auto; }
  progress { vertical-align: baseline; }
  summary { display: list-item; }
  ol, ul, menu { list-style: none; }
  img, svg, video, canvas, audio, iframe, embed, object { display: block; vertical-align: middle; }
  img, video { max-width: 100%; height: auto; }
  button, input, select, optgroup, textarea, ::file-selector-button {
    font: inherit;
    font-feature-settings: inherit;
    font-variation-settings: inherit;
    letter-spacing: inherit;
    color: inherit;
    border-radius: 0;
    background-color: transparent;
    opacity: 1;
  }
  :where(select:is([multiple], [size])) optgroup { font-weight: bolder; }
  :where(select:is([multiple], [size])) optgroup option { padding-inline-start: 20px; }
  ::file-selector-button { margin-inline-end: 4px; }
  ::placeholder { opacity: 1; color: color-mix(in oklab, currentcolor 50%, transparent); }
  textarea { resize: vertical; }
  ::-webkit-search-decoration { -webkit-appearance: none; }
  ::-webkit-date-and-time-value { min-height: 1lh; text-align: inherit; }
  ::-webkit-datetime-edit { display: inline-flex; }
  ::-webkit-datetime-edit-fields-wrapper { padding: 0; }
  ::-webkit-datetime-edit,
  ::-webkit-datetime-edit-year-field,
  ::-webkit-datetime-edit-month-field,
  ::-webkit-datetime-edit-day-field,
  ::-webkit-datetime-edit-hour-field,
  ::-webkit-datetime-edit-minute-field,
  ::-webkit-datetime-edit-second-field,
  ::-webkit-datetime-edit-millisecond-field,
  ::-webkit-datetime-edit-meridiem-field { padding-block: 0; }
  ::-webkit-calendar-picker-indicator { line-height: 1; }
  :-moz-ui-invalid { box-shadow: none; }
  button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button { appearance: button; }
  button { cursor: pointer; }
  ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; }
  [hidden]:where(:not([hidden="until-found"])) { display: none !important; }
}

/* tokens.css */
/* StellarAdmin foundation: theme variables (tier 0) and foundation tokens (tier 1).
 *
 * The one source of theme values. Theme variables generate the foundation tokens; components read the
 * theme variables and foundation tokens directly and have no public tokens of their own. The public names are
 * documented in docs/design/tokens.md; anything starting --_ is internal.
 *
 *   Tier 0  variables    --sa-accent, --sa-danger, --sa-neutral-*, --sa-radius, --sa-density, … and the
 *                        tier 1 tokens that need no formula (fonts, weights, label case, switches).
 *                        A theme is usually a few of these:
 *                          :root { --sa-accent: #0f766e; --sa-radius: 2px; --sa-density: 0.85; }
 *   Tier 1  foundation   --sa-color-*, --sa-text-*, --sa-radius-*, --sa-control-*, --sa-space-*,
 *                        --sa-focus-*, --sa-shadow-*: derived here. A theme may still set one directly.
 *   Tier 2  overrides    Raw .sa-* rules in sa.overrides. The escape hatch; every rule there is a sign
 *                        the vocabulary is missing something.
 *
 * Kinds of theme variable:
 *   - required theme variables have a default on :root;
 *   - optional theme variables have no default and are read through a var() fallback (--sa-accent-dark,
 *     --sa-radius-outer, --sa-on-accent, --sa-focus-color, --sa-danger-dark, --sa-neutral-hue-dark,
 *     --sa-neutral-chroma-dark, and per-component ones: --sa-dialog-footer-fill/-rule, --sa-kbd-font), so when unset
 *     they re-derive in every scope from the theme variables they would otherwise follow.
 *
 * Scoping. Custom properties that reference other custom properties resolve where they are declared,
 * and descendants inherit the resolved value. So formulas are declared on every element that can change
 * a theme variable: :root, a .dark scope, a [data-sa-density] scope and a [data-sa-scope] (any element that
 * sets its own theme variables, e.g. a branded panel). Colour formulas are split by mode; geometry is mode-independent.
 *
 * Modifier rule. A modifier class (a variant, MenuAccent.Bold, …) never redefines a token. It sets a
 * private --_* variable that the component's rules read.
 */

/* Layer order. Tailwind's layers are named too, so that a page that also loads Tailwind CSS keeps an
   author's utilities above the components, and the reset above preflight. A stylesheet that declares
   layers first fixes the order for the page, so a Tailwind build loaded before this one starts with
   the same statement. */
@layer theme, base, sa.reset, sa.tokens, sa.components, components, sa.theme, sa.overrides, utilities;

@layer sa.tokens {
  /* --- Theme variables, with the base theme's values ------------------------------------------ */
  :root {
    /* Colour */
    --sa-accent: oklch(0.5 0.16 258);    /* brand colour: primary buttons, focus, bold highlights */
    --sa-danger: oklch(0.58 0.22 27);
    --sa-success: oklch(0.6 0.15 150);   /* status colours: toast icons (later alerts, status badges) */
    --sa-warning: oklch(0.72 0.16 70);
    --sa-info: oklch(0.6 0.14 240);
    --sa-neutral-hue: 255;               /* greys lean toward this hue … */
    --sa-neutral-chroma: 0.006;          /* … by this much (0 = pure grey) */
    --sa-accent-tint: 0.15;              /* 0–1: how much the accent tints hover, selection, highlight */
    --sa-surface-depth: 0.8;             /* 0–1: canvas vs card separation (0 = one flat surface) */
    --sa-nav-tint: 0.5;                  /* 0–1: sidebar from canvas to sunken */
    --sa-line-strength: 1;               /* 0.75–2: dividers and control borders */

    /* Shape and depth: one decision each, applied to every component */
    --sa-radius: 6px;                    /* controls; 9999px for pill controls */
    --sa-pills: 0;                       /* 0 or 1: tags (badges, chips, the switch) are pills, or follow --sa-radius */
    --sa-outlines: 1;                    /* 0 or 1: filled parts draw an outline too (buttons, badges, chips,
                                            the switch track); 0 leaves outlines to outline-style parts */
    --sa-relief: 0;                      /* 0 flat; 1 raised (a drop shadow under buttons); 2 tactile (also a
                                            bottom edge, a hover lift, a pressed state and recessed fields) */
    --sa-sheen: 1;                       /* 0 flat; 1 solid buttons get a lit surface: a top-to-bottom gradient, a
                                            highlight along the top edge, a darker edge and a pressed shadow */
    --sa-stroke: 1px;
    --sa-elevation: 0.7;                 /* 0 = flat, 1 = soft, 2+ = floating */

    /* Space and type */
    --sa-density: 1;                     /* 0.75 dense … 1.25 roomy; spacing only, not type */
    --sa-type-scale: 1;

    /* Focus */
    --sa-focus-width: 3px;
    --sa-focus-offset: 0px;              /* > 0 draws a surface-coloured gap before the ring */

    /* Type: tier 1 tokens that need no formula, so they act as theme variables as they are */
    --sa-font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
    --sa-font-mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    --sa-font-heading: var(--sa-font-sans);
    --sa-weight-control: 500;
    --sa-weight-heading: 600;
    --sa-leading-body: 1.5;

    /* Section labels: menu labels, sidebar group labels (and column heads, see --sa-column-head-label) */
    --sa-section-label-font: inherit;
    --sa-section-label-text: calc(0.71875rem * var(--sa-type-scale));   /* 11.5px, between the 2xs and xs steps */
    --sa-section-label-weight: 500;
    --sa-section-label-transform: none;
    --sa-section-label-tracking: 0em;            /* a length, so switches can scale it */

    /* Structural switches: 0 or 1 (some blend in between), read by the components */
    --sa-footer-fill: 0;                 /* card footer: tinted band */
    --sa-footer-rule: 1;                 /* card footer: divider above it */
    --sa-column-head-label: 0;           /* column heads take the section label role */
    --sa-column-head-fill: 1;            /* column heads sit on a sunken band */
    --sa-column-head-case: none;         /* keyword: switches cannot scale it */
    --sa-column-head-font: inherit;      /* keyword too: e.g. var(--sa-font-mono) */
    --sa-current-page-fill: 0;           /* current page: 0 outline … 1 solid accent */
    --sa-solid-destructive: 1;           /* destructive button: 0 soft tint … 1 solid */
    --sa-filled-secondary: 1;            /* secondary button: 0 bordered surface … 1 sunken fill */
    --sa-link-decoration: none;          /* keyword: link buttons at rest (underline or none) */

    /* Fixed tokens */
    --sa-radius-round: 9999px;           /* avatars, dots: meaning, not style */
    --sa-control-icon: 1rem;
    --sa-motion-fast: 150ms;
    --sa-motion-ease: cubic-bezier(0.4, 0, 0.2, 1);
    --sa-press-offset: 1px;              /* button nudge on :active */
    --sa-disabled-opacity: 0.5;
  }

  [data-sa-density="compact"] { --sa-density: 0.8; }
  [data-sa-density="comfortable"] { --sa-density: 1.2; }

  /* --- Geometry and type: re-derived wherever density or theme variables change -------------- */
  :root,
  [data-sa-density],
  [data-sa-scope] {
    --sa-unit: calc(0.25rem * var(--sa-density));

    --sa-text-2xs: calc(0.6875rem * var(--sa-type-scale));
    --sa-text-xs: calc(0.75rem * var(--sa-type-scale));
    --sa-text-sm: calc(0.875rem * var(--sa-type-scale));
    --sa-text-base: calc(1rem * var(--sa-type-scale));
    --sa-text-body: var(--sa-text-sm);
    --sa-text-control: var(--sa-text-sm);
    --sa-leading-ui: calc(var(--sa-text-body) * 1.4286);

    --sa-radius-control: var(--sa-radius);
    --sa-radius-control-sm: max(0px, calc(var(--sa-radius) - 2px));
    --sa-radius-box: min(var(--sa-radius), var(--sa-radius-container));  /* boxes taller than a control: textareas, alerts, items */
    --sa-radius-container: var(--sa-radius-outer, min(calc(var(--sa-radius) * 1.5), 1.25rem));
    --sa-radius-overlay: min(var(--sa-radius-container), calc(var(--sa-radius) * 1.25));
    --sa-radius-item: max(0px, calc(var(--sa-radius-overlay) - var(--sa-space-overlay)));  /* concentric */
    --sa-radius-inner: calc(var(--sa-radius) * 0.6);
    --sa-radius-tag: calc(var(--sa-radius) + var(--sa-pills) * 9999px);                   /* badges, chips, switch */

    --sa-control-h-xs: calc(6 * var(--sa-unit));
    --sa-control-h-sm: calc(7 * var(--sa-unit));
    --sa-control-h: calc(8 * var(--sa-unit));
    --sa-control-h-lg: calc(9 * var(--sa-unit));
    --sa-control-px: calc(2.5 * var(--sa-unit));
    --sa-control-gap: calc(1.5 * var(--sa-unit));
    --sa-space-container: calc(4 * var(--sa-unit));
    --sa-space-container-sm: calc(3 * var(--sa-unit));
    --sa-space-cell-x: calc(2 * var(--sa-unit));
    --sa-space-cell-y: calc(2 * var(--sa-unit));
    --sa-space-overlay: calc(1 * var(--sa-unit));
    --sa-space-item-x: calc(1.5 * var(--sa-unit));
    --sa-space-item-y: calc(1 * var(--sa-unit));
    --sa-space-item-gap: calc(1.5 * var(--sa-unit));

    --sa-border-width: var(--sa-stroke);
    --sa-focus-ring-width: var(--sa-focus-width);
  }

  /* --- Colour ramps: the only mode-specific part ---------------------------------------------- */
  :root,
  [data-sa-scope] {
    --_h: var(--sa-neutral-hue);
    --_c: var(--sa-neutral-chroma);
    --_d: var(--sa-surface-depth);
    --_s: max(0.75, var(--sa-line-strength));  /* below 0.75 lines stop separating anything */
    --_e: var(--sa-elevation);

    --sa-color-canvas: oklch(calc(1 - 0.035 * var(--_d)) calc(var(--_c) * 0.6) var(--_h));
    --sa-color-surface: oklch(0.999 calc(var(--_c) * 0.2) var(--_h));
    --sa-color-surface-subtle: oklch(0.982 calc(var(--_c) * 0.6) var(--_h));
    --sa-color-surface-sunken: oklch(calc(0.96 - 0.035 * var(--_d)) var(--_c) var(--_h));   /* always 0.04 below the page */
    --sa-color-surface-raised: var(--sa-color-surface);
    --sa-color-field: var(--sa-color-surface);
    --sa-color-field-disabled: color-mix(in oklab, var(--sa-color-surface-sunken) 70%, transparent);

    --sa-color-ink: oklch(0.18 calc(var(--_c) * 2) var(--_h));
    --sa-color-ink-muted: oklch(calc(0.5 - 0.02 * var(--_d)) calc(var(--_c) * 1.5) var(--_h));   /* 4.5:1 on the sunken band too */
    --sa-color-ink-placeholder: oklch(0.62 var(--_c) var(--_h));

    /* Lines darken with the page, so surface depth cannot fade them into it. */
    --sa-color-line: oklch(min(1 - 0.08 * var(--_s), 1 - 0.035 * var(--_d) - 0.052 * var(--_s)) var(--_c) var(--_h));
    --sa-color-line-control: oklch(min(1 - 0.12 * var(--_s), 1 - 0.035 * var(--_d) - 0.092 * var(--_s)) var(--_c) var(--_h));
    --sa-color-line-control-hover: oklch(min(1 - 0.2 * var(--_s), 1 - 0.035 * var(--_d) - 0.172 * var(--_s)) var(--_c) var(--_h));
    --sa-color-nav-line: oklch(from var(--sa-color-nav-surface) calc(l - 0.06 * var(--_s)) c h);   /* a step below the sidebar */

    --sa-color-accent: var(--sa-accent);
    --sa-color-accent-text: oklch(from var(--sa-accent) min(l, 0.5) min(c, 0.2) h);   /* 4.5:1 on light surfaces, whatever the hue */
    --sa-color-danger: var(--sa-danger);
    --sa-color-danger-text: oklch(from var(--sa-danger) min(l, 0.48) c h);   /* danger as text: 4.5:1 on light surfaces and its tint */
    --sa-color-success: var(--sa-success);
    --sa-color-warning: var(--sa-warning);
    --sa-color-info: var(--sa-info);
    --sa-color-danger-soft: color-mix(in oklab, oklch(from var(--sa-color-danger) min(l, 0.58) c h) 10%, transparent);   /* a light danger would give no tint */
    --sa-color-danger-soft-hover: color-mix(in oklab, oklch(from var(--sa-color-danger) min(l, 0.58) c h) 18%, transparent);
    --sa-invalid-ring-color: color-mix(in oklab, var(--sa-color-danger) 22%, transparent);

    --_shadow-a: var(--_e);
    --sa-color-scrim: oklch(0.2 var(--_c) var(--_h) / 0.25);
  }

  .dark,
  .dark [data-sa-scope] {
    --_h: var(--sa-neutral-hue-dark, var(--sa-neutral-hue));
    --_c: var(--sa-neutral-chroma-dark, var(--sa-neutral-chroma));
    --sa-color-canvas: oklch(0.155 calc(var(--_c) * 1.2) var(--_h));
    --sa-color-surface: oklch(calc(0.155 + 0.1 * var(--_d)) calc(var(--_c) * 1.2) var(--_h));
    --sa-color-surface-subtle: oklch(calc(0.175 + 0.1 * var(--_d)) calc(var(--_c) * 1.2) var(--_h));
    --sa-color-surface-sunken: oklch(calc(0.24 + 0.06 * var(--_d)) calc(var(--_c) * 1.2) var(--_h));
    --sa-color-surface-raised: oklch(calc(0.17 + 0.1 * var(--_d)) calc(var(--_c) * 1.2) var(--_h));
    --sa-color-field: oklch(1 0 0 / 0.04);
    --sa-color-field-disabled: oklch(1 0 0 / 0.08);

    --sa-color-ink: oklch(0.97 calc(var(--_c) * 0.5) var(--_h));
    --sa-color-ink-muted: oklch(0.71 var(--_c) var(--_h));
    --sa-color-ink-placeholder: oklch(0.6 var(--_c) var(--_h));

    --sa-color-line: oklch(0.9 var(--_c) var(--_h) / calc(0.11 * var(--_s)));
    --sa-color-line-control: oklch(0.9 var(--_c) var(--_h) / calc(0.16 * var(--_s)));
    --sa-color-line-control-hover: oklch(0.9 var(--_c) var(--_h) / calc(0.26 * var(--_s)));
    --sa-color-nav-line: var(--sa-color-line);

    --sa-color-accent: var(--sa-accent-dark, oklch(from var(--sa-accent) max(l, 0.72) c h));
    --sa-color-accent-text: oklch(from var(--sa-color-accent) max(l, 0.75) c h);
    --sa-color-danger: var(--sa-danger-dark, oklch(from var(--sa-danger) max(l, 0.68) c h));
    --sa-color-danger-text: oklch(from var(--sa-color-danger) max(l, 0.88) c h);   /* 4.5:1 on its hover tint over raised surfaces too */
    --sa-color-success: oklch(from var(--sa-success) max(l, 0.72) c h);
    --sa-color-warning: oklch(from var(--sa-warning) max(l, 0.78) c h);
    --sa-color-info: oklch(from var(--sa-info) max(l, 0.72) c h);
    --sa-color-danger-soft: color-mix(in oklab, var(--sa-color-danger) 20%, transparent);
    --sa-color-danger-soft-hover: color-mix(in oklab, var(--sa-color-danger) 30%, transparent);
    --sa-invalid-ring-color: color-mix(in oklab, var(--sa-color-danger) 40%, transparent);

    --_shadow-a: calc(var(--_e) * 2.5);
    --sa-color-scrim: oklch(0 0 0 / 0.5);
  }

  /* --- Relations: the same formula in every mode, so declared on every colour scope ---------- */
  :root,
  [data-sa-scope],
  .dark,
  .dark [data-sa-scope] {
    /* Solid fills (primary buttons, badges, the switch, the current page, bold highlights) and the text on
       them, computed from WCAG luminance (Y, from linear sRGB clipped to the sRGB gamut, as the screen shows it). Text is white on a fill below Y 0.18 and
       near-black above it, whichever contrasts more. A fill between Y 0.18 and 0.37 (about lightness 0.57 to
       0.72, depending on hue) reaches 4.5:1 with neither, and saturated oranges and reds read better with
       white than the formula suggests, so it darkens, keeping its hue, to Y 0.175, where white passes.
       Focus rings, washes and tints keep the colour as set. */
    --sa-color-accent-fill: color(from var(--sa-color-accent) srgb-linear
      calc(clamp(0, r, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)))))
      calc(clamp(0, g, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)))))
      calc(clamp(0, b, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))))));
    --sa-color-danger-fill: color(from var(--sa-color-danger) srgb-linear
      calc(clamp(0, r, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)))))
      calc(clamp(0, g, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)))))
      calc(clamp(0, b, 1) * (1 - clamp(0, ((0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1)) - 0.18) * 1e6, 1) * clamp(0, (0.37 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) * (1 - 0.175 / (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))))));
    --sa-color-on-accent: var(--sa-on-accent, color(from var(--sa-color-accent-fill) srgb-linear clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1)));
    --sa-color-on-danger: color(from var(--sa-color-danger-fill) srgb-linear clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1) clamp(0.0015, (0.18 - (0.2126 * clamp(0, r, 1) + 0.7152 * clamp(0, g, 1) + 0.0722 * clamp(0, b, 1))) * 1e6, 1));
    --sa-color-accent-hover: color-mix(in oklab, var(--sa-color-accent-fill) 88%, var(--sa-color-ink));
    --sa-color-hover: color-mix(in oklab, var(--sa-color-accent) calc(var(--sa-accent-tint) * 8%), var(--sa-color-surface-sunken));
    --sa-color-selected: color-mix(in oklab, var(--sa-color-accent) calc(var(--sa-accent-tint) * 14%), var(--sa-color-surface-sunken));
    --sa-color-highlight: color-mix(in oklab, var(--sa-color-accent) calc(var(--sa-accent-tint) * 16%), var(--sa-color-surface-sunken));
    --sa-color-on-highlight: var(--sa-color-ink);
    --sa-color-tint: color-mix(in oklab, var(--sa-color-ink) 8%, transparent);   /* translucent, so it steps from whatever it sits on: tracks, keys, chips, skeletons */

    --sa-color-nav-surface: color-mix(in oklab, var(--sa-color-surface-sunken) calc(var(--sa-nav-tint) * 100%), var(--sa-color-canvas));
    --sa-color-nav-ink: var(--sa-color-ink);
    --sa-color-nav-highlight: color-mix(in oklab, var(--sa-color-accent) calc(var(--sa-accent-tint) * 18%),
      color-mix(in oklab, var(--sa-color-ink) 6%, var(--sa-color-nav-surface)));
    --sa-color-on-nav-highlight: var(--sa-color-ink);
    --sa-color-nav-accent: var(--sa-color-accent-fill);

    --sa-focus-border: var(--sa-color-accent);
    --sa-focus-ring-color: var(--sa-focus-color, color-mix(in oklab, var(--sa-color-accent) 40%, transparent));
    --sa-focus-shadow: 0 0 0 var(--sa-focus-offset) var(--sa-color-surface),
      0 0 0 calc(var(--sa-focus-offset) + var(--sa-focus-width)) var(--sa-focus-ring-color);
    --sa-focus-shadow-field: var(--sa-focus-shadow);
    --sa-invalid-shadow: 0 0 #0000;
    --sa-invalid-focus-shadow: 0 0 0 var(--sa-focus-width) var(--sa-invalid-ring-color);

    /* One elevation theme variable scales every shadow's opacity; dark mode needs about 2.5× to read. */
    --_shadow: oklch(0.2 calc(var(--_c) * 3) var(--_h) / calc(0.07 * var(--_shadow-a)));
    --_shadow-soft: oklch(0.2 calc(var(--_c) * 3) var(--_h) / calc(0.04 * var(--_shadow-a)));
    --sa-shadow-control: 0 1px 2px 0 var(--_shadow-soft);
    --sa-shadow-container: 0 1px 3px 0 var(--_shadow-soft), 0 1px 2px -1px var(--_shadow-soft);
    --sa-shadow-raised: 0 1px 3px 0 var(--_shadow), 0 1px 2px -1px var(--_shadow);
    --sa-shadow-overlay: 0 10px 24px -6px var(--_shadow), 0 2px 6px -2px var(--_shadow-soft);
    --sa-shadow-dialog: 0 24px 56px -12px oklch(0.2 calc(var(--_c) * 3) var(--_h) / calc(0.22 * var(--_shadow-a)));
  }

  /* Dark mode: the hover fill moves away from the text on it (black under light text, white under
     dark text), not toward the light ink, which cost white text its contrast (3.8:1). */
  .dark,
  .dark [data-sa-scope] {
    --sa-color-accent-hover: color-mix(in oklab, var(--sa-color-accent-fill) 88%, oklch(from var(--sa-color-on-accent) clamp(0, (0.62 - l) * 1000, 1) 0 0));
  }
}

/* structure.css */
/* Structure no theme touches: the few plain classes the tag helpers emit for anchor positioning, hidden
   text and icon size, and the field's child widths. The rules are in sa.components, so an author's own
   classes (sa.overrides, or Tailwind's utilities) still win. */

@layer sa.reset {
  /* The UA's popover defaults (centred, canvas colours); each overlay sets its own inset, margin and
     colours. */
  [popover] {
    inset: 0;
    margin: auto;
    background-color: canvas;
    color: canvastext;
  }
}

@layer sa.components {
  /* Anchor positioning: anchored-* mirrors the PositionArea enum (TagHelpers/PositionArea.cs). */
  .anchored-top { position-area: top; }
  .anchored-top-center { position-area: top center; }
  .anchored-top-span-left { position-area: top span-left; }
  .anchored-top-span-right { position-area: top span-right; }
  .anchored-top-left { position-area: top left; }
  .anchored-top-right { position-area: top right; }
  .anchored-bottom { position-area: bottom; }
  .anchored-bottom-center { position-area: bottom center; }
  .anchored-bottom-span-left { position-area: bottom span-left; }
  .anchored-bottom-span-right { position-area: bottom span-right; }
  .anchored-bottom-left { position-area: bottom left; }
  .anchored-bottom-right { position-area: bottom right; }
  .anchored-left { position-area: left; }
  .anchored-left-center { position-area: left center; }
  .anchored-left-span-top { position-area: left span-top; }
  .anchored-left-span-bottom { position-area: left span-bottom; }
  .anchored-right { position-area: right; }
  .anchored-right-center { position-area: right center; }
  .anchored-right-span-top { position-area: right span-top; }
  .anchored-right-span-bottom { position-area: right span-bottom; }

  /* The gap between an anchored panel and its trigger, from the data-anchor-side attribute the
     overlay tag helpers emit. [popover] out-ranks the panels' own margin: 0. */
  [popover][data-anchor-side="top"] { margin-bottom: calc(2 * var(--sa-unit)); }
  [popover][data-anchor-side="bottom"] { margin-top: calc(2 * var(--sa-unit)); }
  [popover][data-anchor-side="left"] { margin-inline-end: calc(2 * var(--sa-unit)); }
  [popover][data-anchor-side="right"] { margin-inline-start: calc(2 * var(--sa-unit)); }

  /* Text for screen readers only. */
  .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border-width: 0;
  }

  /* Icons the tag helpers size in markup; components size an icon only when its class names no
     size (svg:not([class*="size-"])). */
  .size-4 {
    width: calc(4 * var(--sa-unit));
    height: calc(4 * var(--sa-unit));
  }

  /* A vertical or responsive field stretches its children, over their own widths (a toggle group's
     fit-content); a responsive field stops once its field group is wide enough for a row. */
  .sa-field.sa-field:is([data-orientation="vertical"], [data-orientation="responsive"]) > :not(.sr-only) {
    width: 100%;
  }
  @container field-group (width >= 28rem) {
    .sa-field.sa-field[data-orientation="responsive"] > :not(.sr-only) { width: auto; }
  }
}

/* components/accordion.css */
/* Accordion: <sa-accordion>, a column of <details> items whose summary is the trigger.
   Replaces: .sa-accordion, .sa-accordion-item, .sa-accordion-trigger, .sa-accordion-trigger-icon,
   .sa-accordion-content, .sa-accordion-content-inner */

@layer sa.components {
  .sa-accordion {
    display: flex;
    flex-direction: column;
    width: 100%;
  }
  .sa-accordion-item:not(:last-child) {
    border-bottom: var(--sa-border-width) solid var(--sa-color-line);
  }

  .sa-accordion-trigger {
    position: relative;
    display: flex;
    flex: 1;
    align-items: flex-start;
    justify-content: space-between;
    padding-block: calc(2.5 * var(--sa-unit));
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-control);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    font-weight: var(--sa-weight-control);
    text-align: left;
    list-style: none;
    cursor: default;
    outline: none;
    transition-property: color, border-color, box-shadow;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    &::-webkit-details-marker { display: none; }
    &:hover { text-decoration: underline; }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
    details[disabled] > & {
      opacity: var(--sa-disabled-opacity);
      pointer-events: none;
    }
  }
  .sa-accordion-trigger-icon {
    color: var(--sa-color-ink-muted);
    & > svg {
      display: block;
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
      transition: rotate 300ms var(--sa-motion-ease);
      details[open] > .sa-accordion-trigger & { rotate: 180deg; }
    }
  }

  .sa-accordion-content {
    overflow: hidden;
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    details[disabled]:not([open]) > summary + & { display: none; }
  }
  .sa-accordion-content-inner {
    padding-bottom: calc(2.5 * var(--sa-unit));
    & a {
      text-decoration: underline;
      text-underline-offset: 3px;
      &:hover { color: var(--sa-color-ink); }
    }
    & p:not(:last-child) { margin-bottom: calc(4 * var(--sa-unit)); }
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-accordion-trigger, .sa-accordion-trigger-icon > svg { transition-duration: 0s; }
  }
}

/* components/alert-dialog.css */
/* Alert dialog: a confirmation over a native <dialog>, drawn like the dialog (scrim, raised surface,
   footer switches), with optional media beside or above the title, and a small size.
   Replaces: .sa-alert-dialog-content, .sa-alert-dialog-overlay, .sa-alert-dialog-header,
   .sa-alert-dialog-media, .sa-alert-dialog-title, .sa-alert-dialog-description,
   .sa-alert-dialog-footer */

@layer sa.tokens {
  .sa-alert-dialog-content {
    /* The dialog's footer switches: banded or ruled like the dialog's footer. */
    --_footer-fill: var(--sa-dialog-footer-fill, var(--sa-footer-fill));
    --_footer-rule: var(--sa-dialog-footer-rule, var(--sa-footer-rule));
  }
}

@layer sa.components {
  .sa-alert-dialog-content {
    --_max-w: 20rem;
    position: fixed;
    inset: 0;
    margin: auto;
    width: 100%;
    max-width: min(var(--_max-w), calc(100% - 2rem));
    height: fit-content;
    padding: var(--sa-space-container);
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface-raised);
    box-shadow: var(--sa-shadow-dialog);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: calc(1.25 / 0.875);
    outline: none;
    &[open] {
      display: grid;
      gap: var(--sa-space-container);
      animation: sa-dialog-in var(--sa-motion-fast) var(--sa-motion-ease);   /* keyframes in dialog.css */
    }
    &::backdrop {
      background: var(--sa-color-scrim);
    }
    &[open]::backdrop {
      animation: sa-dialog-backdrop-in var(--sa-motion-fast) var(--sa-motion-ease);
    }
  }

  /* Centred, the media above the title; a default-size dialog with room aligns to the start and
     puts the media beside the title and description. */
  .sa-alert-dialog-header {
    display: grid;
    grid-template-rows: auto 1fr;
    place-items: center;
    gap: calc(1.5 * var(--sa-unit));
    text-align: center;
    &:has(> [data-slot="alert-dialog-media"]) {
      grid-template-rows: auto auto 1fr;
      column-gap: calc(4 * var(--sa-unit));
    }
  }
  .sa-alert-dialog-media {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: calc(10 * var(--sa-unit));
    height: calc(10 * var(--sa-unit));
    margin-bottom: calc(2 * var(--sa-unit));
    border-radius: var(--sa-radius-control-sm);
    background: var(--sa-color-surface-sunken);
    color: var(--sa-color-ink);
    & > svg:not([class*="size-"]) {
      width: 1.5rem;
      height: 1.5rem;
    }
  }
  .sa-alert-dialog-title {
    font-family: var(--sa-font-heading);
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-heading);
    line-height: 1.5;
  }
  .sa-alert-dialog-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
    text-wrap: balance;
    & a {
      text-decoration: underline;
      text-underline-offset: 3px;
      &:hover { color: var(--sa-color-ink); }
    }
    @media (width >= 48rem) {
      text-wrap: pretty;
    }
  }
  .sa-alert-dialog-footer {
    display: flex;
    flex-direction: column-reverse;
    gap: calc(2 * var(--sa-unit));
    margin: 0 calc(-1 * var(--sa-space-container)) calc(-1 * var(--sa-space-container));
    padding: calc(var(--sa-space-container) * max(var(--_footer-fill), var(--_footer-rule))) var(--sa-space-container) var(--sa-space-container);
    border-top: var(--sa-border-width) solid color-mix(in oklab, var(--sa-color-line) calc(var(--_footer-rule) * 100%), transparent);
    border-radius: 0 0 var(--sa-radius-container) var(--sa-radius-container);
    background: color-mix(in oklab, var(--sa-color-surface-subtle) calc(var(--_footer-fill) * 100%), transparent);
  }
  /* Small: two equal buttons side by side. */
  .sa-alert-dialog-content[data-size="sm"] .sa-alert-dialog-footer {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  @media (width >= 40rem) {
    .sa-alert-dialog-content[data-size="default"] {
      --_max-w: 24rem;
      & .sa-alert-dialog-header {
        place-items: start;
        text-align: start;
        &:has(> [data-slot="alert-dialog-media"]) {
          grid-template-rows: auto 1fr;
        }
      }
      & .sa-alert-dialog-media {
        grid-row: span 2;
      }
      & .sa-alert-dialog-header:has(> [data-slot="alert-dialog-media"]) .sa-alert-dialog-title {
        grid-column-start: 2;
      }
    }
    .sa-alert-dialog-footer {
      flex-direction: row;
      justify-content: flex-end;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-alert-dialog-content[open],
    .sa-alert-dialog-content[open]::backdrop {
      animation: none;
    }
  }
}

/* components/alert.css */
/* Alert: a bordered message box with an optional leading icon, title, description and action.
   Replaces: .sa-alert, .sa-alert-variant-default, .sa-alert-variant-destructive, .sa-alert-title,
   .sa-alert-description, .sa-alert-action */

@layer sa.tokens {
  .sa-alert {
    /* Danger: the danger tint over the surface, made opaque (danger-soft is translucent), so the text
       is measured against a known colour. Danger text passes 4.5:1 on its tint in both modes. */
    --_alert-danger-bg: color-mix(in oklab, oklch(from var(--sa-color-danger) min(l, 0.58) c h) 6%, var(--sa-color-surface));
    --_alert-danger-border: color-mix(in oklab, var(--sa-color-danger) 35%, var(--sa-color-surface));
  }
  .dark .sa-alert {
    --_alert-danger-bg: color-mix(in oklab, var(--sa-color-danger) 12%, var(--sa-color-surface));
    --_alert-danger-border: color-mix(in oklab, var(--sa-color-danger) 40%, var(--sa-color-surface));
  }
}

@layer sa.components {
  .sa-alert {
    --_bg: var(--sa-color-surface);
    --_fg: var(--sa-color-ink);
    --_border: var(--sa-color-line);
    --_description-fg: var(--sa-color-ink-muted);
    position: relative;
    display: grid;
    gap: calc(0.5 * var(--sa-unit));
    width: 100%;
    padding: calc(2 * var(--sa-unit)) calc(2.5 * var(--sa-unit));
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--sa-radius-box);
    background: var(--_bg);
    color: var(--_fg);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    text-align: start;

    &:has(> [data-slot="alert-action"]) {
      padding-inline-end: calc(18 * var(--sa-unit));
    }
    &:has(> svg) {
      grid-template-columns: auto 1fr;
      column-gap: calc(2 * var(--sa-unit));
    }
    & > svg {
      grid-row: span 2;
      translate: 0 calc((var(--sa-leading-ui) - var(--sa-control-icon)) / 2);
      color: currentColor;
      &:not([class*="size-"]) {
        width: var(--sa-control-icon);
        height: var(--sa-control-icon);
      }
    }
  }
  .sa-alert-variant-destructive {
    --_bg: var(--_alert-danger-bg);
    --_fg: var(--sa-color-danger-text);
    --_border: var(--_alert-danger-border);
    --_description-fg: var(--sa-color-danger-text);
  }
  .sa-alert-title {
    font-weight: var(--sa-weight-control);
    .sa-alert:has(> svg) > & {
      grid-column-start: 2;
    }
  }
  .sa-alert-description {
    color: var(--_description-fg);
    font-size: var(--sa-text-sm);
    text-wrap: pretty;
    & p:not(:last-child) {
      margin-bottom: calc(4 * var(--sa-unit));
    }
    .sa-alert:has(> svg) > & {
      grid-column-start: 2;
    }
  }
  :is(.sa-alert-title, .sa-alert-description) a {
    text-decoration: underline;
    text-underline-offset: 3px;
    &:hover {
      color: var(--sa-color-ink);
    }
  }
  .sa-alert-variant-destructive :is(.sa-alert-title, .sa-alert-description) a:hover {
    color: inherit;
  }
  .sa-alert-action {
    position: absolute;
    top: calc(2 * var(--sa-unit));
    right: calc(2 * var(--sa-unit));
  }
}

/* components/app-header.css */
/* App header: <sa-app-header>, the bar across the top of the main area, with actions at the end and
   vertical separators.
   Replaces: .sa-app-header, .sa-app-header-actions, .sa-app-header-separator */

@layer sa.components {
  .sa-app-header {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    column-gap: calc(2 * var(--sa-unit));
    height: calc(14 * var(--sa-unit));
    padding-inline: calc(4 * var(--sa-unit));
    border-bottom: var(--sa-border-width) solid var(--sa-color-line);
    background: transparent;
  }
  .sa-app-header-actions {
    display: flex;
    align-items: center;
    column-gap: calc(1 * var(--sa-unit));
    margin-left: auto;
  }
  .sa-separator.sa-app-header-separator {
    height: calc(4 * var(--sa-unit));
    margin-inline: calc(1 * var(--sa-unit));
  }
}

/* components/attachment.css */
/* Attachment: a file card (media, title, description, actions, an optional whole-card trigger) in
   three sizes, horizontal or vertical, with idle, uploading, processing, done and error states; and the
   attachment group, a horizontally scrolling, snapping row with faded edges.
   Replaces: .sa-attachment, .sa-attachment-actions, .sa-attachment-content, .sa-attachment-description,
   .sa-attachment-group, .sa-attachment-media, .sa-attachment-media-variant-image,
   .sa-attachment-orientation-horizontal, .sa-attachment-orientation-vertical, .sa-attachment-size-default,
   .sa-attachment-size-sm, .sa-attachment-size-xs, .sa-attachment-title, .sa-attachment-trigger */

@layer sa.components {
  .sa-attachment {
    --_p: calc(2 * var(--sa-unit));
    --_px: calc(2.5 * var(--sa-unit));
    --_py: calc(2 * var(--sa-unit));
    --_media-w: calc(10 * var(--sa-unit));
    --_media-radius: var(--sa-radius-box);
    --_media-icon: 1rem;
    position: relative;
    display: flex;
    flex-wrap: wrap;
    flex-shrink: 0;
    gap: calc(2 * var(--sa-unit));
    width: fit-content;
    min-width: 0;
    max-width: 100%;
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-sm);
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &:has(> [data-slot="attachment-content"]) {
      padding: var(--_py) var(--_px);
    }
    &:has(> [data-slot="attachment-media"]) {
      padding: var(--_p);
    }
    &:has(> a, > button):hover {
      background-color: color-mix(in oklab, var(--sa-color-hover) 60%, var(--sa-color-surface));
    }
    &:has(> [data-slot="attachment-trigger"]:focus-visible) {
      box-shadow: var(--sa-focus-shadow);
    }
    &[data-state="idle"] {
      border-style: dashed;
    }
    &[data-state="error"] {
      border-color: color-mix(in oklab, var(--sa-color-danger) 45%, transparent);
    }
  }

  .sa-attachment-orientation-horizontal {
    align-items: center;
  }
  .sa-attachment-orientation-vertical {
    --_media-w: 100%;
    --_media-icon: 1.5rem;
    flex-direction: column;
    width: calc(24 * var(--sa-unit));
    &:has([data-slot="attachment-content"]) {
      width: calc(30 * var(--sa-unit));
    }
  }

  .sa-attachment-size-sm {
    --_p: calc(1.5 * var(--sa-unit));
    --_px: calc(2 * var(--sa-unit));
    --_py: calc(1.5 * var(--sa-unit));
    --_media-w: calc(8 * var(--sa-unit));
    gap: calc(2.5 * var(--sa-unit));
    font-size: var(--sa-text-xs);
  }
  .sa-attachment-size-xs {
    --_p: var(--sa-unit);
    --_px: calc(1.5 * var(--sa-unit));
    --_py: var(--sa-unit);
    --_media-w: calc(7 * var(--sa-unit));
    --_media-radius: max(0px, calc(var(--sa-radius-box) - 2px));
    --_media-icon: 0.875rem;
    gap: calc(1.5 * var(--sa-unit));
    border-radius: var(--sa-radius-box);
    font-size: var(--sa-text-xs);
  }
  .sa-attachment-orientation-vertical:is(.sa-attachment-size-sm, .sa-attachment-size-xs) {
    --_media-w: 100%;
    --_media-icon: 1.5rem;
  }

  .sa-attachment-media {
    position: relative;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: var(--_media-w);
    aspect-ratio: 1;
    overflow: hidden;
    border-radius: var(--_media-radius);
    background: var(--sa-color-surface-sunken);
    color: var(--sa-color-ink);

    & svg {
      pointer-events: none;
    }
    & svg:not([class*="size-"]),
    & > [data-slot="spinner"] {
      width: var(--_media-icon);
      height: var(--_media-icon);
    }
    [data-state="error"] > & {
      background: var(--sa-color-danger-soft);
      color: var(--sa-color-danger-text);
    }
  }
  .sa-attachment-media-variant-image {
    opacity: 0.6;
    & > img {
      width: 100%;
      aspect-ratio: 1;
      object-fit: cover;
    }
    :is([data-state="idle"], [data-state="done"]) > & {
      opacity: 1;
    }
  }

  .sa-attachment-content {
    flex: 1;
    min-width: 0;
    max-width: 100%;
    line-height: 1.25;
    .sa-attachment-orientation-vertical > & {
      padding-inline: var(--sa-unit);
    }
  }
  .sa-attachment-title {
    display: block;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    font-weight: var(--sa-weight-control);
    text-overflow: ellipsis;
    white-space: nowrap;
    :is([data-state="processing"], [data-state="uploading"]) > .sa-attachment-content > & {
      --_spread: calc(3ch + 40px);
      --_highlight: oklch(from currentColor l c h / calc(alpha * 0.2));
      background-image: linear-gradient(
        110deg,
        currentColor calc(50% - var(--_spread)),
        color-mix(in oklch, var(--_highlight), currentColor 50%) calc(50% - var(--_spread) * 0.5),
        var(--_highlight) 50%,
        color-mix(in oklch, var(--_highlight), currentColor 50%) calc(50% + var(--_spread) * 0.5),
        currentColor calc(50% + var(--_spread))
      );
      background-repeat: no-repeat;
      background-size: calc(200% + var(--_spread) * 2) 100%;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      animation: sa-attachment-shimmer 2s linear infinite;
    }
    .dark :is([data-state="processing"], [data-state="uploading"]) > .sa-attachment-content > & {
      --_highlight: oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.4));
    }
  }
  .sa-attachment-description {
    display: block;
    min-width: 0;
    max-width: 100%;
    margin-top: calc(0.5 * var(--sa-unit));
    overflow: hidden;
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-xs);
    line-height: 1.3333;
    text-overflow: ellipsis;
    white-space: nowrap;
    [data-state="error"] > .sa-attachment-content > & {
      color: var(--sa-color-danger-text);
    }
  }

  .sa-attachment-actions {
    position: relative;
    z-index: 20;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    .sa-attachment-orientation-vertical > & {
      position: absolute;
      top: calc(3 * var(--sa-unit));
      right: calc(3 * var(--sa-unit));
      gap: var(--sa-unit);
    }
  }

  .sa-attachment-trigger {
    position: absolute;
    inset: 0;
    z-index: 10;
    outline: none;
  }

  .sa-attachment-group {
    display: flex;
    gap: calc(3 * var(--sa-unit));
    min-width: 0;
    padding-block: var(--sa-unit);
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-padding-inline: var(--sa-unit);
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    /* Edges fade where the row scrolls on, revealed by its scroll position. */
    --_fade-dir: to right;
    mask-image: linear-gradient(
      var(--_fade-dir),
      transparent 0,
      #000 var(--_sa-attachment-fade-s),
      #000 calc(100% - var(--_sa-attachment-fade-e)),
      transparent 100%
    );
    mask-repeat: no-repeat;
    &:where([dir="rtl"], [dir="rtl"] *) {
      --_fade-dir: to left;
    }
    &::-webkit-scrollbar {
      display: none;
    }
    & > [data-slot="attachment"] {
      flex: none;
      scroll-snap-align: start;
    }

    @supports (animation-timeline: scroll()) {
      animation:
        sa-attachment-fade-s 1ms ease-in-out,
        sa-attachment-fade-e 1ms ease-in-out;
      animation-timeline: scroll(self inline), scroll(self inline);
      animation-range:
        0 calc(24 * var(--sa-unit)),
        calc(100% - 24 * var(--sa-unit)) 100%;
      animation-fill-mode: both;
    }
    @supports not (animation-timeline: scroll()) {
      --_sa-attachment-fade-s: min(12%, calc(10 * var(--sa-unit)));
      --_sa-attachment-fade-e: min(12%, calc(10 * var(--sa-unit)));
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-attachment {
      transition-duration: 0s;
    }
    .sa-attachment-title {
      animation-duration: 6s;
    }
  }
}

@property --_sa-attachment-fade-s {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 0px;
}
@property --_sa-attachment-fade-e {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 0px;
}
@keyframes sa-attachment-fade-s {
  from { --_sa-attachment-fade-s: 0px; }
  to { --_sa-attachment-fade-s: min(12%, calc(10 * var(--sa-unit))); }
}
@keyframes sa-attachment-fade-e {
  from { --_sa-attachment-fade-e: min(12%, calc(10 * var(--sa-unit))); }
  to { --_sa-attachment-fade-e: 0px; }
}
@keyframes sa-attachment-shimmer {
  from { background-position: 100% 0; }
  to { background-position: 0 0; }
}

/* components/avatar.css */
/* Avatar: a round image or initials, with an optional status badge, alone or in an overlapping group.
   Replaces: .sa-avatar, .sa-avatar-image, .sa-avatar-fallback, .sa-avatar-badge, .sa-avatar-group,
   .sa-avatar-group-count */

@layer sa.components {
  .sa-avatar {
    --_size: calc(8 * var(--sa-unit));
    --_text: var(--sa-text-sm);
    --_badge: calc(2.5 * var(--sa-unit));
    position: relative;
    display: flex;
    flex-shrink: 0;
    width: var(--_size);
    height: var(--_size);
    border-radius: var(--sa-radius-round);
    user-select: none;
    &::after {
      content: "";
      position: absolute;
      inset: 0;
      border: var(--sa-border-width) solid var(--sa-color-line);
      border-radius: inherit;
      mix-blend-mode: darken;
      pointer-events: none;
    }
    &[data-size="sm"] {
      --_size: calc(6 * var(--sa-unit));
      --_text: var(--sa-text-xs);
      --_badge: calc(2 * var(--sa-unit));
    }
    &[data-size="lg"] {
      --_size: calc(10 * var(--sa-unit));
      --_badge: calc(3 * var(--sa-unit));
    }
  }
  .dark .sa-avatar::after {
    mix-blend-mode: lighten;
  }
  .sa-avatar-image {
    width: 100%;
    height: 100%;
    aspect-ratio: 1 / 1;
    border-radius: inherit;
    object-fit: cover;
  }
  .sa-avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    border-radius: inherit;
    background: var(--sa-color-surface-sunken);
    color: var(--sa-color-ink-muted);
    font-size: var(--_text);
    line-height: 1;
  }
  .sa-avatar-badge {
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 10;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--_badge);
    height: var(--_badge);
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-accent-fill);
    box-shadow: 0 0 0 2px var(--sa-color-surface);
    color: var(--sa-color-on-accent);
    user-select: none;
    & > svg {
      width: calc(2 * var(--sa-unit));
      height: calc(2 * var(--sa-unit));
    }
    [data-size="sm"] > & > svg {
      display: none;
    }
  }

  .sa-avatar-group {
    display: flex;
    & > :not(:last-child) {
      margin-inline-end: calc(-1 * calc(2 * var(--sa-unit)));
    }
    & > [data-slot="avatar"] {
      box-shadow: 0 0 0 2px var(--sa-color-surface);
    }
  }
  .sa-avatar-group-count {
    --_size: calc(8 * var(--sa-unit));
    --_icon: var(--sa-control-icon);
    position: relative;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: var(--_size);
    height: var(--_size);
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-surface-sunken);
    box-shadow: 0 0 0 2px var(--sa-color-surface);
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: 1;
    & > svg {
      width: var(--_icon);
      height: var(--_icon);
    }
    .sa-avatar-group:has([data-size="sm"]) > & {
      --_size: calc(6 * var(--sa-unit));
      --_icon: 0.75rem;
    }
    .sa-avatar-group:has([data-size="lg"]) > & {
      --_size: calc(10 * var(--sa-unit));
      --_icon: 1.25rem;
    }
  }
}

/* components/badge.css */
/* Badge: a short label on a tag-shaped fill (<sa-badge>, also as a link).
   Replaces: .sa-badge, .sa-badge-variant-default, .sa-badge-variant-secondary,
   .sa-badge-variant-outline, .sa-badge-variant-destructive, .sa-badge-variant-ghost,
   .sa-badge-variant-link */

@layer sa.tokens {
  .sa-badge {
    --_badge-danger-fg: var(--sa-color-danger-text);
  }
  .dark .sa-badge {
    /* Lighter than danger text: the soft tint is translucent, and on a tinted row (a selected or
       hovered data grid row) it keeps 4.5:1 only with more room. */
    --_badge-danger-fg: oklch(from var(--sa-color-danger) max(l, 0.82) min(c, 0.12) h);
  }
}

@layer sa.components {
  .sa-badge {
    --_bg: transparent;
    --_bg-hover: var(--_bg);
    --_fg: inherit;
    --_border: transparent;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--sa-unit);
    width: fit-content;
    height: calc(5 * var(--sa-unit));
    padding-inline: calc(2 * var(--sa-unit));
    overflow: hidden;
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--sa-radius-tag);
    background: var(--_bg);
    color: var(--_fg);
    font-size: var(--sa-text-xs);
    font-weight: var(--sa-weight-control);
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    outline: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      color var(--sa-motion-fast) var(--sa-motion-ease);

    & > svg {
      flex-shrink: 0;
      width: 0.75rem;
      height: 0.75rem;
      pointer-events: none;
    }
    &:has(> [data-icon="inline-start"]) { padding-inline-start: calc(calc(2 * var(--sa-unit)) - 0.125rem); }
    &:has(> [data-icon="inline-end"]) { padding-inline-end: calc(calc(2 * var(--sa-unit)) - 0.125rem); }
    &:is(a):hover { background-color: var(--_bg-hover); }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
    &[aria-invalid="true"] {
      border-color: var(--sa-color-danger);
      &:focus-visible { box-shadow: var(--sa-invalid-focus-shadow); }
    }
  }
  .sa-badge-variant-default {
    --_bg: var(--sa-color-accent-fill);
    --_bg-hover: var(--sa-color-accent-hover);
    --_fg: var(--sa-color-on-accent);
    --_border: oklch(0.2 0 0 / calc(var(--sa-outlines) * 0.2));
  }
  .sa-badge-variant-secondary {
    --_bg: var(--sa-color-surface-sunken);
    --_bg-hover: color-mix(in oklab, var(--sa-color-surface-sunken), var(--sa-color-ink) 6%);
    --_fg: var(--sa-color-ink);
    --_border: color-mix(in oklab, var(--sa-color-line) calc(var(--sa-outlines) * 100%), transparent);
  }
  .sa-badge-variant-outline {
    --_bg-hover: var(--sa-color-hover);
    --_fg: var(--sa-color-ink);
    --_border: var(--sa-color-line);
  }
  .sa-badge-variant-destructive {
    --_bg: var(--sa-color-danger-soft);
    --_bg-hover: var(--sa-color-danger-soft-hover);
    --_fg: var(--_badge-danger-fg);
    --_border: color-mix(in oklab, var(--sa-color-danger) calc(var(--sa-outlines) * 45%), transparent);
    --sa-focus-border: var(--sa-color-danger);
    --sa-focus-shadow: var(--sa-invalid-focus-shadow);
  }
  .sa-badge-variant-ghost {
    --_fg: var(--sa-color-ink);
    &:hover { background-color: var(--sa-color-hover); }
  }
  .sa-badge-variant-link {
    --_fg: var(--sa-color-accent-text);
    text-underline-offset: 4px;
    &:hover { text-decoration: underline; }
  }
}

/* components/breadcrumb.css */
/* Breadcrumb: <sa-breadcrumb>, a trail of links, separators and an optional ellipsis, ending at the page.
   Replaces: .sa-breadcrumb-list, .sa-breadcrumb-item, .sa-breadcrumb-link, .sa-breadcrumb-page,
   .sa-breadcrumb-separator, .sa-breadcrumb-ellipsis */

@layer sa.components {
  .sa-breadcrumb-list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: calc(1.5 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    list-style: none;
    overflow-wrap: break-word;
  }
  .sa-breadcrumb-item {
    display: inline-flex;
    align-items: center;
    gap: calc(1 * var(--sa-unit));
  }
  .sa-breadcrumb-link {
    transition: color var(--sa-motion-fast) var(--sa-motion-ease);
    &:hover { color: var(--sa-color-ink); }
  }
  .sa-breadcrumb-page {
    color: var(--sa-color-ink);
    font-weight: 400;
  }
  .sa-breadcrumb-separator > svg:not([class*="size-"]) {
    width: 0.875rem;
    height: 0.875rem;
  }
  .sa-breadcrumb-ellipsis {
    display: flex;
    align-items: center;
    justify-content: center;
    width: calc(5 * var(--sa-unit));
    height: calc(5 * var(--sa-unit));
    & > svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-breadcrumb-link { transition-duration: 0s; }
  }
}

/* components/bubble.css */
/* Bubble: a chat bubble (its content a div, link or button), with optional reactions pinned to its
   edge, alone or in a group.
   Replaces: .sa-bubble, .sa-bubble-content, .sa-bubble-group, .sa-bubble-reactions,
   .sa-bubble-reactions-side-top, .sa-bubble-reactions-side-bottom, .sa-bubble-reactions-align-start,
   .sa-bubble-reactions-align-end, .sa-bubble-variant-default, .sa-bubble-variant-secondary,
   .sa-bubble-variant-muted, .sa-bubble-variant-tinted, .sa-bubble-variant-outline,
   .sa-bubble-variant-ghost, .sa-bubble-variant-destructive */

@layer sa.tokens {
  .sa-bubble,
  .sa-bubble-group {
    /* A light (dark mode: deep) wash of the accent, whatever the accent's own lightness. */
    --_bubble-tinted-bg: oklch(from var(--sa-color-accent) 0.92 calc(c * 0.4) h);
    --_bubble-tinted-bg-hover: oklch(from var(--sa-color-accent) 0.87 calc(c * 0.5) h);
  }
  .dark :is(.sa-bubble, .sa-bubble-group) {
    --_bubble-tinted-bg: oklch(from var(--sa-color-accent) 0.3 calc(c * 0.4) h);
    --_bubble-tinted-bg-hover: oklch(from var(--sa-color-accent) 0.35 calc(c * 0.5) h);
  }
}

@layer sa.components {
  .sa-bubble {
    --_bg: transparent;
    --_bg-hover: var(--_bg);
    --_fg: inherit;
    --_fg-hover: var(--_fg);
    --_border: transparent;
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--sa-unit);
    width: fit-content;
    min-width: 0;
    max-width: 80%;
    &[data-align="end"],
    .sa-message[data-align="end"] & {
      align-self: flex-end;
    }
  }
  .sa-bubble-content {
    width: fit-content;
    min-width: 0;
    max-width: 100%;
    padding: calc(2 * var(--sa-unit)) calc(3 * var(--sa-unit));
    overflow: hidden;
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--sa-radius-container);
    background: var(--_bg);
    color: var(--_fg);
    font-size: var(--sa-text-sm);
    line-height: 1.625;
    overflow-wrap: break-word;
    .sa-bubble[data-align="end"] > & {
      align-self: flex-end;
    }
    &:is(button) {
      text-align: start;
    }
    &:is(button, a) {
      outline: none;
      transition:
        background-color var(--sa-motion-fast) var(--sa-motion-ease),
        border-color var(--sa-motion-fast) var(--sa-motion-ease),
        color var(--sa-motion-fast) var(--sa-motion-ease);
      &:hover {
        background-color: var(--_bg-hover);
        color: var(--_fg-hover);
      }
      &:focus-visible {
        border-color: var(--sa-focus-border);
        box-shadow: var(--sa-focus-shadow);
      }
    }
  }

  .sa-bubble-variant-default {
    --_bg: var(--sa-color-accent-fill);
    --_bg-hover: var(--sa-color-accent-hover);
    --_fg: var(--sa-color-on-accent);
  }
  .sa-bubble-variant-secondary {
    --_bg: var(--sa-color-surface-sunken);
    --_bg-hover: color-mix(in oklab, var(--sa-color-surface-sunken), var(--sa-color-ink) 6%);
    --_fg: var(--sa-color-ink);
  }
  .sa-bubble-variant-muted {
    --_bg: var(--sa-color-surface-sunken);
    --_bg-hover: color-mix(in oklab, var(--sa-color-surface-sunken), var(--sa-color-ink) 6%);
    --_fg: var(--sa-color-ink-muted);
  }
  .sa-bubble-variant-tinted {
    --_bg: var(--_bubble-tinted-bg);
    --_bg-hover: var(--_bubble-tinted-bg-hover);
    --_fg: var(--sa-color-ink);
  }
  .sa-bubble-variant-outline {
    --_bg: var(--sa-color-surface);
    --_bg-hover: var(--sa-color-hover);
    --_fg: var(--sa-color-ink);
    --_border: var(--sa-color-line);
  }
  .sa-bubble-variant-ghost {
    --_bg-hover: var(--sa-color-hover);
    --_fg: initial;   /* no colour of its own: the text inherits */
    max-width: 100%;
    & > .sa-bubble-content {
      padding: 0;
      border-radius: 0;
    }
  }
  .sa-bubble-variant-destructive {
    --_bg: var(--sa-color-danger-soft);
    --_bg-hover: var(--sa-color-danger-soft-hover);
    --_fg: var(--sa-color-danger-text);
    --sa-focus-border: var(--sa-color-danger);
    --sa-focus-shadow: var(--sa-invalid-focus-shadow);
  }

  .sa-bubble-reactions {
    position: absolute;
    z-index: 10;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--sa-unit);
    width: fit-content;
    padding: calc(0.5 * var(--sa-unit)) calc(1.5 * var(--sa-unit));
    border-radius: var(--sa-radius-tag);
    background: var(--sa-color-surface-sunken);
    box-shadow: 0 0 0 3px var(--sa-color-surface);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    &:has(button) {
      padding: 0;
    }
    &[data-side="top"] {
      top: 0;
      translate: 0 -75%;
    }
    &[data-side="bottom"] {
      bottom: 0;
      translate: 0 75%;
    }
    &[data-align="start"] {
      left: calc(3 * var(--sa-unit));
    }
    &[data-align="end"] {
      right: calc(3 * var(--sa-unit));
    }
  }

  .sa-bubble-group {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
    min-width: 0;
  }
}

/* components/button-group.css */
/* Button group: buttons, inputs, selects and text joined into one row or column, with shared edges
   and only the outer corners rounded. Nested groups sit apart.
   Replaces: .sa-button-group, .sa-button-group-orientation-horizontal,
   .sa-button-group-orientation-vertical, .sa-button-group-separator, .sa-button-group-text */

@layer sa.components {
  .sa-button-group {
    display: flex;
    align-items: stretch;
    width: fit-content;

    &:has(> [data-slot="button-group"]) {
      gap: calc(2 * var(--sa-unit));
    }
    & > *:focus-visible,
    & > :has(:focus-visible) {
      position: relative;
      z-index: 10;
    }
    & > [data-slot="select-trigger"]:not([class*="w-"]) {
      width: fit-content;
    }
    & > input {
      flex: 1;
    }
  }

  /* Every part but the last gives up its end corners; every part but the first its start corners and
     its start edge, so neighbours share one line. Small buttons keep the group's radius (button.css). */
  .sa-button-group-orientation-horizontal {
    & > [data-slot]:has(~ [data-slot]) {
      border-start-end-radius: 0;
      border-end-end-radius: 0;
    }
    & > [data-slot] ~ [data-slot] {
      border-inline-start-width: 0;
      border-start-start-radius: 0;
      border-end-start-radius: 0;
    }
  }
  .sa-button-group-orientation-vertical {
    flex-direction: column;

    & > [data-slot]:has(~ [data-slot]) {
      border-end-start-radius: 0;
      border-end-end-radius: 0;
    }
    & > [data-slot] ~ [data-slot] {
      border-top-width: 0;
      border-start-start-radius: 0;
      border-start-end-radius: 0;
    }
  }

  /* A native select draws its edge on the select inside its wrapper. */
  .sa-button-group-orientation-horizontal {
    & > [data-slot="native-select-wrapper"]:has(~ [data-slot]) > [data-slot="native-select"] {
      border-start-end-radius: 0;
      border-end-end-radius: 0;
    }
    & > [data-slot] ~ [data-slot="native-select-wrapper"] > [data-slot="native-select"] {
      border-inline-start-width: 0;
      border-start-start-radius: 0;
      border-end-start-radius: 0;
    }
  }
  .sa-button-group-orientation-vertical {
    & > [data-slot="native-select-wrapper"]:has(~ [data-slot]) > [data-slot="native-select"] {
      border-end-start-radius: 0;
      border-end-end-radius: 0;
    }
    & > [data-slot] ~ [data-slot="native-select-wrapper"] > [data-slot="native-select"] {
      border-top-width: 0;
      border-start-start-radius: 0;
      border-start-end-radius: 0;
    }
  }

  .sa-button-group-text {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    padding-inline: var(--sa-control-px);
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-control);
    background: var(--sa-color-surface-sunken);
    background-clip: padding-box;
    color: var(--sa-color-ink);
    font-size: var(--sa-text-control);
    font-weight: var(--sa-weight-control);
    white-space: nowrap;

    & svg {
      pointer-events: none;
    }
    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
  }

  /* The separator is a Separator (separator.css); this out-ranks its rules by selector. */
  .sa-separator.sa-button-group-separator {
    position: relative;
    align-self: stretch;
    background: var(--sa-color-line-control);
    &[data-orientation="horizontal"] {
      width: auto;
      margin-inline: 1px;
    }
    &[data-orientation="vertical"] {
      height: auto;
      margin-block: 1px;
    }
  }
}

/* components/button.css */
/* Button: <sa-button> and the parts other components render as buttons (ButtonRenderingHelper).
   Replaces: .sa-button, .sa-button-variant-default, .sa-button-variant-secondary,
   .sa-button-variant-outline, .sa-button-variant-ghost, .sa-button-variant-destructive,
   .sa-button-variant-link, .sa-button-size-default, .sa-button-size-xs, .sa-button-size-sm,
   .sa-button-size-lg, .sa-button-size-icon, .sa-button-size-icon-xs, .sa-button-size-icon-sm,
   .sa-button-size-icon-lg */

@layer sa.tokens {
  .sa-button {
    /* Relief (see --sa-relief): raised from 1, tactile at 2. */
    --_relief-lift: clamp(0, var(--sa-relief), 1);
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;                                      /* dark mode weights the edges and the drop more */
    --_relief-k-drop: 1;
    --_relief-edge: rgb(0 0 0 / calc(0.25 * var(--_relief-press) * var(--_relief-k)));
    /* Sheen (see --sa-sheen): the solid variants set --_s, its strength for that button. */
    --_sheen-k: 1;                                       /* dark mode weakens the white highlight */
    --_s: 0;
    /* With sheen on, the light-mode secondary is white shading to grey, as macOS push buttons; in dark
       mode its grey fill is already lighter than the surface, so the sheen lights it as it is. */
    --_secondary-lit: 1;
    --_secondary-sheen: 1.2;

    --_button-outline-bg: var(--sa-color-surface);
    --_button-outline-border: var(--sa-color-line);
    --_danger-hover: color-mix(in oklab, var(--sa-color-danger-fill) 88%, var(--sa-color-ink));
  }
  .dark .sa-button {
    --_relief-k: 1.45;
    --_relief-k-drop: 2.5;
    --_sheen-k: 0.7;
    --_secondary-lit: 0;
    --_secondary-sheen: 0.6;
    --_button-outline-bg: var(--sa-color-field);
    --_button-outline-border: var(--sa-color-line-control);
    /* Away from the label, as --sa-color-accent-hover in dark mode. */
    --_danger-hover: color-mix(in oklab, var(--sa-color-danger-fill) 88%, oklch(from var(--sa-color-on-danger) clamp(0, (0.62 - l) * 1000, 1) 0 0));
  }
}

@layer sa.components {
  .sa-button {
    --_h: var(--sa-control-h);
    --_px: var(--sa-control-px);
    --_radius: var(--sa-radius-control);
    --_text: var(--sa-text-control);
    --_icon: var(--sa-control-icon);
    --_bg: transparent;
    --_bg-hover: var(--_bg);
    --_fg: inherit;
    --_fg-hover: var(--_fg);
    --_bg-active: var(--_bg-hover);
    --_border: transparent;
    --_border-hover: var(--_border);
    --_sheen-highlight: inset 0 1px 0 rgb(255 255 255 / calc(0.14 * var(--_s)));
    --_shadow: var(--sa-shadow-control), var(--_sheen-highlight), inset 0 -1px 0 var(--_relief-edge), 0 1px 1px rgb(0 0 0 / calc((0.07 + 0.03 * var(--_relief-press)) * var(--_relief-lift) * var(--_relief-k-drop)));
    --_shadow-hover: var(--sa-shadow-control), var(--_sheen-highlight), inset 0 -1px 0 var(--_relief-edge), 0 calc(1px + 1px * var(--_relief-press)) calc(1px + 2px * var(--_relief-press)) rgb(0 0 0 / calc((0.07 + 0.05 * var(--_relief-press)) * var(--_relief-lift) * var(--_relief-k-drop)));
    --_shadow-active: var(--sa-shadow-control), inset 0 1px 2px rgb(0 0 0 / calc(max(0.3 * var(--_relief-press) * var(--_relief-k), 0.15 * var(--_s))));

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--sa-control-gap);
    height: var(--_h);
    padding-inline: var(--_px);
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--_radius);
    background: var(--_bg);
    background-clip: padding-box;
    /* The sheen: translucent white to black over the fill, so it shades every variant and state. Under
       a light label (lightness above 0.62) a black layer first darkens the fill by 10%, so the lit top
       keeps the label's contrast; a dark label has the headroom. */
    background-image:
      linear-gradient(rgb(255 255 255 / calc(0.125 * var(--_s))), rgb(0 0 0 / calc(0.075 * var(--_s)))),
      linear-gradient(oklch(from currentColor 0 0 0 / calc(0.1 * var(--_s) * clamp(0, (l - 0.62) * 1000, 1))) 0 0);
    box-shadow: var(--_shadow);
    color: var(--_fg);
    font-size: var(--_text);
    font-weight: var(--sa-weight-control);
    line-height: var(--sa-leading-ui);  /* a taller line box than the text, so a truncating child keeps its descenders */
    white-space: nowrap;
    outline: none;
    user-select: none;
    transition-property: background-color, border-color, color, box-shadow, transform;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);

    & svg { flex-shrink: 0; pointer-events: none; }
    & svg:not([class*="size-"]) { width: var(--_icon); height: var(--_icon); }
    &:has(> [data-icon="inline-start"]) { padding-inline-start: calc(var(--_px) - 0.125rem); }
    &:has(> [data-icon="inline-end"]) { padding-inline-end: calc(var(--_px) - 0.125rem); }

    &:hover:not(:disabled, [aria-disabled="true"]),
    &[aria-expanded="true"] {
      background-color: var(--_bg-hover);
      border-color: var(--_border-hover);
      box-shadow: var(--_shadow-hover);
      color: var(--_fg-hover);
    }
    &:active:not(:disabled, [aria-disabled="true"], [aria-haspopup]) {
      background-color: var(--_bg-active);
      box-shadow: var(--_shadow-active);
      transform: translateY(var(--sa-press-offset));
    }
    &:focus-visible {
      border-color: color-mix(in oklab, var(--sa-focus-border) 100%, var(--_border));
      box-shadow: var(--_shadow), var(--sa-focus-shadow);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_shadow), var(--sa-invalid-shadow);
      &:focus-visible { box-shadow: var(--_shadow), var(--sa-invalid-focus-shadow); }
    }
    &:disabled, &[aria-disabled="true"] {
      box-shadow: none;
      opacity: var(--sa-disabled-opacity);
      pointer-events: none;
    }
  }

  .sa-button-variant-default {
    --_bg: var(--sa-color-accent-fill);
    --_bg-hover: var(--sa-color-accent-hover);
    --_bg-active: var(--sa-color-accent-hover);
    --_border: color-mix(in oklab, oklch(from var(--sa-color-accent-fill) calc(l - 0.1) c h) calc(max(var(--sa-outlines), var(--sa-sheen)) * 100%), transparent);
    --_fg: var(--sa-color-on-accent);
    --_s: calc(var(--sa-sheen) * var(--_sheen-k));
  }
  .sa-button-variant-secondary {
    --_lit: calc(clamp(0, var(--sa-sheen), 1) * var(--_secondary-lit) * 100%);
    --_flat-hover: color-mix(in oklab, color-mix(in oklab, var(--sa-color-surface-sunken), var(--sa-color-ink) 6%) calc(var(--sa-filled-secondary) * 100%), var(--sa-color-hover));
    --_bg: color-mix(in oklab, var(--sa-color-surface) var(--_lit), color-mix(in oklab, var(--sa-color-surface-sunken) calc(var(--sa-filled-secondary) * 100%), var(--sa-color-surface)));
    --_bg-hover: color-mix(in oklab, color-mix(in oklab, var(--sa-color-surface), var(--sa-color-ink) 4%) var(--_lit), var(--_flat-hover));
    --_bg-active: color-mix(in oklab, color-mix(in oklab, var(--sa-color-surface), var(--sa-color-ink) 6%) var(--_lit), var(--_flat-hover));
    --_border: color-mix(in oklab, var(--sa-color-line-control) var(--_lit), color-mix(in oklab, var(--sa-color-line) calc(max(var(--sa-outlines), 1 - var(--sa-filled-secondary), 0.5 * var(--sa-sheen)) * 100%), transparent));
    --_fg: var(--sa-color-ink);
    --_s: calc(var(--_secondary-sheen) * var(--sa-sheen) * var(--_sheen-k));   /* dark: lighter, as a full edge on the grey reads as an outline button */
  }
  .sa-button-variant-outline {
    --_bg: var(--_button-outline-bg);
    --_bg-hover: var(--sa-color-hover);
    --_bg-active: var(--sa-color-hover);
    --_border: var(--_button-outline-border);
    --_border-hover: var(--_button-outline-border);
    --_fg: var(--sa-color-ink);
    --_shadow: var(--sa-shadow-control), inset 0 -1px 0 var(--_relief-edge), 0 1px 1px rgb(0 0 0 / calc((0.07 + 0.03 * var(--_relief-press)) * var(--_relief-lift) * var(--_relief-k-drop)));
    --_shadow-hover: var(--sa-shadow-control), inset 0 -1px 0 var(--_relief-edge), 0 calc(1px + 1px * var(--_relief-press)) calc(1px + 2px * var(--_relief-press)) rgb(0 0 0 / calc((0.07 + 0.05 * var(--_relief-press)) * var(--_relief-lift) * var(--_relief-k-drop)));
    --_shadow-active: var(--sa-shadow-control), inset 0 1px 2px rgb(0 0 0 / calc(0.3 * var(--_relief-press) * var(--_relief-k)));
  }
  .sa-button-variant-ghost {
    --_fg: var(--sa-color-ink);
    --_fg-hover: var(--sa-color-ink);
    --_bg-hover: var(--sa-color-hover);
    --_bg-active: var(--sa-color-hover);
  }
  :is(.sa-button-variant-ghost, .sa-button-variant-link) {
    --_shadow: 0 0 #0000;
    --_shadow-hover: 0 0 #0000;
    --_shadow-active: 0 0 #0000;
  }
  .sa-button-variant-destructive {
    --_bg: color-mix(in oklab, var(--sa-color-danger-fill) calc(var(--sa-solid-destructive) * 100%), var(--sa-color-danger-soft));
    --_bg-hover: color-mix(in oklab, var(--_danger-hover) calc(var(--sa-solid-destructive) * 100%), var(--sa-color-danger-soft-hover));
    --_bg-active: color-mix(in oklab, var(--_danger-hover) calc(var(--sa-solid-destructive) * 100%), var(--sa-color-danger-soft-hover));
    --_border: color-mix(in oklab, color-mix(in oklab, oklch(from var(--sa-color-danger-fill) calc(l - 0.1) c h) calc(var(--sa-solid-destructive) * 100%), color-mix(in oklab, var(--sa-color-danger) 45%, transparent)) calc(max(var(--sa-outlines), var(--sa-sheen) * var(--sa-solid-destructive)) * 100%), transparent);
    --_fg: color-mix(in oklab, var(--sa-color-on-danger) calc(var(--sa-solid-destructive) * 100%), var(--sa-color-danger-text));
    --_s: calc(var(--sa-sheen) * var(--_sheen-k) * var(--sa-solid-destructive));   /* the soft tint gets none */
    --sa-focus-border: var(--sa-color-danger);
    --sa-focus-shadow: var(--sa-invalid-focus-shadow);
  }
  .sa-button-variant-link {
    --_fg: var(--sa-color-accent-text);
    text-decoration: var(--sa-link-decoration);
    text-underline-offset: 4px;
    &:hover { text-decoration: underline; }
  }

  .sa-button-size-xs {
    --_h: var(--sa-control-h-xs);
    --_px: calc(2 * var(--sa-unit));
    --_radius: var(--sa-radius-control-sm);
    --_text: min(var(--sa-text-control), var(--sa-text-xs));
    --_icon: 0.75rem;
    gap: 0.25rem;
  }
  .sa-button-size-sm {
    --_h: var(--sa-control-h-sm);
    --_px: var(--sa-control-px);
    --_radius: var(--sa-radius-control-sm);
    --_text: min(var(--sa-text-control), 0.8rem);
    --_icon: 0.875rem;
    gap: 0.25rem;
  }
  .sa-button-size-lg {
    --_h: var(--sa-control-h-lg);
    --_px: var(--sa-control-px);
    --_text: var(--sa-text-control);
  }
  .sa-button-size-icon-xs { --_h: var(--sa-control-h-xs); --_radius: var(--sa-radius-control-sm); --_icon: 0.75rem; }
  .sa-button-size-icon-sm { --_h: var(--sa-control-h-sm); --_radius: var(--sa-radius-control-sm); }
  .sa-button-size-icon-lg { --_h: var(--sa-control-h-lg); }
  :is(.sa-button-size-icon, .sa-button-size-icon-xs, .sa-button-size-icon-sm, .sa-button-size-icon-lg) {
    width: var(--_h);
    padding: 0;
  }
  /* Small buttons in a button group keep the group's corners. */
  [data-slot="button-group"] :is(.sa-button-size-xs, .sa-button-size-sm, .sa-button-size-icon-xs, .sa-button-size-icon-sm) {
    --_radius: var(--sa-radius-control);
  }

  /* A keyboard key in a button takes the button's text colour for its text and border, so it follows
     every variant, hover and dark mode; it is sized to the button. Its tint is white under dark
     text (lightness below 0.62) and black under light text, so the key's background moves away
     from its text and keeps the label's contrast. A link button has no fill to tint against. */
  .sa-button .sa-kbd {
    --_bg: oklch(from currentColor clamp(0, (0.62 - l) * 1000, 1) 0 h / 0.14);
    --_border: color-mix(in oklab, currentColor 28%, transparent);
    --_fg: currentColor;
  }
  .sa-button-variant-link .sa-kbd {
    --_bg: transparent;
  }
  .sa-button-size-xs .sa-kbd {
    height: calc(4 * var(--sa-unit));
    min-width: calc(4 * var(--sa-unit));
    padding-inline: calc(0.75 * var(--sa-unit));
    font-size: 0.625rem;
  }
  .sa-button-size-sm .sa-kbd {
    height: calc(4.5 * var(--sa-unit));
    min-width: calc(4.5 * var(--sa-unit));
    font-size: 0.6875rem;
  }
  .sa-button-size-lg .sa-kbd {
    height: calc(5.5 * var(--sa-unit));
    min-width: calc(5.5 * var(--sa-unit));
  }
}

/* components/card.css */
/* Card: a surface with an edge, a header (title, description, action), content and a footer.
   The data grid rides this chassis (data-grid.css).
   Replaces: .sa-card, .sa-card-header, .sa-card-title, .sa-card-description, .sa-card-action,
   .sa-card-content, .sa-card-footer */

@layer sa.components {
  .sa-card {
    --_card-p: var(--sa-space-container);
    --_card-gap: var(--sa-space-container);
    --_card-title-text: var(--sa-text-base);

    display: flex;
    flex-direction: column;
    gap: var(--_card-gap);
    padding-block: var(--_card-p);
    overflow: hidden;
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface);
    box-shadow: var(--sa-shadow-container);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);

    &[data-size="sm"] {
      --_card-p: var(--sa-space-container-sm);
      --_card-gap: var(--sa-space-container-sm);
      --_card-title-text: var(--sa-text-sm);
    }
    &:has(> .sa-card-footer) { padding-bottom: 0; }
    &:has(> img:first-child) { padding-top: 0; }
  }
  .sa-card-header {
    container: card-header / inline-size;
    display: grid;
    grid-auto-rows: min-content;
    align-items: start;
    gap: var(--sa-unit);
    padding-inline: var(--_card-p);
    border-bottom-color: var(--sa-color-line);

    &:has(> [data-slot="card-description"]) { grid-template-rows: auto auto; }
    &:has(> [data-slot="card-action"]) { grid-template-columns: 1fr auto; }
    &.border-b { padding-bottom: var(--_card-p); }
  }
  .sa-card-title {
    font-family: var(--sa-font-heading);
    font-size: var(--_card-title-text);
    font-weight: var(--sa-weight-heading);
    line-height: 1.375;
  }
  .sa-card-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
  }
  .sa-card-action {
    grid-column-start: 2;
    grid-row: 1 / span 2;
    align-self: start;
    justify-self: end;
  }
  .sa-card-content { padding-inline: var(--_card-p); }
  .sa-card-footer {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    /* With neither a band nor a rule, the footer sits flush: the card's gap already spaces it. */
    padding: calc(var(--_card-p) * max(var(--sa-footer-fill), var(--sa-footer-rule))) var(--_card-p) var(--_card-p);
    border-top: var(--sa-border-width) solid color-mix(in oklab, var(--sa-color-line) calc(var(--sa-footer-rule) * 100%), transparent);
    background: color-mix(in oklab, var(--sa-color-surface-subtle) calc(var(--sa-footer-fill) * 100%), transparent);
    color: inherit;
    font-size: inherit;
  }
}

/* components/carousel.css */
/* Carousel: a scroll-snapping row (or column) of items, with previous and next buttons (sa-button)
   beside it and optional indicator dots below. sel-carousel sets data-ready and builds the dots.
   Replaces: .sa-carousel, .sa-carousel-content, .sa-carousel-item, .sa-carousel-previous,
   .sa-carousel-next, .sa-carousel-indicators, .sa-carousel-indicator */

@layer sa.components {
  .sa-carousel {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    min-width: 0;
    &:not([data-ready]) > :is(.sa-carousel-previous, .sa-carousel-next, .sa-carousel-indicators) {
      visibility: hidden;
    }
    &[data-ready]:has(> .sa-carousel-previous):has(> .sa-carousel-next) > .sa-carousel-content {
      scrollbar-width: none;
    }
  }
  .sa-carousel-content {
    display: flex;
    grid-area: 1 / 1;
    gap: var(--carousel-spacing, calc(4 * var(--sa-unit)));
    min-width: 0;
    overflow: auto;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    &:focus-visible {
      outline: var(--sa-focus-ring-width) solid var(--sa-focus-ring-color);
      outline-offset: 4px;
    }
    &[data-orientation="vertical"] {
      flex-direction: column;
      scroll-snap-type: y mandatory;
      overscroll-behavior-y: contain;
    }
  }
  .sa-carousel-item {
    flex: 0 0 100%;
    min-width: 0;
    padding: 1px;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }

  /* The buttons are sa-button: placed with translate, so the button's pressed transform still applies. */
  .sa-button:is(.sa-carousel-previous, .sa-carousel-next) {
    --_radius: var(--sa-radius-round);
    position: absolute;
    grid-area: 1 / 1;
    top: 50%;
    translate: 0 -50%;
    touch-action: manipulation;
    &[data-orientation="vertical"] {
      top: auto;
      left: 50%;
      translate: -50% 0;
      rotate: 90deg;
    }
    &:dir(rtl):not([data-orientation="vertical"]) > svg {
      transform: rotate(180deg);
    }
  }
  .sa-button.sa-carousel-previous {
    &[data-orientation="horizontal"] { inset-inline-start: calc(-1 * 3rem); }
    &[data-orientation="vertical"] { top: calc(-1 * 3rem); }
  }
  .sa-button.sa-carousel-next {
    &[data-orientation="horizontal"] { inset-inline-end: calc(-1 * 3rem); }
    &[data-orientation="vertical"] { bottom: calc(-1 * 3rem); }
  }

  .sa-carousel-indicators {
    display: flex;
    flex-wrap: wrap;
    grid-area: 2 / 1;
    justify-content: center;
    gap: var(--sa-unit);
    padding-top: calc(3 * var(--sa-unit));
  }
  .sa-carousel-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    width: calc(6 * var(--sa-unit));
    height: calc(6 * var(--sa-unit));
    border-radius: var(--sa-radius-round);
    outline: none;
    &::before {
      content: "";
      width: calc(2 * var(--sa-unit));
      height: calc(2 * var(--sa-unit));
      border-radius: var(--sa-radius-round);
      background: color-mix(in oklab, var(--sa-color-ink-muted) 40%, transparent);
      transition: background-color var(--sa-motion-fast) var(--sa-motion-ease);
    }
    &[aria-current="true"]::before {
      background: var(--sa-color-ink);
    }
    &:focus-visible {
      box-shadow: var(--sa-focus-shadow);
    }
  }
}

/* components/checkbox.css */
/* Checkbox: <sa-input type="checkbox">, a native checkbox drawn as a small field, with a sibling check
   icon, in a wrapper (shared with the radio, radio.css) that centres the icon over it. The variables sit
   on the wrapper, as the switch's do, so the icon reads them too. The indeterminate dash is drawn in
   CSS, since scripts set that state as a DOM property.
   Replaces: .sa-checkbox, .sa-checkbox-indicator, .sa-checkbox-indicator-icon, .sa-input-control-wrapper */

@layer sa.tokens {
  .sa-input-control-wrapper {
    /* Recessed when tactile (--sa-relief 2), as the input; dark mode weights the inset more. */
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_checkbox-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark .sa-input-control-wrapper {
    --_relief-k: 4;
  }
}

@layer sa.components {
  /* inline-flex so the wrapper shrink-wraps the control in any container: the icon centres on it. */
  .sa-input-control-wrapper {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
  }

  .sa-checkbox {
    position: relative;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: calc(4 * var(--sa-unit));
    height: calc(4 * var(--sa-unit));
    margin: 0;
    appearance: none;
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: min(var(--sa-radius-control-sm), 5px);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--_checkbox-shadow);
    cursor: pointer;
    outline: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    /* A larger hit area around the small box. */
    &::after {
      content: "";
      position: absolute;
      inset: calc(-2 * var(--sa-unit)) calc(-3 * var(--sa-unit));
    }
    /* The indeterminate dash. */
    &::before {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      display: none;
      width: calc(2 * var(--sa-unit));
      height: 2px;
      border-radius: var(--sa-radius-round);
      background: var(--sa-color-on-accent);
      translate: -50% -50%;
    }
    &:hover:not(:disabled, :focus-visible, :checked, :indeterminate) {
      border-color: var(--sa-color-line-control-hover);
    }
    &:is(:checked, :indeterminate) {
      border-color: var(--sa-color-accent-fill);
      background: var(--sa-color-accent-fill);
    }
    &:indeterminate::before {
      display: block;
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_checkbox-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_checkbox-shadow), var(--sa-invalid-shadow);
      &:is(:checked, :indeterminate) {
        border-color: var(--sa-color-accent-fill);
      }
      &:focus-visible {
        box-shadow: var(--_checkbox-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      cursor: not-allowed;
      opacity: var(--sa-disabled-opacity);
    }
  }
  .sa-checkbox-indicator {
    visibility: hidden;
    & > svg {
      width: calc(3.5 * var(--sa-unit));
      height: calc(3.5 * var(--sa-unit));
    }
  }
  .sa-checkbox:checked ~ .sa-checkbox-indicator {
    visibility: visible;
  }
  .sa-checkbox-indicator-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    color: var(--sa-color-on-accent);
    pointer-events: none;
    translate: -50% -50%;
  }
  /* In a choice card (a field label around the field), the card shows focus instead. */
  [data-slot="field-label"] .sa-checkbox:focus-visible {
    border-color: var(--sa-color-line-control);
    box-shadow: var(--_checkbox-shadow);
    &:is(:checked, :indeterminate) {
      border-color: var(--sa-color-accent-fill);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-checkbox {
      transition-duration: 0s;
    }
  }
}

/* components/chip.css */
/* Chip: a compact tag for a chosen value, with optional media and a remove button, in a plain or
   input-styled group.
   Replaces: .sa-chip, .sa-chip-group */

@layer sa.tokens {
  /* The input-styled group is a field: it reads the input's variables, declared here as on .sa-input. */
  .sa-chip-group[data-appearance="input"] {
    --_input-h: var(--sa-control-h);
    --_input-radius: var(--sa-radius-box);  /* the group wraps onto more lines, so it rounds like a textarea */
    --_input-text: var(--sa-text-control);
    --_input-bg: var(--sa-color-field);
    --_input-bg-disabled: var(--sa-color-field-disabled);
    --_input-border: var(--sa-color-line-control);
    --_input-border-hover: var(--sa-color-line-control-hover);
    --_input-fg: var(--sa-color-ink);
    --_input-placeholder-fg: var(--sa-color-ink-placeholder);
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_input-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark .sa-chip-group[data-appearance="input"] {
    --_relief-k: 4;
  }
}

@layer sa.components {
  .sa-chip {
    --_media: calc(calc(5.25 * var(--sa-unit)) - 2 * var(--sa-border-width) - 2 * 2px);
    --_media-radius: max(0px, calc(var(--sa-radius-tag) - var(--sa-border-width) - 2px));
    --_bg: var(--sa-color-tint);
    --_border: color-mix(in oklab, var(--sa-color-line) calc(var(--sa-outlines) * 100%), transparent);
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: var(--sa-unit);
    height: calc(5.25 * var(--sa-unit));
    padding-inline: calc(1.5 * var(--sa-unit));
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--sa-radius-tag);
    background: var(--_bg);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-xs);
    font-weight: var(--sa-weight-control);
    line-height: 1;
    white-space: nowrap;

    &[data-disabled],
    &:has(> .sa-chip-remove:disabled) {
      opacity: var(--sa-disabled-opacity);
    }

    /* Media goes directly in the chip, before the label. Avatars, images and codes sit the inset from
       the chip's edge, with corners that follow the chip's. */
    & > svg {
      flex-shrink: 0;
      width: 0.875rem;
      height: 0.875rem;
    }
    & > :is([data-slot="avatar"], img, code) {
      flex-shrink: 0;
      margin-inline-start: calc(2px - calc(1.5 * var(--sa-unit)));
      border-radius: var(--_media-radius);
    }
    & > :is([data-slot="avatar"], img) {
      width: var(--_media);
      height: var(--_media);
      object-fit: cover;
    }
    & > [data-slot="avatar"] > *,
    & > [data-slot="avatar"]::after {
      border-radius: inherit;
    }
    /* Initials take a step from the chip's fill, as the code does, not the avatar's own fill. */
    & > [data-slot="avatar"] > [data-slot="avatar-fallback"] {
      background: color-mix(in oklab, currentColor 14%, transparent);
      color: inherit;
      font-size: 0.5rem;
    }
    & > code {
      display: inline-block;
      padding: calc((var(--_media) - 1cap) / 2) 0.25rem;
      background: color-mix(in oklab, currentColor 12%, transparent);
      font-family: var(--sa-font-mono);
      font-size: 0.625rem;
      font-weight: 500;
      /* Trims the line to the capitals, so the padding centres capitals and digits whatever the mono
         font's ascent. text-box needs an inline-block: it does not reach text in an inline-flex box. */
      line-height: 1;
      text-box: trim-both cap alphabetic;
    }
  }

  /* The remove button is a ghost icon button (sa-button), resized to the media box and shaped like the
     media. It keeps the button's focus ring; the chip dims instead of the button when it is disabled. */
  .sa-chip > .sa-chip-remove {
    --_h: var(--_media);
    --_radius: var(--_media-radius);
    --_fg: var(--sa-color-ink-muted);
    --_fg-hover: var(--sa-color-ink);
    --_bg-hover: color-mix(in oklab, var(--sa-color-ink) 12%, transparent);
    --_bg-active: color-mix(in oklab, var(--sa-color-ink) 12%, transparent);
    min-width: 0;
    margin-inline: -0.125rem calc(2px - calc(1.5 * var(--sa-unit)));
    border: 0;
    & svg {
      width: 0.75rem;
      height: 0.75rem;
    }
    &:disabled {
      opacity: 1;
    }
  }

  .sa-chip-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: calc(1.5 * var(--sa-unit));
  }
  /* A button beside the chips (Add) takes the chip's height, padding, corners, type and icon size, so
     it lines up with them whatever its own size. */
  .sa-chip-group > .sa-button {
    --_h: calc(5.25 * var(--sa-unit));
    --_px: calc(1.5 * var(--sa-unit));
    --_radius: var(--sa-radius-tag);
    --_text: var(--sa-text-xs);
    --_icon: 0.875rem;
    gap: var(--sa-unit);
    min-height: 0;
  }

  .sa-chip-group[data-appearance="input"] {
    gap: var(--sa-unit);
    min-height: var(--_input-h);
    padding: max(2px, calc((var(--_input-h) - 2 * var(--sa-border-width) - calc(5.25 * var(--sa-unit))) / 2)) var(--sa-unit);
    border: var(--sa-border-width) solid var(--_input-border);
    border-radius: var(--_input-radius);
    background: var(--_input-bg);
    background-clip: padding-box;
    box-shadow: var(--_input-shadow);
    color: var(--_input-fg);
    font-size: var(--_input-text);
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    /* Any chip in the group, so chips can sit in a display: contents wrapper that a script replaces. */
    & .sa-chip {
      --_bg: var(--sa-color-tint);
      --_border: transparent;
    }
    &:hover:not([data-disabled], :focus-within) {
      border-color: var(--_input-border-hover);
    }
    &:focus-within {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_input-shadow), var(--sa-focus-shadow-field);
    }
    &[aria-invalid="true"] {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_input-shadow), var(--sa-invalid-shadow);
      &:focus-within {
        box-shadow: var(--_input-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &[data-disabled] {
      background: var(--_input-bg-disabled);
    }
    & > input {
      flex: 1;
      min-width: 4rem;
      height: calc(5.25 * var(--sa-unit));
      padding-inline: 0.25rem;
      border: 0;
      background: transparent;
      outline: none;
      &::placeholder {
        color: var(--_input-placeholder-fg);
      }
    }
  }
}

/* components/command.css */
/* Command: a search field over a filtered list of commands, inline or in a command dialog.
   Replaces: .sa-command, .sa-command-dialog, .sa-command-input-wrapper, .sa-command-input-group,
   .sa-command-input-icon, .sa-command-input, .sa-command-list, .sa-command-empty, .sa-command-group,
   .sa-command-separator, .sa-command-item, .sa-command-item-indicator, .sa-command-shortcut */

@layer sa.components {
  .sa-command {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    padding: var(--sa-space-overlay);
    overflow: hidden;
    border-radius: var(--sa-radius-overlay);
    background: var(--sa-color-surface-raised);
    color: var(--sa-color-ink);
  }

  .sa-command-input-wrapper {
    padding: var(--sa-space-overlay) var(--sa-space-overlay) 0;
  }
  /* The search field is an input group (input-group.css), out-ranked by selector. */
  .sa-input-group.sa-command-input-group {
    height: var(--sa-control-h);
    border-color: var(--sa-color-line-control);
    border-radius: max(0px, calc(var(--sa-radius-overlay) - var(--sa-space-overlay)));
    background: var(--sa-color-field);
    box-shadow: none;

    & > .sa-input-group-addon { padding-inline-start: calc(2 * var(--sa-unit)); }
  }
  .sa-command-input-icon {
    flex-shrink: 0;
    width: var(--sa-control-icon);
    height: var(--sa-control-icon);
  }
  .sa-command-input {
    flex: 1;
    width: 100%;
    min-width: 0;
    height: 100%;
    padding: 0 calc(2 * var(--sa-unit)) 0 calc(1.5 * var(--sa-unit));
    border: 0;
    background: transparent;
    color: var(--sa-color-ink);
    font-size: var(--sa-text-control);
    outline: none;

    &::placeholder { color: var(--sa-color-ink-placeholder); }
    &:disabled { opacity: var(--sa-disabled-opacity); cursor: not-allowed; }
  }

  .sa-command-list {
    max-height: 18rem;
    overflow: hidden auto;
    scroll-padding-block: var(--sa-space-overlay);
    outline: none;
    scrollbar-width: none;

    &::-webkit-scrollbar { display: none; }
  }
  .sa-command-empty {
    padding-block: calc(6 * var(--sa-unit));
    font-size: var(--sa-text-body);
    text-align: center;
  }
  .sa-command-group {
    padding: var(--sa-space-overlay);
    overflow: hidden;
    color: var(--sa-color-ink);

    & [data-slot="command-group-heading"] {
      padding: calc(1.5 * var(--sa-unit)) calc(2 * var(--sa-unit));
      color: var(--sa-color-ink-muted);
      font-family: var(--sa-section-label-font);
      font-size: var(--sa-section-label-text);
      font-weight: var(--sa-section-label-weight);
      letter-spacing: var(--sa-section-label-tracking);
      line-height: 1rem;
      text-transform: var(--sa-section-label-transform);
    }
  }
  .sa-command-separator {
    height: 1px;
    margin-inline: calc(-1 * var(--sa-space-overlay));
    background: var(--sa-color-line);
  }
  .sa-command-item {
    position: relative;
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    padding: calc(1.5 * var(--sa-unit)) calc(2 * var(--sa-unit));
    border-radius: var(--sa-radius-item);
    color: inherit;
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
    text-decoration: none;
    cursor: default;
    outline: none;
    user-select: none;

    & svg { flex-shrink: 0; pointer-events: none; }
    & svg:not([class*="size-"]) { width: var(--sa-control-icon); height: var(--sa-control-icon); }
    &[data-selected="true"] {
      background: var(--sa-color-highlight);
      color: var(--sa-color-on-highlight);
    }
    &[data-disabled="true"] { opacity: var(--sa-disabled-opacity); pointer-events: none; }
  }
  /* The check of a checked item; a shortcut takes its place. */
  .sa-command-item-indicator {
    margin-inline-start: auto;
    opacity: 0;

    [data-checked="true"] > & { opacity: 1; }
    :has(> [data-slot="command-shortcut"]) > & { display: none; }
  }
  .sa-command-shortcut {
    margin-inline-start: auto;
    color: var(--sa-color-ink-muted);
    font-family: inherit;
    font-size: var(--sa-text-xs);
    letter-spacing: 0.1em;
    line-height: calc(4 / 3);

    [data-selected="true"] > & { color: inherit; }
  }
  .sa-command :is(.sa-command-item, .sa-command-group, .sa-command-empty, .sa-command-separator)[hidden] {
    display: none;
  }

  /* In a command dialog the command fills the dialog, a third of the way down the viewport. */
  dialog.sa-dialog-content.sa-command-dialog {
    top: 33.333%;
    bottom: auto;
    margin-top: 0;
    padding: 0;
    gap: 0;
    overflow: hidden;
    translate: none;
  }
}

/* components/data-grid.css */
/* Data grid: a table on the card chassis (the markup also carries sa-card and sa-card-footer), with a
   footer holding the page size tabs, the range and the pager. The table bleeds to the card's edges
   and its outer cells take the card's spacing, so they line up with the footer. Builds on the card
   (card.css) and the table (table.css); the tabs, checkboxes and pager style themselves.
   Replaces: .sa-data-grid, .sa-data-grid-footer, .sa-data-grid-page-size,
   .sa-data-grid-page-size-label, .sa-data-grid-range, .sa-data-grid-range-value */

@layer sa.components {
  /* Out-ranks the card's own gap and padding. */
  .sa-card.sa-data-grid {
    gap: 0;
    padding-block: 0;

    /* Only the grid's own rows: rows of a table nested in a cell (such as a row's details) keep their
       padding, and the detail cell stays unpadded since its content measures its insets from the row. */
    & tr:not(td tr) > :first-child:not(.sa-table-row-detail-cell) { padding-inline-start: var(--_card-p); }
    & tr:not(td tr) > :last-child:not(.sa-table-row-detail-cell) { padding-inline-end: var(--_card-p); }
  }
  .sa-card-footer.sa-data-grid-footer {
    justify-content: flex-end;
    gap: calc(4 * var(--sa-unit));
    padding-block: calc(2 * var(--sa-unit));
    border-top: var(--sa-border-width) solid var(--sa-color-line);

    /* The pager centres itself standalone; here it shrinks and sits in flow. */
    & > [data-slot="data-grid-pager"] {
      width: auto;
      margin: 0;
    }
  }
  /* A leading child (the page size selector) claims the left; the rest stay right-aligned. */
  .sa-data-grid-page-size {
    display: flex;
    align-items: center;
    gap: calc(2.5 * var(--sa-unit));
    margin-inline-end: auto;
  }
  .sa-data-grid-page-size-label,
  .sa-data-grid-range {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
  }
  .sa-data-grid-range { font-variant-numeric: tabular-nums; }
  .sa-data-grid-range-value {
    color: var(--sa-color-ink);
    font-weight: var(--sa-weight-control);
  }

  /* A sort link is a small ghost button (button.css) that takes on the column head's type. */
  .sa-table-head > .sa-button[data-slot="data-grid-sort-link"] {
    color: inherit;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    & svg { color: var(--sa-color-ink-muted); }
    &[data-active="true"] svg { color: currentColor; }
  }
}

/* components/dialog.css */
/* Dialog: a modal window over a native <dialog>, with a header, title, description and footer.
   Replaces: .sa-dialog-content, .sa-dialog-overlay, .sa-dialog-close, .sa-dialog-header,
   .sa-dialog-footer, .sa-dialog-title, .sa-dialog-description */

@layer sa.tokens {
  .sa-dialog-content {
    /* The footer switches default to the card's; a theme sets --sa-dialog-footer-fill/-rule only
       when its dialogs should differ (e.g. plain card footers but a banded dialog footer). */
    --_footer-fill: var(--sa-dialog-footer-fill, var(--sa-footer-fill));
    --_footer-rule: var(--sa-dialog-footer-rule, var(--sa-footer-rule));
  }
}

@layer sa.components {
  .sa-dialog-content {
    position: fixed;
    inset: 0;
    margin: auto;
    width: 100%;
    max-width: min(24rem, calc(100% - 2rem));
    height: fit-content;
    padding: var(--sa-space-container);
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface-raised);
    box-shadow: var(--sa-shadow-dialog);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: calc(1.25 / 0.875);
    outline: none;
    &[open] {
      display: grid;
      gap: var(--sa-space-container);
      animation: sa-dialog-in var(--sa-motion-fast) var(--sa-motion-ease);
    }
    &::backdrop {
      background: var(--sa-color-scrim);
    }
    &[open]::backdrop {
      animation: sa-dialog-backdrop-in var(--sa-motion-fast) var(--sa-motion-ease);
    }
  }
  .sa-dialog-close {
    position: absolute;
    top: calc(2 * var(--sa-unit));
    right: calc(2 * var(--sa-unit));
  }
  .sa-dialog-header {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
  }
  .sa-dialog-title {
    font-family: var(--sa-font-heading);
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-heading);
    line-height: 1;
  }
  .sa-dialog-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
    & a {
      text-decoration: underline;
      text-underline-offset: 3px;
      &:hover { color: var(--sa-color-ink); }
    }
  }
  /* Stacked, primary action on top, until there is room for a row. */
  .sa-dialog-footer {
    display: flex;
    flex-direction: column-reverse;
    gap: calc(2 * var(--sa-unit));
    margin: 0 calc(-1 * var(--sa-space-container)) calc(-1 * var(--sa-space-container));
    padding: calc(var(--sa-space-container) * max(var(--_footer-fill), var(--_footer-rule))) var(--sa-space-container) var(--sa-space-container);
    border-top: var(--sa-border-width) solid color-mix(in oklab, var(--sa-color-line) calc(var(--_footer-rule) * 100%), transparent);
    border-radius: 0 0 var(--sa-radius-container) var(--sa-radius-container);
    background: color-mix(in oklab, var(--sa-color-surface-subtle) calc(var(--_footer-fill) * 100%), transparent);
    @media (width >= 40rem) {
      flex-direction: row;
      justify-content: flex-end;
    }
  }

  @keyframes sa-dialog-in {
    from { opacity: 0; scale: 0.95; }
  }
  @keyframes sa-dialog-backdrop-in {
    from { opacity: 0; }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-dialog-content[open],
    .sa-dialog-content[open]::backdrop {
      animation: none;
    }
  }
}

/* components/dropdown-menu.css */
/* Dropdown menu: the menu and submenu popovers and their rows. The surface modifiers are in menu.css.
   Replaces: .sa-dropdown-menu-content, .sa-dropdown-menu-content-logical, .sa-dropdown-menu-sub-content,
   .sa-dropdown-menu-subcontent, .sa-dropdown-menu-item, .sa-dropdown-menu-checkbox-item,
   .sa-dropdown-menu-radio-item, .sa-dropdown-menu-item-indicator, .sa-dropdown-menu-sub-trigger,
   .sa-dropdown-menu-label, .sa-dropdown-menu-separator, .sa-dropdown-menu-shortcut */

@layer sa.components {
  /* Defaults the surface modifiers (menu.css) replace; :where() keeps them below any modifier. */
  :where(.sa-dropdown-menu-content, .sa-dropdown-menu-sub-content) {
    --_bg: var(--sa-color-surface-raised);
    --_highlight-bg: var(--sa-color-highlight);
    --_highlight-fg: var(--sa-color-on-highlight);
    --_separator-border: var(--sa-color-line);
  }

  /* Popovers anchored to their trigger (anchors.css places them; the gap comes from the
     [data-anchor-side] rules in components.css). */
  .sa-dropdown-menu-content,
  .sa-dropdown-menu-sub-content {
    z-index: 50;
    inset: auto;
    margin: 0;
    min-width: 8rem;
    padding: var(--sa-space-overlay) var(--sa-space-overlay);
    overflow: hidden auto;
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-overlay);
    background: var(--_bg);
    box-shadow: var(--sa-shadow-overlay);
    color: var(--sa-color-ink);
    outline: none;
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    opacity: 1;
    transition-property: opacity, display, overlay;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    transition-behavior: allow-discrete;

    &:not(:popover-open) { opacity: 0; }
    @starting-style {
      &:popover-open { opacity: 0; }
    }
    @media (prefers-reduced-motion: reduce) {
      transition: none;
    }
  }
  .sa-dropdown-menu-sub-content {
    min-width: 6rem;
  }

  .sa-dropdown-menu-item,
  .sa-dropdown-menu-checkbox-item,
  .sa-dropdown-menu-radio-item,
  .sa-dropdown-menu-sub-trigger {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--sa-space-item-gap);
    padding: var(--sa-space-item-y) var(--sa-space-item-x);
    border-radius: var(--sa-radius-item);
    color: inherit;
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
    text-decoration: none;
    cursor: default;
    outline: none;
    user-select: none;

    & svg { flex-shrink: 0; pointer-events: none; }
    & svg:not([class*="size-"]) { width: var(--sa-control-icon); height: var(--sa-control-icon); }
    &:is(:focus, [data-highlighted]) {
      background: var(--_highlight-bg);
      color: var(--_highlight-fg);
    }
    &[data-inset] { padding-inline-start: calc(var(--sa-space-item-x) + var(--sa-control-icon) + var(--sa-space-item-gap)); }
    &[data-disabled] { opacity: var(--sa-disabled-opacity); pointer-events: none; }
  }
  .sa-dropdown-menu-sub-trigger {
    &:is([data-open], [aria-expanded="true"]) {
      background: var(--_highlight-bg);
      color: var(--_highlight-fg);
    }
    & > svg:last-child { margin-inline-start: auto; }
  }
  .sa-dropdown-menu-item[data-variant="destructive"] {
    color: var(--sa-color-danger-text);
    &:is(:focus, [data-highlighted]) {
      background: var(--sa-color-danger-soft);
      color: var(--sa-color-danger-text);
    }
  }
  .sa-dropdown-menu-checkbox-item,
  .sa-dropdown-menu-radio-item {
    padding-inline-end: calc(var(--sa-control-icon) + 4 * var(--sa-unit));
  }
  .sa-dropdown-menu-item-indicator {
    position: absolute;
    inset-inline-end: calc(2 * var(--sa-unit));
    display: flex;
    align-items: center;
    justify-content: center;
    color: currentColor;
    pointer-events: none;

    [data-state="unchecked"] > & { display: none; }
  }

  .sa-dropdown-menu-label {
    padding: var(--sa-space-item-y) var(--sa-space-item-x) var(--sa-space-item-y);
    color: var(--sa-color-ink-muted);
    font-family: var(--sa-section-label-font);
    font-size: var(--sa-section-label-text);
    font-weight: var(--sa-section-label-weight);
    letter-spacing: var(--sa-section-label-tracking);
    line-height: 1rem;
    text-transform: var(--sa-section-label-transform);

    &[data-inset] { padding-inline-start: calc(var(--sa-space-item-x) + var(--sa-control-icon) + var(--sa-space-item-gap)); }
  }
  .sa-dropdown-menu-separator {
    height: 1px;
    margin: var(--sa-unit) calc(-1 * var(--sa-space-overlay));
    background: var(--_separator-border);
  }
  .sa-dropdown-menu-shortcut {
    margin-inline-start: auto;
    color: var(--sa-color-ink-muted);
    font-family: inherit;
    font-size: var(--sa-text-xs);
    letter-spacing: 0.1em;
    line-height: calc(4 / 3);

    :is(:focus, [data-highlighted], [data-open]) > & { color: inherit; }
  }
}

/* components/empty.css */
/* Empty: an empty state, centred: media (an icon on a tile), title, description and actions. Draws
   no edge itself; an author's border utility gets a dashed line.
   Replaces: .sa-empty, .sa-empty-header, .sa-empty-media, .sa-empty-media-default,
   .sa-empty-media-icon, .sa-empty-title, .sa-empty-description, .sa-empty-content */

@layer sa.components {
  .sa-empty {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(4 * var(--sa-unit));
    width: 100%;
    min-width: 0;
    padding: calc(6 * var(--sa-unit));
    border-style: dashed;
    border-color: var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    text-align: center;
    text-wrap: balance;
  }
  .sa-empty-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    max-width: 24rem;
  }
  .sa-empty-media {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    margin-bottom: calc(2 * var(--sa-unit));
    & svg { flex-shrink: 0; pointer-events: none; }
  }
  .sa-empty-media-default { background: transparent; }
  .sa-empty-media-icon {
    width: calc(8 * var(--sa-unit));
    height: calc(8 * var(--sa-unit));
    border-radius: var(--sa-radius-control);
    background: var(--sa-color-surface-sunken);
    color: var(--sa-color-ink);
    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
  }
  .sa-empty-title {
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    font-weight: var(--sa-weight-control);
    letter-spacing: -0.025em;
  }
  .sa-empty-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: 1.625;
    & > a {
      text-decoration: underline;
      text-underline-offset: 4px;
      &:hover { color: var(--sa-color-accent-text); }
    }
  }
  .sa-empty-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(2.5 * var(--sa-unit));
    width: 100%;
    max-width: 24rem;
    min-width: 0;
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    text-wrap: balance;
  }
}

/* components/field.css */
/* Field: a control with its label, description and error, stacked or side by side; field groups and
   field sets that space fields; and choice cards, a field label drawn around a horizontal field (the
   card variant of CheckboxGroup, RadioGroup and ChoiceGroup, or written by hand). CheckboxGroup and
   RadioGroup render field groups (data-slot checkbox-group or radio-group) with field parts, so they
   are styled here too. Field labels are also labels (label.css).
   Vertical and responsive fields force their children's widths with utility classes the tag helper
   emits ([&>*]:w-full, components.css), so a child component's own width cannot win; the responsive
   field's switch to a row uses the field group's container query, so the group stays a container
   named field-group.
   Replaces: .sa-field, .sa-field-content, .sa-field-description, .sa-field-error, .sa-field-group,
   .sa-field-label, .sa-field-legend, .sa-field-separator, .sa-field-separator-content,
   .sa-field-separator-line, .sa-field-set, .sa-field-title */

@layer sa.tokens {
  .sa-field-label {
    /* Choice cards: the selected card's accent wash. */
    --_field-card-selected-bg: color-mix(in oklab, var(--sa-color-accent) 6%, var(--sa-color-field));
  }
  .dark .sa-field-label {
    --_field-card-selected-bg: color-mix(in oklab, var(--sa-color-accent) 12%, var(--sa-color-field));
  }
}

@layer sa.components {
  /* --- Field set, legend and group --------------------------------------------------------- */
  .sa-field-set {
    display: flex;
    flex-direction: column;
    gap: calc(4 * var(--sa-unit));
    &:has(> [data-slot="checkbox-group"], > [data-slot="radio-group"]) {
      gap: calc(3 * var(--sa-unit));
    }
  }
  .sa-field-legend {
    margin-bottom: calc(1.5 * var(--sa-unit));
    font-family: inherit;
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-control);
    &[data-variant="label"] {
      font-size: var(--sa-text-sm);
    }
  }
  .sa-field-group {
    container: field-group / inline-size;
    display: flex;
    flex-direction: column;
    gap: calc(5 * var(--sa-unit));
    width: 100%;
    &:is([data-slot="checkbox-group"], [data-slot="radio-group"]) {
      gap: calc(3 * var(--sa-unit));
    }
    & > .sa-field-group[data-slot="field-group"] {
      gap: calc(4 * var(--sa-unit));
    }
  }

  /* --- Field -------------------------------------------------------------------------------- */
  .sa-field {
    display: flex;
    gap: calc(2 * var(--sa-unit));
    width: 100%;
    &[data-invalid="true"] {
      color: var(--sa-color-danger-text);
    }
    &[data-orientation="vertical"] {
      flex-direction: column;
    }
    &[data-orientation="horizontal"] {
      flex-direction: row;
      align-items: center;
      & > [data-slot="field-label"] {
        flex: auto;
      }
      &:has(> [data-slot="field-content"]) {
        align-items: flex-start;
      }
    }
    &[data-orientation="responsive"] {
      flex-direction: column;
    }
  }
  @container field-group (min-width: 28rem) {
    .sa-field[data-orientation="responsive"] {
      flex-direction: row;
      align-items: center;
      & > [data-slot="field-label"] {
        flex: auto;
      }
      &:has(> [data-slot="field-content"]) {
        align-items: flex-start;
      }
    }
  }
  .sa-field-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: calc(0.5 * var(--sa-unit));
    line-height: 1.375;
  }

  /* --- Label, title, description, error ------------------------------------------------------ */
  .sa-field-label {
    display: flex;
    gap: calc(2 * var(--sa-unit));
    width: fit-content;
    font-size: var(--sa-text-sm);
    line-height: 1.375;
  }
  .sa-field-title {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    width: fit-content;
    font-size: var(--sa-text-sm);
    font-weight: var(--sa-weight-control);
    line-height: 1.375;
  }
  /* A CheckboxGroup's option labels are regular weight (choice cards keep their title's). Its role
     tells it from a field group an author marks as a checkbox group, whose labels keep theirs. */
  [data-slot="checkbox-group"][role="group"] > .sa-field [data-slot="field-label"] {
    font-weight: 400;
  }
  .sa-field[data-disabled="true"] :is(.sa-field-label, .sa-field-title) {
    opacity: var(--sa-disabled-opacity);
  }
  .sa-field-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    font-weight: 400;
    line-height: 1.5;
    text-align: start;
    [data-variant="legend"] + & {
      margin-top: calc(-1.5 * var(--sa-unit));
    }
    &:nth-last-child(2) {
      margin-top: calc(-1 * var(--sa-unit));
    }
    &:last-child {
      margin-top: 0;
    }
    & > a {
      text-decoration: underline;
      text-underline-offset: 4px;
      &:hover {
        color: var(--sa-color-accent-text);
      }
    }
  }
  .sa-field:has([data-orientation="horizontal"]) .sa-field-description {
    text-wrap: balance;
  }
  .sa-field-error {
    display: none;
    color: var(--sa-color-danger-text);
    font-size: var(--sa-text-sm);
    font-weight: 400;
    line-height: var(--sa-leading-ui);
    &.field-validation-error {
      display: block;
    }
  }

  /* --- Choice card: a field label around a horizontal field --------------------------------- */
  .sa-field-label:has(> [data-slot="field"]) {
    flex-direction: column;
    width: 100%;
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-box);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--sa-shadow-control);
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);
    & > [data-slot="field"] {
      padding: calc(2.5 * var(--sa-unit));
    }
    &:hover:not(:has(:disabled, [data-disabled])) {
      border-color: var(--sa-color-line-control-hover);
      background: var(--sa-color-hover);
    }
    &:has(:checked) {
      border-color: color-mix(in oklab, var(--sa-color-accent) 45%, var(--sa-color-line-control));
      background: var(--_field-card-selected-bg);
    }
    &:has(:focus-visible) {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-shadow-control), var(--sa-focus-shadow-field);
    }
  }

  /* --- Separator: a rule, with optional text in a gap in the middle --------------------------- */
  .sa-field-separator {
    position: relative;
    height: calc(5 * var(--sa-unit));
    margin-block: calc(-2 * var(--sa-unit));
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    &[data-content="true"] {
      display: flex;
      align-items: center;
      gap: calc(2 * var(--sa-unit));
      &::before,
      &::after {
        content: "";
        flex: 1;
        border-top: var(--sa-border-width) solid var(--sa-color-line);
      }
    }
  }
  /* The rule is a separator (separator.css); this out-ranks its rules by selector. With text, the
     field separator draws the rule itself on either side, so no background has to hide it. */
  .sa-field-separator > .sa-separator.sa-field-separator-line {
    position: absolute;
    inset: 50% 0 auto;
    [data-content="true"] > & {
      display: none;
    }
  }
  .sa-field-separator-content {
    position: relative;
    display: block;
    width: fit-content;
    color: var(--sa-color-ink-muted);
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-field-label {
      transition-duration: 0s;
    }
  }
}

/* components/form-row.css */
/* Form row: fields side by side in equal columns once the row is wide enough, stacked below that.
   Replaces: .sa-form-row, .sa-form-row-content */

@layer sa.components {
  .sa-form-row {
    container: form-row / inline-size;
    width: 100%;
    min-width: 0;
    gap: calc(4 * var(--sa-unit));
  }
  .sa-form-row-content {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: inherit;
    & > * {
      min-width: 0;
    }
  }
  @container form-row (min-width: 40rem) {
    .sa-form-row > .sa-form-row-content {
      grid-template-columns: none;
      grid-auto-flow: column;
      grid-auto-columns: minmax(0, 1fr);
    }
  }
}

/* components/form-section.css */
/* Form section: a titled group of fields, stacked, split (header beside the fields once wide enough)
   or in a card. Consecutive plain sections are divided by a rule.
   Replaces: .sa-form-section, .sa-form-section-inner, .sa-form-section-header, .sa-form-section-title,
   .sa-form-section-description, .sa-form-section-content */

@layer sa.components {
  .sa-form-section {
    container: form-section / inline-size;
    width: 100%;
    min-width: 0;
    & + & {
      margin-top: calc(8 * var(--sa-unit));
    }
    & + &:not([data-layout="card"]) {
      padding-top: calc(8 * var(--sa-unit));
      border-top: var(--sa-border-width) solid var(--sa-color-line);
    }
  }
  .sa-form-section-inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: calc(5 * var(--sa-unit)) calc(8 * var(--sa-unit));
    min-width: 0;
  }
  .sa-form-section-header {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
    min-width: 0;
  }
  .sa-form-section-title {
    font-family: var(--sa-font-heading);
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-heading);
    line-height: 1.375;
  }
  .sa-form-section-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: 1.625;
  }
  .sa-form-section-content {
    display: flex;
    flex-direction: column;
    gap: calc(5 * var(--sa-unit));
    min-width: 0;
  }
  .sa-form-section[data-layout="card"] {
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface);
    box-shadow: var(--sa-shadow-container);
    color: var(--sa-color-ink);
    & > .sa-form-section-inner {
      gap: 0;
      & > .sa-form-section-header {
        padding: calc(5 * var(--sa-unit));
        border-bottom: var(--sa-border-width) solid var(--sa-color-line);
      }
      & > .sa-form-section-content {
        padding: calc(5 * var(--sa-unit));
      }
    }
  }
  @container form-section (min-width: 48rem) {
    .sa-form-section[data-layout="split"] > .sa-form-section-inner {
      grid-template-columns: minmax(0, 1fr) minmax(0, 2.3fr);
    }
  }
}

/* components/group.css */
/* Group: <sa-group>, a row of items with a gap from a five-step scale, alignment and justification.
   Replaces: .sa-group, .sa-group-align-baseline, .sa-group-align-center, .sa-group-align-end,
   .sa-group-align-start, .sa-group-align-stretch, .sa-group-gap-xs, .sa-group-gap-sm, .sa-group-gap-md,
   .sa-group-gap-lg, .sa-group-gap-xl, .sa-group-justify-around, .sa-group-justify-between,
   .sa-group-justify-center, .sa-group-justify-end, .sa-group-justify-start */

@layer sa.components {
  .sa-group {
    display: flex;
    flex-direction: row;
  }
  .sa-group-gap-xs { column-gap: calc(1 * var(--sa-unit)); }
  .sa-group-gap-sm { column-gap: calc(2 * var(--sa-unit)); }
  .sa-group-gap-md { column-gap: calc(4 * var(--sa-unit)); }
  .sa-group-gap-lg { column-gap: calc(5 * var(--sa-unit)); }
  .sa-group-gap-xl { column-gap: calc(8 * var(--sa-unit)); }
  .sa-group-align-start { align-items: flex-start; }
  .sa-group-align-center { align-items: center; }
  .sa-group-align-end { align-items: flex-end; }
  .sa-group-align-baseline { align-items: baseline; }
  .sa-group-align-stretch { align-items: stretch; }
  .sa-group-justify-start { justify-content: flex-start; }
  .sa-group-justify-center { justify-content: center; }
  .sa-group-justify-end { justify-content: flex-end; }
  .sa-group-justify-between { justify-content: space-between; }
  .sa-group-justify-around { justify-content: space-around; }
}

/* components/input-group.css */
/* Input group: one field drawn around an input or textarea, with addons (icons, text, kbd, buttons)
   inline or above and below. The group draws the field; the control inside gives up its own edge.
   Reads the input's tokens (input.css).
   Replaces: .sa-input-group, .sa-input-group-addon, .sa-input-group-addon-align-inline-start,
   .sa-input-group-addon-align-inline-end, .sa-input-group-addon-align-block-start,
   .sa-input-group-addon-align-block-end, .sa-input-group-button, .sa-input-group-button-size-xs,
   .sa-input-group-button-size-icon-xs, .sa-input-group-button-size-icon-sm, .sa-input-group-text,
   .sa-input-group-input, .sa-input-group-textarea */

@layer sa.components {
  .sa-input-group {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    min-width: 0;
    height: var(--_input-h);
    border: var(--sa-border-width) solid var(--_input-border);
    border-radius: var(--_input-radius);
    background: var(--_input-bg);
    background-clip: padding-box;
    box-shadow: var(--_input-shadow);
    outline: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &:hover:not(:has([data-slot="input-group-control"]:is(:disabled, :focus-visible))) {
      border-color: var(--_input-border-hover);
    }
    &:has([data-slot="input-group-control"]:focus-visible) {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_input-shadow), var(--sa-focus-shadow-field);
    }
    &:has([data-slot][aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_input-shadow), var(--sa-invalid-shadow);
      &:has([data-slot="input-group-control"]:focus-visible) {
        box-shadow: var(--_input-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:has(:disabled),
    &[data-disabled] {
      background: var(--_input-bg-disabled);
      opacity: var(--sa-disabled-opacity);
    }
    &:has(> textarea),
    &:has(> [data-align="block-start"], > [data-align="block-end"]) {
      height: auto;
      border-radius: var(--sa-radius-box);
    }
    &:has(> [data-align="block-start"], > [data-align="block-end"]) {
      flex-direction: column;
    }

    /* The control fills the group and draws nothing itself; addons set the padding beside it. */
    & > .sa-input-group-input {
      flex: 1;
      height: 100%;
      border: 0;
      border-radius: 0;
      background: transparent;
      box-shadow: none;
      &:is(:focus-visible, [aria-invalid="true"], .input-validation-error) {
        box-shadow: none;
      }
      &:disabled {
        background: transparent;
        opacity: 1;
      }
    }
    &:has(> [data-align="inline-start"]) > .sa-input-group-input {
      padding-inline-start: calc(1.5 * var(--sa-unit));
    }
    &:has(> [data-align="inline-end"]) > .sa-input-group-input {
      padding-inline-end: calc(1.5 * var(--sa-unit));
    }
    &:has(> [data-align="block-start"]) > .sa-input-group-input {
      padding-bottom: calc(3 * var(--sa-unit));
    }
    &:has(> [data-align="block-end"]) > .sa-input-group-input {
      padding-top: calc(3 * var(--sa-unit));
    }
  }

  .sa-input-group-addon {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: calc(2 * var(--sa-unit));
    height: auto;
    padding-block: calc(1.5 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    font-weight: var(--sa-weight-control);
    cursor: text;
    user-select: none;

    & > svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
    & > kbd {
      border-radius: var(--sa-radius-inner);
    }
  }
  .sa-input-group-addon-align-inline-start {
    order: -1;
    padding-inline-start: calc(2 * var(--sa-unit));
    &:has(> button) {
      margin-inline-start: calc(-1.2 * var(--sa-unit));
    }
    &:has(> kbd) {
      margin-inline-start: calc(-0.6 * var(--sa-unit));
    }
  }
  .sa-input-group-addon-align-inline-end {
    order: 1;
    padding-inline-end: calc(2 * var(--sa-unit));
    &:has(> button) {
      margin-inline-end: calc(-1.2 * var(--sa-unit));
    }
    &:has(> kbd) {
      margin-inline-end: calc(-0.6 * var(--sa-unit));
    }
  }
  .sa-input-group-addon-align-block-start,
  .sa-input-group-addon-align-block-end {
    justify-content: flex-start;
    width: 100%;
    padding-inline: var(--sa-control-px);
  }
  .sa-input-group-addon-align-block-start {
    order: -1;
    padding-top: calc(2 * var(--sa-unit));
    &.border-b {
      padding-bottom: calc(2 * var(--sa-unit));
    }
  }
  .sa-input-group-addon-align-block-end {
    order: 1;
    padding-bottom: calc(2 * var(--sa-unit));
    &.border-t {
      padding-top: calc(2 * var(--sa-unit));
    }
  }
  .sa-input-group[data-disabled] .sa-input-group-addon {
    opacity: var(--sa-disabled-opacity);
  }

  .sa-input-group-text {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);

    & svg {
      pointer-events: none;
    }
    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
  }

  /* In-group buttons are buttons (button.css); these out-rank its rules by selector. */
  .sa-button.sa-input-group-button {
    --_shadow: 0 0 #0000;
    --_shadow-hover: 0 0 #0000;
    --_shadow-active: 0 0 #0000;
    --_text: var(--sa-text-sm);
    gap: calc(2 * var(--sa-unit));
  }
  .sa-button.sa-input-group-button-size-xs {
    --_h: calc(6 * var(--sa-unit));
    --_px: calc(1.5 * var(--sa-unit));
    --_radius: var(--sa-radius-inner);
    --_icon: 0.875rem;
    gap: var(--sa-unit);
  }
  .sa-button.sa-input-group-button-size-sm {
    --_h: calc(8 * var(--sa-unit));
  }
  .sa-button.sa-input-group-button-size-icon-xs {
    --_h: calc(6 * var(--sa-unit));
    --_radius: var(--sa-radius-inner);
    width: var(--_h);
    padding: 0;
  }
  .sa-button.sa-input-group-button-size-icon-sm {
    --_h: calc(8 * var(--sa-unit));
    width: var(--_h);
    padding: 0;
  }

  /* The in-group textarea is a textarea (textarea.css); these out-rank its rules by selector. */
  .sa-input-group .sa-textarea.sa-input-group-textarea {
    flex: 1;
    padding-block: calc(2 * var(--sa-unit));
    resize: none;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    &:is(:focus-visible, [aria-invalid="true"], .input-validation-error, :disabled) {
      background: transparent;
      box-shadow: none;
    }
    &:disabled {
      opacity: 1;
    }
  }
}

/* components/input-otp.css */
/* Input OTP: <sel-input-otp>, a row of character slots over one transparent native input (styled
   inline by the script), in groups with separators. The active slot shows focus and a blinking caret.
   Replaces: .sa-input-otp, .sa-input-otp-caret, .sa-input-otp-caret-line, .sa-input-otp-group,
   .sa-input-otp-input, .sa-input-otp-separator, .sa-input-otp-slot */

@layer sa.components {
  .sa-input-otp {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    &:has(:disabled) {
      opacity: var(--sa-disabled-opacity);
    }
  }

  .sa-input-otp-group {
    display: flex;
    align-items: center;
    border-radius: var(--sa-radius-control);
    box-shadow: var(--sa-shadow-control);
    &:has([aria-invalid="true"], .input-validation-error) {
      box-shadow: var(--sa-shadow-control), var(--sa-invalid-shadow);
    }
  }

  .sa-input-otp-slot {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--sa-control-h);
    height: var(--sa-control-h);
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-inline-start-width: 0;
    background: var(--sa-color-field);
    background-clip: padding-box;
    color: var(--sa-color-ink);
    font-size: var(--sa-text-control);
    outline: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &:first-child {
      border-inline-start-width: var(--sa-border-width);
      border-start-start-radius: var(--sa-radius-control);
      border-end-start-radius: var(--sa-radius-control);
    }
    &:last-child {
      border-start-end-radius: var(--sa-radius-control);
      border-end-end-radius: var(--sa-radius-control);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
    }
    &[data-active="true"] {
      z-index: 10;
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow-field);
      &:is([aria-invalid="true"], .input-validation-error) {
        border-color: var(--sa-color-danger);
        box-shadow: var(--sa-invalid-focus-shadow);
      }
    }
  }

  .sa-input-otp-separator {
    display: flex;
    align-items: center;
    color: var(--sa-color-ink);
    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
  }

  .sa-input-otp-caret {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
  }
  .sa-input-otp-caret-line {
    width: 1px;
    height: 1rem;
    background: var(--sa-color-ink);
    animation: sa-input-otp-caret-blink 1s ease-out infinite;
  }
  .sa-input-otp-input:disabled {
    cursor: not-allowed;
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-input-otp-slot {
      transition-duration: 0s;
    }
    .sa-input-otp-caret-line {
      animation: none;
    }
  }
}

@keyframes sa-input-otp-caret-blink {
  0%, 70%, 100% { opacity: 1; }
  20%, 50% { opacity: 0; }
}

/* components/input.css */
/* Input: a text-like field (every <sa-input> type but checkbox and radio).
   Replaces: .sa-input */

@layer sa.tokens {
  .sa-input,
  .sa-input-group {
    --_input-h: var(--sa-control-h);
    --_input-radius: var(--sa-radius-control);
    --_input-text: var(--sa-text-control);
    --_input-bg: var(--sa-color-field);
    --_input-bg-disabled: var(--sa-color-field-disabled);
    --_input-border: var(--sa-color-line-control);
    --_input-border-hover: var(--sa-color-line-control-hover);
    --_input-fg: var(--sa-color-ink);
    --_input-placeholder-fg: var(--sa-color-ink-placeholder);
    /* Recessed when tactile (--sa-relief 2); dark mode weights the inset more. */
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_input-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark :is(.sa-input, .sa-input-group) {
    --_relief-k: 4;
  }
}

@layer sa.components {
  .sa-input {
    width: 100%;
    min-width: 0;
    height: var(--_input-h);
    padding: 0.25rem var(--sa-control-px);
    border: var(--sa-border-width) solid var(--_input-border);
    border-radius: var(--_input-radius);
    background: var(--_input-bg);
    background-clip: padding-box;
    box-shadow: var(--_input-shadow);
    color: var(--_input-fg);
    font-size: var(--_input-text);
    outline: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &::placeholder {
      color: var(--_input-placeholder-fg);
    }
    &::file-selector-button {
      display: inline-flex;
      height: calc(var(--_input-h) - 2 * var(--sa-unit));
      margin-inline-end: calc(2 * var(--sa-unit));
      border: 0;
      background: transparent;
      color: var(--_input-fg);
      font-size: var(--sa-text-sm);
      font-weight: var(--sa-weight-control);
    }
    &:hover:not(:disabled, :focus-visible) {
      border-color: var(--_input-border-hover);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_input-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_input-shadow), var(--sa-invalid-shadow);
      &:focus-visible {
        box-shadow: var(--_input-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      background: var(--_input-bg-disabled);
      opacity: var(--sa-disabled-opacity);
      cursor: not-allowed;
      pointer-events: none;
    }
  }
}

/* components/item.css */
/* Item: a row of media, content (title and description) and actions, with optional header and
   footer rows; plain, outlined or on a muted fill, in three sizes. An item link (<a>) highlights on
   hover. Items stack in an item group, optionally with separators.
   Replaces: .sa-item, .sa-item-variant-default, .sa-item-variant-outline, .sa-item-variant-muted,
   .sa-item-size-default, .sa-item-size-sm, .sa-item-size-xs, .sa-item-media,
   .sa-item-media-variant-default, .sa-item-media-variant-icon, .sa-item-media-variant-image,
   .sa-item-content, .sa-item-title, .sa-item-description, .sa-item-actions, .sa-item-header,
   .sa-item-footer, .sa-item-group, .sa-item-separator */

@layer sa.components {
  .sa-item {
    --_item-gap: calc(2.5 * var(--sa-unit));
    --_item-px: calc(3 * var(--sa-unit));
    --_item-py: calc(2.5 * var(--sa-unit));
    --_item-media-size: calc(10 * var(--sa-unit));
    --_item-description-text: var(--sa-text-sm);
    --_item-content-gap: var(--sa-unit);

    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--_item-gap);
    width: 100%;
    padding: var(--_item-py) var(--_item-px);
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-box);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    outline: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &:is(a):hover { background-color: var(--sa-color-hover); }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
  }
  .sa-item-variant-outline { border-color: var(--sa-color-line); }
  .sa-item-variant-muted { background-color: var(--sa-color-surface-sunken); }
  .sa-item-size-sm {
    --_item-gap: calc(2.5 * var(--sa-unit));
    --_item-px: calc(3 * var(--sa-unit));
    --_item-py: calc(2.5 * var(--sa-unit));
    --_item-media-size: calc(8 * var(--sa-unit));
  }
  .sa-item-size-xs {
    --_item-gap: calc(2 * var(--sa-unit));
    --_item-px: calc(2.5 * var(--sa-unit));
    --_item-py: calc(2 * var(--sa-unit));
    --_item-media-size: calc(6 * var(--sa-unit));
    --_item-description-text: var(--sa-text-xs);
    --_item-content-gap: 0px;
    [data-slot="dropdown-menu-content"] & { padding: 0; }
  }

  .sa-item-media {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: calc(2 * var(--sa-unit));
    & svg { pointer-events: none; }
    /* Beside a two-line content block, media aligns with the title. */
    .sa-item:has([data-slot="item-description"]) > & {
      align-self: flex-start;
      translate: 0 calc(0.5 * var(--sa-unit));
    }
  }
  .sa-item-media-variant-default { background: transparent; }
  .sa-item-media-variant-icon svg:not([class*="size-"]) {
    width: var(--sa-control-icon);
    height: var(--sa-control-icon);
  }
  .sa-item-media-variant-image {
    width: var(--_item-media-size);
    height: var(--_item-media-size);
    overflow: hidden;
    border-radius: var(--sa-radius-inner);
    & img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  .sa-item-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--_item-content-gap);
    & + [data-slot="item-content"] { flex: none; }
  }
  .sa-item-title {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    width: fit-content;
    overflow: hidden;
    font-size: var(--sa-text-sm);
    font-weight: var(--sa-weight-control);
    line-height: 1.375;
    text-underline-offset: 4px;
  }
  .sa-item-description {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    color: var(--sa-color-ink-muted);
    font-size: var(--_item-description-text);
    font-weight: 400;
    line-height: 1.5;
    text-align: left;
    & > a {
      text-decoration: underline;
      text-underline-offset: 4px;
      &:hover { color: var(--sa-color-accent-text); }
    }
  }
  .sa-item-actions {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
  }
  .sa-item-header,
  .sa-item-footer {
    display: flex;
    flex-basis: 100%;
    align-items: center;
    justify-content: space-between;
    gap: calc(2 * var(--sa-unit));
  }

  .sa-item-group {
    display: flex;
    flex-direction: column;
    gap: calc(4 * var(--sa-unit));
    width: 100%;
    &:has([data-size="sm"]) { gap: calc(2.5 * var(--sa-unit)); }
    &:has([data-size="xs"]) { gap: calc(2 * var(--sa-unit)); }
  }
  .sa-item-separator { margin-block: calc(2 * var(--sa-unit)); }
}

/* components/kbd.css */
/* Kbd: a keyboard key, alone or in a group; also inside input groups, buttons and tooltips (button.css and tooltip.css set its colours there).
   Replaces: .sa-kbd, .sa-kbd-group */

@layer sa.components {
  .sa-kbd {
    --_bg: var(--sa-color-tint);
    --_fg: color-mix(in oklab, var(--sa-color-ink-muted) 65%, var(--sa-color-ink));
    --_border: color-mix(in oklab, var(--sa-color-line) calc(var(--sa-outlines) * 100%), transparent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sa-unit);
    width: fit-content;
    min-width: calc(5 * var(--sa-unit));
    height: calc(5 * var(--sa-unit));
    padding-inline: var(--sa-unit);
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--sa-radius-inner);
    background: var(--_bg);
    background-clip: padding-box;
    color: var(--_fg);
    font-family: var(--sa-kbd-font, var(--sa-font-sans));
    font-size: var(--sa-text-xs);
    font-weight: var(--sa-weight-control);
    line-height: 1;
    pointer-events: none;
    user-select: none;

    & svg:not([class*="size-"]) {
      width: 0.75rem;
      height: 0.75rem;
    }
  }
  .sa-kbd-group {
    display: inline-flex;
    align-items: center;
    gap: var(--sa-unit);
  }
}

/* components/label.css */
/* Label: a control's caption. Field labels are labels too (field.css), and refine these rules: the
   label's rules sit at zero specificity under :where() so a field label's own rules win.
   Replaces: .sa-label */

@layer sa.components {
  :where(.sa-label) {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    font-size: var(--sa-text-sm);
    font-weight: var(--sa-weight-control);
    line-height: 1;
    user-select: none;
  }
  /* A disabled control just before the label, or a field marked disabled. */
  :where(:disabled ~ .sa-label) {
    cursor: not-allowed;
    opacity: var(--sa-disabled-opacity);
  }
  :where([data-disabled="true"] .sa-label) {
    pointer-events: none;
    opacity: var(--sa-disabled-opacity);
  }
}

/* components/marker.css */
/* Marker: a muted inline note in a transcript or list (a status line, a date separator), as a div,
   a link or a button.
   Replaces: .sa-marker, .sa-marker-variant-separator, .sa-marker-variant-border, .sa-marker-icon,
   .sa-marker-content */

@layer sa.components {
  .sa-marker {
    position: relative;
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    width: 100%;
    min-height: calc(4 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    text-align: start;

    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
    &:is(a) {
      text-decoration: underline;
      text-underline-offset: 3px;
    }
    &:is(a, button):hover {
      color: var(--sa-color-ink);
    }
    &:is(a, button):focus-visible {
      border-radius: var(--sa-radius-control-sm);
      outline: none;
      box-shadow: var(--sa-focus-shadow);
    }
  }
  .sa-marker-variant-separator {
    &::before,
    &::after {
      content: "";
      flex: 1;
      min-width: 0;
      height: var(--sa-border-width);
      background: var(--sa-color-line);
    }
    &::before { margin-inline-end: var(--sa-unit); }
    &::after { margin-inline-start: var(--sa-unit); }
  }
  .sa-marker-variant-border {
    padding-bottom: calc(2 * var(--sa-unit));
    border-bottom: var(--sa-border-width) solid var(--sa-color-line);
  }
  .sa-marker-icon {
    display: inline-flex;
    flex-shrink: 0;
    width: var(--sa-control-icon);
    height: var(--sa-control-icon);
  }
  .sa-marker-content {
    min-width: 0;
    overflow-wrap: break-word;
    & > a {
      text-decoration: underline;
      text-underline-offset: 3px;
      &:hover { color: var(--sa-color-ink); }
    }
    .sa-marker-variant-separator > & {
      flex: none;
      text-align: center;
    }
  }
}

/* components/menu.css */
/* Menu: the surface modifiers MenuAppearance and MenuAccent emit, shared by every floating menu (the
   dropdown menu now; context menus and menubars when they ship). MenuColor.Inverted is the dark
   class itself, which re-derives the colours for the menu and everything in it.
   Replaces: .sa-menu-translucent, .sa-menu-accent-bold */

@layer sa.components {
  /* MenuAccent.Bold: the highlighted row takes the solid accent. */
  .sa-menu-accent-bold {
    --_highlight-bg: var(--sa-color-accent-fill);
    --_highlight-fg: var(--sa-color-on-accent);
  }

  /* MenuAppearance.Translucent. The blur sits on a layer behind the rows rather than on the menu
     itself, so the menu stays an ordinary box for its rows and nested menus. */
  .sa-menu-translucent {
    --_bg: color-mix(in oklab, var(--sa-color-surface-raised) 70%, transparent);
    --_highlight-bg: color-mix(in oklab, var(--sa-color-ink) 10%, transparent);
    --_separator-border: color-mix(in oklab, var(--sa-color-ink) 10%, transparent);

    &::before {
      content: "";
      position: absolute;
      inset: 0;
      z-index: -1;
      border-radius: inherit;
      backdrop-filter: blur(40px) saturate(1.5);
      pointer-events: none;
    }
    &.sa-menu-accent-bold {
      --_highlight-bg: var(--sa-color-accent-fill);
    }
  }
}

/* components/message-scroller.css */
/* MessageScroller: a scrolling transcript (sel-message-scroller) whose end fades out while there is
   more below, with a floating button (sa-button) that jumps to the start or the end.
   Replaces: .sa-message-scroller, .sa-message-scroller-viewport, .sa-message-scroller-content,
   .sa-message-scroller-item, .sa-message-scroller-button */

@property --_message-scroller-fade {
  syntax: "<length-percentage>";
  inherits: false;
  initial-value: 0px;
}

@layer sa.components {
  .sa-message-scroller {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    min-height: 0;
    overflow: hidden;
  }
  .sa-message-scroller-viewport {
    --_message-scroller-fade: 0px;
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    contain: content;
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - var(--_message-scroller-fade)), transparent 100%);
    mask-repeat: no-repeat;
    @supports (animation-timeline: scroll()) {
      animation: sa-message-scroller-fade 1ms ease-in-out both;
      animation-timeline: scroll(self y);
      animation-range: calc(100% - calc(24 * var(--sa-unit))) 100%;
    }
    @supports not (animation-timeline: scroll()) {
      --_message-scroller-fade: min(12%, calc(10 * var(--sa-unit)));
    }
    &[data-pending-scroll] {
      visibility: hidden;
    }
  }
  .sa-message-scroller-content {
    display: flex;
    flex-direction: column;
    gap: calc(6 * var(--sa-unit));
    height: max-content;
    min-height: 100%;
  }
  .sa-message-scroller-item {
    flex-shrink: 0;
    min-width: 0;
    contain-intrinsic-size: auto 10rem;
    content-visibility: auto;
  }

  /* The jump button is an sa-button, drawn as a bordered surface whatever its variant. It moves with
     translate and scale, so the button's pressed transform still applies. */
  .sa-button.sa-message-scroller-button {
    --_bg: var(--sa-color-surface);
    --_bg-hover: var(--sa-color-hover);
    --_bg-active: var(--sa-color-hover);
    --_fg: var(--sa-color-ink);
    --_border: var(--sa-color-line);
    --_s: 0;                     /* no sheen: a surface, not a fill */
    --_x: -50%;
    --_y: 0;
    position: absolute;
    inset-inline-start: 50%;
    translate: var(--_x) var(--_y);
    transition-property: background-color, border-color, color, box-shadow, transform, translate, scale, opacity;
    transition-duration: 200ms;
    transition-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
    &:dir(rtl) {
      --_x: 50%;
    }
    &[data-direction="end"] {
      bottom: calc(4 * var(--sa-unit));
    }
    &[data-direction="start"] {
      top: calc(4 * var(--sa-unit));
      & svg {
        rotate: 180deg;
      }
    }
    &[data-active="false"] {
      pointer-events: none;
      opacity: 0;
      scale: 0.95;
      transition-duration: 400ms;
      transition-timing-function: cubic-bezier(0.7, 0, 0.84, 0);
      &[data-direction="end"] { --_y: 100%; }
      &[data-direction="start"] { --_y: -100%; }
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-button.sa-message-scroller-button {
      transition-duration: 0s;
    }
  }
}

@keyframes sa-message-scroller-fade {
  from {
    --_message-scroller-fade: min(12%, calc(10 * var(--sa-unit)));
  }
  to {
    --_message-scroller-fade: 0px;
  }
}

/* components/message.css */
/* Message: one entry in a conversation: an avatar beside a column of bubbles, with an optional header
   and footer, aligned to the start or the end.
   Replaces: .sa-message, .sa-message-avatar, .sa-message-content, .sa-message-header,
   .sa-message-footer, .sa-message-group */

@layer sa.components {
  .sa-message {
    position: relative;
    display: flex;
    gap: calc(2 * var(--sa-unit));
    width: 100%;
    min-width: 0;
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
    &[data-align="end"] {
      flex-direction: row-reverse;
    }
  }
  .sa-message-avatar {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    align-self: flex-end;
    justify-content: center;
    width: fit-content;
    min-width: calc(8 * var(--sa-unit));
    overflow: hidden;
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-surface-sunken);
    .sa-message:has([data-slot="message-footer"]) > & {
      translate: 0 calc(-1 * calc(8 * var(--sa-unit)));
    }
  }
  .sa-message-content {
    display: flex;
    flex-direction: column;
    gap: calc(2.5 * var(--sa-unit));
    width: 100%;
    min-width: 0;
    overflow-wrap: break-word;
    .sa-message[data-align="end"] > & > [data-slot] {
      align-self: flex-end;
    }
  }
  .sa-message-header,
  .sa-message-footer {
    display: flex;
    align-items: center;
    min-width: 0;
    max-width: 100%;
    padding-inline: calc(3 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-xs);
    font-weight: var(--sa-weight-control);
    line-height: calc(var(--sa-text-xs) * 1.3333);
    .sa-message:has([data-variant="ghost"]) & {
      padding-inline: 0;
    }
  }
  .sa-message-footer {
    .sa-message[data-align="end"] & {
      justify-content: flex-end;
    }
  }
  .sa-message-group {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
    min-width: 0;
  }
}

/* components/page-container.css */
/* Page container: <sa-page-container>, the padded, centred column a page's content sits in, full width
   or capped at one of three widths.
   Replaces: .sa-page-container, .sa-page-container-width-large, .sa-page-container-width-medium,
   .sa-page-container-width-small */

@layer sa.components {
  .sa-page-container {
    display: flex;
    flex-direction: column;
    gap: calc(5 * var(--sa-unit));
    width: 100%;
    margin-inline: auto;
    padding: calc(5 * var(--sa-unit));
    @media (width >= 48rem) { padding: calc(8 * var(--sa-unit)); }
  }
  .sa-page-container-width-small { max-width: 42rem; }
  .sa-page-container-width-medium { max-width: 56rem; }
  .sa-page-container-width-large { max-width: 72rem; }
}

/* components/page-header.css */
/* Page header: a title with an optional breadcrumb above, description below, actions beside (below on
   narrow screens) and a nav row (usually line tabs) underneath.
   Replaces: .sa-page-header, .sa-page-header-title, .sa-page-header-description,
   .sa-page-header-actions, .sa-page-header-nav */

@layer sa.components {
  .sa-page-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: calc(1.5 * var(--sa-unit)) calc(4 * var(--sa-unit));

    & > [data-slot="breadcrumb"] {
      grid-column: 1 / -1;
      padding-bottom: var(--sa-unit);
    }
  }
  .sa-page-header-title {
    color: var(--sa-color-ink);
    font-family: var(--sa-font-heading);
    font-size: calc(var(--sa-text-base) * 1.25);
    font-weight: var(--sa-weight-heading);
    letter-spacing: -0.01em;
    line-height: 1.4;
  }
  .sa-page-header-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    line-height: var(--sa-leading-ui);
  }
  .sa-page-header-actions {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    margin-top: calc(2 * var(--sa-unit));
  }
  .sa-page-header-nav {
    grid-column: 1 / -1;
    margin-top: calc(3 * var(--sa-unit));
    padding-bottom: var(--sa-unit);
    overflow-x: auto;
  }

  /* From the sm breakpoint the actions sit beside the title, spanning the description's row, or
     beside the title's row when a breadcrumb leads. */
  @media (width >= 40rem) {
    .sa-page-header {
      grid-template-columns: minmax(0, 1fr) auto;
    }
    .sa-page-header-description { grid-column-start: 1; }
    .sa-page-header-actions {
      grid-column-start: 2;
      grid-row: 1;
      align-self: start;
      justify-self: end;
      margin-top: 0;
    }
    .sa-page-header:has(> [data-slot="page-header-description"]) > .sa-page-header-actions {
      grid-row: 1 / span 2;
    }
    .sa-page-header:has(> [data-slot="breadcrumb"]) > .sa-page-header-actions {
      grid-row-start: 2;
    }
  }
}

/* components/pagination.css */
/* Pagination: a row of page links. Links are buttons (button.css): ghost, with the current page an
   outline button by default (--sa-current-page-fill blends it toward a solid accent).
   Replaces: .sa-pagination, .sa-pagination-content, .sa-pagination-ellipsis, .sa-pagination-previous,
   .sa-pagination-next, .sa-pagination-link-label */

@layer sa.components {
  .sa-pagination {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-inline: auto;
  }
  .sa-pagination-content {
    display: flex;
    align-items: center;
    gap: calc(0.5 * var(--sa-unit));
    list-style: none;
  }
  .sa-button.sa-pagination-link {
    min-width: var(--_h);
    &[data-active="true"] {
      --_bg: color-mix(in oklab, var(--sa-color-accent-fill) calc(var(--sa-current-page-fill) * 100%), var(--_button-outline-bg));
      --_bg-hover: color-mix(in oklab, var(--sa-color-accent-hover) calc(var(--sa-current-page-fill) * 100%), var(--sa-color-hover));
      --_bg-active: color-mix(in oklab, var(--sa-color-accent-hover) calc(var(--sa-current-page-fill) * 100%), var(--sa-color-hover));
      --_fg: color-mix(in oklab, var(--sa-color-on-accent) calc(var(--sa-current-page-fill) * 100%), var(--sa-color-ink));
      --_border: color-mix(in oklab, var(--sa-color-accent-fill) calc(var(--sa-current-page-fill) * 100%), var(--_button-outline-border));
    }
  }
  /* First and Previous carry .sa-pagination-previous, Next and Last .sa-pagination-next. */
  .sa-button.sa-pagination-previous:not([class*="size-icon"]) { padding-inline-start: calc(1.5 * var(--sa-unit)); }
  .sa-button.sa-pagination-next:not([class*="size-icon"]) { padding-inline-end: calc(1.5 * var(--sa-unit)); }
  .sa-pagination-ellipsis {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--sa-control-h);
    height: var(--sa-control-h);
    color: var(--sa-color-ink-muted);
    & svg:not([class*="size-"]) { width: var(--sa-control-icon); height: var(--sa-control-icon); }
  }
  /* The Previous/Next words hide below the sm breakpoint, leaving the chevrons. */
  @media (width < 40rem) {
    .sa-pagination-link-label {
      position: absolute;
      width: 1px;
      height: 1px;
      margin: -1px;
      padding: 0;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
      border-width: 0;
    }
  }
}

/* components/popover.css */
/* Popover: a panel of content anchored to its trigger, with an optional header (title and description).
   Replaces: .sa-popover-content, .sa-popover-content-logical, .sa-popover-header, .sa-popover-title,
   .sa-popover-description */

@layer sa.components {
  /* Anchored to its trigger (anchors.css places it; the gap comes from the [data-anchor-side]
     rules in components.css). */
  .sa-popover-content {
    inset: auto;
    width: 18rem;
    margin: 0;
    padding: calc(2.5 * var(--sa-unit));
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-overlay);
    background: var(--sa-color-surface-raised);
    box-shadow: var(--sa-shadow-overlay);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
    outline: none;
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    opacity: 1;
    transition-property: opacity, display, overlay;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    transition-behavior: allow-discrete;

    &:not(:popover-open) { opacity: 0; }
    @starting-style {
      &:popover-open { opacity: 0; }
    }
    @media (prefers-reduced-motion: reduce) {
      transition: none;
    }
  }
  .sa-popover-header {
    display: flex;
    flex-direction: column;
    gap: calc(0.5 * var(--sa-unit));
    font-size: var(--sa-text-body);
  }
  .sa-popover-title {
    font-family: var(--sa-font-heading);
    font-weight: var(--sa-weight-heading);
  }
  .sa-popover-description {
    color: var(--sa-color-ink-muted);
  }
}

/* components/progress.css */
/* Progress: a thin track with a filled indicator, and an optional label and value above it.
   Replaces: .sa-progress, .sa-progress-root, .sa-progress-track, .sa-progress-indicator,
   .sa-progress-label, .sa-progress-value */

@layer sa.components {
  .sa-progress-root {
    display: flex;
    flex-wrap: wrap;
    gap: calc(3 * var(--sa-unit));
  }
  .sa-progress-track {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    height: var(--sa-unit);
    overflow-x: hidden;
    border-radius: var(--sa-radius-tag);
    background: var(--sa-color-tint);
  }
  .sa-progress-indicator {
    height: 100%;
    background: var(--sa-color-accent-fill);
    transition: width var(--sa-motion-fast) var(--sa-motion-ease);
  }
  .sa-progress-label {
    font-size: var(--sa-text-sm);
    font-weight: var(--sa-weight-control);
    line-height: var(--sa-leading-ui);
  }
  .sa-progress-value {
    margin-inline-start: auto;
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    font-variant-numeric: tabular-nums;
    line-height: var(--sa-leading-ui);
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-progress-indicator {
      transition-duration: 0s;
    }
  }
}

/* components/questionnaire.css */
/* Questionnaire: questions with choice cards, free-text answers, progress and step actions. Each choice
   card holds a native radio or checkbox stretched over it, so the card styles itself from the input's
   checked, disabled, focus and validation state, with no script.
   Replaces: .sa-questionnaire, .sa-questionnaire-progress, .sa-questionnaire-item,
   .sa-questionnaire-title, .sa-questionnaire-description, .sa-questionnaire-choices,
   .sa-questionnaire-choice, .sa-questionnaire-choice-input, .sa-questionnaire-choice-indicator,
   .sa-questionnaire-choice-indicator-dot, .sa-questionnaire-choice-indicator-check,
   .sa-questionnaire-choice-label, .sa-questionnaire-choice-content,
   .sa-questionnaire-choice-description, .sa-questionnaire-choice-shortcut, .sa-questionnaire-shortcut,
   .sa-questionnaire-input-wrapper, .sa-questionnaire-input, .sa-questionnaire-error,
   .sa-questionnaire-actions, .sa-questionnaire-previous, .sa-questionnaire-skip,
   .sa-questionnaire-next, .sa-questionnaire-submit */

@layer sa.tokens {
  .sa-questionnaire {
    /* The free-text answer, recessed like an input when tactile. */
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_questionnaire-input-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark .sa-questionnaire {
    --_relief-k: 4;
  }
}

@layer sa.components {
  .sa-questionnaire {
    display: flex;
    flex-direction: column;
    gap: calc(4 * var(--sa-unit));
    width: 100%;
    min-width: 0;
  }
  .sa-questionnaire-progress {
    width: fit-content;
    min-width: 14ch;
    min-height: 1lh;
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-xs);
    line-height: calc(4 / 3);
    font-weight: var(--sa-weight-control);
    font-variant-numeric: tabular-nums;
  }
  /* A fieldset: the title is its legend, which sits outside the flex flow, so the description
     follows it directly. */
  .sa-questionnaire-item {
    display: flex;
    flex-direction: column;
    gap: calc(4 * var(--sa-unit));
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    outline: none;
  }
  .sa-questionnaire-title {
    padding: 0;
    font-family: var(--sa-font-heading);
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-heading);
    line-height: 1.375;
    text-wrap: pretty;
    &:not(:has(~ [data-slot="questionnaire-description"])) {
      margin-bottom: calc(4 * var(--sa-unit));
    }
  }
  .sa-questionnaire-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
    text-wrap: pretty;
  }
  .sa-questionnaire-choices {
    display: grid;
    gap: calc(2 * var(--sa-unit));
    min-width: 0;
  }

  .sa-questionnaire-choice {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: calc(2.5 * var(--sa-unit));
    min-height: 2.75rem;
    padding: calc(2.5 * var(--sa-unit)) calc(3 * var(--sa-unit));
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-box);
    background: var(--sa-color-field);
    background-clip: padding-box;
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
    text-align: start;
    cursor: pointer;
    outline: none;
    user-select: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);
    &:hover:not(:has(> input:checked)) {
      border-color: var(--sa-color-line-control-hover);
      background-color: var(--sa-color-hover);
    }
    &:has(> input:checked) {
      border-color: color-mix(in oklab, var(--sa-color-accent) 55%, var(--sa-color-line-control));
      background-color: var(--sa-color-selected);
    }
    &:has(> input:is([aria-invalid="true"], .input-validation-error)) {
      border-color: var(--sa-color-danger);
    }
    &:has(> input:focus-visible) {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow-field);
    }
    &:has(> input:disabled) {
      cursor: not-allowed;
      opacity: var(--sa-disabled-opacity);
      pointer-events: none;
    }
  }
  .sa-questionnaire-choice-input {
    position: absolute;
    inset: 0;
    z-index: 10;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    opacity: 0;
  }
  .sa-questionnaire-choice-indicator {
    position: relative;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: calc(4 * var(--sa-unit));
    height: calc(4 * var(--sa-unit));
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-control-sm);
    background: var(--sa-color-field);
    pointer-events: none;
    /* Centred on the first line of the label. */
    translate: 0 calc((var(--sa-leading-ui) - calc(4 * var(--sa-unit))) / 2);
    .sa-questionnaire-choice[data-type="radio"] > & {
      border-radius: var(--sa-radius-round);
    }
    .sa-questionnaire-choice:has(> input:checked) > & {
      border-color: var(--sa-color-accent-fill);
      background: var(--sa-color-accent-fill);
      color: var(--sa-color-on-accent);
    }
  }
  .sa-questionnaire-choice-indicator-dot,
  .sa-questionnaire-choice-indicator-check {
    display: none;
    .sa-questionnaire-choice:has(> input:checked) & {
      display: block;
    }
  }
  .sa-questionnaire-choice-indicator-dot {
    width: calc(2 * var(--sa-unit));
    height: calc(2 * var(--sa-unit));
    border-radius: var(--sa-radius-round);
    background: currentColor;
  }
  .sa-questionnaire-choice-indicator-check {
    width: calc(3.5 * var(--sa-unit));
    height: calc(3.5 * var(--sa-unit));
  }
  .sa-questionnaire-choice-label {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: calc(0.5 * var(--sa-unit));
    min-width: 0;
    line-height: 1.375;
  }
  .sa-questionnaire-choice-description {
    color: var(--sa-color-ink-muted);
  }
  .sa-questionnaire-choice-shortcut {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: calc(5 * var(--sa-unit));
    height: calc(5 * var(--sa-unit));
    margin-inline-start: auto;
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-control-sm);
    background: var(--sa-color-surface);
    color: var(--sa-color-ink-muted);
    font-family: var(--sa-font-mono);
    font-size: calc(0.625rem * var(--sa-type-scale));
    font-weight: var(--sa-weight-control);
    line-height: 1;
    pointer-events: none;
    translate: 0 calc((var(--sa-leading-ui) - calc(5 * var(--sa-unit))) / 2);
  }

  .sa-questionnaire-input-wrapper {
    position: relative;
    width: 100%;
    min-width: 0;
  }
  .sa-questionnaire-input {
    width: 100%;
    min-width: 0;
    min-height: 2.75rem;
    height: var(--sa-control-h);
    padding: 0.25rem var(--sa-control-px);
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-control);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--_questionnaire-input-shadow);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-base);   /* 16px on small screens keeps mobile browsers from zooming in */
    outline: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);
    @media (width >= 40rem) {
      min-height: 0;
    }
    @media (width >= 48rem) {
      font-size: var(--sa-text-control);
    }

    &::placeholder {
      color: var(--sa-color-ink-placeholder);
    }
    &::selection {
      background: var(--sa-color-accent-fill);
      color: var(--sa-color-on-accent);
    }
    &:hover:not(:disabled, :focus-visible) {
      border-color: var(--sa-color-line-control-hover);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_questionnaire-input-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_questionnaire-input-shadow), var(--sa-invalid-shadow);
      &:focus-visible {
        box-shadow: var(--_questionnaire-input-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      background: var(--sa-color-field-disabled);
      opacity: var(--sa-disabled-opacity);
      cursor: not-allowed;
      pointer-events: none;
    }
  }

  .sa-questionnaire-error {
    margin-top: calc(2 * var(--sa-unit));
    color: var(--sa-color-danger-text);
    font-size: var(--sa-text-body);
    /* A bound answer renders its message even while it is valid, so unobtrusive validation has
       somewhere to write into. Hidden until it says something, or it takes a gap in the item. */
    &:empty {
      display: none;
    }
  }

  /* Back on the left; skip, then next or submit, on the right. */
  .sa-questionnaire-actions {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    width: 100%;
    min-height: calc(11 * var(--sa-unit));
  }
  .sa-questionnaire-previous,
  .sa-questionnaire-skip,
  .sa-questionnaire-next,
  .sa-questionnaire-submit {
    grid-row-start: 1;
    min-height: 2.75rem;   /* touch targets on small screens */
    @media (width >= 40rem) {
      min-height: 0;
    }
  }
  .sa-questionnaire-previous {
    grid-column-start: 1;
    justify-self: start;
  }
  .sa-questionnaire-skip {
    grid-column-start: 2;
    justify-self: end;
  }
  .sa-questionnaire-next,
  .sa-questionnaire-submit {
    grid-column-start: 3;
    justify-self: end;
  }
}

/* components/radio.css */
/* Radio: <sa-input type="radio">, a native radio drawn as a small round field with a sibling dot, in
   the control wrapper (checkbox.css), which carries the variables so the dot reads them too.
   Replaces: .sa-radiobutton, .sa-radiobutton-indicator, .sa-radiobutton-indicator-icon */

@layer sa.tokens {
  .sa-input-control-wrapper {
    --_radio-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_radio-k: 1;
    --_radio-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_radio-press) * var(--_radio-k)));
  }
  .dark .sa-input-control-wrapper {
    --_radio-k: 4;
  }
}

@layer sa.components {
  .sa-radiobutton {
    position: relative;
    display: flex;
    flex-shrink: 0;
    width: calc(4 * var(--sa-unit));
    height: calc(4 * var(--sa-unit));
    margin: 0;
    appearance: none;
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--_radio-shadow);
    cursor: pointer;
    outline: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    /* A larger hit area around the small circle. */
    &::after {
      content: "";
      position: absolute;
      inset: calc(-2 * var(--sa-unit)) calc(-3 * var(--sa-unit));
    }
    &:hover:not(:disabled, :focus-visible, :checked) {
      border-color: var(--sa-color-line-control-hover);
    }
    &:checked {
      border-color: var(--sa-color-accent-fill);
      background: var(--sa-color-accent-fill);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_radio-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_radio-shadow), var(--sa-invalid-shadow);
      &:checked {
        border-color: var(--sa-color-accent-fill);
      }
      &:focus-visible {
        box-shadow: var(--_radio-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      cursor: not-allowed;
      opacity: var(--sa-disabled-opacity);
    }
  }
  .sa-radiobutton-indicator {
    width: 0;
    height: 0;
    visibility: hidden;
  }
  .sa-radiobutton:checked ~ .sa-radiobutton-indicator {
    visibility: visible;
  }
  .sa-radiobutton-indicator-icon {
    position: absolute;
    top: 50%;
    left: 50%;
    width: calc(2 * var(--sa-unit));
    height: calc(2 * var(--sa-unit));
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-on-accent);
    pointer-events: none;
    stroke: none;
    translate: -50% -50%;
  }
  /* In a choice card (a field label around the field), the card shows focus instead. */
  [data-slot="field-label"] .sa-radiobutton:focus-visible {
    border-color: var(--sa-color-line-control);
    box-shadow: var(--_radio-shadow);
    &:checked {
      border-color: var(--sa-color-accent-fill);
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-radiobutton {
      transition-duration: 0s;
    }
  }
}

/* components/segmented-control.css */
/* Segmented control: a radio group drawn as a track of segments, like the tabs list. Each segment is a
   label around a visually hidden radio, so its states come from the radio (:checked, :focus-visible,
   :disabled).
   Replaces: .sa-segmented-control, .sa-segmented-control-input, .sa-segmented-control-item */

@layer sa.tokens {
  .sa-segmented-control {
    --_segmented-control-item-fg: color-mix(in oklab, var(--sa-color-ink) 66%, transparent);   /* 4.5:1 on the darkest band */
    --_segmented-control-selected-bg: var(--sa-color-surface);
    --_segmented-control-selected-border: transparent;
  }
  .dark .sa-segmented-control {
    --_segmented-control-item-fg: var(--sa-color-ink-muted);
    --_segmented-control-selected-bg: var(--sa-color-field);
    --_segmented-control-selected-border: var(--sa-color-line-control);
  }
}

@layer sa.components {
  .sa-segmented-control {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    max-width: 100%;
    height: var(--sa-control-h);
    padding: 3px;
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-control);
    background: var(--sa-color-tint);
    color: var(--_segmented-control-item-fg);

    &[aria-invalid="true"] {
      border-color: var(--sa-color-danger);
      box-shadow: var(--sa-invalid-shadow);
    }
  }

  .sa-segmented-control-input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .sa-segmented-control-item {
    position: relative;
    display: inline-flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    gap: calc(1.5 * var(--sa-unit));
    height: 100%;
    padding: calc(0.5 * var(--sa-unit)) calc(1.5 * var(--sa-unit));
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-item);
    color: var(--_segmented-control-item-fg);
    font-size: var(--sa-text-control);
    font-weight: var(--sa-weight-control);
    line-height: var(--sa-leading-ui);
    white-space: nowrap;
    cursor: pointer;
    transition:
      color var(--sa-motion-fast) var(--sa-motion-ease),
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    & svg {
      flex-shrink: 0;
      pointer-events: none;
    }
    & svg:not([class*="size-"]) {
      width: var(--sa-control-icon);
      height: var(--sa-control-icon);
    }
    &:has(> [data-icon="inline-start"]) {
      padding-inline-start: var(--sa-unit);
    }
    &:has(> [data-icon="inline-end"]) {
      padding-inline-end: var(--sa-unit);
    }
    &:hover {
      color: var(--sa-color-ink);
    }
    &:has(:checked) {
      border-color: var(--_segmented-control-selected-border);
      background: var(--_segmented-control-selected-bg);
      box-shadow: var(--sa-shadow-raised);
      color: var(--sa-color-ink);
    }
    &:has(:focus-visible) {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
    &:has(:disabled) {
      opacity: var(--sa-disabled-opacity);
      cursor: not-allowed;
      pointer-events: none;
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-segmented-control-item {
      transition-duration: 0s;
    }
  }
}

/* components/select.css */
/* Select: a native select drawn like the input, in a wrapper that places the dropdown icon over it.
   Replaces: .sa-native-select, .sa-native-select-icon, .sa-native-select-wrapper */

@layer sa.tokens {
  .sa-native-select-wrapper {
    /* Recessed when tactile (--sa-relief 2), as the input; dark mode weights the inset more. */
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_select-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark .sa-native-select-wrapper {
    --_relief-k: 4;
  }
}

@layer sa.components {
  .sa-native-select-wrapper {
    position: relative;
    width: fit-content;
    &:has(select:disabled) {
      opacity: var(--sa-disabled-opacity);
    }
  }
  .sa-native-select {
    --_h: var(--sa-control-h);
    --_radius: var(--sa-radius-control);
    --_py: var(--sa-unit);
    width: 100%;
    min-width: 0;
    height: var(--_h);
    padding-block: var(--_py);
    padding-inline: var(--sa-control-px) calc(8 * var(--sa-unit));
    appearance: none;
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--_radius);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--_select-shadow);
    color: var(--sa-color-ink);
    font: inherit;
    font-size: var(--sa-text-control);
    line-height: var(--sa-leading-ui);
    outline: none;
    user-select: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &[data-size="sm"] {
      --_h: var(--sa-control-h-sm);
      --_radius: var(--sa-radius-control-sm);
      --_py: calc(0.5 * var(--sa-unit));
    }
    & option,
    & optgroup {
      background-color: var(--sa-color-surface-raised);
      color: var(--sa-color-ink);
    }
    &:hover:not(:disabled, :focus-visible) {
      border-color: var(--sa-color-line-control-hover);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_select-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_select-shadow), var(--sa-invalid-shadow);
      &:focus-visible {
        box-shadow: var(--_select-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      background: var(--sa-color-field-disabled);
      cursor: not-allowed;
      pointer-events: none;
    }
  }
  .sa-native-select-icon {
    position: absolute;
    top: 50%;
    right: var(--sa-control-px);
    width: var(--sa-control-icon);
    height: var(--sa-control-icon);
    color: var(--sa-color-ink-muted);
    pointer-events: none;
    user-select: none;
    translate: 0 -50%;
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-native-select {
      transition-duration: 0s;
    }
  }
}

/* components/separator.css */
/* Separator: <sa-separator>, a one-stroke rule, horizontal or vertical; other components' separators
   (sidebar, app header, …) render it and adjust it by selector.
   Replaces: .sa-separator, .sa-separator-horizontal, .sa-separator-vertical */

@layer sa.components {
  .sa-separator {
    flex-shrink: 0;
    background: var(--sa-color-line);
  }
  .sa-separator-horizontal {
    width: 100%;
    height: var(--sa-border-width);
  }
  .sa-separator-vertical {
    width: var(--sa-border-width);
    height: 100%;
  }
}

/* components/sheet.css */
/* Sheet: a panel over a native <dialog> that slides in from an edge of the screen (data-side), drawn
   like the dialog (scrim, raised surface, footer switches), with a corner close button and a body
   that stretches the footer to the bottom.
   Replaces: .sa-sheet-content, .sa-sheet-overlay, .sa-sheet-close, .sa-sheet-body,
   .sa-sheet-header, .sa-sheet-footer, .sa-sheet-title, .sa-sheet-description */

@layer sa.tokens {
  .sa-sheet-content {
    /* The dialog's footer switches: banded or ruled like the dialog's footer. */
    --_footer-fill: var(--sa-dialog-footer-fill, var(--sa-footer-fill));
    --_footer-rule: var(--sa-dialog-footer-rule, var(--sa-footer-rule));
  }
}

@layer sa.components {
  .sa-sheet-content {
    --_from: 100% 0;
    position: fixed;
    inset: auto;
    width: auto;
    max-width: 100%;
    height: auto;
    max-height: 100%;
    margin: 0;
    padding: 0;
    border: 0 solid var(--sa-color-line);
    border-radius: 0;
    background: var(--sa-color-surface-raised);
    background-clip: padding-box;
    box-shadow: var(--sa-shadow-dialog);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-body);
    line-height: calc(1.25 / 0.875);
    outline: none;
    &[open] {
      animation: sa-sheet-in calc(2 * var(--sa-motion-fast)) var(--sa-motion-ease);
    }
    &::backdrop {
      background: var(--sa-color-scrim);
    }
    &[open]::backdrop {
      animation: sa-dialog-backdrop-in calc(2 * var(--sa-motion-fast)) var(--sa-motion-ease);   /* keyframes in dialog.css */
    }

    &[data-side="right"],
    &[data-side="left"] {
      inset-block: 0;
      width: 75%;
      height: 100%;
      @media (width >= 40rem) {
        max-width: 24rem;
      }
    }
    &[data-side="right"] {
      right: 0;
      border-left-width: var(--sa-border-width);
    }
    &[data-side="left"] {
      --_from: -100% 0;
      left: 0;
      border-right-width: var(--sa-border-width);
    }
    &[data-side="top"],
    &[data-side="bottom"] {
      inset-inline: 0;
      width: 100%;
    }
    &[data-side="top"] {
      --_from: 0 -100%;
      top: 0;
      border-bottom-width: var(--sa-border-width);
    }
    &[data-side="bottom"] {
      --_from: 0 100%;
      bottom: 0;
      border-top-width: var(--sa-border-width);
    }
  }
  .sa-sheet-close {
    position: absolute;
    top: calc(3 * var(--sa-unit));
    right: calc(3 * var(--sa-unit));
  }
  .sa-sheet-body {
    display: flex;
    flex-direction: column;
    height: 100%;
  }
  .sa-sheet-header {
    display: flex;
    flex-direction: column;
    gap: calc(0.5 * var(--sa-unit));
    padding: var(--sa-space-container);
  }
  .sa-sheet-title {
    color: var(--sa-color-ink);
    font-family: var(--sa-font-heading);
    font-size: var(--sa-text-base);
    font-weight: var(--sa-weight-heading);
    line-height: 1.5;
  }
  .sa-sheet-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
  }
  .sa-sheet-footer {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
    margin-top: auto;
    padding: var(--sa-space-container);
    border-top: var(--sa-border-width) solid color-mix(in oklab, var(--sa-color-line) calc(var(--_footer-rule) * 100%), transparent);
    background: color-mix(in oklab, var(--sa-color-surface-subtle) calc(var(--_footer-fill) * 100%), transparent);
  }

  @keyframes sa-sheet-in {
    from { translate: var(--_from); }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-sheet-content[open],
    .sa-sheet-content[open]::backdrop {
      animation: none;
    }
  }
}

/* components/sidebar.css */
/* Sidebar: the navigation region (sel-sidebar wrapper, the sidebar with its gap, container and inner panel,
   and the inset main area), with its groups, menus, sub menus and badges; collapsing off-canvas or to icons
   on desktop and an off-canvas drawer below 48rem.
   Replaces: .sa-sidebar, .sa-sidebar-backdrop, .sa-sidebar-container, .sa-sidebar-content,
   .sa-sidebar-footer, .sa-sidebar-gap, .sa-sidebar-group, .sa-sidebar-group-content,
   .sa-sidebar-group-label, .sa-sidebar-header, .sa-sidebar-inner, .sa-sidebar-inset, .sa-sidebar-menu,
   .sa-sidebar-menu-badge, .sa-sidebar-menu-button, .sa-sidebar-menu-button-variant-default,
   .sa-sidebar-menu-button-variant-outline, .sa-sidebar-menu-button-size-default,
   .sa-sidebar-menu-button-size-sm, .sa-sidebar-menu-button-size-lg, .sa-sidebar-menu-item,
   .sa-sidebar-menu-sub, .sa-sidebar-menu-sub-button, .sa-sidebar-menu-sub-item, .sa-sidebar-separator,
   .sa-sidebar-wrapper */

@layer sa.components {
  .sa-sidebar-wrapper {
    display: flex;
    width: 100%;
    min-height: 100svh;
    &:has([data-slot="sidebar"][data-variant="inset"]) { background: var(--sa-color-nav-surface); }
  }

  .sa-sidebar {
    color: var(--sa-color-nav-ink);
    &[data-side="right"] { order: 9999; }
  }

  /* Mobile drawer backdrop: a button that closes the drawer. */
  .sa-sidebar-backdrop {
    position: fixed;
    inset: 0;
    z-index: 20;
    background: var(--sa-color-scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--sa-motion-fast) var(--sa-motion-ease);
    .sa-sidebar[data-mobile="open"] > & { opacity: 1; pointer-events: auto; }
    @media (width >= 48rem) { display: none; }
  }

  /* Desktop spacer that pushes the inset over by the sidebar's width. */
  .sa-sidebar-gap {
    position: relative;
    display: none;
    width: var(--sidebar-width);
    height: 100svh;
    background: transparent;
    transition: width var(--sa-motion-fast) var(--sa-motion-ease);
    @media (width >= 48rem) { display: block; }
    .sa-sidebar[data-collapsible="offcanvas"] > & { width: 0; }
    .sa-sidebar[data-collapsible="icon"] > & { width: var(--sidebar-width-icon); }
    .sa-sidebar:is([data-variant="floating"], [data-variant="inset"])[data-collapsible="icon"] > & {
      width: calc(var(--sidebar-width-icon) + 4 * var(--sa-unit));
    }
  }

  /* Desktop panel and mobile drawer in one element. */
  .sa-sidebar-container {
    position: fixed;
    inset-block: 0;
    z-index: 30;
    display: flex;
    width: var(--sidebar-width-mobile);
    height: 100svh;
    transition-property: left, right, width, transform;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    @media (width >= 48rem) { width: var(--sidebar-width); }

    .sa-sidebar[data-side="left"] > & { left: 0; }
    .sa-sidebar[data-side="right"] > & { right: 0; }
    @media (width < 48rem) {
      .sa-sidebar[data-side="left"][data-mobile="closed"] > & { transform: translateX(-100%); }
      .sa-sidebar[data-side="right"][data-mobile="closed"] > & { transform: translateX(100%); }
    }
    .sa-sidebar[data-side="left"][data-collapsible="offcanvas"] > & { left: calc(var(--sidebar-width) * -1); }
    .sa-sidebar[data-side="right"][data-collapsible="offcanvas"] > & { right: calc(var(--sidebar-width) * -1); }

    .sa-sidebar[data-variant="sidebar"][data-side="left"] > & {
      border-inline-end: var(--sa-border-width) solid var(--sa-color-nav-line);
    }
    .sa-sidebar[data-variant="sidebar"][data-side="right"] > & {
      border-inline-start: var(--sa-border-width) solid var(--sa-color-nav-line);
    }
    .sa-sidebar[data-variant="sidebar"][data-collapsible="icon"] > & { width: var(--sidebar-width-icon); }
    .sa-sidebar:is([data-variant="floating"], [data-variant="inset"]) > & { padding: calc(2 * var(--sa-unit)); }
    .sa-sidebar:is([data-variant="floating"], [data-variant="inset"])[data-collapsible="icon"] > & {
      width: calc(var(--sidebar-width-icon) + 4 * var(--sa-unit) + 2px);
    }
  }

  .sa-sidebar-inner {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    background: var(--sa-color-nav-surface);
    color: var(--sa-color-nav-ink);
    /* collapsible="none": the inner panel is the sidebar itself, in flow. */
    &[data-side="left"] { border-inline-end: var(--sa-border-width) solid var(--sa-color-nav-line); }
    &[data-side="right"] { border-inline-start: var(--sa-border-width) solid var(--sa-color-nav-line); }
    .sa-sidebar[data-variant="floating"] & {
      border: var(--sa-border-width) solid var(--sa-color-nav-line);
      border-radius: var(--sa-radius-container);
      box-shadow: var(--sa-shadow-container);
    }
  }

  :is(.sa-sidebar-header, .sa-sidebar-footer) {
    display: flex;
    flex-direction: column;
    gap: calc(2 * var(--sa-unit));
    padding: calc(2 * var(--sa-unit));
  }

  .sa-sidebar-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0px;
    min-height: 0;
    overflow: auto;
    scrollbar-width: none;
    &::-webkit-scrollbar { display: none; }
    .sa-sidebar[data-collapsible="icon"] & { overflow: hidden; }
  }

  .sa-separator.sa-sidebar-separator {
    width: auto;
    margin-inline: calc(2 * var(--sa-unit));
    background: var(--sa-color-nav-line);
  }

  .sa-sidebar-group {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0px;
    width: 100%;
    min-width: 0;
    padding: calc(2 * var(--sa-unit));
  }

  .sa-sidebar-group-content {
    width: 100%;
    font-size: var(--sa-text-body);
  }

  .sa-sidebar-group-label {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    height: calc(8 * var(--sa-unit));
    padding-inline: calc(2 * var(--sa-unit));
    border-radius: var(--sa-radius-item);
    color: color-mix(in oklab, var(--sa-color-nav-ink) 70%, transparent);
    font-family: var(--sa-section-label-font);
    font-size: var(--sa-section-label-text);
    font-weight: var(--sa-section-label-weight);
    letter-spacing: var(--sa-section-label-tracking);
    text-transform: var(--sa-section-label-transform);
    outline: none;
    transition-property: margin, opacity;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    & > svg { flex-shrink: 0; width: var(--sa-control-icon); height: var(--sa-control-icon); }
    &:focus-visible { box-shadow: inset 0 0 0 2px var(--sa-focus-border); }
    .sa-sidebar[data-collapsible="icon"] & { margin-top: calc(calc(8 * var(--sa-unit)) * -1); opacity: 0; }
  }

  :is(.sa-sidebar-menu, .sa-sidebar-menu-sub) {
    display: flex;
    flex-direction: column;
    min-width: 0;
    list-style: none;
  }
  .sa-sidebar-menu {
    gap: 0px;
    width: 100%;
  }
  :is(.sa-sidebar-menu-item, .sa-sidebar-menu-sub-item) { position: relative; }

  :is(.sa-sidebar-menu-button, .sa-sidebar-menu-sub-button) {
    display: flex;
    align-items: center;
    gap: calc(2 * var(--sa-unit));
    overflow: hidden;
    border: 0px solid transparent;
    border-radius: var(--sa-radius-item);
    color: var(--sa-color-nav-ink);
    font-weight: 400;
    text-align: left;
    outline: none;
    transition-property: background-color, color, box-shadow, width, height, padding;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);

    & svg { flex-shrink: 0; }
    & svg:not([class*="size-"]) { width: var(--sa-control-icon); height: var(--sa-control-icon); }
    & > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    &:hover, &:active {
      background: var(--sa-color-nav-highlight);
      color: var(--sa-color-on-nav-highlight);
    }
    &[data-active] {
      border-color: transparent;
      background: var(--sa-color-nav-highlight);
      box-shadow: inset 3px 0 0 transparent, 0 0 #0000;
      color: var(--sa-color-on-nav-highlight);
      font-weight: 500;
    }
    &:focus-visible { box-shadow: inset 0 0 0 2px var(--sa-focus-border); }
    &:disabled, &[aria-disabled="true"] { opacity: var(--sa-disabled-opacity); pointer-events: none; }
  }

  .sa-sidebar-menu-button {
    --_h: var(--sa-control-h);
    width: 100%;
    height: var(--_h);
    padding: calc(2 * var(--sa-unit));
    font-size: var(--sa-text-body);
    &[data-size="sm"] { --_h: var(--sa-control-h-sm); font-size: var(--sa-text-xs); }
    &[data-size="lg"] { --_h: calc(12 * var(--sa-unit)); }
    &[data-state="open"]:hover {
      background: var(--sa-color-nav-highlight);
      color: var(--sa-color-on-nav-highlight);
    }
    .sa-sidebar[data-collapsible="icon"] & {
      width: var(--sa-control-h);
      height: var(--sa-control-h);
      padding: calc(2 * var(--sa-unit));
      &[data-size="lg"] { padding: 0; }
    }
  }
  .sa-sidebar-menu-button-variant-outline {
    background: var(--sa-color-surface);
    box-shadow: 0 0 0 var(--sa-border-width) var(--sa-color-nav-line);
    &:hover { box-shadow: 0 0 0 var(--sa-border-width) var(--sa-color-line-control-hover); }
  }

  /* A badge follows its menu button, at the right of the row. */
  .sa-sidebar-menu-badge {
    position: absolute;
    top: calc(1.5 * var(--sa-unit));
    right: calc(1 * var(--sa-unit));
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: calc(5 * var(--sa-unit));
    height: calc(5 * var(--sa-unit));
    padding-inline: calc(1 * var(--sa-unit));
    border-radius: var(--sa-radius-item);
    background: transparent;
    color: var(--sa-color-nav-ink);
    font-family: inherit;
    font-size: var(--sa-text-xs);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
    user-select: none;
    .sa-sidebar-menu-button[data-size="sm"] ~ & { top: calc(1 * var(--sa-unit)); }
    .sa-sidebar-menu-button[data-size="lg"] ~ & { top: calc(2.5 * var(--sa-unit)); }
    .sa-sidebar-menu-button:is(:hover, [data-active]) ~ & { color: var(--sa-color-on-nav-highlight); }
    .sa-sidebar[data-collapsible="icon"] & { display: none; }
  }

  .sa-sidebar-menu-sub {
    gap: calc(1 * var(--sa-unit));
    margin-inline: calc(3.5 * var(--sa-unit));
    padding: calc(0.5 * var(--sa-unit)) calc(2.5 * var(--sa-unit)) calc(0.5 * var(--sa-unit)) calc(2.5 * var(--sa-unit));
    border-inline-start: var(--sa-border-width) solid var(--sa-color-nav-line);
    translate: 1px 0;
    .sa-sidebar[data-collapsible="icon"] & { display: none; }
  }
  .sa-sidebar-menu-sub-button {
    min-width: 0;
    height: calc(7 * var(--sa-unit));
    padding-inline: calc(2 * var(--sa-unit));
    translate: -1px 0;
    &[data-size="md"] { font-size: var(--sa-text-body); }
    &[data-size="sm"] { font-size: var(--sa-text-xs); }
    & > svg { color: var(--sa-color-on-nav-highlight); }
    .sa-sidebar[data-collapsible="icon"] & { display: none; }
  }

  .sa-sidebar-inset {
    position: relative;
    display: flex;
    flex: 1;
    flex-direction: column;
    width: 100%;
    background: var(--sa-color-canvas);
    @media (width >= 48rem) {
      .sa-sidebar[data-variant="inset"] ~ & {
        margin: calc(2 * var(--sa-unit));
        margin-inline-start: 0;
        border-radius: var(--sa-radius-container);
        box-shadow: 0 0 0 var(--sa-border-width) var(--sa-color-nav-line), var(--sa-shadow-container);
      }
      .sa-sidebar[data-variant="inset"][data-state="collapsed"] ~ & { margin-inline-start: calc(2 * var(--sa-unit)); }
    }
  }

  @media (prefers-reduced-motion: reduce) {
    :is(.sa-sidebar-backdrop, .sa-sidebar-gap, .sa-sidebar-container, .sa-sidebar-group-label,
      .sa-sidebar-menu-button, .sa-sidebar-menu-sub-button) {
      transition-duration: 0s;
    }
  }
}

/* components/skeleton.css */
/* Skeleton: a pulsing placeholder block, sized by the author.
   Replaces: .sa-skeleton */

@layer sa.components {
  .sa-skeleton {
    border-radius: var(--sa-radius-control-sm);
    background: var(--sa-color-tint);
    animation: sa-skeleton-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-skeleton {
      animation: none;
    }
  }
}

@keyframes sa-skeleton-pulse {
  50% {
    opacity: 0.5;
  }
}

/* components/slider.css */
/* Slider: <sel-slider> with a track, a filled range, one or more thumbs, optional marks (ticks and
   labels) and a value readout. The script positions the thumbs, range and marks inline and publishes
   the measured thumb size as --_slider-thumb-measured on the host, which marks use to inset their ends.
   Replaces: .sa-slider, .sa-slider-mark, .sa-slider-mark-label, .sa-slider-mark-tick, .sa-slider-marks,
   .sa-slider-range, .sa-slider-thumb, .sa-slider-track, .sa-slider-value */

@layer sa.tokens {
  .sa-slider,
  .sa-slider-value {
    --_slider-thumb-size: calc(3 * var(--sa-unit));
    --_slider-thumb-bg: var(--sa-color-surface);
  }
  .dark :is(.sa-slider, .sa-slider-value) {
    --_slider-thumb-bg: var(--sa-color-ink);
  }
}

@layer sa.components {
  .sa-slider {
    --_slider-thumb: var(--_slider-thumb-measured, var(--_slider-thumb-size));
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    touch-action: none;
    user-select: none;

    &[data-orientation="vertical"] {
      flex-direction: column;
      width: auto;
      height: 100%;
      min-height: calc(40 * var(--sa-unit));
    }
    &:is([data-disabled]:not([data-disabled="false"])) {
      opacity: var(--sa-disabled-opacity);
    }
    /* Mark labels hang outside the host, which stays as tight as the track; reserve their room. */
    &[data-orientation="horizontal"]:has([data-slot="slider-mark-label"]) {
      margin-bottom: calc(var(--_slider-thumb) / 2 + 1.25rem);
    }
    &[data-orientation="vertical"]:has([data-slot="slider-mark-label"]) {
      margin-inline-end: calc(var(--_slider-thumb) / 2 + 3rem);
    }
  }

  .sa-slider-track {
    position: relative;
    flex-grow: 1;
    overflow: hidden;
    border-radius: var(--sa-radius-round);
    background: var(--sa-color-surface-sunken);
    user-select: none;

    &[data-orientation="horizontal"] {
      width: 100%;
      height: var(--sa-unit);
    }
    &[data-orientation="vertical"] {
      width: var(--sa-unit);
      height: 100%;
    }
  }

  .sa-slider-range {
    position: absolute;
    background: var(--sa-color-accent-fill);
    user-select: none;

    &[data-orientation="horizontal"] {
      height: 100%;
    }
    &[data-orientation="vertical"] {
      width: 100%;
    }
  }

  .sa-slider-thumb {
    position: absolute;
    display: block;
    flex-shrink: 0;
    width: var(--_slider-thumb-size);
    height: var(--_slider-thumb-size);
    border: var(--sa-border-width) solid var(--sa-color-accent-fill);
    border-radius: var(--sa-radius-round);
    background: var(--_slider-thumb-bg);
    box-shadow: var(--sa-shadow-control);
    outline: none;
    user-select: none;
    transition:
      color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    /* A larger hit area than the thumb draws. */
    &::after {
      content: "";
      position: absolute;
      inset: calc(-2 * var(--sa-unit));
    }
    &:is(:hover, :focus-visible, :active) {
      box-shadow: var(--sa-shadow-control), var(--sa-focus-shadow);
    }
  }

  .sa-slider-marks {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .sa-slider-mark {
    position: absolute;
    width: 0;
    height: 0;
    &[data-orientation="horizontal"] {
      top: 50%;
    }
    &[data-orientation="vertical"] {
      left: 50%;
    }
  }
  .sa-slider-mark-tick {
    position: absolute;
    width: 2px;
    height: calc(2.5 * var(--sa-unit));
    border-radius: var(--sa-radius-round);
    background: color-mix(in oklab, var(--sa-color-ink-muted) 35%, transparent);
    translate: -50% -50%;

    [data-orientation="vertical"] > & {
      width: calc(2.5 * var(--sa-unit));
      height: 2px;
    }
    [data-state="in-range"] > & {
      background: color-mix(in oklab, var(--sa-color-on-accent) 70%, transparent);
    }
  }
  /* Keyed to the mark, its parent: a field around the slider also carries data-orientation. */
  .sa-slider-mark-label {
    position: absolute;
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-xs);
    font-variant-numeric: tabular-nums;
    line-height: 1.3333;
    white-space: nowrap;

    [data-orientation="horizontal"] > & {
      top: calc(var(--_slider-thumb) / 2 + 0.25rem);
      translate: -50% 0;
    }
    [data-orientation="vertical"] > & {
      left: calc(var(--_slider-thumb) / 2 + 0.5rem);
      translate: 0 -50%;
    }
    /* Labels at the bounds align to the track's ends; edge-aligned thumbs inset the end marks by half
       a thumb. */
    [data-orientation="horizontal"][data-bound="min"] > & {
      translate: 0 0;
    }
    [data-orientation="horizontal"][data-bound="max"] > & {
      translate: -100% 0;
    }
    [data-orientation="vertical"][data-bound="min"] > & {
      translate: 0 -100%;
    }
    [data-orientation="vertical"][data-bound="max"] > & {
      translate: 0 0;
    }
    [data-thumb-alignment="edge"] [data-orientation="horizontal"][data-bound="min"] > & {
      margin-inline-start: calc(var(--_slider-thumb) / -2);
    }
    [data-thumb-alignment="edge"] [data-orientation="horizontal"][data-bound="max"] > & {
      margin-inline-start: calc(var(--_slider-thumb) / 2);
    }
    [data-thumb-alignment="edge"] [data-orientation="vertical"][data-bound="min"] > & {
      margin-top: calc(var(--_slider-thumb) / 2);
    }
    [data-thumb-alignment="edge"] [data-orientation="vertical"][data-bound="max"] > & {
      margin-top: calc(var(--_slider-thumb) / -2);
    }
  }

  .sa-slider-value {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
    font-variant-numeric: tabular-nums;
  }
  /* The value inside running text takes the text's font. */
  :where(p, [data-slot="field-description"]) .sa-slider-value {
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
    letter-spacing: inherit;
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-slider-thumb {
      transition-duration: 0s;
    }
  }
}

/* components/spinner.css */
/* Spinner: the loading icon, turning. Its colour is the text colour; authors size it with size-*.
   Replaces: .sa-spinner */

@layer sa.components {
  .sa-spinner {
    flex-shrink: 0;
    width: var(--sa-control-icon);
    height: var(--sa-control-icon);
    animation: sa-spinner-spin 1s linear infinite;
  }
  /* A spinner still has to show that something is happening, so reduced motion slows it down. */
  @media (prefers-reduced-motion: reduce) {
    .sa-spinner {
      animation-duration: calc(1s * 3);
    }
  }
}

@keyframes sa-spinner-spin {
  to {
    transform: rotate(360deg);
  }
}

/* components/stack.css */
/* Stack: <sa-stack>, a column of items with a gap from a five-step scale, alignment and justification.
   Replaces: .sa-stack, .sa-stack-align-center, .sa-stack-align-end, .sa-stack-align-start,
   .sa-stack-align-stretch, .sa-stack-gap-xs, .sa-stack-gap-sm, .sa-stack-gap-md, .sa-stack-gap-lg,
   .sa-stack-gap-xl, .sa-stack-justify-around, .sa-stack-justify-between, .sa-stack-justify-center,
   .sa-stack-justify-end, .sa-stack-justify-start */

@layer sa.components {
  .sa-stack {
    display: flex;
    flex-direction: column;
  }
  .sa-stack-gap-xs { row-gap: calc(1 * var(--sa-unit)); }
  .sa-stack-gap-sm { row-gap: calc(2 * var(--sa-unit)); }
  .sa-stack-gap-md { row-gap: calc(4 * var(--sa-unit)); }
  .sa-stack-gap-lg { row-gap: calc(5 * var(--sa-unit)); }
  .sa-stack-gap-xl { row-gap: calc(8 * var(--sa-unit)); }
  .sa-stack-align-start { align-items: flex-start; }
  .sa-stack-align-center { align-items: center; }
  .sa-stack-align-end { align-items: flex-end; }
  .sa-stack-align-stretch { align-items: stretch; }
  .sa-stack-justify-start { justify-content: flex-start; }
  .sa-stack-justify-center { justify-content: center; }
  .sa-stack-justify-end { justify-content: flex-end; }
  .sa-stack-justify-between { justify-content: space-between; }
  .sa-stack-justify-around { justify-content: space-around; }
}

/* components/switch.css */
/* Switch: a checkbox drawn as a track, with a sibling thumb, in a wrapper that carries the size.
   Replaces: .sa-switch, .sa-switch-thumb, .sa-switch-wrapper */

@layer sa.tokens {
  .sa-switch-wrapper {
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    /* Outlined, a grey thumb reads as off. */
    --_switch-thumb-bg: color-mix(
      in oklab,
      var(--sa-color-ink-muted) calc(var(--sa-outlines) * 100%),
      var(--sa-color-surface)
    );
  }
  .dark .sa-switch-wrapper {
    --_switch-thumb-bg: color-mix(
      in oklab,
      var(--sa-color-ink-muted) calc(var(--sa-outlines) * 100%),
      var(--sa-color-ink)
    );
  }
}

@layer sa.components {
  .sa-switch-wrapper {
    --_h: calc(var(--sa-control-h) * 0.575);
    --_w: calc(calc(var(--sa-control-h) * 0.575) * 1.75);
    --_bw: var(--sa-border-width);
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    &[data-size="sm"] {
      --_h: calc(calc(var(--sa-control-h) * 0.575) * 0.8);
      --_w: calc(calc(calc(var(--sa-control-h) * 0.575) * 1.75) * 0.8);
    }
  }
  .sa-switch {
    position: relative;
    flex-shrink: 0;
    width: var(--_w);
    height: var(--_h);
    margin: 0;
    appearance: none;
    border: var(--_bw) solid color-mix( in oklab, var(--sa-color-line) calc(var(--sa-outlines) * 100%), transparent );
    border-radius: var(--sa-radius-tag);
    background: color-mix( in oklab, var(--sa-color-surface-sunken) calc(var(--sa-outlines) * 100%), var(--sa-color-line-control) );
    box-shadow: inset 0 1px 2px rgb(0 0 0 / calc(0.18 * var(--_relief-press)));
    cursor: pointer;
    outline: none;
    transition:
      background-color var(--sa-motion-fast) var(--sa-motion-ease),
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);
    &:checked {
      border-color: color-mix( in oklab, oklch(from var(--sa-color-accent-fill) calc(l - 0.1) c h) calc(var(--sa-outlines) * 100%), transparent );
      background: var(--sa-color-accent-fill);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: inset 0 1px 2px rgb(0 0 0 / calc(0.18 * var(--_relief-press))), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: inset 0 1px 2px rgb(0 0 0 / calc(0.18 * var(--_relief-press))), var(--sa-invalid-shadow);
      &:focus-visible {
        box-shadow: inset 0 1px 2px rgb(0 0 0 / calc(0.18 * var(--_relief-press))), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      cursor: not-allowed;
    }
  }
  /* In a choice card (a field label around the field), the card shows focus instead. */
  [data-slot="field-label"] .sa-switch:focus-visible {
    border-color: color-mix( in oklab, var(--sa-color-line) calc(var(--sa-outlines) * 100%), transparent );
    box-shadow: inset 0 1px 2px rgb(0 0 0 / calc(0.18 * var(--_relief-press)));
    &:checked {
      border-color: color-mix( in oklab, oklch(from var(--sa-color-accent-fill) calc(l - 0.1) c h) calc(var(--sa-outlines) * 100%), transparent );
    }
  }
  .sa-switch-thumb {
    --_t: calc(var(--_h) - 2 * var(--_bw) - 2 * calc(2px * var(--sa-outlines)));
    position: absolute;
    top: 50%;
    left: calc(var(--_bw) + calc(2px * var(--sa-outlines)));
    width: var(--_t);
    height: var(--_t);
    border-radius: max(0px, calc(var(--sa-radius-tag) - var(--_bw) - calc(2px * var(--sa-outlines))));
    background: var(--_switch-thumb-bg);
    box-shadow: 0 0 #0000;
    pointer-events: none;
    translate: 0 -50%;
    transition:
      transform var(--sa-motion-fast) var(--sa-motion-ease),
      background-color var(--sa-motion-fast) var(--sa-motion-ease);
  }
  .sa-switch:checked ~ .sa-switch-thumb {
    background: var(--sa-color-on-accent);
    transform: translateX(calc(var(--_w) - var(--_h)));
  }
  .sa-switch:disabled,
  .sa-switch:disabled ~ .sa-switch-thumb {
    opacity: var(--sa-disabled-opacity);
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-switch,
    .sa-switch-thumb {
      transition-duration: 0s;
    }
  }
}

/* components/table.css */
/* Table: rows divided by lines, column heads on a band, an optional footer and caption, selected
   rows (sel-table-selection) and expandable row details (sel-table-row-details).
   Replaces: .sa-table-container, .sa-table, .sa-table-header, .sa-table-body, .sa-table-footer,
   .sa-table-row, .sa-table-head, .sa-table-cell, .sa-table-caption, .sa-table-row-details,
   .sa-table-row-detail, .sa-table-row-detail-cell, .sa-table-row-detail-reveal,
   .sa-table-row-detail-clip, .sa-table-row-detail-content, .sa-table-row-detail-toggle */

@layer sa.tokens {
  .sa-table-container,
  .sa-table {
    /* The two switches blend between plain heads and section labels on a band. */
    --_label: var(--sa-column-head-label);
  }
}

@layer sa.components {
  .sa-table-container {
    position: relative;
    width: 100%;
    overflow-x: auto;
    background: transparent;
  }
  .sa-table {
    width: 100%;
    caption-side: bottom;
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
  }
  .sa-table-header { background: color-mix(in oklab, var(--sa-color-surface-sunken) calc(var(--sa-column-head-fill) * 100%), transparent); }
  .sa-table-row {
    border-bottom: var(--sa-border-width) solid var(--sa-color-line);
    transition: background-color var(--sa-motion-fast) var(--sa-motion-ease);
  }
  .sa-table-body > .sa-table-row {
    &:last-child { border-bottom-width: 0; }
    &:hover { background: color-mix(in oklab, var(--sa-color-surface-sunken) 50%, transparent); }
    &[data-state="selected"] { background: var(--sa-color-selected); }
  }
  .sa-table-head {
    height: calc(10 * var(--sa-unit));
    padding: 0px var(--sa-space-cell-x);
    color: color-mix(in oklab, var(--sa-color-ink-muted) calc(var(--_label) * 100%), var(--sa-color-ink));
    font-family: var(--sa-column-head-font);
    font-size: calc(var(--sa-section-label-text) * var(--_label) + var(--sa-text-body) * (1 - var(--_label)));
    font-weight: calc(var(--sa-section-label-weight) * var(--_label) + var(--sa-weight-control) * (1 - var(--_label)));
    letter-spacing: calc(var(--sa-section-label-tracking) * var(--_label));
    text-align: left;
    text-transform: var(--sa-column-head-case);
    vertical-align: middle;
    white-space: nowrap;
    &:has([role="checkbox"]) { padding-inline-end: 0; }
  }
  .sa-table-cell {
    padding: var(--sa-space-cell-y) var(--sa-space-cell-x);
    vertical-align: middle;
    white-space: nowrap;
    &:has([role="checkbox"]) { padding-inline-end: 0; }
  }
  .sa-table-footer {
    border-top: var(--sa-border-width) solid var(--sa-color-line);
    background: var(--sa-color-surface-subtle);
    font-weight: var(--sa-weight-control);
    & > .sa-table-row:last-child { border-bottom-width: 0; }
  }
  .sa-table-caption {
    margin-top: calc(4 * var(--sa-unit));
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-sm);
  }

  /* Row details. sel-table-row-details publishes --sa-table-row-detail-width (the container's
     visible width) and --sa-table-row-detail-inset-start/-end (measured from the row's cells, so the
     content lines up with the cell padding); the fallbacks apply until the script runs. */
  .sa-table-row-details {
    display: block;

    /* An expanded row and its details read as one unit: no divider between them. */
    & tr:has(+ .sa-table-row-detail[data-state="open"]) {
      border-bottom-color: transparent;
    }
    /* A collapsed last detail row leaves its row as the visual last row. */
    & tbody > tr:has(+ .sa-table-row-detail[hidden]:last-child) {
      border-bottom-width: 0;
    }
    &[data-row-click="true"] tbody > tr:has(+ .sa-table-row-detail) {
      cursor: pointer;
    }
    &[data-emphasis="band"] :is(tr:has(+ .sa-table-row-detail[data-state="open"]), .sa-table-row-detail) {
      background: var(--sa-color-surface-sunken);
    }
    &[data-emphasis="rail"] :is(
      tr:has(+ .sa-table-row-detail[data-state="open"]) > :first-child,
      .sa-table-row-detail > .sa-table-row-detail-cell
    ) {
      box-shadow: inset 2px 0 0 var(--sa-color-accent-fill);
    }
  }
  .sa-table-row-detail {
    border-bottom: var(--sa-border-width) solid var(--sa-color-line);
    &:last-child { border-bottom-width: 0; }
  }
  .sa-table-row-detail-cell { padding: 0; }
  .sa-table-row-detail-reveal {
    /* Animating grid-template-rows from 0fr to 1fr reveals the content at its natural height,
       including content that htmx swaps in after the row opens. */
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows calc(var(--sa-motion-fast) * 4 / 3) ease-out;

    .sa-table-row-detail[data-state="open"] > .sa-table-row-detail-cell > & { grid-template-rows: 1fr; }
    .sa-table-row-details[data-animate="false"] & { transition: none; }
    @media (prefers-reduced-motion: reduce) { transition: none; }
  }
  .sa-table-row-detail-clip {
    /* clip, not hidden: hidden would make this box the sticky content's scroll container, so the
       content would no longer stay pinned while the table scrolls sideways. */
    min-height: 0;
    overflow: clip;
  }
  .sa-table-row-detail-content {
    /* Pinned to the visible width so the details stay in view when the table scrolls sideways. */
    position: sticky;
    inset-inline-start: 0;
    width: var(--sa-table-row-detail-width, 100%);
    padding-block: calc(2 * var(--sa-unit)) calc(5 * var(--sa-unit));
    padding-inline: var(--sa-table-row-detail-inset-start, var(--sa-space-cell-x))
      var(--sa-table-row-detail-inset-end, var(--sa-space-cell-x));
    white-space: normal;
  }
  /* The toggle is a ghost button (button.css); these out-rank its rules by selector. */
  .sa-button.sa-table-row-detail-toggle {
    & > svg { transition: rotate var(--sa-motion-fast) var(--sa-motion-ease); }
    &[aria-expanded="true"] > svg { rotate: 90deg; }
    /* The rotated chevron shows the state; drop the fill ghost buttons get when expanded. */
    &[aria-expanded="true"]:not(:hover) { background-color: transparent; }
    .sa-table-row-details[data-animate="false"] & > svg { transition: none; }
    @media (prefers-reduced-motion: reduce) {
      & > svg { transition: none; }
    }
  }
}

/* components/tabs.css */
/* Tabs: <sa-tab-list> (a tab list of links, default or line variant, horizontal or vertical).
   Replaces: .sa-tabs, .sa-tabs-list, .sa-tabs-list-variant-default, .sa-tabs-list-variant-line,
   .sa-tabs-trigger */

@layer sa.tokens {
  .sa-tabs {
    --_tabs-trigger-fg: color-mix(in oklab, var(--sa-color-ink) 66%, transparent);   /* 4.5:1 on the darkest band */
    --_tabs-selected-bg: var(--sa-color-surface);
    --_tabs-selected-border: transparent;
  }
  .dark .sa-tabs {
    --_tabs-trigger-fg: var(--sa-color-ink-muted);
    --_tabs-selected-bg: var(--sa-color-field);
    --_tabs-selected-border: var(--sa-color-line-control);
  }
}

@layer sa.components {
  .sa-tabs {
    display: flex;
    gap: calc(2 * var(--sa-unit));
    &[data-orientation="horizontal"] { flex-direction: column; }
  }

  .sa-tabs-list {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0px;
    width: fit-content;
    /* The padding is measured from the outer edge, so a list border does not shrink the triggers' inset. */
    padding: max(0px, calc(3px - var(--sa-border-width)));
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-control);
    background: var(--sa-color-tint);
    color: var(--_tabs-trigger-fg);
    .sa-tabs[data-orientation="horizontal"] > & { height: var(--sa-control-h); }
    .sa-tabs[data-orientation="vertical"] > & { flex-direction: column; height: fit-content; }
  }

  .sa-tabs-trigger {
    position: relative;
    display: inline-flex;
    flex: 1;
    align-items: center;
    justify-content: center;
    gap: calc(1.5 * var(--sa-unit));
    height: calc(100% - 1px);
    padding: calc(0.5 * var(--sa-unit)) calc(1.5 * var(--sa-unit));
    border: var(--sa-border-width) solid transparent;
    border-radius: var(--sa-radius-item);
    color: var(--_tabs-trigger-fg);
    font-size: var(--sa-text-control);
    font-weight: var(--sa-weight-control);
    line-height: var(--sa-leading-ui);
    white-space: nowrap;
    outline: none;
    transition-property: color, background-color, border-color, box-shadow;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);

    & svg { flex-shrink: 0; pointer-events: none; }
    & svg:not([class*="size-"]) { width: var(--sa-control-icon); height: var(--sa-control-icon); }
    &:has(> [data-icon="inline-start"]) { padding-inline-start: calc(1 * var(--sa-unit)); }
    &:has(> [data-icon="inline-end"]) { padding-inline-end: calc(1 * var(--sa-unit)); }
    &:hover { color: var(--sa-color-ink); background: transparent; }
    &[data-active] {
      border-color: var(--_tabs-selected-border);
      background: var(--_tabs-selected-bg);
      box-shadow: var(--sa-shadow-raised);
      color: var(--sa-color-ink);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
    &[aria-disabled="true"], &:disabled { opacity: var(--sa-disabled-opacity); pointer-events: none; }
    &[data-disabled] { cursor: not-allowed; }
    .sa-tabs[data-orientation="vertical"] & { justify-content: flex-start; width: 100%; }

    /* The line variant's indicator. */
    &::after {
      content: "";
      position: absolute;
      background: var(--sa-color-ink);
      opacity: 0;
      transition: opacity var(--sa-motion-fast) var(--sa-motion-ease);
    }
  }
  /* Not nested in ::after: a nested rule cannot follow a pseudo-element. */
  .sa-tabs[data-orientation="horizontal"] .sa-tabs-trigger::after {
    inset-inline: 0;
    bottom: -5px;
    height: 2px;
  }
  .sa-tabs[data-orientation="vertical"] .sa-tabs-trigger::after {
    inset-block: 0;
    right: calc(-1 * var(--sa-unit));
    width: 2px;
  }

  .sa-tabs-list-variant-line {
    gap: calc(1 * var(--sa-unit));
    border-color: transparent;
    border-radius: 0;
    background: transparent;
    .sa-tabs[data-orientation="horizontal"] > & { border-bottom-color: transparent; }
    .sa-tabs[data-orientation="vertical"] > & { border-inline-end-color: transparent; }

    & .sa-tabs-trigger {
      padding: calc(0.5 * var(--sa-unit)) calc(1.5 * var(--sa-unit)) calc(0.5 * var(--sa-unit));
      border-width: var(--sa-border-width);
      background: transparent;
      font-size: var(--sa-text-control);
      font-weight: var(--sa-weight-control);
      &:has(> [data-icon="inline-start"]) { padding-inline-start: calc(1 * var(--sa-unit)); }
      &:has(> [data-icon="inline-end"]) { padding-inline-end: calc(1 * var(--sa-unit)); }
    }
    & .sa-tabs-trigger[data-active] {
      border-color: transparent;
      background: transparent;
      box-shadow: none;
      color: var(--sa-color-ink);
      font-weight: var(--sa-weight-control);
      &::after { opacity: 1; }
    }
    & .sa-tabs-trigger:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-focus-shadow);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-tabs-trigger, .sa-tabs-trigger::after { transition-duration: 0s; }
  }
}

/* components/textarea.css */
/* Textarea: a multi-line field drawn like the input, growing with its content from a minimum height.
   Replaces: .sa-textarea */

@layer sa.tokens {
  .sa-textarea {
    /* Recessed when tactile (--sa-relief 2), as the input; dark mode weights the inset more. */
    --_relief-press: clamp(0, calc(var(--sa-relief) - 1), 1);
    --_relief-k: 1;
    --_textarea-shadow: var(--sa-shadow-control),
      inset 0 1px 1px rgb(0 0 0 / calc(0.05 * var(--_relief-press) * var(--_relief-k)));
  }
  .dark .sa-textarea {
    --_relief-k: 4;
  }
}

@layer sa.components {
  .sa-textarea {
    display: flex;
    width: 100%;
    min-height: calc(16 * var(--sa-unit));
    field-sizing: content;
    padding: calc(2 * var(--sa-unit)) var(--sa-control-px);
    border: var(--sa-border-width) solid var(--sa-color-line-control);
    border-radius: var(--sa-radius-box);
    background: var(--sa-color-field);
    background-clip: padding-box;
    box-shadow: var(--_textarea-shadow);
    color: var(--sa-color-ink);
    font-size: var(--sa-text-control);
    line-height: var(--sa-leading-ui);
    outline: none;
    transition:
      border-color var(--sa-motion-fast) var(--sa-motion-ease),
      box-shadow var(--sa-motion-fast) var(--sa-motion-ease);

    &::placeholder {
      color: var(--sa-color-ink-placeholder);
    }
    &:hover:not(:disabled, :focus-visible) {
      border-color: var(--sa-color-line-control-hover);
    }
    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_textarea-shadow), var(--sa-focus-shadow-field);
    }
    &:is([aria-invalid="true"], .input-validation-error) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_textarea-shadow), var(--sa-invalid-shadow);
      &:focus-visible {
        box-shadow: var(--_textarea-shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:disabled {
      background: var(--sa-color-field-disabled);
      opacity: var(--sa-disabled-opacity);
      cursor: not-allowed;
    }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-textarea {
      transition-duration: 0s;
    }
  }
}

/* components/toaster.css */
/* Toaster: the toast viewport, the stacked toasts and their contents. sel-toaster reproduces Base UI's
   Toast state contract, so the stacking, swipe and enter/exit rules follow upstream: data-expanded,
   data-behind, data-limited, data-starting-style, data-ending-style and data-swipe-direction on the
   elements, and --toast-index, --toast-height, --toast-offset-y, --toast-swipe-movement-x/-y and (on
   the viewport) --toast-frontmost-height as inputs. Upstream only anchors to the bottom; top positions
   mirror the stack.
   Replaces: .sa-toast-viewport, .sa-toast, .sa-toast-content, .sa-toast-icon, .sa-toast-text,
   .sa-toast-title, .sa-toast-description, .sa-toast-action, .sa-toast-close */

@layer sa.components {
  /* A manual popover: reset the popover's UA inset, margin, border, padding, background and overflow. */
  .sa-toast-viewport {
    --_inset: calc(4 * var(--sa-unit));
    position: fixed;
    inset: auto var(--_inset);
    z-index: 50;
    width: auto;
    max-width: 24rem;
    margin: 0 auto;
    padding: 0;
    overflow: visible;
    border: 0;
    background: transparent;
    color: inherit;
    outline: none;
    pointer-events: none;
    &[data-position^="bottom"] { top: auto; bottom: var(--_inset); }
    &[data-position^="top"] { top: var(--_inset); bottom: auto; }
    @media (width >= 40rem) {
      width: 100%;
      &[data-position$="left"] { right: auto; left: var(--_inset); margin-inline: 0; }
      &[data-position$="right"] { right: var(--_inset); left: auto; margin-inline: 0; }
    }
  }

  .sa-toast {
    --_stack-gap: calc(3 * var(--sa-unit));
    --_peek: calc(3 * var(--sa-unit));
    --_height: var(--toast-frontmost-height, var(--toast-height));
    --_offset-y: calc(var(--toast-offset-y) * -1 - var(--toast-index) * var(--_stack-gap) + var(--toast-swipe-movement-y));
    --_scale: max(0, 1 - var(--toast-index) * 0.1);
    --_shrink: calc(1 - var(--_scale));
    position: absolute;
    right: 0;
    bottom: 0;
    z-index: calc(1000 - var(--toast-index));
    width: 100%;
    max-width: 24rem;
    height: var(--_height);
    border: var(--sa-border-width) solid var(--sa-color-line);
    border-radius: var(--sa-radius-container);
    background: var(--sa-color-surface-raised);
    background-clip: padding-box;
    box-shadow: var(--sa-shadow-overlay);
    color: var(--sa-color-ink);
    outline: none;
    pointer-events: auto;
    user-select: none;
    transform-origin: bottom;
    will-change: transform;
    transform: translateX(var(--toast-swipe-movement-x))
      translateY(calc(var(--toast-swipe-movement-y) - var(--toast-index) * var(--_peek) - var(--_shrink) * var(--_height)))
      scale(var(--_scale));
    transition:
      transform 500ms cubic-bezier(0.22, 1, 0.36, 1),
      opacity 500ms,
      height var(--sa-motion-fast);

    &:focus-visible {
      border-color: var(--sa-focus-border);
      box-shadow: var(--sa-shadow-overlay), var(--sa-focus-shadow);
    }
    /* Bridges the gap between expanded toasts, so moving the pointer across it keeps the stack
       expanded. */
    &::after {
      content: "";
      position: absolute;
      top: 100%;
      left: 0;
      width: 100%;
      height: calc(var(--_stack-gap) + 1px);
    }
    &[data-expanded] {
      height: var(--toast-height);
      transform: translateX(var(--toast-swipe-movement-x)) translateY(var(--_offset-y));
    }
    &[data-limited] {
      opacity: 0;
    }
    &[data-starting-style],
    &[data-ending-style]:not([data-limited]):not([data-swipe-direction]) {
      transform: translateY(150%);
    }
    &[data-ending-style][data-swipe-direction="down"] {
      transform: translateY(calc(var(--toast-swipe-movement-y) + 150%));
    }
    &[data-ending-style][data-swipe-direction="up"] {
      transform: translateY(calc(var(--toast-swipe-movement-y) - 150%));
    }
    &[data-ending-style][data-swipe-direction="left"] {
      transform: translateX(calc(var(--toast-swipe-movement-x) - 150%)) translateY(var(--_offset-y));
    }
    &[data-ending-style][data-swipe-direction="right"] {
      transform: translateX(calc(var(--toast-swipe-movement-x) + 150%)) translateY(var(--_offset-y));
    }

    .sa-toast-viewport[data-position^="top"] & {
      --_offset-y: calc(var(--toast-offset-y) + var(--toast-index) * var(--_stack-gap) + var(--toast-swipe-movement-y));
      top: 0;
      bottom: auto;
      transform-origin: top;
      transform: translateX(var(--toast-swipe-movement-x))
        translateY(calc(var(--toast-swipe-movement-y) + var(--toast-index) * var(--_peek) + var(--_shrink) * var(--_height)))
        scale(var(--_scale));

      &::after {
        top: auto;
        bottom: 100%;
      }
      &[data-expanded] {
        transform: translateX(var(--toast-swipe-movement-x)) translateY(var(--_offset-y));
      }
      &[data-starting-style],
      &[data-ending-style]:not([data-limited]):not([data-swipe-direction]) {
        transform: translateY(-150%);
      }
      &[data-ending-style][data-swipe-direction="up"] {
        transform: translateY(calc(var(--toast-swipe-movement-y) - 150%));
      }
      &[data-ending-style][data-swipe-direction="left"] {
        transform: translateX(calc(var(--toast-swipe-movement-x) - 150%)) translateY(var(--_offset-y));
      }
      &[data-ending-style][data-swipe-direction="right"] {
        transform: translateX(calc(var(--toast-swipe-movement-x) + 150%)) translateY(var(--_offset-y));
      }
    }

    @media (prefers-reduced-motion: reduce) {
      transition-property: opacity;
    }
  }

  .sa-toast-content {
    display: flex;
    align-items: center;
    gap: calc(3 * var(--sa-unit));
    height: 100%;
    padding: calc(4 * var(--sa-unit));
    overflow: hidden;
    transition: opacity 250ms cubic-bezier(0.22, 1, 0.36, 1);
    &[data-behind] { opacity: 0; }
    &[data-expanded] { opacity: 1; }
  }
  .sa-toast-icon {
    display: flex;
    flex-shrink: 0;
    & svg {
      pointer-events: none;
    }
    & svg:not([class*="size-"]) {
      width: 1rem;
      height: 1rem;
    }
    & > [data-toast-icon="success"] { color: var(--sa-color-success); }
    & > [data-toast-icon="info"] { color: var(--sa-color-info); }
    & > [data-toast-icon="warning"] { color: var(--sa-color-warning); }
    & > [data-toast-icon="error"] { color: var(--sa-color-danger); }
    & > [data-toast-icon="loading"] {
      color: var(--sa-color-ink-muted);
      animation: sa-toast-spin 1s linear infinite;
    }
  }
  .sa-toast-text {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: var(--sa-unit);
    min-width: 0;
  }
  .sa-toast-title {
    font-size: var(--sa-text-body);
    font-weight: 500;
    line-height: var(--sa-leading-ui);
  }
  .sa-toast-description {
    color: var(--sa-color-ink-muted);
    font-size: var(--sa-text-body);
    line-height: var(--sa-leading-ui);
  }
  .sa-toast-action {
    flex-shrink: 0;
  }
  /* A ghost button: out-ranks the variant to set its private colours. */
  .sa-button.sa-toast-close {
    --_fg: var(--sa-color-ink-muted);
    --_fg-hover: var(--sa-color-ink);
    position: relative;
    flex-shrink: 0;
    /* A larger hit area than the icon button. */
    &::after {
      content: "";
      position: absolute;
      inset: calc(-2 * var(--sa-unit));
    }
  }

  @keyframes sa-toast-spin {
    to { rotate: 360deg; }
  }
  @media (prefers-reduced-motion: reduce) {
    .sa-toast-icon > [data-toast-icon="loading"] {
      animation-duration: 3s;
    }
  }
}

/* components/toggle-group.css */
/* Toggle group: toggles (toggle.css) in a row or column, spaced by the group's --gap (in density units)
   or, at spacing 0, joined with shared edges and only the outer corners rounded.
   Replaces: .sa-toggle-group, .sa-toggle-group-item */

@layer sa.components {
  .sa-toggle-group {
    display: inline-flex;
    width: fit-content;
    border-radius: var(--sa-radius-control);

    &[data-orientation="horizontal"] {
      align-items: center;
    }
    &[data-orientation="vertical"] {
      flex-direction: column;
      align-items: stretch;
    }
    &:not([data-spacing="0"]) {
      gap: calc(var(--gap, 0) * var(--sa-unit));
    }
  }

  .sa-toggle.sa-toggle-group-item {
    position: relative;
    &:has(> input:checked) {
      z-index: 1;
    }
    &:has(> input:focus-visible) {
      z-index: 10;
    }
  }

  /* Joined: neighbours overlap by one border, so they share a line. */
  .sa-toggle-group[data-spacing="0"] > .sa-toggle.sa-toggle-group-item {
    --_px: calc(2 * var(--sa-unit));
    border-radius: 0;
  }
  .sa-toggle-group[data-spacing="0"][data-orientation="horizontal"] > .sa-toggle-group-item {
    & + .sa-toggle-group-item {
      margin-inline-start: calc(-1 * var(--sa-border-width));
    }
    &:first-of-type {
      border-start-start-radius: var(--sa-radius-control);
      border-end-start-radius: var(--sa-radius-control);
    }
    &:last-of-type {
      border-start-end-radius: var(--sa-radius-control);
      border-end-end-radius: var(--sa-radius-control);
    }
  }
  .sa-toggle-group[data-spacing="0"][data-orientation="vertical"] > .sa-toggle-group-item {
    & + .sa-toggle-group-item {
      margin-top: calc(-1 * var(--sa-border-width));
    }
    &:first-of-type {
      border-start-start-radius: var(--sa-radius-control);
      border-start-end-radius: var(--sa-radius-control);
    }
    &:last-of-type {
      border-end-start-radius: var(--sa-radius-control);
      border-end-end-radius: var(--sa-radius-control);
    }
  }
}

/* components/toggle.css */
/* Toggle: a two-state button, a label around a visually hidden checkbox (or radio, in a toggle group),
   so its states come from the input (:checked, :focus-visible, :disabled, aria-invalid).
   Replaces: .sa-toggle, .sa-toggle-variant-default, .sa-toggle-variant-outline,
   .sa-toggle-size-default, .sa-toggle-size-sm, .sa-toggle-size-lg */

@layer sa.tokens {
  .sa-toggle {
    /* Outline: the field fill and control lines in dark mode. */
    --_toggle-outline-bg: var(--sa-color-surface);
    --_toggle-outline-border: var(--sa-color-line);
    --_toggle-outline-on-border: var(--sa-color-line-control);
  }
  .dark .sa-toggle {
    --_toggle-outline-bg: var(--sa-color-field);
    --_toggle-outline-border: var(--sa-color-line-control);
    --_toggle-outline-on-border: var(--sa-color-line-control-hover);
  }
}

@layer sa.components {
  .sa-toggle {
    --_h: var(--sa-control-h);
    --_px: var(--sa-control-px);
    --_radius: var(--sa-radius-control);
    --_text: var(--sa-text-control);
    --_icon: var(--sa-control-icon);
    --_bg: transparent;
    --_border: transparent;
    --_shadow: 0 0 #0000;
    --_on-border: transparent;

    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: var(--sa-unit);
    min-width: var(--_h);
    height: var(--_h);
    padding-inline: var(--_px);
    border: var(--sa-border-width) solid var(--_border);
    border-radius: var(--_radius);
    background: var(--_bg);
    background-clip: padding-box;
    box-shadow: var(--_shadow);
    color: var(--sa-color-ink);
    font-size: var(--_text);
    font-weight: var(--sa-weight-control);
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    outline: none;
    user-select: none;
    transition-property: background-color, border-color, color, box-shadow;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);

    & svg {
      flex-shrink: 0;
      pointer-events: none;
    }
    & svg:not([class*="size-"]) {
      width: var(--_icon);
      height: var(--_icon);
    }
    &:has(> [data-icon="inline-start"]) {
      padding-inline-start: calc(var(--_px) - 0.5 * var(--sa-unit));
    }
    &:has(> [data-icon="inline-end"]) {
      padding-inline-end: calc(var(--_px) - 0.5 * var(--sa-unit));
    }
    &:hover {
      background-color: var(--sa-color-hover);
    }
    &:has(> input:checked) {
      border-color: var(--_on-border);
      background-color: var(--sa-color-selected);
      color: var(--sa-color-ink);
      &:hover {
        background-color: color-mix(in oklab, var(--sa-color-selected), var(--sa-color-ink) 5%);
      }
    }
    &:has(> input:focus-visible) {
      border-color: var(--sa-focus-border);
      box-shadow: var(--_shadow), var(--sa-focus-shadow);
    }
    &:has(> input:is([aria-invalid="true"], .input-validation-error)) {
      border-color: var(--sa-color-danger);
      box-shadow: var(--_shadow), var(--sa-invalid-shadow);
      &:has(> input:focus-visible) {
        box-shadow: var(--_shadow), var(--sa-invalid-focus-shadow);
      }
    }
    &:has(> input:disabled) {
      opacity: var(--sa-disabled-opacity);
      cursor: not-allowed;
      pointer-events: none;
    }
  }

  /* The plain toggle draws no edge, so it is as wide as its content (Nova's sizes). */
  .sa-toggle-variant-default {
    border-width: 0;
  }
  .sa-toggle-variant-outline {
    --_bg: var(--_toggle-outline-bg);
    --_border: var(--_toggle-outline-border);
    --_shadow: var(--sa-shadow-control);
    --_on-border: var(--_toggle-outline-on-border);
  }

  .sa-toggle-size-sm {
    --_h: var(--sa-control-h-sm);
    --_px: var(--sa-control-px);
    --_radius: var(--sa-radius-control-sm);
    --_text: min(var(--sa-text-control), 0.8rem);
    --_icon: 0.875rem;
    &:has(> [data-icon="inline-start"]) {
      padding-inline-start: calc(var(--_px) - var(--sa-unit));
    }
    &:has(> [data-icon="inline-end"]) {
      padding-inline-end: calc(var(--_px) - var(--sa-unit));
    }
  }
  .sa-toggle-size-lg {
    --_h: var(--sa-control-h-lg);
    --_px: var(--sa-control-px);
  }

  @media (prefers-reduced-motion: reduce) {
    .sa-toggle {
      transition-duration: 0s;
    }
  }
}

/* components/tooltip.css */
/* Tooltip: a short hint popover anchored to its trigger, drawn in the page's inverse colours.
   Replaces: .sa-tooltip-content, .sa-tooltip-content-logical, .sa-tooltip-arrow, .sa-tooltip-arrow-logical */

@layer sa.tokens {
  .sa-tooltip-content {
    --_tooltip-kbd-bg: color-mix(in oklab, var(--sa-color-surface) 20%, transparent);
  }
  .dark .sa-tooltip-content {
    --_tooltip-kbd-bg: color-mix(in oklab, var(--sa-color-surface) 10%, transparent);
  }
}

@layer sa.components {
  /* Anchored to its trigger (anchors.css places it; the gap comes from the [data-anchor-side]
     rules in components.css). */
  .sa-tooltip-content {
    inset: auto;
    width: fit-content;
    max-width: 20rem;
    margin: 0;
    padding: calc(1.5 * var(--sa-unit)) calc(3 * var(--sa-unit));
    border: 0;
    border-radius: var(--sa-radius-control-sm);
    background: var(--sa-color-ink);
    box-shadow: var(--sa-shadow-control);
    color: var(--sa-color-surface);
    font-size: var(--sa-text-xs);
    line-height: calc(4 / 3);
    position-try-fallbacks: flip-block, flip-inline, flip-block flip-inline;
    opacity: 1;
    transition-property: opacity, display, overlay;
    transition-duration: var(--sa-motion-fast);
    transition-timing-function: var(--sa-motion-ease);
    transition-behavior: allow-discrete;

    &:not(:popover-open) { opacity: 0; }
    @starting-style {
      &:popover-open { opacity: 0; }
    }
    @media (prefers-reduced-motion: reduce) {
      transition: none;
    }

    /* A keyboard shortcut sits closer to the end. */
    &:has([data-slot="kbd"]) { padding-inline-end: calc(1.5 * var(--sa-unit)); }
    & [data-slot="kbd"] {
      position: relative;
      isolation: isolate;
      z-index: 50;
      --_bg: var(--_tooltip-kbd-bg);
      --_fg: var(--sa-color-surface);
      --_border: transparent;
      border-radius: var(--sa-radius-inner);
    }
  }
}
