/*! mica — custom elements, native behavior, nearly no JavaScript. */

/* Layer order. User's unlayered CSS always wins over all of it. */
@layer mica.tokens, mica.preset, mica.elements, mica.layout;

/* ------------------------------------------------------------------ *
 * Tokens — mica's only opinion. Spacing and size scales.
 * ------------------------------------------------------------------ */
@layer mica.tokens {
  :root {
    --space-2xs: 0.25rem;
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2.5rem;
    --space-2xl: 4rem;

    --size-xs: 10rem;
    --size-sm: 15rem;
    --size-md: 20rem;
    --size-lg: 30rem;
    --size-xl: 40rem;

    --measure: 60ch;

    --font-body: system-ui, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    --line-height: 1.5;

    /* type scale — UI-centered: md is the interface default (14px),
       lg matches the 16px field floor. The floor itself stays a literal
       1rem where it's enforced (iOS zooms on smaller field text), so a
       theme shrinking the scale can't break it. em-relative sizes
       (code, kbd) stay relative and don't use the scale. */
    --text-2xs: 0.6875rem;
    --text-xs: 0.75rem;
    --text-sm: 0.8125rem;
    --text-md: 0.875rem;
    --text-lg: 1rem;
    --text-xl: 1.5rem;

    /* square is the design language; rounding back on is a theme:
       :root { --radius-sm: .25rem; --radius-md: .375rem; --radius-lg: .75rem } */
    --radius-sm: 0px;
    --radius-md: 0px;
    --radius-lg: 0px;
    --radius-full: 9999px;

    /* control heights, shadcn scale: sm 32 / md 36 / lg 40 */
    --control-height-sm: 2rem;
    --control-height: 2.25rem;
    --control-height-lg: 2.5rem;

    /* Where toasts pin. App-level config — set once, all toasts obey:
       bottom-right (default) | bottom-left | bottom-center |
       top-right | top-left | top-center.
       Read via container style queries (Baseline newly-available
       2026-05); browsers without them keep the bottom-right default. */
    --toast-position: bottom-right;

    /* Standard scrollbars; native rendering is an inherited theme override:
       :root { --scrollbar-color: auto; --scrollbar-width: auto; }
       Unsupported properties are ignored, retaining the browser scrollbar. */
    --scrollbar-color: var(--color-text-muted) transparent;
    --scrollbar-width: thin;

    --focus-ring-width: 2px;
    --focus-ring-offset: 2px;
    --focus-ring-color: var(--color-accent);

    /* checkmark glyph — SVG URIs can't read custom properties, and
       light-dark() only accepts <color>s: feeding it url()s is invalid
       (Chromium computes it to none; iOS Safari drops the glyph at
       paint). So: light glyph by default, dark swapped in by the media
       query after this block. The pair tracks on-primary (white /
       near-black, since primary inverts in dark).
       Forcing a scheme against the OS? Also pin the glyph:
         :root { color-scheme: dark; --check-glyph: var(--check-glyph-dark); } */
    --check-glyph-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
    --check-glyph-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23151922' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' d='M3.5 8.5l3 3 6-7'/%3E%3C/svg%3E");
    --check-glyph: var(--check-glyph-light);

    /* -------------------------------------------------------------- *
     * Color. Two knobs — change the theme by changing the knobs:
     *   --hue: the accent hue (OKLCH degrees)
     *   --chroma: accent intensity
     * Neutrals are faintly tinted toward the accent hue.
     * Components only ever use semantic roles, never raw values.
     * -------------------------------------------------------------- */
    color-scheme: light dark;

    --hue: 263;
    --chroma: 0.21;
    --neutral-chroma: 0;

    /* status hues — knobs, same as the brand hue. statuses deliberately
       do NOT ride --chroma: danger must stay urgent in a muted theme. */
    --danger-hue: 25;
    --success-hue: 150;
    --warn-hue: 48; /* orange — amber reads as mud at solid lightness */
    --status-chroma: 0.18;

    /* Numbered scales — theme-relative (Radix convention): a step means
       the same *thing* in both modes. 1 = app bg … 6–8 = borders …
       9 = solid … 12 = high-contrast text. light-dark() is baked into
       every step, so code written against steps gets dark mode free. */
    --neutral-1:  light-dark(oklch(100%  var(--neutral-chroma) var(--hue)), oklch(14% var(--neutral-chroma) var(--hue)));
    --neutral-2:  light-dark(oklch(97.3% var(--neutral-chroma) var(--hue)), oklch(17% var(--neutral-chroma) var(--hue)));
    --neutral-3:  light-dark(oklch(95.2% var(--neutral-chroma) var(--hue)), oklch(20% var(--neutral-chroma) var(--hue)));
    --neutral-4:  light-dark(oklch(93%   var(--neutral-chroma) var(--hue)), oklch(23% var(--neutral-chroma) var(--hue)));
    --neutral-5:  light-dark(oklch(91%   var(--neutral-chroma) var(--hue)), oklch(26% var(--neutral-chroma) var(--hue)));
    --neutral-6:  light-dark(oklch(89%   var(--neutral-chroma) var(--hue)), oklch(30% var(--neutral-chroma) var(--hue)));
    --neutral-7:  light-dark(oklch(82%   var(--neutral-chroma) var(--hue)), oklch(37% var(--neutral-chroma) var(--hue)));
    --neutral-8:  light-dark(oklch(74%   var(--neutral-chroma) var(--hue)), oklch(46% var(--neutral-chroma) var(--hue)));
    --neutral-9:  light-dark(oklch(55%   var(--neutral-chroma) var(--hue)), oklch(58% var(--neutral-chroma) var(--hue)));
    --neutral-10: light-dark(oklch(50%   var(--neutral-chroma) var(--hue)), oklch(64% var(--neutral-chroma) var(--hue)));
    --neutral-11: light-dark(oklch(44%   var(--neutral-chroma) var(--hue)), oklch(71% var(--neutral-chroma) var(--hue)));
    --neutral-12: light-dark(oklch(18%   var(--neutral-chroma) var(--hue)), oklch(96% var(--neutral-chroma) var(--hue)));

    /* accent scale: chroma tapers at the extremes, peaks at the solid */
    --accent-1:  light-dark(oklch(99%   calc(var(--chroma) * 0.1) var(--hue)), oklch(19% calc(var(--chroma) * 0.15) var(--hue)));
    --accent-2:  light-dark(oklch(97.5% calc(var(--chroma) * 0.15) var(--hue)), oklch(23% calc(var(--chroma) * 0.2) var(--hue)));
    --accent-3:  light-dark(oklch(95%   calc(var(--chroma) * 0.25) var(--hue)), oklch(27% calc(var(--chroma) * 0.35) var(--hue)));
    --accent-4:  light-dark(oklch(92%   calc(var(--chroma) * 0.35) var(--hue)), oklch(31% calc(var(--chroma) * 0.5) var(--hue)));
    --accent-5:  light-dark(oklch(89%   calc(var(--chroma) * 0.45) var(--hue)), oklch(35% calc(var(--chroma) * 0.6) var(--hue)));
    --accent-6:  light-dark(oklch(85%   calc(var(--chroma) * 0.55) var(--hue)), oklch(39% calc(var(--chroma) * 0.7) var(--hue)));
    --accent-7:  light-dark(oklch(79%   calc(var(--chroma) * 0.65) var(--hue)), oklch(46% calc(var(--chroma) * 0.8) var(--hue)));
    --accent-8:  light-dark(oklch(71%   calc(var(--chroma) * 0.8) var(--hue)), oklch(58% calc(var(--chroma) * 0.9) var(--hue)));
    --accent-9:  light-dark(oklch(55%   var(--chroma) var(--hue)), oklch(70% var(--chroma) var(--hue)));
    --accent-10: light-dark(oklch(50%   var(--chroma) var(--hue)), oklch(75% var(--chroma) var(--hue)));
    --accent-11: light-dark(oklch(46%   calc(var(--chroma) * 0.9) var(--hue)), oklch(80% calc(var(--chroma) * 0.9) var(--hue)));
    --accent-12: light-dark(oklch(24%   calc(var(--chroma) * 0.5) var(--hue)), oklch(94% calc(var(--chroma) * 0.3) var(--hue)));

    /* Semantic roles — what components actually use. Defined in terms
       of scale steps: knobs → scales → roles. */
    --color-surface: var(--neutral-1);
    --color-surface-raised: var(--neutral-2);
    /* top-layer panels (dialog, menus, toasts): white in light like the
       page; one step elevated in dark, where shadows can't carry lift */
    --color-surface-overlay: light-dark(var(--neutral-1), var(--neutral-2));
    --color-text: var(--neutral-12);
    --color-text-muted: var(--neutral-11);
    --color-border: var(--neutral-6);
    --color-border-strong: var(--neutral-8);
    --color-accent: var(--accent-9);
    --color-on-accent: light-dark(
      oklch(99% 0.01 var(--hue)),
      oklch(18% 0.02 var(--hue)));

    /* Fill — the quiet interactive band (steps 2–4): secondary and ghost
       buttons, option/menu hover, rails and tracks, disabled fields.
       fill-strong is the off-state track (switch), between border and
       border-strong. */
    --color-fill: var(--neutral-2);
    --color-fill-hover: var(--neutral-3);
    --color-fill-active: var(--neutral-4);
    --color-fill-strong: var(--neutral-7);

    /* Primary — the action color, decoupled from accent (shadcn-school:
       near-black light, near-white dark). The accent appears only where
       attention is earned: focus rings, selection highlights, the
       selected-tab rule, the select picker's ::checkmark, and native
       accent-color. Checkbox/radio/switch checked fills ride primary,
       not accent. Hover/active
       are derived, so ANY value assigned to --color-primary gets correct
       states free. Colorful primary is a two-line theme:
       :root { --color-primary: var(--accent-9);
               --color-on-primary: var(--color-on-accent); } */
    --color-primary: var(--neutral-12);
    --color-on-primary: var(--neutral-1);
    --color-primary-hover: color-mix(in oklch, var(--color-primary) 90%, var(--color-surface));
    --color-primary-active: color-mix(in oklch, var(--color-primary) 80%, var(--color-surface));

    /* Status roles — the step-3/7/9/11 analogs, no full scales.
       Off-role shades: raw oklch(L var(--status-chroma) var(--*-hue)). */
    --color-danger-surface: light-dark(oklch(95% calc(var(--status-chroma) * 0.25) var(--danger-hue)), oklch(27% calc(var(--status-chroma) * 0.35) var(--danger-hue)));
    --color-danger-border:  light-dark(oklch(79% calc(var(--status-chroma) * 0.65) var(--danger-hue)), oklch(46% calc(var(--status-chroma) * 0.8) var(--danger-hue)));
    --color-danger:         light-dark(oklch(52% var(--status-chroma) var(--danger-hue)), oklch(70% var(--status-chroma) var(--danger-hue)));
    --color-on-danger:      light-dark(oklch(99% 0.01 var(--danger-hue)), oklch(18% 0.02 var(--danger-hue)));
    --color-danger-text:    light-dark(oklch(44% calc(var(--status-chroma) * 0.9) var(--danger-hue)), oklch(80% calc(var(--status-chroma) * 0.9) var(--danger-hue)));
    /* Danger states are derived, so any --color-danger gets them. They
       press toward the text color (darker in light, lighter in dark),
       mixed in oklab: the neutrals carry --hue at zero chroma, and an
       oklch mix would rotate the red toward that hue (pink). */
    --color-danger-hover:   color-mix(in oklab, var(--color-danger) 88%, var(--color-text));
    --color-danger-active:  color-mix(in oklab, var(--color-danger) 76%, var(--color-text));

    --color-success-surface: light-dark(oklch(95% calc(var(--status-chroma) * 0.25) var(--success-hue)), oklch(27% calc(var(--status-chroma) * 0.35) var(--success-hue)));
    --color-success-border:  light-dark(oklch(79% calc(var(--status-chroma) * 0.65) var(--success-hue)), oklch(46% calc(var(--status-chroma) * 0.8) var(--success-hue)));
    --color-success:         light-dark(oklch(52% var(--status-chroma) var(--success-hue)), oklch(70% var(--status-chroma) var(--success-hue)));
    --color-on-success:      light-dark(oklch(99% 0.01 var(--success-hue)), oklch(18% 0.02 var(--success-hue)));
    --color-success-text:    light-dark(oklch(44% calc(var(--status-chroma) * 0.9) var(--success-hue)), oklch(80% calc(var(--status-chroma) * 0.9) var(--success-hue)));

    /* warn solid runs lighter than its siblings — amber needs the
       lightness to read as warning, and takes dark text in both modes */
    --color-warn-surface: light-dark(oklch(95% calc(var(--status-chroma) * 0.25) var(--warn-hue)), oklch(27% calc(var(--status-chroma) * 0.35) var(--warn-hue)));
    --color-warn-border:  light-dark(oklch(79% calc(var(--status-chroma) * 0.65) var(--warn-hue)), oklch(46% calc(var(--status-chroma) * 0.8) var(--warn-hue)));
    --color-warn:         light-dark(oklch(78% var(--status-chroma) var(--warn-hue)), oklch(76% var(--status-chroma) var(--warn-hue)));
    --color-on-warn:      oklch(20% 0.03 var(--warn-hue));
    --color-warn-text:    light-dark(oklch(42% calc(var(--status-chroma) * 0.9) var(--warn-hue)), oklch(80% calc(var(--status-chroma) * 0.9) var(--warn-hue)));
  }

  /* scheme swap for image-valued tokens — the one place light-dark()
     can't help (colors only). See --check-glyph above. */
  @media (prefers-color-scheme: dark) {
    :root {
      --check-glyph: var(--check-glyph-dark);
    }
  }
}

/* ------------------------------------------------------------------ *
 * Preset — constructive defaults, Kelp-school not Preflight-school:
 * raw HTML should look finished, not like nothing. Zero-specificity
 * (:where) inside a layer: doubly overridable.
 * ------------------------------------------------------------------ */
@layer mica.preset {
  /* Width does not inherit, so resolve the inherited token on every box.
     A client layer after mica can also override the standard properties
     directly: :where(*) { scrollbar-color: auto; scrollbar-width: auto; }
     No vendor pseudo-elements: preserve platform behavior and easy opt-out. */
  :where(*) {
    scrollbar-color: var(--scrollbar-color);
    scrollbar-width: var(--scrollbar-width);
  }
  @media (forced-colors: active) {
    :where(*) { scrollbar-color: auto; scrollbar-width: auto; }
  }

  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    -webkit-text-size-adjust: none;
    text-size-adjust: none;
  }

  :where(body) {
    margin: 0;
    min-block-size: 100svh;
    font-family: var(--font-body);
    line-height: var(--line-height);
    background: var(--color-surface);
    color: var(--color-text);
    accent-color: var(--color-accent);
  }

  /* Vertical rhythm: flow content spaces itself; last child never
     pushes against its container. Stacks override all of this with gap. */
  :where(p, ol, ul, dl, dd, blockquote, pre, table, figure, fieldset,
         details, address, audio, video, iframe) {
    margin-block: 0 var(--flow-space, var(--space-md));
  }
  :where(p, ol, ul, dl, dd, blockquote, pre, table, figure, fieldset,
         details, address, audio, video, iframe):last-child {
    margin-block-end: 0;
  }

  :where(h1, h2, h3, h4, h5, h6) {
    margin-block: 0 var(--space-sm);
    line-height: 1.2;
    text-wrap: balance;
  }
  /* Headings that follow content get breathing room above. */
  :where(h2, h3, h4, h5, h6):where(:not(:first-child)) {
    margin-block-start: var(--space-xl);
  }

  :where(p) {
    text-wrap: pretty;
  }

  /* Media behaves like content, not like text. */
  :where(img, svg, video, canvas, picture) {
    display: block;
    max-inline-size: 100%;
    block-size: auto;
  }

  /* Form controls inherit typography instead of shipping 2009's. */
  :where(button, input, select, textarea) {
    font: inherit;
  }

  :where(pre, code, kbd, samp) {
    font-family: var(--font-mono);
  }

  /* Links take the colour of the text around them (muted copy keeps
     muted links) and mark themselves with a quiet underline that firms
     up on hover. The accent stays reserved for focus, selection and
     checkmarks. Component links (callout emphasis, nav, pagination…)
     are styled in mica.elements and win over this.
     Accent links are a theme snippet:
       :where(a:any-link) { color: var(--color-accent); } */
  :where(a:any-link) {
    color: inherit;
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--color-border-strong);
    text-underline-offset: .2em;
  }
  :where(a:any-link):hover {
    text-decoration-color: currentColor;
  }

  /* opt in to animating to/from intrinsic sizes (details, etc.) */
  :where(html) {
    interpolate-size: allow-keywords;
  }

  /* Tokenized focus ring — the theming story for focus, day one. */
  :where(:focus-visible) {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
    /* `*` never matches pseudo-elements — ::backdrop needs its own rule
       (and per convention gets its own block: an unrecognized selector
       in the list above would kill the whole kill-switch). Found via
       snapshot flakiness: the backdrop fade survived reduced-motion. */
    *::backdrop {
      animation-duration: 0.01ms !important;
      transition-duration: 0.01ms !important;
    }
  }
}

/* ------------------------------------------------------------------ *
 * Elements — native behavior. Native elements styled directly; behavior is the
 * browser's. Presentation APIs are attributes; user CSS still wins
 * because these rules live in a layer.
 * ------------------------------------------------------------------ */
@layer mica.elements {
  /* --- button (and things dressed as buttons) ---------------------- */
  :where(button, .btn,
         input:is([type="button"], [type="submit"], [type="reset"])) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    block-size: var(--control-height);
    padding: 0 var(--space-md);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-fill);
    color: var(--color-text);
    font-size: var(--text-md);
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s;

    &:hover:not(:disabled, [aria-disabled="true"]) {
      background: var(--color-fill-hover);
    }
    &:active:not(:disabled, [aria-disabled="true"]) {
      background: var(--color-fill-active);
    }

    &:where([data-variant="primary"]) {
      background: var(--color-primary);
      border-color: transparent;
      color: var(--color-on-primary);

      &:hover:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-primary-hover);
      }
      &:active:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-primary-active);
      }

      /* disabled = same fill at the base rule's reduced opacity — a
         color-mix toward gray was tried and reads as an enabled
         secondary button when primary is near-black */
    }

    &:where([data-variant="danger"]) {
      background: var(--color-danger);
      border-color: transparent;
      color: var(--color-on-danger);

      &:hover:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-danger-hover);
      }
      &:active:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-danger-active);
      }
      &:where(:disabled, [aria-disabled="true"]) {
        background: color-mix(in oklab, var(--color-danger) 40%, var(--color-border));
      }
    }

    /* deliberately zero rest affordance — a ghost is invisible until
       hover/focus. use data-variant="ghost" for toolbars and icon rows,
       not as the lone action on a page. */
    &:where([data-variant="ghost"]) {
      background: transparent;
      border-color: transparent;

      &:hover:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-fill-hover);
      }
      &:active:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-fill-active);
      }
    }

    /* sizes (shadcn: h-8 px-3 / h-10 px-6, text-sm throughout) */
    &:where([data-size="small"]) {
      block-size: var(--control-height-sm);
      padding-inline: var(--space-sm);
    }
    &:where([data-size="large"]) {
      block-size: var(--control-height-lg);
      padding-inline: var(--space-lg);
    }

    &:where(:disabled, [aria-disabled="true"]) {
      cursor: not-allowed;
      opacity: 0.55;
    }
  }

  /* --- fields: text inputs, textarea, select ----------------------- *
   * One control family with buttons: same radius, same border weight.
   * Focus ring comes from the preset; text fields match :focus-visible
   * even on mouse focus, per spec.
   * ------------------------------------------------------------------ */
  :where(input, textarea, select):where(:not([type="checkbox"],
         [type="radio"], [type="range"], [type="color"], [type="file"],
         [type="button"], [type="submit"], [type="reset"],
         [type="image"])) {
    inline-size: 100%;
    padding: var(--space-xs) var(--space-sm);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    line-height: 1.375; /* textarea rhythm; single-line heights are fixed below */

    &::placeholder {
      color: var(--color-text-muted);
      opacity: 1;
    }

    &:where(:disabled) {
      cursor: not-allowed;
      opacity: 0.55;
      background: var(--color-fill);
    }

    /* validation — only after the user has interacted (:user-invalid),
       never on pristine fields. First consumer of the status roles. */
    &:where(:user-invalid) {
      border-color: var(--color-danger);
      --focus-ring-color: var(--color-danger);
    }
  }

  /* single-line controls share the fixed control height; text centers
     in the content box (16px field text stays — iOS zoom rule) */
  :where(select:not([multiple], [size]),
         input:not([type="checkbox"], [type="radio"], [type="range"],
           [type="color"], [type="file"], [type="button"],
           [type="submit"], [type="reset"], [type="image"])) {
    block-size: var(--control-height);
    padding-block: 0;
  }

  /* --- customizable select, where the platform allows -------------- *
   * appearance: base-select opts into styleable pickers (Chromium).
   * Elsewhere this whole rule drops (unknown pseudo-element) and the
   * native picker remains — progressive enhancement, zero JS.
   * Both declarations are required for the opt-in, and grouping them
   * means they fail together: never a half-opted-in select.
   * ------------------------------------------------------------------ */
  :where(select),
  ::picker(select) {
    appearance: base-select;
  }

  @supports (appearance: base-select) {
    /* the trigger is a flex row; children default to stretch, which
       top-aligns the value text inside the fixed control height */
    :where(select) {
      align-items: center;
    }

    ::picker(select) {
      border: 1px solid var(--color-border);
      /* the UA paints the picker in CanvasText (pure black/white), which
         options inherit; disabled options mix 50% of currentColor, so
         this one declaration puts both back on the text role */
      color: var(--color-text);
      border-radius: var(--radius-md);
      background: var(--color-surface-overlay);
      padding: var(--space-2xs);
      margin-block: var(--space-2xs);
      /* dark surfaces need heavier shadows to register at all */
      box-shadow: 0 8px 24px light-dark(oklch(0 0 0 / 0.15), oklch(0 0 0 / 0.5));
      /* positioning stays the UA's (position-try-order: most-block-size):
         it can open upward on near-ties, but it guarantees no clipping.
         Forcing block-end + flip-block was tried and clips off-viewport
         in tight space — don't fight the picker's positioning. */
      opacity: 1;
      translate: 0 0;
    }

    /* enter animates; close is instant (shadcn behavior) — the
       transition only exists while open, so unmatching :open drops it */
    :where(select):open::picker(select) {
      transition:
        opacity 0.12s,
        translate 0.12s,
        overlay 0.12s allow-discrete,
        display 0.12s allow-discrete;
    }

    @starting-style {
      ::picker(select) {
        opacity: 0;
        translate: 0 -4px;
      }
    }

    :where(select) :where(option) {
      padding: var(--space-xs) var(--space-sm);
      border-radius: var(--radius-sm);
      cursor: pointer;
    }
    :where(select) :where(option):where(:hover, :focus-visible) {
      background: var(--color-fill-hover);
      outline: none; /* hover-follows-focus pattern; ring is redundant here */
    }
    :where(select) :where(option):checked {
      font-weight: 500;
    }
    :where(select) :where(option)::checkmark {
      color: var(--color-accent);
    }

    :where(select)::picker-icon {
      color: var(--color-text-muted);
      transition: rotate 0.15s;
    }
    :where(select):open::picker-icon {
      rotate: 180deg;
    }

    /* opt-in via select.js: the picker overlays the trigger with the
       selected option kept in place (macOS-native / Base UI behavior).
       JS supplies only --m-sel-index; all geometry lives here.
       offset = index × row (1lh + option padding) + picker padding/border;
       max() keeps the top on-screen for selections deep in long lists. */
    :where(select.picker-aligned)::picker(select) {
      position-area: none;
      margin-block: 0;
      inset-inline-start: calc(anchor(left) - var(--space-2xs) - 1px);
      min-inline-size: calc(anchor-size(width) + 2 * (var(--space-2xs) + 1px));
      inset-block-start: max(
        var(--space-2xs),
        calc(
          anchor(top) - var(--m-sel-index, 0) * (1lh + 2 * var(--space-xs)) -
            var(--space-2xs) - 1px
        )
      );
      /* unfold in place, don't slide */
      translate: 0 0;
    }
  }

  /* textarea grows with content — zero JS */
  :where(textarea) {
    field-sizing: content;
    min-block-size: 3lh;
    resize: vertical;
  }

  /* --- form grouping: label, fieldset, legend ---------------------- *
   * Plain by default (shadcn-school): a fieldset is a titled group,
   * not a bordered box. The legend reads as a small section heading.
   * Space contents with m-vstack or rhythm.
   * ------------------------------------------------------------------ */
  :where(label) {
    font-weight: 500;
  }

  :where(fieldset) {
    border: 0;
    padding: 0;
    margin: 0;
    min-inline-size: 0; /* fieldsets otherwise refuse to shrink */
  }

  :where(legend) {
    font-weight: 600;
    padding: 0;
    margin-block-end: var(--space-md);
  }

  /* a disabled fieldset dims everything it silences */
  :where(fieldset:disabled) {
    color: var(--color-text-muted);

    & :where(label) {
      color: var(--color-text-muted);
      cursor: not-allowed;
    }
  }

  /* --- checkbox, radio, switch: drawn, semantics stay native ------- */
  :where(input:is([type="checkbox"], [type="radio"])) {
    appearance: none;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    margin: 0;
    flex-shrink: 0;
    vertical-align: -0.25em;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-surface) center / contain no-repeat;
    cursor: pointer;
    transition: background-color 0.15s, border-color 0.15s,
      background-position 0.15s;

    &:checked {
      border-color: var(--color-primary);
      background-color: var(--color-primary);
    }

    &:disabled {
      cursor: not-allowed;
      opacity: 0.55;
    }
  }

  :where(input[type="checkbox"]:not([role="switch"])) {
    &:checked {
      background-image: var(--check-glyph);
    }

    /* indeterminate dash — a gradient, no glyph needed */
    &:indeterminate {
      border-color: var(--color-primary);
      background-color: var(--color-primary);
      background-image: linear-gradient(
        var(--color-on-primary),
        var(--color-on-primary)
      );
      background-size: 55% 2px;
      background-position: center;
      background-repeat: no-repeat;
    }
  }

  /* Rounded inner marks, drawn as backgrounds because pseudo-elements on
     native inputs are not portable. Four quarter circles and two center
     strips form a rounded rectangle; radius 0 keeps the square default. */
  :where(input[type="radio"], input[type="checkbox"][role="switch"]) {
    --m-mark-size: 8px;
    --m-mark-radius: min(var(--radius-sm), calc(var(--m-mark-size) / 2));
    --m-mark-color: var(--color-border-strong);
    --m-mark-align: .5;
    --m-mark-inset: 0px;
    --m-mark-left: calc(var(--m-mark-align) * (100% - var(--m-mark-size) + var(--m-mark-radius)) + var(--m-mark-inset));
    --m-mark-top: calc(50% - (var(--m-mark-size) - var(--m-mark-radius)) / 2);
    background-image:
      radial-gradient(circle var(--m-mark-radius) at 100% 100%, var(--m-mark-color) 99%, transparent 100%),
      radial-gradient(circle var(--m-mark-radius) at 0 100%, var(--m-mark-color) 99%, transparent 100%),
      radial-gradient(circle var(--m-mark-radius) at 100% 0, var(--m-mark-color) 99%, transparent 100%),
      radial-gradient(circle var(--m-mark-radius) at 0 0, var(--m-mark-color) 99%, transparent 100%),
      linear-gradient(var(--m-mark-color), var(--m-mark-color)),
      linear-gradient(var(--m-mark-color), var(--m-mark-color));
    background-size:
      var(--m-mark-radius) var(--m-mark-radius),
      var(--m-mark-radius) var(--m-mark-radius),
      var(--m-mark-radius) var(--m-mark-radius),
      var(--m-mark-radius) var(--m-mark-radius),
      calc(var(--m-mark-size) - 2 * var(--m-mark-radius)) var(--m-mark-size),
      var(--m-mark-size) calc(var(--m-mark-size) - 2 * var(--m-mark-radius));
    /* Account for each image's size: percentage positions resolve against
       the positioning area minus that image, not the whole input. */
    background-position:
      left var(--m-mark-left) top var(--m-mark-top),
      left calc(var(--m-mark-left) + var(--m-mark-size) - var(--m-mark-radius)) top var(--m-mark-top),
      left var(--m-mark-left) top calc(var(--m-mark-top) + var(--m-mark-size) - var(--m-mark-radius)),
      left calc(var(--m-mark-left) + var(--m-mark-size) - var(--m-mark-radius)) top calc(var(--m-mark-top) + var(--m-mark-size) - var(--m-mark-radius)),
      left calc(var(--m-mark-align) * (100% - 2 * var(--m-mark-radius)) + var(--m-mark-inset) + var(--m-mark-radius)) top 50%,
      left calc(var(--m-mark-align) * 100% + var(--m-mark-inset)) top 50%;
    background-repeat: no-repeat;

    &:checked { --m-mark-color: var(--color-on-primary); }
  }

  /* Switch: square by default; the track and thumb follow --radius-sm.
     Set --radius-sm: var(--radius-full) for circular inner marks and a
     pill track. Keep the thumb square by overriding --m-mark-radius: 0px. */
  :where(input[type="checkbox"][role="switch"]) {
    --m-mark-size: 14px;
    --m-mark-align: 0;
    --m-mark-inset: 2px;
    --m-mark-color: light-dark(var(--color-surface), var(--color-text));
    inline-size: 2.25rem;
    border-color: transparent;
    border-radius: var(--radius-sm);
    background-color: var(--color-fill-strong);

    &:checked {
      --m-mark-align: 1;
      --m-mark-inset: -2px;
      --m-mark-color: var(--color-on-primary);
      background-color: var(--color-primary);
    }
  }

  /* disabled + on: desaturate toward neutral, same recipe as disabled
     data-variant="primary" buttons — inert, not just faded (placed after
     the switch block so it wins its background-color at equal specificity).
     :indeterminate is checkbox-only here: a radio matches :indeterminate
     whenever its group has nothing checked, which would paint a disabled,
     unselected radio as disabled + on. Split (not [type] inside :is()) to
     keep both branches at the same specificity as before. */
  :where(input[type="checkbox"]):disabled:is(:checked, :indeterminate),
  :where(input[type="radio"]):disabled:checked {
    border-color: transparent;
    background-color: color-mix(in oklch, var(--color-primary) 40%, var(--color-border));
  }

  /* labels that wrap a check control become the click target */
  :where(label:has(> input:is([type="checkbox"], [type="radio"]))) {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    cursor: pointer;
  }

  /* a disabled control dims its whole label, not just itself */
  :where(label:has(> input:disabled)) {
    color: var(--color-text-muted);
    cursor: not-allowed;
  }

  /* segmented control: native radios fused into one control. The input
     remains the form/keyboard/AT primitive; the label carries the visual
     state because inputs cannot safely own pseudo-elements. Lives after
     the generic label:has(> radio) rules so its zero-specificity
     display: grid / place-items: center wins by source order. */
  :where(m-segmented) {
    display: inline-flex;
    inline-size: fit-content;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-sm);
  }

  :where(m-segmented) > :where(label) {
    position: relative;
    display: grid;
    place-items: center;
    min-block-size: var(--control-height);
    padding-inline: var(--space-sm);
    margin: 0;
    font-size: var(--text-md);
    font-weight: 400;
    line-height: 1;
    cursor: pointer;
    user-select: none;
  }

  :where(m-segmented) > :where(label + label) {
    border-inline-start: 1px solid var(--color-border-strong);
  }

  /* The radio itself is hidden but focusable and announced — the label
     is the visible control. Shares the one hiding rule at the end of
     this layer (see "visually hidden"). */

  :where(m-segmented) > :where(label):has(> input:checked) {
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-weight: 600;
  }

  :where(m-segmented) > :where(label):has(> input:focus-visible) {
    outline: var(--focus-ring-width) solid var(--focus-ring-color);
    outline-offset: var(--focus-ring-offset);
    z-index: 1;
  }

  :where(m-segmented) > :where(label):has(> input:disabled) {
    color: var(--color-text-muted);
    cursor: not-allowed;
    opacity: 0.55;
  }

  /* checked + disabled: the selection still reads, only dimmed. Without
     this the :disabled color above wins (same specificity, later) and
     paints muted text on the primary fill (~1.6:1). The checkbox family's
     desaturated fill was tried: with the 0.55 opacity, text drops to ~2:1. */
  :where(m-segmented) > :where(label):has(> input:checked:disabled) {
    color: var(--color-on-primary);
  }

  /* --- badge: quiet metadata, not a control ------------------------ */
  :where(m-badge) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-inline-size: var(--m-badge-min-width, auto);
    min-block-size: 1.5rem;
    padding-inline: var(--m-badge-padding, var(--space-xs));
    border: 1px solid var(--m-badge-border, var(--color-border));
    border-radius: var(--radius-sm);
    background: var(--m-badge-background, transparent);
    color: var(--m-badge-color, var(--color-text-muted));
    font-family: var(--m-badge-font, inherit);
    font-size: var(--text-xs);
    font-weight: 500;
    font-variant-numeric: var(--m-badge-numerals, normal);
    line-height: 1;
    white-space: nowrap;
  }

  :where(m-badge[variant="primary"]) {
    --m-badge-border: var(--color-primary);
    --m-badge-background: var(--color-primary);
    --m-badge-color: var(--color-on-primary);
  }

  :where(m-badge[variant="success"]) {
    --m-badge-border: var(--color-success-border);
    --m-badge-background: var(--color-success-surface);
    --m-badge-color: var(--color-success-text);
  }

  :where(m-badge[variant="warning"]) {
    --m-badge-border: var(--color-warn-border);
    --m-badge-background: var(--color-warn-surface);
    --m-badge-color: var(--color-warn-text);
  }

  :where(m-badge[variant="danger"]) {
    --m-badge-border: var(--color-danger-border);
    --m-badge-background: var(--color-danger-surface);
    --m-badge-color: var(--color-danger-text);
  }

  /* Callouts are CSS-only content. Variants never imply role=alert.
     Optional icons and dismissal controls are authored, not generated.
     For a neutral panel with colored emphasis, override --callout-background
     and --callout-border to the shared surface and border roles. */
  :where(m-callout) {
    --callout-background: var(--color-surface-raised);
    --callout-border: var(--color-border);
    --callout-emphasis: var(--color-text);
    display: flex;
    align-items: flex-start;
    gap: var(--callout-gap, var(--space-sm));
    padding: var(--callout-padding, var(--space-md));
    border: 1px solid var(--callout-border);
    border-radius: var(--radius-md);
    background: var(--callout-background);
    color: var(--color-text);
    font-size: var(--callout-font-size, var(--text-md));
    line-height: var(--callout-line-height, 1.5);
  }
  :where(m-callout[variant="success"]) {
    --callout-background: var(--color-success-surface);
    --callout-border: var(--color-success-border);
    --callout-emphasis: var(--color-success-text);
  }
  :where(m-callout[variant="warning"]) {
    --callout-background: var(--color-warn-surface);
    --callout-border: var(--color-warn-border);
    --callout-emphasis: var(--color-warn-text);
  }
  :where(m-callout[variant="danger"]) {
    --callout-background: var(--color-danger-surface);
    --callout-border: var(--color-danger-border);
    --callout-emphasis: var(--color-danger-text);
  }
  :where(m-callout[hidden]) { display: none; }
  :where(m-callout > [data-callout-body]) { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
  :where(m-callout [data-callout-title]) {
    margin: 0 0 var(--space-2xs);
    color: var(--callout-emphasis);
    font: inherit;
    font-weight: var(--callout-title-weight, 600);
  }
  :where(m-callout > [data-callout-body] > p:not([data-callout-title])) { margin: 0; }
  /* the title keeps its own --space-2xs whatever its element: a
     p[data-callout-title] must not pick up the p + p gap */
  :where(m-callout > [data-callout-body] > p:not([data-callout-title]) + p) { margin-block-start: var(--space-xs); }
  :where(m-callout a) { color: var(--callout-emphasis); }
  :where(m-callout > [data-callout-icon]) {
    inline-size: var(--callout-icon-size, 1.125rem);
    block-size: var(--callout-icon-size, 1.125rem);
    flex: 0 0 auto;
    margin-block-start: var(--callout-icon-offset, .125rem);
    color: var(--callout-emphasis);
  }
  :where(m-callout [data-callout-actions]) { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-block-start: var(--space-sm); }
  :where(m-callout > button[data-callout-dismiss]) {
    flex: 0 0 auto;
    inline-size: var(--callout-dismiss-size, 2rem);
    block-size: var(--callout-dismiss-size, 2rem);
    padding: 0;
    margin-block-start: calc(-1 * var(--space-2xs));
    margin-inline-end: calc(-1 * var(--space-2xs));
  }
  /* an authored dismiss icon is sized, not stretched to the button */
  :where(m-callout > button[data-callout-dismiss] > svg) {
    inline-size: 1rem;
    block-size: 1rem;
  }

  :where(m-badge[count]) {
    --m-badge-min-width: 1.5rem;
    --m-badge-padding: var(--space-2xs);
    --m-badge-font: var(--font-mono);
    --m-badge-numerals: tabular-nums;
  }

  /* --- avatar: authored initials, optionally Blobatar-painted -------- */
  :where(m-avatar) {
    display: inline-grid;
    place-items: center;
    position: relative;
    flex: none;
    box-sizing: border-box;
    inline-size: var(--avatar-size, 3rem);
    block-size: var(--avatar-size, 3rem);
    overflow: hidden;
    border-radius: var(--radius-md);
    background: var(--color-surface-raised);
    color: var(--m-avatar-content-color, var(--color-text));
    font-size: calc(var(--avatar-size, 3rem) * 0.5);
    font-weight: 600;
    line-height: 1;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
    user-select: none;
  }

  :where(m-avatar > img) {
    position: absolute;
    inset: 0;
    z-index: 1;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
  }

  /* Attribute selectors only transport values. The pseudo rules below
     render them, so missing avatar.js leaves authored initials untouched. */
  :where(m-avatar[blobatar]) {
    --m-avatar-decoration: "";
    --m-avatar-render-inset-block: 0;
    --m-avatar-render-inset-inline: 0;
    --m-avatar-render-x: 0;
    --m-avatar-render-y: 0;
  }

  :where(m-avatar[blobatar][contained]) {
    --m-avatar-render-inset-block: var(--m-avatar-body-inset-block);
    --m-avatar-render-inset-inline: var(--m-avatar-body-inset-inline);
    --m-avatar-render-x: var(--m-avatar-body-x);
    --m-avatar-render-y: var(--m-avatar-body-y);
  }

  :where(m-avatar)::before {
    content: var(--m-avatar-decoration, none);
    position: absolute;
    inset-block: var(--m-avatar-render-inset-block);
    inset-inline: var(--m-avatar-render-inset-inline);
    border-radius: inherit;
    background: var(--m-avatar-body-color);
    transform: translate(var(--m-avatar-render-x), var(--m-avatar-render-y));
  }

  :where(m-avatar)::after {
    content: var(--m-avatar-decoration, none);
    position: absolute;
    inset: 0;
    background:
      radial-gradient(
        ellipse var(--m-avatar-eye-width) var(--m-avatar-eye-height)
        at var(--m-avatar-eye-left) var(--m-avatar-eye-top),
        var(--m-avatar-eye-color) 98%, transparent 100%
      ),
      radial-gradient(
        ellipse var(--m-avatar-eye-width) var(--m-avatar-eye-height)
        at calc(var(--m-avatar-eye-left) + var(--m-avatar-eye-gap))
          calc(var(--m-avatar-eye-top) + var(--m-avatar-eye-drop)),
        var(--m-avatar-eye-color) 98%, transparent 100%
      );
  }

  /* --- skeleton: quiet CSS-only loading placeholder ---------------- */
  :where(m-skeleton) {
    display: block;
    flex: none;
    inline-size: var(--skeleton-width, 100%);
    block-size: var(--skeleton-height, 0.75rem);
    overflow: hidden;
    border-radius: var(--skeleton-radius, var(--radius-md));
    background-color: var(--color-surface-raised);
    animation: mica-skeleton-pulse 1.6s ease-in-out infinite alternate;
  }

  @keyframes mica-skeleton-pulse {
    to {
      background-color: var(--color-border);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    :where(m-skeleton) {
      animation: none;
      background-color: var(--color-border);
    }
  }

  /* --- stat grid: semantic summaries in a fused frame -------------- */
  /* The 1px gaps show the frame background as separators; the outer edge
     is a real border, not 1px padding, so overflow clips the stats to the
     inner radius (outer minus border) and the edge stays a full 1px on
     rounded corners. Padding + overflow clipped at the outer radius and
     the corner stats' surfaces covered the edge along the curve. */
  :where(dl.stat-grid) {
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    margin-block: 0;
    padding: 0;
    border: 1px solid var(--color-border);
    overflow: hidden;
    border-radius: var(--radius-md);
    background: var(--color-border);
  }

  :where(dl.stat-grid) > :where(div.stat) {
    display: flex;
    flex-direction: column;
    flex: 1 1 min(100%, 8rem);
    gap: var(--space-sm);
    min-inline-size: 0;
    padding: var(--space-md);
    background: var(--color-surface);
  }

  :where(dl.stat-grid) > :where(div.stat) > :where(dt) {
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    font-weight: 500;
    line-height: 1.4;
  }

  :where(dl.stat-grid) > :where(div.stat) > :where(dd) {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    gap: var(--space-2xs);
    min-inline-size: 0;
    margin-block: 0;
  }

  :where(dl.stat-grid) > :where(div.stat) > :where(dd) > :first-child {
    color: var(--color-text);
    font-size: var(--text-xl);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    overflow-wrap: anywhere;
  }

  :where(dl.stat-grid) > :where(div.stat) > :where(dd) > :where(small) {
    margin-block-start: auto;
    color: var(--color-text-muted);
    font-size: var(--text-xs);
    line-height: 1.4;
  }

  /* --- content: tables, lists, code, quotes ------------------------ */
  :where(table) {
    inline-size: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
  }
  :where(caption) {
    caption-side: bottom;
    margin-block-start: var(--space-xs);
    color: var(--color-text-muted);
    font-size: var(--text-md);
    text-align: start;
  }
  :where(th) {
    text-align: start;
    font-weight: 500;
    color: var(--color-text-muted);
  }
  :where(th, td) {
    padding: var(--space-sm);
    border-block-end: 1px solid var(--color-border);
  }
  :where(tbody tr:last-child) :where(th, td) {
    border-block-end: 0;
  }
  :where(tbody tr):hover {
    background: var(--color-surface-raised);
  }

  :where(ul, ol) {
    padding-inline-start: var(--space-lg);
  }
  :where(li) {
    margin-block: var(--space-2xs);
  }
  :where(li)::marker {
    color: var(--color-text-muted);
  }
  :where(dt) {
    font-weight: 500;
  }
  :where(dd) {
    margin-inline-start: 0;
  }

  :where(code, kbd, samp) {
    font-size: 0.875em;
  }
  :where(:not(pre) > code) {
    background: var(--color-surface-raised);
    border: 1px solid var(--color-border);
    padding: 0.125em 0.375em;
    border-radius: var(--radius-sm);
  }
  :where(pre) {
    background: var(--color-surface-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: var(--space-md);
    overflow-x: auto;
  }
  :where(kbd) {
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-block-end-width: 2px;
    padding: 0.125em 0.375em;
    border-radius: var(--radius-sm);
    font-size: 0.8em;
  }

  :where(blockquote) {
    margin-inline: 0;
    border-inline-start: 2px solid var(--color-border-strong);
    padding-inline-start: var(--space-md);
    color: var(--color-text-muted);
  }

  :where(hr) {
    border: 0;
    border-block-start: 1px solid var(--color-border-strong);
    margin-block: var(--space-lg);
  }

  /* --- progress & meter: thin bars (shadcn-school) ------------------ *
   * vendor pseudos must stay in separate rules — an unknown selector
   * in a list invalidates the whole rule.
   * ------------------------------------------------------------------ */
  :where(progress, meter) {
    appearance: none;
    inline-size: 100%;
    block-size: 0.5rem;
    border: 0;
    border-radius: var(--radius-sm);
    overflow: hidden;
  }

  :where(progress) {
    background: color-mix(in oklch, var(--color-primary) 20%, transparent);
  }
  :where(progress)::-webkit-progress-bar {
    background: transparent;
  }
  :where(progress)::-webkit-progress-value {
    background: var(--color-primary);
  }
  :where(progress)::-moz-progress-bar {
    background: var(--color-primary);
  }

  /* meter grades through the status roles */
  :where(meter) {
    background: var(--color-fill-active);
  }
  :where(meter)::-webkit-meter-bar {
    background: transparent;
    border: 0;
    block-size: 0.5rem;
  }
  :where(meter)::-webkit-meter-optimum-value {
    background: var(--color-success);
  }
  :where(meter)::-webkit-meter-suboptimum-value {
    background: var(--color-warn);
  }
  :where(meter)::-webkit-meter-even-less-good-value {
    background: var(--color-danger);
  }
  :where(meter):-moz-meter-optimum::-moz-meter-bar {
    background: var(--color-success);
  }
  :where(meter):-moz-meter-sub-optimum::-moz-meter-bar {
    background: var(--color-warn);
  }
  :where(meter):-moz-meter-sub-sub-optimum::-moz-meter-bar {
    background: var(--color-danger);
  }

  /* --- stepper: framed sequence controls --------------------------- *
   * Mica owns only the fused layout. Consumers own labels, disabled
   * state, events, routing, and value changes. The frame deliberately does
   * not clip overflow: native focus rings must remain fully visible.
   * ------------------------------------------------------------------ */
  :where(m-stepper) {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: stretch;
    min-inline-size: 0;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
  }

  :where(m-stepper:has(> [data-reset])) {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
  }

  :where(m-stepper) > :where(button) {
    border: 0;
    border-radius: 0;
    background: transparent;

    &:focus-visible {
      z-index: 1;
    }
  }

  :where(m-stepper) > :where(button:first-child) {
    border-start-start-radius: inherit;
    border-end-start-radius: inherit;
  }

  :where(m-stepper) > :where(button:last-child) {
    border-start-end-radius: inherit;
    border-end-end-radius: inherit;
  }

  :where(m-stepper) > :where([data-step]) {
    inline-size: var(--control-height);
    padding-inline: 0;
  }

  /* Block, not grid: text-overflow only draws on a block container's own
     line boxes. In a grid the text sits in an anonymous grid item that
     doesn't inherit overflow/text-overflow, so long values hard-clipped
     with no ellipsis. One nowrap line as tall as the box centers it. */
  :where(m-stepper) > :where(:nth-child(2)) {
    display: block;
    min-inline-size: 0;
    block-size: var(--control-height);
    padding-inline: var(--space-sm);
    overflow: hidden;
    border-inline: 1px solid var(--color-border);
    background: var(--color-surface-raised);
    color: var(--color-text);
    font-size: var(--text-md);
    font-weight: 600;
    line-height: var(--control-height);
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  :where(m-stepper) > :where([data-reset]) {
    border-inline-start: 1px solid var(--color-border);
  }

  /* --- dialog: modal + drawer --------------------------------------- *
   * The browser brings focus trapping, Esc, top layer, ::backdrop, and
   * form[method=dialog] closing. Invoker commands (commandfor/command)
   * make open/close zero-JS. Exit animations: transition-behavior
   * allow-discrete + @starting-style.
   * ------------------------------------------------------------------ */
  :where(dialog) {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface-overlay);
    color: var(--color-text);
    /* sections carry their own padding; the dialog is a bare frame */
    padding: 0;
    overflow: hidden;
    inline-size: calc(100vw - 2rem);
    max-inline-size: var(--size-lg);
    max-block-size: calc(100svh - 2rem);
    box-shadow: 0 16px 48px light-dark(oklch(0 0 0 / 0.2), oklch(0 0 0 / 0.6));
    opacity: 0;
    scale: 0.95;
    transition:
      opacity 0.15s,
      scale 0.15s,
      translate 0.15s,
      overlay 0.15s allow-discrete,
      display 0.15s allow-discrete;
  }
  /* composition: dialog > header (title + description) / body / footer.
     layout lives on [open] — unconditional display would defeat the
     UA's display:none on closed dialogs */
  /* Composition is UNCONDITIONAL so it survives the exit: the dialog
     stays rendered (display transitions via allow-discrete) for 0.15s
     after [open] is removed. Structure gated on [open] snaps back to
     defaults the instant [open] goes — flex-direction reverts to row,
     children lose their sizing — and the content visibly deforms while
     fading out. Only `display` stays conditional (unconditional flex
     would defeat the UA's display:none on a closed dialog); opacity and
     scale are the open visual state that transitions on exit. */
  :where(dialog) {
    flex-direction: column;

    & > :where(*) {
      margin-block: 0; /* the dialog owns spacing, like a stack */
    }

    /* the body: whatever sits between header and footer. one wrapper
       element; it pads itself and is the scrollable region.
       flex-basis must stay `auto` (not `flex: 1`'s 0%): iOS Safari sizes
       the dialog's fit-content height from the basis, so 0% collapses
       the body to a one-line scroll strip (iOS 26.0; Chromium and newer
       WebKit use the content contribution either way). */
    & > :where(:not(header, footer, button.close)) {
      padding: var(--space-md);
      flex: 1 1 auto;
      min-block-size: 0;
      overflow-y: auto;
      /* break the scroll chain: at the region's scroll limit iOS
         otherwise hands the gesture to the page behind the modal —
         the root's overflow:hidden can't stop a chained scroll. */
      overscroll-behavior: contain;
      font-size: var(--text-md); /* body must not outweigh the 14px title */
    }

    /* when the dialog hits its max height, only the body compresses */
    & > :where(header, footer) {
      flex-shrink: 0;
    }
  }

  :where(dialog[open]) {
    display: flex;
    opacity: 1;
    scale: 1;
  }

  /* corner close button — <button class="close" commandfor="…"
     command="close" aria-label="Close">✕</button> (or wrap it in a
     method=dialog form). absolute is safe: the dialog is positioned.
     shared with toasts (popovertarget/popovertargetaction=hide there). */
  :where(dialog, m-toast[popover]) > :where(button.close) {
    position: absolute;
    inset-block-start: var(--space-sm);
    inset-inline-end: var(--space-sm);
    /* size to the glyph: the button preset's control height would
       stretch this into a tall narrow strip */
    block-size: auto;
    padding: var(--space-2xs);
    border: 0;
    background: transparent;
    color: var(--color-text-muted);
    line-height: 1;

    &:hover:not(:disabled, [aria-disabled="true"]) {
      background: var(--color-fill-hover);
      color: var(--color-text);
    }
    &:active:not(:disabled, [aria-disabled="true"]) {
      background: var(--color-fill-active);
    }
  }

  :where(dialog) > :where(header) {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
    padding: var(--space-md);
    border-block-end: 1px solid var(--color-border);

    /* long titles must not run under the corner X */
    :where(dialog:has(> button.close)) > & {
      padding-inline-end: calc(var(--space-md) + var(--space-xl));
    }

    & > :where(*) {
      margin-block: 0;
    }

    & :where(h1, h2, h3, h4) {
      font-size: var(--text-md);
      font-weight: 500;
    }

    & :where(p) {
      color: var(--color-text-muted);
      font-size: var(--text-xs);
      line-height: 1.6;
    }
  }

  :where(dialog) > :where(footer) {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm);
    justify-content: flex-end;
    padding: var(--space-md);
    border-block-start: 1px solid var(--color-border);

    & > :where(*) {
      margin-block: 0;
    }

    /* a method=dialog form is the idiomatic close mechanism — let its
       buttons participate in the footer's row directly */
    & > :where(form[method="dialog" i]) {
      display: contents;
    }
  }
  @starting-style {
    :where(dialog[open]) {
      opacity: 0;
      scale: 0.95;
    }
  }

  :where(dialog)::backdrop {
    /* explicit oklch alpha, not the `transparent` keyword: iOS won't
       interpolate oklch()→transparent and cuts the scrim instantly,
       desyncing it from the sheet. same-space endpoints animate. */
    background: oklch(0 0 0 / 0);
    /* size to the LARGE viewport, don't trust inset: shipped iOS sizes
       the top layer to the small viewport, so an inset-based backdrop
       ends above the real bottom edge when the toolbar collapses —
       page content peeked through the strip. (Radix/vaul overlays are
       ordinary fixed divs and don't have this problem; ::backdrop
       lives in the top layer, so we overpaint instead.) */
    inline-size: 100lvw;
    block-size: 100lvh;
    transition:
      background-color 0.15s,
      overlay 0.15s allow-discrete,
      display 0.15s allow-discrete;
  }
  :where(dialog[open])::backdrop {
    background: oklch(0 0 0 / 0.4);
  }
  @starting-style {
    :where(dialog[open])::backdrop {
      background: oklch(0 0 0 / 0);
    }
  }

  /* drawer (shadcn sheet anatomy): inline-end panel, fade + 2.5rem
     nudge rather than a full slide; no section dividers; footer pinned
     to the bottom with stacked actions. */
  :where(dialog[data-drawer]) {
    margin-inline: auto 0;
    margin-block: 0;
    /* full height WITHOUT an explicit block-size: the UA gives
       dialog:modal `position: fixed; inset-block: 0` — leaving height
       auto stretches between both edges, and on iOS that bottom edge
       tracks toolbar collapse like any bottom-fixed bar. Explicit
       100svh left a gap behind the collapsed toolbar; 100dvh lagged
       in the top layer on shipped iOS. Don't reintroduce either. */
    block-size: auto;
    max-block-size: none;
    inline-size: 75vw;
    max-inline-size: 24rem; /* sheet's max-w-sm */
    border: 0;
    border-inline-start: 1px solid var(--color-border);
    font-size: var(--text-xs);
    line-height: 1.6;
    scale: 1;
    translate: 2.5rem 0;
  }
  :where(dialog[data-drawer][open]) {
    translate: 0 0;
  }
  /* unconditional (survives the exit, like the rest of composition) */
  :where(dialog[data-drawer]) > :where(:not(header, footer, button.close)) {
    font-size: inherit; /* panel runs 12/relaxed throughout */
  }
  @starting-style {
    :where(dialog[data-drawer][open]) {
      translate: 2.5rem 0;
    }
  }

  /* The compact sheet typography must not trigger iOS input-focus zoom.
     Consumers can override this floor in their own CSS layer. */
  :where(dialog[data-drawer] input:not([type="checkbox"], [type="radio"],
    [type="range"], [type="color"], [type="file"], [type="button"],
    [type="submit"], [type="reset"], [type="image"], [type="hidden"]),
    dialog[data-drawer] textarea, dialog[data-drawer] select) {
    font-size: max(1em, 1rem); /* iOS field floor — a platform limit, not a scale step */
  }

  :where(dialog[data-drawer]) > :where(header) {
    border-block-end: 0;
  }
  :where(dialog[data-drawer]) > :where(footer) {
    margin-block-start: auto;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-xs);
    border-block-start: 0;
  }

  /* Internal visual layer injected by drawer.js. It stays ordinary page
     content beneath the dialog's transparent top-layer ::backdrop, so it
     survives iOS removing that backdrop on close. Hidden outside the
     mobile-sheet breakpoint; aria-hidden + inert are set by the module. */
  :where([data-mica-drawer-overlay]) {
    display: none;
  }

  /* small screens: the drawer becomes a bottom sheet — shadcn's own
     mobile drawer (vaul/radix) is exactly this. Anchored to the bottom
     edge via auto top margin: bottom attachment is the one thing iOS
     tracks reliably through toolbar collapse (same mechanism as bottom
     nav bars). Explicit 100svh gapped behind the collapsed toolbar and
     100dvh lagged in the top layer — don't reintroduce heights here. */
  @media (max-width: 40rem) {
    :where(dialog[data-drawer]) {
      inset-block: auto 0;       /* release the UA's top anchor… */
      margin-block: 0;           /* …so height resolves from content */
      block-size: auto;          /* content height, like vaul */
      max-block-size: calc(100dvh - 3rem);
      inline-size: 100vw;
      max-inline-size: none;
      border-inline-start: 0;
      border-block-start: 1px solid var(--color-border);
      /* CSS-only fallback: two shadows painted by the SHEET so they
         persist through the exit (display:allow-discrete keeps the box
         rendered) — unlike ::backdrop, which iOS drops from the top
         layer the instant you close, cutting the scrim. So the dim
         rides the sheet here and stays in sync with the slide:
           1) bleed slab below the edge (vaul's trick) — fills any strip
              iOS exposes under the top layer when the toolbar collapses;
           2) full-screen scrim via 100vmax spread — the visible dim,
              its alpha animating with the sheet. 100vmax keeps coverage
              even as the shadow rides the sliding sheet down. */
      box-shadow:
        0 4rem 0 0 var(--color-surface-overlay),
        0 0 0 100vmax oklch(0 0 0 / 0);
      transition:
        box-shadow 0.15s, translate 0.15s,
        overlay 0.15s allow-discrete, display 0.15s allow-discrete;
      /* the sheet SLIDES fully off the bottom and stays opaque — only
         the scrim fades. A small nudge + opacity fade read as a
         dissolve-in-place, wrong for a bottom sheet. */
      translate: 0 100%;
      opacity: 1;
    }
    :where(dialog[data-drawer][open]) {
      translate: 0 0;
      box-shadow:
        0 4rem 0 0 var(--color-surface-overlay),
        0 0 0 100vmax oklch(0 0 0 / 0.4);
    }
    @starting-style {
      :where(dialog[data-drawer][open]) {
        translate: 0 100%;
        box-shadow:
          0 4rem 0 0 var(--color-surface-overlay),
          0 0 0 100vmax oklch(0 0 0 / 0);
      }
    }
    /* With drawer.js, keep only the bleed slab; its ordinary fixed
       overlay owns the visible scrim and follows drag progress. */
    :where(:root[data-drawer-gestures])
      :where(dialog[data-drawer]) {
      box-shadow: 0 4rem 0 0 var(--color-surface-overlay);
    }

    :where([data-mica-drawer-overlay]) {
      display: block;
      position: fixed;
      inset: 0;
      z-index: 50;
      inline-size: 100lvw;
      block-size: 100lvh;
      background: oklch(0 0 0 / 0.4);
      opacity: var(--m-drawer-overlay-opacity, 0);
      pointer-events: none;
      transition: opacity 0.15s;
    }

    /* The fallback shadow or managed overlay replaces ::backdrop here;
       keep it clear so the scrims don't double up or flash on iOS. */
    :where(dialog[data-drawer][open])::backdrop {
      background: oklch(0 0 0 / 0);
    }

    /* grab handle — only when drawer.js is loaded (an affordance
       without its behavior would fake interactivity; PROGRESSIVE.md).
       the handle is the first flex item of the open sheet. */
    :where(:root[data-drawer-gestures])
      :where(dialog[data-drawer][open])::before {
      content: "";
      align-self: center;
      flex-shrink: 0;
      inline-size: 2.5rem;
      block-size: 0.25rem;
      margin-block-start: var(--space-sm);
      background: var(--color-border-strong);
      border-radius: var(--radius-full);
    }
    :where(:root[data-drawer-gestures])
      :where(dialog[data-drawer]) > :where(header) {
      touch-action: none; /* the drag surface must own its touches */
    }
  }

  /* scroll lock: the page must not scroll behind any modal dialog.
     CSS-only best effort (→ no faked-behavior violation); iOS honors
     overflow:hidden on the root for modern versions. */
  :where(html):has(:where(dialog:modal)) {
    overflow: hidden;
    overscroll-behavior: none;
  }

  /* --- accordion / disclosure: details + summary -------------------- *
   * shadcn accordion look; exclusivity is <details name="group">.
   * open/close animation via ::details-content + interpolate-size,
   * graceful (instant) where unsupported.
   * ------------------------------------------------------------------ */
  :where(details) {
    border-block-end: 1px solid var(--color-border);
  }
  /* Stacked disclosures sit flush, one divider between them; the flow
     margin only follows the last of a run. */
  :where(details:has(+ details)) {
    margin-block-end: 0;
  }

  :where(summary) {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-block: var(--space-md);
    font-size: var(--text-md);
    font-weight: 500;
    cursor: pointer;
    list-style: none;

    &:hover {
      text-decoration: underline;
    }

    /* chevron — masked so it rides currentColor-ish tokens */
    &::after {
      content: "";
      inline-size: 1rem;
      block-size: 1rem;
      flex-shrink: 0;
      background: var(--color-text-muted);
      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='m6 9 6 6 6-6'/%3E%3C/svg%3E")
        center / contain no-repeat;
      transition: rotate 0.2s;
    }
  }
  :where(summary)::-webkit-details-marker {
    display: none;
  }
  :where(details[open]) > :where(summary)::after {
    rotate: 180deg;
  }

  /* content: everything after the summary */
  :where(details) > :where(:not(summary)) {
    margin-block: 0 var(--space-md);
    font-size: var(--text-md);
  }

  :where(details)::details-content {
    block-size: 0;
    overflow-y: clip;
    transition:
      block-size 0.2s,
      content-visibility 0.2s allow-discrete;
  }
  :where(details[open])::details-content {
    block-size: auto;
  }

  /* --- popover: panels + menus -------------------------------------- *
   * toggle/light-dismiss/Esc are the browser's (popovertarget). anchored
   * to the invoker where anchor positioning exists; elsewhere the UA's
   * centered fallback applies. items close declaratively via
   * popovertarget/command — zero JS throughout.
   * ------------------------------------------------------------------ */
  :where([popover]) {
    border: 1px solid color-mix(in oklch, var(--color-text) 12%, transparent);
    border-radius: var(--radius-md);
    background: var(--color-surface-overlay);
    color: var(--color-text);
    padding: var(--space-sm);
    inline-size: max-content;
    max-inline-size: min(18rem, calc(100vw - 2rem));
    font-size: var(--text-xs);
    line-height: 1.6;
    box-shadow: 0 8px 24px light-dark(oklch(0 0 0 / 0.15), oklch(0 0 0 / 0.5));
    opacity: 1;
    scale: 1;
  }
  /* enter animates; close is instant (house rule for transient layers).
     Gated on `overlay` support: iOS lacks it, and its top-layer
     transitions are broken — a popover with an @starting-style entry
     freezes at the start (opacity:0 = invisible) with no reflow to kick
     it, and there's no CSS way to force one. Where overlay is
     unsupported, skip the entrance so popovers render at their resting
     opacity:1 instead of vanishing. (This is why toasts "didn't work"
     on iOS.) */
  @supports (overlay: auto) {
    :where([popover]:popover-open) {
      transition:
        opacity 0.1s,
        scale 0.1s,
        overlay 0.1s allow-discrete,
        display 0.1s allow-discrete;
    }
    @starting-style {
      :where([popover]:popover-open) {
        opacity: 0;
        scale: 0.95;
      }
    }
  }
  /* anchor to the invoker where the platform can */
  @supports (position-area: block-end) {
    :where([popover]) {
      position-area: block-end span-inline-end;
      position-try-fallbacks: flip-block, flip-inline;
      /* block axis only: the gap sits between invoker and panel, and the
         panel's start (or, flipped, end) edge lines up with the invoker */
      margin: var(--space-2xs) 0;
    }
  }

  /* menu: a popover of buttons/links; separators are plain hrs */
  :where([popover].menu) {
    padding: var(--space-2xs);
    min-inline-size: 8rem;

    & > :where(button, a) {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      gap: var(--space-xs);
      inline-size: 100%;
      block-size: auto;
      padding: var(--space-xs);
      border: 0;
      border-radius: var(--radius-sm);
      background: transparent;
      color: var(--color-text);
      font-size: var(--text-xs);
      font-weight: 400;
      text-align: start;
      text-decoration: none;
      cursor: default;

      /* :not() guards mirror the base button states — an override of
         state must match the state's specificity (house rule) */
      &:hover:not(:disabled, [aria-disabled="true"]),
      &:focus-visible:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-accent);
        color: var(--color-on-accent);
        outline: none; /* the highlight is the focus indicator here */
      }
      &:active:not(:disabled, [aria-disabled="true"]) {
        background: var(--color-accent);
        color: var(--color-on-accent);
      }

      &:is([data-variant="danger"]) {
        color: var(--color-danger-text);

        &:hover:not(:disabled, [aria-disabled="true"]),
        &:active:not(:disabled, [aria-disabled="true"]),
        &:focus-visible:not(:disabled, [aria-disabled="true"]) {
          background: var(--color-danger-surface);
          color: var(--color-danger-text);
        }
      }

      /* aria-disabled links/buttons dim like :disabled (links have no
         :disabled; a button's aria-disabled would otherwise take the base
         button's 0.55). :is() keeps the (0,1,0) that beats danger color. */
      &:is(:disabled, [aria-disabled="true"]) {
        opacity: 0.5;
        background: transparent;
        color: var(--color-text);
      }
    }

    & > :where(hr) {
      margin-block: var(--space-2xs);
      margin-inline: calc(-1 * var(--space-2xs));
      border-block-start-color: var(--color-border);
    }
  }

  /* --- combobox: m-combobox + combobox.js (JS-enhanced) ------------------ *
   * without the module: a native datalist — functional autocomplete.
   * with it: styled listbox, filtering, active-descendant keys.
   * positioned within the wrapper (no top layer) so it works everywhere.
   * ------------------------------------------------------------------ */
  :where(m-combobox) {
    display: block;
    position: relative;
  }

  :where(m-combobox) > :where([data-combobox-popup]) {
    position: absolute;
    inset-block-start: calc(100% + var(--space-xs));
    inset-inline: 0;
    z-index: 50;
    max-block-size: 15rem;
    overflow-y: auto;
    padding: var(--space-2xs);
    border: 1px solid color-mix(in oklch, var(--color-text) 12%, transparent);
    border-radius: var(--radius-md);
    background: var(--color-surface-overlay);
    box-shadow: 0 8px 24px light-dark(oklch(0 0 0 / 0.15), oklch(0 0 0 / 0.5));
  }

  :where(m-combobox) :where([role="option"]) {
    padding: var(--space-xs);
    border-radius: var(--radius-sm);
    font-size: var(--text-md);
    cursor: default;

    /* disabled rows can't be chosen (combobox.js skips them): no fill */
    &:hover:not([aria-disabled="true"]),
    &[aria-selected="true"] {
      background: color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay));
      color: var(--color-text);
    }
  }

  :where(m-combobox > input) { display: block; inline-size: 100%; }
  :where(m-combobox [role="option"] > small) { display: block; color: var(--color-text-muted); font-size: var(--text-xs); }
  :where(m-combobox [role="option"][aria-disabled="true"]) { opacity: .45; }
  /* the popup's copy of the authored status (combobox.js). Inline padding
     matches options so status text lines up with labels. */
  :where(m-combobox [data-combobox-popup] > [data-combobox-status]) { margin: 0; padding: var(--space-sm) var(--space-xs); font-size: var(--text-md); color: var(--color-text-muted); }
  :where(m-combobox [data-combobox-status] > *) { margin: 0; }
  /* the authored status stays in place as the live region, heard not seen */
  :where(m-combobox[data-m-combobox-ready] > [role="status"]) {
    position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  :where(m-combobox) [hidden] { display: none; }

  /* --- tabs: m-tabs + tabs.js (JS-enhanced) ------------------------------ *
   * without the module: inert nav, all panels visible in order —
   * complete content. with it: tablist semantics + roving focus.
   * default: muted track + surface active tab. variant="underline":
   * quiet rail + accent selection line; behavior stays identical.
   * ------------------------------------------------------------------ */
  :where(m-tabs) {
    --m-tabs-rail-gap: var(--space-2xs);
    --m-tabs-rail-padding: var(--space-2xs);
    --m-tabs-rail-radius: var(--radius-md);
    --m-tabs-rail-background: var(--color-fill-hover);
    --m-tabs-overflow-cover: var(--color-fill-hover);
    --m-tabs-overflow-duration: 0.15s;
    --m-tabs-overflow-marker: color-mix(in oklch, var(--color-text-muted) 70%, transparent);
    --m-tabs-overflow-start-gutter: 0px;
    --m-tabs-overflow-end-gutter: 0px;
    --m-tabs-overflow-start: 0;
    --m-tabs-overflow-end: 0;
    --m-tabs-overflow-block-end: 0px;
    --m-tabs-tab-radius: var(--radius-sm);
    --m-tabs-tab-edge-padding: var(--space-sm);
    --m-tabs-tab-focus-offset: var(--focus-ring-offset);
    --m-tabs-tab-selected-background: var(--color-surface);
    --m-tabs-tab-selected-shadow: 0 1px 2px oklch(0 0 0 / 0.08);
    display: block;
  }

  :where(m-tabs[variant="underline"]) {
    --m-tabs-rail-gap: 0;
    --m-tabs-rail-padding: 0px; /* a length: the markers negate it */
    --m-tabs-rail-radius: 0;
    /* The rail line is the nav's bottom pixel, not a border: the selected
       tab's 1px accent line replaces it instead of stacking above it, and
       markers stop short of it so it runs unbroken. Background, not
       border, also keeps it above a classic scrollbar (padding-box
       origin) before enhancement. */
    --m-tabs-rail-background: linear-gradient(var(--color-border), var(--color-border))
      bottom / 100% 1px no-repeat;
    --m-tabs-overflow-cover: var(--color-surface);
    --m-tabs-overflow-block-end: 1px;
    --m-tabs-tab-radius: 0;
    --m-tabs-tab-edge-padding: 0;
    --m-tabs-tab-focus-offset: -2px;
    --m-tabs-tab-selected-background: transparent;
    --m-tabs-tab-selected-shadow: inset 0 -1px var(--color-accent);
  }

  :where(m-tabs) > :where(nav) {
    display: inline-flex;
    gap: var(--m-tabs-rail-gap);
    padding: var(--m-tabs-rail-padding);
    border-radius: var(--m-tabs-rail-radius);
    background: var(--m-tabs-rail-background);

    /* Graceful collapse: labels never wrap inside a tab — when the rail
       is narrower than its tabs it scrolls horizontally instead. Before
       enhancement, the native scrollbar remains the overflow affordance.
       tabs.js hides it, activates sticky direction markers in clear
       gutters, and reveals a selected tab within those gutters. Scroll
       chaining stays contained. */
    max-inline-size: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;

    &[role="tablist"] {
      scrollbar-width: none;
    }

    /* Sticky insets resolve against the padding-deflated scrollport;
       the negative rail padding pins each marker to the rail's outer
       edge so scrolled labels can't show through the padding strip —
       and the marker covers exactly the gutter #reveal clears. */
    &::before,
    &::after {
      content: "";
      position: sticky;
      z-index: 1;
      align-self: stretch;
      margin-block-end: var(--m-tabs-overflow-block-end);
      background-color: var(--m-tabs-overflow-cover);
      background-position: center;
      background-size: 6px 10px;
      background-repeat: no-repeat;
      pointer-events: none;
    }

    &::before {
      inset-inline-start: calc(-1 * var(--m-tabs-rail-padding));
      flex: 0 0 var(--space-md);
      inline-size: var(--space-md); /* WebKit sizes the rail from this, not flex-basis */
      margin-inline-end: calc(var(--m-tabs-overflow-start-gutter) - var(--space-md));
      opacity: var(--m-tabs-overflow-start);
      background-image: conic-gradient(from 45deg at left center,
        var(--m-tabs-overflow-marker) 0 25%, transparent 0);
      transition:
        opacity var(--m-tabs-overflow-duration),
        margin-inline-end var(--m-tabs-overflow-duration);
    }

    &::after {
      inset-inline-end: calc(-1 * var(--m-tabs-rail-padding));
      flex: 0 0 var(--space-md);
      inline-size: var(--space-md);
      margin-inline-start: calc(var(--m-tabs-overflow-end-gutter) - var(--space-md));
      opacity: var(--m-tabs-overflow-end);
      background-image: conic-gradient(from 225deg at right center,
        var(--m-tabs-overflow-marker) 0 25%, transparent 0);
      transition:
        opacity var(--m-tabs-overflow-duration),
        margin-inline-start var(--m-tabs-overflow-duration);
    }

    &:dir(rtl)::before {
      background-image: conic-gradient(from 225deg at right center,
        var(--m-tabs-overflow-marker) 0 25%, transparent 0);
    }

    &:dir(rtl)::after {
      background-image: conic-gradient(from 45deg at left center,
        var(--m-tabs-overflow-marker) 0 25%, transparent 0);
    }

    & > :where(button) {
      flex-shrink: 0;
      white-space: nowrap;
      block-size: var(--control-height-sm);
      padding-inline: var(--space-sm);
      border: 0;
      border-radius: var(--m-tabs-tab-radius);
      background: transparent;
      color: var(--color-text-muted);

      &:first-of-type {
        padding-inline-start: var(--m-tabs-tab-edge-padding);
      }

      &:last-of-type {
        padding-inline-end: var(--m-tabs-tab-edge-padding);
      }

      &:focus-visible {
        outline-offset: var(--m-tabs-tab-focus-offset);
      }

      /* :not() guards mirror the base button states (house rule) */
      &:hover:not(:disabled, [aria-disabled="true"]),
      &:active:not(:disabled, [aria-disabled="true"]) {
        background: transparent;
        color: var(--color-text);
      }

      &[aria-selected="true"] {
        background: var(--m-tabs-tab-selected-background);
        color: var(--color-text);
        box-shadow: var(--m-tabs-tab-selected-shadow);

        &:hover:not(:disabled, [aria-disabled="true"]),
        &:active:not(:disabled, [aria-disabled="true"]) {
          background: var(--m-tabs-tab-selected-background);
          color: var(--color-text);
        }
      }
    }
  }

  /* Vendor pseudo gets its own rule: one unknown selector in a list
     invalidates the whole list. */
  :where(m-tabs) > :where(nav[role="tablist"])::-webkit-scrollbar {
    display: none;
  }

  :where(m-tabs) > :where(section) {
    padding-block: var(--space-md);
  }

  /* --- toast: display only (queueing/auto-dismiss are JS-enhanced) ------- *
   * <m-toast popover="manual" role="status"> — manual so it survives
   * light dismiss and other popovers; role=status announces.
   * ------------------------------------------------------------------ */
  :where(m-toast[popover]) {
    position-area: none; /* not anchored — pinned to the corner */
    /* --m-toast-offset comes from toast.js when stacking; 0 without it */
    inset: auto var(--space-lg) calc(var(--space-lg) + var(--m-toast-offset, 0px)) auto;
    margin: 0;
    /* the corner inset on both sides, so phones get even gutters */
    inline-size: min(22rem, calc(100vw - 2 * var(--space-lg)));
    max-inline-size: none;
    padding: var(--space-md);
    padding-inline-end: var(--space-2xl); /* room for the corner X */
    translate: 0 0;

    & :where(b) {
      display: block;
      font-weight: 500;
    }
    & :where(span, p) {
      color: var(--color-text-muted);
    }

    /* variant = a status glyph before the title, masked so it takes
       the status color; the content indents to clear it */
    &:where([variant]) {
      padding-inline-start: calc(var(--space-md) + 0.875rem + var(--space-xs));
    }
    &:where([variant])::before {
      content: "";
      position: absolute;
      /* centered on the title's first line */
      inset-block-start: calc(var(--space-md) + (1lh - 0.875rem) / 2);
      inset-inline-start: var(--space-md);
      inline-size: 0.875rem;
      block-size: 0.875rem;
      background: var(--m-toast-tone);
      mask: var(--m-toast-glyph) center / contain no-repeat;
    }
    &:where([variant="success"]) {
      --m-toast-tone: var(--color-success);
      --m-toast-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='square'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m8 12 3 3 5-6'/%3E%3C/svg%3E");
    }
    &:where([variant="warning"]) {
      --m-toast-tone: var(--color-warn);
      --m-toast-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='square'%3E%3Cpath d='M12 3 2 21h20z'/%3E%3Cpath d='M12 10v4M12 17.5v.5'/%3E%3C/svg%3E");
    }
    &:where([variant="danger"]) {
      --m-toast-tone: var(--color-danger);
      --m-toast-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.25' stroke-linecap='square'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 7v6M12 16.5v.5'/%3E%3C/svg%3E");
    }
  }
  /* --toast-position overrides (base = bottom-right). Style queries read
     the token from the toast's parent; without support the default
     corner stands — graceful. Stack offset feeds whichever block inset
     is active; centers use inset-inline 0 + auto margins. */
  @container style(--toast-position: bottom-left) {
    :where(m-toast[popover]) {
      inset: auto auto calc(var(--space-lg) + var(--m-toast-offset, 0px)) var(--space-lg);
    }
  }
  @container style(--toast-position: bottom-center) {
    :where(m-toast[popover]) {
      inset: auto 0 calc(var(--space-lg) + var(--m-toast-offset, 0px)) 0;
      margin-inline: auto;
    }
  }
  @container style(--toast-position: top-right) {
    :where(m-toast[popover]) {
      inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) var(--space-lg) auto auto;
    }
  }
  @container style(--toast-position: top-left) {
    :where(m-toast[popover]) {
      inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) auto auto var(--space-lg);
    }
  }
  @container style(--toast-position: top-center) {
    :where(m-toast[popover]) {
      inset: calc(var(--space-lg) + var(--m-toast-offset, 0px)) 0 auto 0;
      margin-inline: auto;
    }
  }

  /* restacking motion always (both block insets — only the active one
     ever changes); the entrance slide/fade only where overlay
     transitions work — see the base popover note. */
  :where(m-toast[popover]:popover-open) {
    transition:
      inset-block-end 0.15s,
      inset-block-start 0.15s;
  }
  @supports (overlay: auto) {
    :where(m-toast[popover]:popover-open) {
      transition:
        opacity 0.1s,
        translate 0.1s,
        inset-block-end 0.15s,
        inset-block-start 0.15s,
        overlay 0.1s allow-discrete,
        display 0.1s allow-discrete;
    }
    @starting-style {
      :where(m-toast[popover]:popover-open) {
        translate: 0 0.75rem;
      }
    }
    /* top positions enter from above — must follow the base
       @starting-style in source order to win at equal specificity */
    @container style(--toast-position: top-right) or
               style(--toast-position: top-left) or
               style(--toast-position: top-center) {
      @starting-style {
        :where(m-toast[popover]:popover-open) {
          translate: 0 -0.75rem;
        }
      }
    }
  }

  /* --- tooltip: css-only, [data-tip] -------------------------------- *
   * inverted chip (primary on on-primary), shows on hover/focus after a
   * beat, hides instantly. data-tip is visual — pair it with aria-label
   * or visible text for AT.
   * ------------------------------------------------------------------ */
  :where([data-tip]) {
    position: relative;
  }
  :where([data-tip])::after {
    content: attr(data-tip);
    position: absolute;
    inset-block-end: calc(100% + var(--space-xs));
    inset-inline-start: 50%;
    translate: -50% 2px;
    inline-size: max-content;
    max-inline-size: 18rem;
    padding: 0.375rem var(--space-sm);
    border-radius: var(--radius-sm);
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-size: var(--text-xs);
    font-weight: 400;
    line-height: 1.4;
    opacity: 0;
    pointer-events: none;
    transition:
      opacity 0.1s,
      translate 0.1s;
    z-index: 10;
  }
  :where([data-tip]:hover, [data-tip]:focus-visible)::after {
    opacity: 1;
    translate: -50% 0;
    transition-delay: 0.3s;
  }

  /* --- validation errors ------------------------------------------- *
   * No JS: a generic <m-error> after a field shows when the
   * field is :user-invalid. Submit attempts fall back to native bubbles.
   * Enhanced (mica/field.js): <m-field> suppresses bubbles and activates
   * per-cause <m-error match="..."> messages. Rules below are all
   * zero-specificity; source order resolves them.
   * ------------------------------------------------------------------ */
  :where(m-field) {
    display: flex;
    flex-direction: column;
    gap: var(--space-2xs);
  }

  /* a disabled field dims its label and helper, like a disabled
     fieldset: the label is a sibling (for=), so the wrapping-label
     rule never reaches it */
  :where(m-field:has(:is(input, textarea, select):disabled)) {
    color: var(--color-text-muted);

    & :where(label) {
      color: var(--color-text-muted);
      cursor: not-allowed;
    }
  }

  /* every rule here is zero-specificity: source order alone resolves */
  :where(m-error) {
    display: none;
    font-size: var(--text-md);
    color: var(--color-danger-text);
  }

  /* no-JS fallback: generic (matchless) error after user interaction */
  :where(input:user-invalid, textarea:user-invalid, select:user-invalid)
    ~ :where(m-error:not([match])) {
    display: block;
  }

  /* enhanced: once m-field upgrades, the module owns visibility */
  :where(m-field:defined) :where(m-error) {
    display: none;
  }
  :where(m-error[active]) {
    display: block;
  }

  /* --- header navigation: native links + optional header.js collapse --- */
  :where(m-header) {
    container: m-header / inline-size;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--header-gap, var(--space-md));
    padding: var(--header-pad, var(--space-sm)) var(--header-gutter, var(--space-md));
    border-block-end: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
    /* align="end" is also an HTML presentational hint (text-align: end on
       any element); reset so it only places links, not panel text. */
    text-align: start;
  }
  :where(m-header > [data-brand]) {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    min-block-size: var(--control-height);
    color: var(--color-text);
    font-weight: var(--header-strong-weight, 650);
    text-decoration: none;
    overflow-wrap: anywhere;
  }
  :where(m-header > nav) {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2xs);
    min-inline-size: 0;
    justify-content: var(--header-nav-align, start);
  }
  :where(m-header[align="end"]) { --header-nav-align: end; }
  :where(m-header > nav > a) {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--control-height);
    padding: var(--space-2xs) var(--space-sm);
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    font-size: var(--header-font-size, var(--text-md));
    font-weight: var(--header-font-weight, 500);
    text-decoration: none;
    overflow-wrap: anywhere;
  }
  :where(m-header > nav > a):hover:not([aria-disabled="true"]) { background: var(--color-surface-raised); color: var(--color-text); }
  :where(m-header > nav > a)[aria-current="page"]{ background: var(--color-surface-raised); color: var(--color-text); font-weight: var(--header-strong-weight, 650); }
  :where(m-header > nav > a)[aria-disabled="true"]{ color: var(--color-text-muted); opacity: .5; }
  :where(m-header > [data-actions]) { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-xs); margin-inline-start: auto; }
  /* A small enhancement switches the same nav between inline and native
     popover. Without script, all links stay visible in the wrapping header. */
  :where(m-header > [data-menu]) { display: none; }
  :where(m-header > nav > [data-compact]) { display: none; }
  :where(m-header[data-m-header-collapsed]) { flex-wrap: nowrap; }
  :where(m-header[data-m-header-collapsed] > [data-brand]) { min-inline-size: 0; }
  :where(m-header[data-m-header-collapsed] > [data-actions]) { display: none; }
  :where(m-header[data-m-header-collapsed] > [data-menu]) { display: inline-flex; margin-inline-start: auto; flex: none; }
  :where(m-header > nav[popover]):not(:popover-open) { display: none; }
  :where(m-header > nav[popover]):popover-open{
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: start;
    align-items: stretch;
    gap: var(--space-2xs);
    position: fixed;
    position-area: none;
    max-inline-size: none;
    scale: 1;
    inset: auto;
    top: var(--m-header-menu-top);
    left: var(--m-header-menu-left);
    width: var(--m-header-menu-width);
    max-block-size: var(--m-header-menu-height);
    overflow-y: auto;
    margin: 0;
    padding: var(--space-xs);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface-overlay);
    color: var(--color-text);
    box-shadow: none;
    opacity: 1;
    transform: none;
    transition: none;
    animation: none;
  }
  :where(m-header > nav[popover] > a) { min-block-size: var(--header-target-height, 2.75rem); flex-shrink: 0; }
  /* Shared overlay-row fill (select, menu, command, breadcrumbs): the panel
     is surface-overlay, which equals surface-raised in dark, so the inline
     hover/current fill would vanish. Specificity matches the inline rules. */
  :where(m-header > nav[popover] > a):hover:not([aria-disabled="true"]),
  :where(m-header > nav[popover] > a)[aria-current="page"] {
    background: color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay));
  }
  :where(m-header > nav[popover] > [data-compact]) { display: inline-flex; }
  :where(m-header > nav[popover] > :not([data-compact]) + [data-compact]) { border-block-start: 1px solid var(--color-border); }
  :where(m-header > [data-menu] svg) { inline-size: 1rem; block-size: 1rem; }


  :where(m-header > [data-menu]) { --m-header-collapse: 0; }
  @container m-header (inline-size < 40rem) {
    :where(m-header > [data-menu]) { --m-header-collapse: 1; }
  }


  /* Navigation disclosures: native details remain usable without header.js.
     Enhancement adds floating placement; mobile keeps content in flow.
     Panel contents are authored links and layouts, never ARIA menu widgets. */
  :where(m-header > nav[data-navigation-menu]) {
    --nav-panel-width: 34rem;
    --nav-panel-gap: var(--space-xs);
    --nav-panel-pad: var(--space-xs);
    --nav-panel-link-pad: var(--space-sm);
    --nav-panel-description-size: var(--text-sm);
    --nav-panel-heading-size: var(--text-2xs);
    --nav-panel-z: 10;
  }
  :where(m-header > nav[data-navigation-menu] > details) { margin: 0; padding: 0; border: 0; background: none; max-inline-size: 100%; }
  :where(m-header > nav[data-navigation-menu] > details)::details-content { transition: none; overflow: visible; }
  :where(m-header > nav[data-navigation-menu] > details > summary) {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    min-block-size: var(--control-height);
    padding: var(--space-2xs) var(--space-sm);
    font-size: var(--header-font-size, var(--text-md));
    font-weight: var(--header-font-weight, 500);
    color: var(--color-text-muted);
    border-radius: var(--radius-md);
  }
  :where(m-header > nav[data-navigation-menu] > details > summary):hover {
    text-decoration: none; color: var(--color-text); background: var(--color-surface-raised);
  }
  :where(m-header > nav[data-navigation-menu] > details)[open] > :where(summary) {
    color: var(--color-text); background: var(--color-surface-raised);
  }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel]) {
    inline-size: min(var(--nav-panel-width), var(--m-nav-max-width, calc(100vw - 2 * var(--nav-panel-gap))));
    max-inline-size: 100%;
    max-block-size: var(--m-nav-height, none);
    margin: 0;
    padding: var(--nav-panel-pad);
    row-gap: var(--nav-panel-gap);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-overlay);
    overflow: auto;
  }
  :where(m-header > nav[data-m-navigation-ready] > details > [data-nav-panel]) {
    position: fixed; z-index: var(--nav-panel-z);
    left: var(--m-nav-left); top: var(--m-nav-top);
  }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] a) {
    display: block;
    padding: var(--nav-panel-link-pad);
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
    font-size: var(--header-font-size, var(--text-md));
    overflow-wrap: anywhere;
  }
  /* Panels (and the collapsed Menu) are surface-overlay, which equals
     surface-raised in dark: rows use the shared overlay-row fill. */
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] a):hover:not([aria-disabled="true"]),
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] a)[aria-current="page"] {
    background: color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay));
  }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] a)[aria-disabled="true"] { opacity: .5; }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] strong) { display: block; font-weight: var(--header-strong-weight, 650); }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] small) {
    display: block; margin-block-start: var(--space-2xs);
    font-size: var(--nav-panel-description-size); color: var(--color-text-muted);
  }
  :where(m-header > nav[data-navigation-menu] [data-nav-panel] h2) {
    margin: 0; padding: var(--nav-panel-link-pad);
    font-size: var(--nav-panel-heading-size); font-weight: var(--header-font-weight, 500); color: var(--color-text-muted);
  }
  :where(m-header[data-m-header-collapsed] > nav[data-navigation-menu] > details) { flex-shrink: 0; }
  :where(m-header[data-m-header-collapsed] > nav[data-navigation-menu] > details > summary) { min-block-size: var(--header-target-height, 2.75rem); }
  /* Inside the surface-overlay Menu, summaries take the overlay-row fill
     too; specificity matches the bar's :hover / [open] rules. */
  :where(m-header[data-m-header-collapsed] > nav[data-navigation-menu] > details > summary):hover,
  :where(m-header[data-m-header-collapsed] > nav[data-navigation-menu] > details)[open] > :where(summary) {
    background: color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay));
  }
  :where(m-header[data-m-header-collapsed] > nav[data-navigation-menu] > details > [data-nav-panel]) {
    position: static; inline-size: auto; max-block-size: none;
    margin: var(--space-xs) var(--space-sm); padding: 0 0 0 var(--space-xs);
    padding-inline: var(--space-xs) 0;
    border: 0; border-inline-start: 1px solid var(--color-border);
    border-radius: 0; background: transparent; overflow: visible;
  }

  /* Cards are presentation shells, not landmarks or click targets.
     Each part is optional. A flush body delegates spacing to its child.
     Borderless theme: --card-border: transparent; --card-background: transparent. */
  :where(m-card) {
    --card-pad: var(--space-lg);
    --card-background: var(--color-surface);
    --card-border: var(--color-border);
    display: block;
    min-inline-size: 0;
    border: 1px solid var(--card-border);
    border-radius: var(--radius-md);
    background: var(--card-background);
  }
  :where(m-card-header, m-card-body, m-card-footer) {
    --m-card-divider-width: 0px;
    min-inline-size: 0;
    border-block-start: var(--m-card-divider-width) solid var(--card-divider-color, var(--color-border));
  }
  :where(m-card-header[divider], m-card-body[divider], m-card-footer[divider]) { --m-card-divider-width: 1px; }
  :where(m-card-header) {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--card-gap, var(--space-md)); padding: var(--card-pad, var(--space-lg));
  }
  :where(m-card-header > div) { min-inline-size: 0; overflow-wrap: anywhere; }
  :where(m-card-header :is(h1,h2,h3,h4,h5,h6)) { margin: 0; font-size: var(--card-title-size, var(--text-lg)); }
  :where(m-card-header p) { margin: var(--space-2xs) 0 0; font-size: var(--card-description-size, var(--text-sm)); color: var(--color-text-muted); }
  :where(m-card-header > button, m-card-header > a) { flex-shrink: 0; }
  /* A bare header link sits at the description's size, a footer link at
     the footer text's size; body-size links read as louder than either.
     Links dressed as buttons (.btn) keep the button's size. */
  :where(m-card-header > a:not(.btn)) { font-size: var(--card-description-size, var(--text-sm)); }
  /* Header actions are quiet: a button without a data-variant is ghost
     (no rest fill or border; the button's own hover/active fills still
     apply). Set data-variant="primary" or "danger" to emphasise one.
     Bordered header buttons, as a theme snippet (unlayered CSS):
       m-card-header > :is(button, .btn):not([data-variant]) {
         background: var(--color-fill);
         border-color: var(--color-border-strong);
         margin-inline-end: 0;
       } */
  /* With no visible box, the label (not the box) aligns with the
     content edge: pull the button out by its own inline padding. */
  :where(m-card-header > :is(button, .btn):not([data-variant])) {
    background: transparent;
    border-color: transparent;
    margin-inline-end: calc(-1 * var(--space-md));
  }
  :where(m-card-header > :is(button, .btn):not([data-variant])[data-size="small"]) { margin-inline-end: calc(-1 * var(--space-sm)); }
  :where(m-card-header > :is(button, .btn):not([data-variant])[data-size="large"]) { margin-inline-end: calc(-1 * var(--space-lg)); }
  :where(m-card-body) { --m-card-body-padding: var(--card-pad, var(--space-lg)); display: block; padding: var(--m-card-body-padding); }
  :where(m-card-body[flush]) { --m-card-body-padding: 0px; }
  :where(m-card-body > :first-child) { margin-block-start: 0; }
  :where(m-card-body > :last-child) { margin-block-end: 0; }
  :where(m-card-footer) {
    display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
    gap: var(--card-footer-gap, var(--space-sm)); padding: var(--space-md) var(--card-pad, var(--space-lg));
  }
  :where(m-card-footer > p) { margin: 0; font-size: var(--card-footer-size, var(--text-xs)); color: var(--color-text-muted); }
  :where(m-card-footer > a:not(.btn)) { font-size: var(--card-footer-size, var(--text-xs)); }
  :where(m-card[hidden], m-card-header[hidden], m-card-body[hidden], m-card-footer[hidden]) { display: none; }

  /* Native lists retain their semantics with role=list (Safari marker reset).
     Dividers align with content edges, never the surrounding card's border.
     Hiding their paint preserves row geometry. No selection or row-wide click. */
  :where(ul[data-list], ol[data-list]) {
    --list-inset: 0px;
    --list-divider-color: var(--color-border);
    list-style: none; margin: 0; padding: 0 var(--list-inset); min-inline-size: 0;
  }
  :where([data-list][data-dividers="none"]) { --list-divider-color: transparent; }
  :where([data-list] > li) {
    margin: 0;
    display: flex; align-items: var(--list-align, flex-start); gap: var(--list-gap, var(--space-sm));
    padding-block: var(--list-row-padding, var(--space-md)); min-inline-size: 0;
  }
  :where([data-list] > li + li) { border-block-start: 1px solid var(--list-divider-color); }
  :where([data-list-body]) { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
  :where([data-list-body] > p) { margin: 0; font-size: var(--list-font-size, var(--text-md)); line-height: var(--list-line-height, 1.55); }
  :where([data-list-body] > p + p) { margin-block-start: var(--space-xs); }
  /* A row that is one run of text may leave out the body: the li is then
     its own body (same type and wrapping), and its trailing part still
     sits at the inline end. Several paragraphs, a title with a
     description, or meta need data-list-body. Rows with a body are
     untouched. */
  :where([data-list] > li:not(:has(> [data-list-body]))) {
    font-size: var(--list-font-size, var(--text-md));
    line-height: var(--list-line-height, 1.55);
    overflow-wrap: anywhere;
  }
  :where([data-list] > li:not(:has(> [data-list-body])) > [data-list-trailing]) { margin-inline-start: auto; }
  :where([data-list-meta]) {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
    gap: var(--space-xs) var(--space-md); margin-block-start: var(--space-xs);
    color: var(--color-text-muted); font-size: var(--list-meta-size, var(--text-xs));
  }
  :where([data-list-actions]) { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
  :where([data-list-actions] button) {
    border: 0; background: transparent; color: var(--color-text-muted);
    font-size: var(--list-meta-size, var(--text-xs)); block-size: var(--control-height-sm); padding-inline: var(--space-xs);
  }
  :where([data-list-title]) { font-weight: var(--list-title-weight, 600); color: var(--color-text); font-size: var(--list-font-size, var(--text-md)); text-decoration: none; }
  :where(a[data-list-title]):hover { text-decoration: underline; }
  :where([data-list-description]) { display: block; color: var(--color-text-muted); font-size: var(--list-description-size, var(--text-sm)); margin-block-start: var(--space-2xs); }
  :where([data-list-leading]) {
    flex: 0 0 auto; inline-size: var(--list-leading-size, 2rem); block-size: var(--list-leading-size, 2rem);
    display: grid; place-items: center; color: var(--color-text-muted);
  }
  /* An avatar leading sizes its initials from the leading box (not its own
     3rem default) and keeps its own text colour, not the icon-muted one. */
  :where(m-avatar[data-list-leading]) {
    --avatar-size: var(--list-leading-size, 2rem);
    color: var(--m-avatar-content-color, var(--color-text));
  }
  :where([data-list-trailing]) {
    flex: 0 1 auto; min-inline-size: 0; overflow-wrap: anywhere;
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm);
    color: var(--color-text-muted); font-size: var(--list-description-size, var(--text-sm));
  }
  :where([data-list][hidden], [data-list] > li[hidden]) { display: none; }
  :where(m-card-body[flush] > [data-list]) { --list-inset: var(--card-pad, var(--space-lg)); }

  /* Data collections: application-owned rows and state, native table semantics.
     Column widths and sticky offsets are authored for the application's schema.
     Selection actions replace filters; keep filters inert while selection is active.
     For a taller action set, increase --table-toolbar-min-height to reserve space. */
  :where(:root) {
    --table-font-size: var(--text-sm);
    --table-padding: var(--space-lg);
    --table-cell-padding: var(--space-sm);
    --table-min-width: 54rem;
    --table-toolbar-min-height: 0px;
    --table-selected-background: var(--color-surface-raised);
    --table-edge-width: var(--space-md);
    --table-edge-color: color-mix(in oklch, var(--color-text) 14%, transparent);
    --table-state-padding: var(--space-2xl);
  }
  :where([data-data-table]) { container: mica-table / inline-size; background: var(--color-surface); border: 1px solid var(--color-border); min-inline-size: 0; }
  :where([data-table-heading]) { display:flex; justify-content:space-between; align-items:center; gap:var(--space-md); padding:var(--table-padding) var(--table-padding) var(--space-sm); }
  :where([data-table-heading] > button) { flex-shrink:0; white-space:nowrap; }
  :where([data-table-heading] h2) { margin:0; font-size:var(--table-heading-size, 1.375rem); }
  :where([data-table-heading] p) { margin:var(--space-2xs) 0 0; color:var(--color-text-muted); font-size:var(--table-font-size); }
  :where([data-table-toolbar]) { position:relative; min-block-size:var(--table-toolbar-min-height); }
  :where([data-table-filters], [data-table-selection]) { display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-xs); padding:var(--space-sm) var(--table-padding); }
  :where([data-table-filters] [data-table-search]) { flex:1; min-inline-size:12rem; }
  :where([data-table-search] input) { inline-size:100%; }
  :where([data-table-filters] select) { max-inline-size:11rem; }
  :where([data-table-filters] button) { white-space:nowrap; }
  :where([data-table-selection]) { position:absolute; inset:0; align-content:center; gap:var(--space-sm); font-size:var(--table-font-size); }
  :where([data-table-toolbar]):has(> [data-table-selection]:not([hidden])) > :where([data-table-filters]) { visibility:hidden; }
  :where([data-table-selection] [data-table-clear]) { margin-inline-start:auto; }
  :where([data-data-table] [hidden], [data-pagination] [hidden], [data-table-selection][hidden], [data-table-filters] [hidden], [data-table] [hidden]) { display:none; }
  :where(m-table-scroll) { display:block; position:relative; min-inline-size:0; }
  :where(m-table-scroll)::before, :where(m-table-scroll)::after { content:''; position:absolute; inset-block:1px; inline-size:var(--table-edge-width); z-index:4; pointer-events:none; opacity:0; }
  :where(m-table-scroll)::before { left:var(--m-table-edge-left, 0px); background:linear-gradient(to right,var(--table-edge-color),transparent); }
  :where(m-table-scroll)::after { right:var(--m-table-edge-right, 0px); background:linear-gradient(to left,var(--table-edge-color),transparent); }
  :where(m-table-scroll[data-m-overflow-left])::before, :where(m-table-scroll[data-m-overflow-right])::after { opacity:1; }
  :where([data-table-region]) { position:relative; overflow:auto; overscroll-behavior:contain; border-block:1px solid var(--color-border); }
  :where(table[data-table]) { margin:0; inline-size:100%; min-inline-size:var(--table-min-width, 54rem); border-collapse:separate; border-spacing:0; table-layout:fixed; }
  :where([data-table] th, [data-table] td) { padding:var(--table-cell-padding, var(--space-sm)); vertical-align:middle; font-size:var(--table-font-size, var(--text-sm)); }
  :where([data-table] thead th) { background:var(--color-surface-raised); color:var(--color-text-muted); font-weight:500; border-block-end:1px solid var(--color-border); }
  /* block-size undoes the button preset so --table-sort-target sets the height. */
  :where([data-table] th button) { display:inline-flex; align-items:center; gap:var(--space-xs); padding:0; block-size:auto; min-block-size:var(--table-sort-target, 2rem); border:0; background:none; color:inherit; font:inherit; text-align:inherit; white-space:nowrap; }
  :where([data-table] th[aria-sort]) button { color:var(--color-text); }
  :where([data-table] td a) { color:var(--color-text); font-weight:600; text-decoration:none; }
  :where([data-table] td) a:hover { text-decoration:underline; }
  :where([data-table-description]) { display:block; color:var(--color-text-muted); margin-block-start:var(--space-2xs); font-size:var(--table-description-size, var(--text-xs)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  :where([data-table] tbody tr:last-child td) { border-block-end:0; }
  :where([data-table] tbody tr[data-selected]) > td { background:var(--table-selected-background, var(--color-surface-raised)); }
  /* State and decorative loading rows are not records; they take no row hover.
     Matches the base tbody tr:hover rule at (0,1,0) and follows it. */
  :where([data-table] tbody tr:is([aria-hidden="true"], :has(> [data-table-state]))):hover { background:none; }
  :where([data-table-state]) { padding:var(--table-state-padding, var(--space-2xl)) var(--table-padding, var(--space-lg)); text-align:center; white-space:normal; }
  :where([data-table-state] strong) { display:block; color:var(--color-text); font-size:var(--table-state-font-size, var(--text-lg)); }
  :where([data-table-state] p) { margin-block:var(--space-xs) var(--space-md); color:var(--color-text-muted); }
  :where([data-table-region][data-state] table) { min-inline-size:100%; table-layout:auto; }
  :where([data-table-region][data-state] thead) { display:none; }
  :where([data-table-footer]) { container: mica-pagination / inline-size; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--space-md); padding:var(--space-md) var(--table-padding); font-size:var(--table-font-size); }
  :where([data-page-meta]) { display:flex; align-items:center; gap:var(--space-md); flex-wrap:wrap; color:var(--color-text-muted); }
  :where([data-page-size]) { display:flex; align-items:center; gap:var(--space-xs); }
  /* The value inherits the footer text size so the row reads as one line of
     metadata. Touch pointers keep the 16px floor: iOS zooms the page when a
     smaller field is focused. Theme snippet for 16px everywhere:
     :where([data-page-size] select) { font-size: 1rem } */
  :where([data-page-size] select) { inline-size:auto; block-size:var(--control-height-sm); padding-block:var(--space-2xs); font-size:inherit; }
  @media (pointer: coarse) {
    :where([data-page-size] select) { font-size:1rem; /* iOS field floor */ }
  }
  /* font-size on the nav reaches the ellipsis and status spans too. */
  :where(nav[data-pagination]) { --pagination-target:2.125rem; --pagination-font-size:var(--text-sm); display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2xs); font-size:var(--pagination-font-size); }
  /* block-size, weight and radius undo the button preset so button pages
     match link pages. */
  :where([data-pagination] > a, [data-pagination] > button, [data-pagination] > [aria-disabled]) { display:inline-flex; justify-content:center; align-items:center; min-inline-size:var(--pagination-target); min-block-size:var(--pagination-target); block-size:auto; padding:var(--space-2xs) var(--space-xs); border:0; border-radius:0; background:transparent; color:var(--color-text); font-size:var(--pagination-font-size); font-weight:inherit; text-decoration:none; }
  :where([data-pagination]) > a:hover { background:var(--color-surface-raised); }
  /* Outranks the button preset's :hover/:active:not(:disabled, …) at (0,2,0). */
  :where([data-pagination]) > button:is(:hover, :active):not(:disabled) { background:var(--color-surface-raised); }
  :where([data-page-ellipsis]) { color:var(--color-text-muted); }
  :where([data-pagination]) > [aria-current=page] { background:var(--color-surface-raised); font-weight:650; color:var(--color-text); }
  :where([data-pagination]) > :is([aria-disabled=true], :disabled) { color:var(--color-text-muted); cursor:default; opacity:1; }
  :where([data-page-status]) { display:none; color:var(--color-text-muted); font-size:var(--pagination-font-size); }
  @container mica-table (max-width:44rem) {
    :where([data-table-heading]) { padding:var(--space-md); }
    :where([data-table-filters]) { padding:0 var(--space-md) var(--space-sm); }
    :where([data-table-search]) { flex-basis:100%; }
    /* Selects grow from their content width (a basis of 0 squeezed the value
       text into two lines). One wrapped in a label for its name stretches
       through the label. */
    :where([data-table-filters] select) { flex:1 1 auto; min-inline-size:0; max-inline-size:none; }
    :where([data-table-filters] > label:has(> select)) { display:flex; flex:1 1 auto; min-inline-size:0; }
    :where([data-table-filters] > label > select) { inline-size:100%; }
    :where([data-table-selection]) { padding-inline:var(--space-md); }
    :where([data-table-footer]) { padding:var(--space-md); gap:var(--space-sm); }
    :where([data-table] [data-table-sticky]) { position:sticky; inset-inline-start:var(--table-sticky-offset, 0px); background:var(--color-surface); z-index:1; }
    :where([data-table] thead [data-table-sticky]) { background:var(--color-surface-raised); z-index:3; }
    /* Pinned cells are opaque; they carry the row hover fill themselves.
       Selected rows keep their fill: that rule outranks this one at (0,0,1). */
    :where([data-table] tbody tr:hover > [data-table-sticky]) { background:var(--color-surface-raised); }
  }
  /* A compact status is opt-in: include data-page-status to let numbered
     links collapse. Without it, every authored page link remains visible. */
  @container mica-pagination (max-width:40rem) {
    :where([data-page-meta]) { inline-size:100%; justify-content:space-between; gap:var(--space-xs); }
    :where([data-pagination]):has([data-page-status]) { inline-size:100%; justify-content:space-between; }
    :where([data-pagination]):has([data-page-status]) > :is([data-page-number], [data-page-ellipsis]) { display:none; }
    :where([data-pagination] [data-page-status]) { display:block; }
  }

  /* Breadcrumbs: native hierarchy with decorative separators. The current
     page is plain text; nothing is automatically removed on narrow screens.
     Override --breadcrumb-current-weight or --breadcrumb-separator-color
     to tune emphasis without changing the authored trail. */
  :where(nav[data-breadcrumbs]) {
    --breadcrumb-font-size: var(--text-sm);
    --breadcrumb-gap: var(--space-xs);
    --breadcrumb-row-gap: var(--space-2xs);
    --breadcrumb-current-weight: 500;
    --breadcrumb-separator-size: .3rem;
    --breadcrumb-separator-color: var(--color-text-muted);
    --breadcrumb-menu-width: 14rem;
    --breadcrumb-overflow-font-size: var(--text-lg);
    --breadcrumb-menu-target: 2.25rem;
    --breadcrumb-menu-z: 5;
    font-size: var(--breadcrumb-font-size);
    line-height: 1.5;
    color: var(--color-text-muted);
  }
  :where(nav[data-breadcrumbs] ol) {
    display: flex; align-items: center; flex-wrap: wrap;
    list-style: none; margin: 0; padding: 0;
    column-gap: var(--breadcrumb-gap); row-gap: var(--breadcrumb-row-gap);
  }
  /* margin resets the prose li rhythm in both the trail and the menu. */
  :where(nav[data-breadcrumbs] li) {
    display: flex; align-items: center; gap: var(--breadcrumb-gap); margin: 0;
    min-inline-size: 0; max-inline-size: 100%;
  }
  :where(nav[data-breadcrumbs] > ol > li + li)::before {
    content: ''; display: block; flex: none;
    inline-size: var(--breadcrumb-separator-size); block-size: var(--breadcrumb-separator-size);
    border: solid var(--breadcrumb-separator-color); border-width: 1px 1px 0 0;
    transform: rotate(45deg); margin-inline: var(--space-2xs);
  }
  :where(nav[data-breadcrumbs]:dir(rtl) > ol > li + li)::before { transform: rotate(225deg); }
  :where(nav[data-breadcrumbs] a) {
    color: var(--color-text-muted); text-decoration: none;
    overflow-wrap: anywhere; padding-block: var(--space-2xs);
  }
  :where(nav[data-breadcrumbs] a):hover { text-decoration: underline; color: var(--color-text); }
  :where(nav[data-breadcrumbs] [aria-current="page"]) {
    color: var(--color-text); font-weight: var(--breadcrumb-current-weight);
    overflow-wrap: anywhere; padding-block: var(--space-2xs);
  }
  :where(m-breadcrumb-overflow) { display: block; min-inline-size: 0; }
  :where(nav[data-breadcrumbs] details) { position: relative; margin: 0; border: 0; padding: 0; flex: none; }
  /* justify-content resets the accordion summary's space-between, which
     a single-track grid resolves to start (glyph pinned left). */
  :where(nav[data-breadcrumbs] summary) {
    display: grid; place-items: center; justify-content: center;
    inline-size: var(--breadcrumb-menu-target); min-block-size: var(--breadcrumb-menu-target);
    padding: 0; list-style: none; font-size: var(--breadcrumb-overflow-font-size);
    font-weight: var(--breadcrumb-current-weight); border-radius: var(--radius-md);
    color: var(--color-text-muted); cursor: pointer;
  }
  :where(nav[data-breadcrumbs] summary)::-webkit-details-marker { display: none; }
  :where(nav[data-breadcrumbs] summary)::after { display: none; }
  :where(nav[data-breadcrumbs] summary):hover,
  :where(nav[data-breadcrumbs] details)[open] > :where(summary) {
    background: var(--color-surface-raised); color: var(--color-text); text-decoration: none;
  }
  :where(nav[data-breadcrumbs] details)::details-content { transition: none; overflow: visible; }
  :where(nav[data-breadcrumbs] [data-breadcrumb-menu]) {
    position: absolute; inset-block-start: 100%; inset-inline-start: 0;
    inline-size: var(--breadcrumb-menu-width); max-inline-size: calc(100vw - var(--space-2xl));
    max-block-size: var(--m-breadcrumb-height, none); overflow: auto;
    z-index: var(--breadcrumb-menu-z); display: flex; flex-direction: column;
    align-items: stretch; flex-wrap: nowrap; gap: 0;
    margin: var(--space-2xs) 0 0; padding: var(--space-xs);
    border: 1px solid var(--color-border); border-radius: var(--radius-md);
    background: var(--color-surface-overlay);
    /* Restates the trail size over the accordion's content font-size. */
    font-size: var(--breadcrumb-font-size);
  }
  :where(m-breadcrumb-overflow[data-m-breadcrumb-ready] [data-breadcrumb-menu]) {
    position: fixed; inset: auto; left: var(--m-breadcrumb-left); top: var(--m-breadcrumb-top);
  }
  :where(nav[data-breadcrumbs] [data-breadcrumb-menu] li) { display: block; max-inline-size: none; flex: none; }
  :where(nav[data-breadcrumbs] [data-breadcrumb-menu] a) {
    display: block; padding: var(--space-xs); min-block-size: var(--breadcrumb-menu-target);
  }
  /* Shared overlay-row hover (select, menu, command): surface-raised equals
     surface-overlay in dark and would leave the row unfilled. */
  :where(nav[data-breadcrumbs] [data-breadcrumb-menu] a):hover {
    background: color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay)); text-decoration: none;
  }

  /* Bottom navigation is ordinary site navigation, not a tab widget.
     Place it in the last row of an app shell; no fixed positioning or
     breakpoint is imposed. For emphasis without fill, override
     --bottom-nav-active-background: transparent on the nav. */
  :where(nav[data-bottom-nav]) {
    --bottom-nav-pad: var(--space-xs);
    --bottom-nav-gap: var(--space-2xs);
    --bottom-nav-target-height: 3.5rem;
    --bottom-nav-font-size: var(--text-xs);
    --bottom-nav-font-weight: 500;
    --bottom-nav-active-weight: 650;
    --bottom-nav-icon-size: 1.125rem;
    --bottom-nav-active-background: var(--color-surface-raised);
    display: flex;
    gap: var(--bottom-nav-gap);
    padding: var(--bottom-nav-pad);
    padding-block-end: max(var(--bottom-nav-pad), env(safe-area-inset-bottom));
    /* Safe-area insets are physical, even in an RTL document. */
    padding-left: max(var(--bottom-nav-pad), env(safe-area-inset-left));
    padding-right: max(var(--bottom-nav-pad), env(safe-area-inset-right));
    border-block-start: 1px solid var(--color-border);
    background: var(--color-surface);
  }
  :where(nav[data-bottom-nav]:not(:has([data-bottom-icon]))) {
    --bottom-nav-target-height: 2.75rem;
    --bottom-nav-font-size: var(--text-sm);
  }
  :where(nav[data-bottom-nav] > a) {
    display: flex;
    flex: 1;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: var(--bottom-nav-gap);
    min-inline-size: 0;
    min-block-size: var(--bottom-nav-target-height);
    padding: var(--space-xs) var(--space-2xs);
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
    font-size: var(--bottom-nav-font-size);
    font-weight: var(--bottom-nav-font-weight);
    line-height: 1.25;
    text-align: center;
    text-decoration: none;
    overflow-wrap: anywhere;
  }
  :where(nav[data-bottom-nav] > a):hover:not([aria-disabled="true"]) {
    background: var(--color-surface-raised);
    color: var(--color-text);
  }
  :where(nav[data-bottom-nav] > a)[aria-current="page"] {
    background: var(--bottom-nav-active-background);
    color: var(--color-text);
    font-weight: var(--bottom-nav-active-weight);
  }
  :where(nav[data-bottom-nav] > a)[aria-disabled="true"] { opacity: .45; cursor: default; }
  :where(nav[data-bottom-nav] [data-bottom-icon]) {
    inline-size: var(--bottom-nav-icon-size);
    block-size: var(--bottom-nav-icon-size);
    flex: none;
  }

  /* --- sidebar: authored navigation, optional sidebar.js shell behavior --- */
  :where(m-sidebar-layout) {
    --sidebar-width: 15.5rem;
    --sidebar-rail-width: 3.75rem;
    --sidebar-mobile-width: 18rem;
    --sidebar-pad: var(--space-xs);
    --sidebar-icon-size: 1rem;
    --sidebar-font-size: var(--text-md);
    --sidebar-group-size: var(--text-2xs);
    --sidebar-subnav-size: var(--text-sm);
    --sidebar-active-weight: 600;
    --sidebar-close-size: 2.75rem;
    --sidebar-inset: 0px;
    --sidebar-content-border: 0px;
    --sidebar-edge: 1px;
    display: grid;
    grid-template-columns: var(--m-sidebar-track, var(--sidebar-width)) minmax(0, 1fr);
    block-size: var(--sidebar-height, 100svh);
    min-block-size: 0;
    background: var(--color-surface-raised);
  }
  :where(m-sidebar-layout[variant="inset"]) {
    --sidebar-inset: var(--space-xs);
    --sidebar-content-border: 1px;
    --sidebar-edge: 0px;
  }
  :where(m-sidebar-layout > [data-sidebar-main]) {
    min-inline-size: 0;
    min-block-size: 0;
    overflow: auto;
    margin-block: var(--sidebar-inset);
    margin-inline: 0 var(--sidebar-inset);
    border: var(--sidebar-content-border) solid var(--color-border);
    background: var(--color-surface);
  }
  :where(m-sidebar) {
    display: flex;
    flex-direction: column;
    min-inline-size: 0;
    min-block-size: 0;
    block-size: 100%;
    padding: var(--sidebar-pad, var(--space-xs));
    border-inline-end: var(--sidebar-edge, 1px) solid var(--color-border);
    background: var(--color-surface-raised);
  }
  :where(m-sidebar > header, m-sidebar > footer) { flex: none; }
  :where(m-sidebar > header) { display: flex; align-items: center; }
  :where(m-sidebar > nav) {
    flex: 1 1 auto;
    min-block-size: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-block: var(--space-md);
  }
  :where(m-sidebar > nav section) { margin: 0 0 var(--space-lg); }
  :where(m-sidebar > nav h2) {
    margin: 0;
    padding: var(--space-xs);
    font-size: var(--sidebar-group-size, var(--text-2xs));
    font-weight: 500;
    color: var(--color-text-muted);
  }
  :where(m-sidebar [data-sidebar-item], m-sidebar [data-sidebar-subnav] > a) {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    min-block-size: var(--control-height);
    block-size: auto;
    padding: var(--space-xs);
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-muted);
    font-size: var(--sidebar-font-size, var(--text-md));
    text-decoration: none;
    text-align: start;
  }
  :where(m-sidebar [data-sidebar-item], m-sidebar [data-sidebar-subnav] > a):hover:not(:disabled, [aria-disabled="true"]) {
    color: var(--color-text);
    background: var(--color-surface);
  }
  :where(m-sidebar a)[aria-current="page"] {
    color: var(--color-text);
    background: var(--color-surface);
    font-weight: var(--sidebar-active-weight, 600);
    /* Active is a quiet fill, never a framed button. */
    box-shadow: none;
  }
  :where(m-sidebar [data-sidebar-item])[aria-disabled="true"] { opacity: .45; }
  :where(m-sidebar [data-sidebar-icon]:not(m-avatar)) {
    inline-size: var(--sidebar-icon-size, 1rem);
    block-size: var(--sidebar-icon-size, 1rem);
    flex: none;
    object-fit: contain;
  }
  :where(m-sidebar [data-sidebar-label]) { flex: 1; min-inline-size: 0; }
  :where(m-sidebar [data-sidebar-badge]) { margin-inline-start: auto; color: var(--color-text-muted); font-size: var(--sidebar-subnav-size, var(--text-sm)); }
  :where(m-sidebar > header > [data-sidebar-item], m-sidebar > footer > [data-sidebar-item]) { inline-size: 100%; }
  :where(m-sidebar details) { margin: 0; padding: 0; border: 0; background: none; }
  :where(m-sidebar summary) { cursor: pointer; list-style: none; }
  :where(m-sidebar summary)::-webkit-details-marker { display: none; }
  :where(m-sidebar summary)::after { display: none; }
  :where(m-sidebar [data-sidebar-chevron]) { inline-size: var(--space-sm); block-size: var(--space-sm); flex: none; }
  :where(m-sidebar details)[open] > :where(summary) > :where([data-sidebar-chevron]) { transform: rotate(90deg); }
  :where(m-sidebar [data-sidebar-subnav]) {
    margin: var(--space-2xs) 0 var(--space-xs) var(--sidebar-icon-size, 1rem);
    margin-inline: var(--sidebar-icon-size, 1rem) 0;
    padding: 0;
    padding-inline-start: var(--space-md);
    border-inline-start: 1px solid var(--color-border);
  }
  :where(m-sidebar [data-sidebar-subnav] > a) { font-size: var(--sidebar-subnav-size, var(--text-sm)); }
  :where([data-sidebar-toggle], [data-sidebar-close]) { display: none; }
  :where(m-sidebar-layout[data-m-sidebar-rail]) { --m-sidebar-track: var(--sidebar-rail-width); }
  :where(m-sidebar-layout[data-m-sidebar-rail] m-sidebar) :where([data-sidebar-label], [data-sidebar-badge], h2, [data-sidebar-chevron], [data-sidebar-subnav]) { display: none; }
  :where(m-sidebar-layout[data-m-sidebar-rail] m-sidebar [data-sidebar-item]) { justify-content: center; }
  :where(m-sidebar-layout[data-m-sidebar-rail] m-sidebar details:has([aria-current="page"]) > summary) { color: var(--color-text); background: var(--color-surface); }
  :where(m-sidebar-layout[data-m-sidebar-collapse-blocked] [data-sidebar-toggle], m-sidebar-layout[data-m-sidebar-can-rail] [data-sidebar-toggle], m-sidebar-layout[data-m-sidebar-mobile] [data-sidebar-toggle]) { display: inline-flex; }
  :where(m-sidebar-layout[data-m-sidebar-mobile]) { grid-template-columns: minmax(0, 1fr); --sidebar-inset: 0px; --sidebar-content-border: 0px; }
  /* Mobile: sidebar.js makes the panel itself a modal (a manual popover
     in the top layer). Nothing moves; closed, it is simply not shown. */
  :where(m-sidebar-layout[data-m-sidebar-mobile] > m-sidebar:not(:popover-open)) { display: none; }
  :where(m-sidebar-layout[data-m-sidebar-mobile] > m-sidebar) {
    position: fixed;
    inset: 0 auto 0 0;
    inset-inline: 0 auto;
    margin: 0;
    inline-size: min(var(--sidebar-mobile-width, 18rem), calc(100vw - var(--space-2xl)));
    max-inline-size: none;
    block-size: 100dvh;
    max-block-size: 100dvh;
    overflow: hidden;
    border: 0;
    padding: var(--sidebar-pad, var(--space-xs));
    padding-block-start: max(var(--sidebar-pad, var(--space-xs)), env(safe-area-inset-top));
    padding-block-end: max(var(--sidebar-pad, var(--space-xs)), env(safe-area-inset-bottom));
    border-radius: 0;
    background: var(--color-surface-raised);
    color: var(--color-text);
    font-size: inherit;
    line-height: inherit;
    box-shadow: 0 16px 48px light-dark(oklch(0 0 0 / 0.2), oklch(0 0 0 / 0.6));
    position-area: none;
    /* No popover entrance: the panel is shown at rest. */
    opacity: 1;
    scale: 1;
    transform: none;
    transition: none;
    animation: none;
  }
  /* Initial modal focus belongs to the named panel, not a nav action.
     Controls retain their ordinary keyboard focus indicators. */
  :where(m-sidebar-layout[data-m-sidebar-mobile] > m-sidebar):focus-visible { outline: none; }
  /* Same scrim as a dialog's, at the same large-viewport size. */
  :where(m-sidebar-layout[data-m-sidebar-mobile] > m-sidebar)::backdrop {
    background: oklch(0 0 0 / 0.4);
    inline-size: 100lvw;
    block-size: 100lvh;
  }
  :where(m-sidebar-layout[data-m-sidebar-mobile] > m-sidebar > header > [data-sidebar-item]) { flex: 1; inline-size: 0; min-inline-size: 0; }
  :where(m-sidebar-layout[data-m-sidebar-mobile] [data-sidebar-close]) { display: inline-flex; flex: none; inline-size: var(--sidebar-close-size, 2.75rem); block-size: var(--sidebar-close-size, 2.75rem); padding: var(--space-xs); }
  @media (max-width: 44rem) {
    :where(m-sidebar-layout:not([data-m-sidebar-ready])) { grid-template-columns: minmax(0, 1fr); block-size: auto; }
  }

  /* --- visually hidden: off-screen, still announced ------------------ *
   *
   * The one utility mica ships, and an accessibility primitive rather
   * than a style: content that assistive tech must reach but sighted
   * users must not see. `display: none` and `inline-size: 0` would drop
   * it from the accessibility tree; this keeps a 1px box in flow-ish
   * and clips it away.
   *
   * An attribute, not a class: `class` stays the app's, `data-*` is
   * valid HTML and needs no React `HTMLAttributes` augmentation, and
   * `.visually-hidden`/`.sr-only` are the most copy-pasted names in
   * accessibility — a consumer arriving with their own copy is the
   * likely case. Lives at the end of this layer, not a new one, because
   * the layer list is a published contract; being last lets it beat the
   * element rules it is applied to (`caption`, `legend`, headings).
   *
   *   <caption data-visually-hidden>Standings</caption>
   *   <a href="#main" data-visually-hidden="focusable">Skip to content</a>
   *
   * The `focusable` variant is the skip-link primitive: hidden until it
   * takes focus, then it simply stops being hidden — no undo rule, so
   * the element keeps whatever styling the app gave it. */
  [data-visually-hidden]:not([data-visually-hidden="focusable"]),
  [data-visually-hidden="focusable"]:not(:focus, :focus-within),
  :where(m-segmented) > :where(label) > :where(input[type="radio"]) {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  /* --- command: authored actions, optionally enhanced by command.js --- */
  :where(m-command-palette) {
    display: block;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface-overlay);
    overflow: hidden;
  }
  /* Text start edges line up: header, headings and footer sit at the
     list inset + item padding, the same edge as item labels. */
  :where(m-command-palette > header) {
    display: flex; align-items: center; gap: var(--space-sm);
    padding: var(--space-sm) var(--space-xs); border-block-end: 1px solid var(--color-border);
  }
  /* command.js reveals the input; without it the header would be an empty band */
  :where(m-command-palette:not(:defined)) > :where(header) { display: none; }
  :where(m-command-palette [data-command-input]) {
    flex: 1; min-inline-size: 0; font-size: 1rem; /* iOS field floor */ border: 0; background: transparent;
  }
  :where(m-command-list) {
    display: block; max-block-size: var(--command-list-height, 23rem);
    overflow: auto; overscroll-behavior: contain; padding: var(--space-xs);
  }
  :where(m-command-list[dividers]) {
    --command-group-border: 1px;
    --command-group-gap: var(--space-xs);
    --command-group-pad: var(--space-xs);
  }
  :where(m-command-group) { display: block; }
  /* Separate from the previous VISIBLE group: filtering hides groups, and a
     plain + would leave a stray rule/gap above the first one shown. */
  :where(m-command-group:not([hidden]) ~ m-command-group) {
    margin-block-start: var(--command-group-gap, var(--space-md));
    padding-block-start: var(--command-group-pad, 0);
    border-block-start: var(--command-group-border, 0) solid var(--color-border);
  }
  :where(m-command-group > :is(h2,h3,h4,h5,h6)) {
    margin: var(--space-xs) var(--space-sm); font-size: var(--text-2xs); font-weight: 500; color: var(--color-text-muted);
  }
  :where(m-command-palette [data-command-item]) {
    display: flex; align-items: center; gap: var(--space-sm); inline-size: 100%;
    padding: var(--space-sm); block-size: auto; min-block-size: var(--control-height);
    border: 0; background: transparent; color: var(--color-text);
    border-radius: var(--radius-sm); text-align: start; text-decoration: none;
    font-size: var(--text-md); font-weight: 400; cursor: pointer;
  }
  :where(m-command-palette [data-command-item]):is(:hover:not([aria-selected]), [aria-selected="true"]) {
    background: var(--command-active-background, color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay)));
    color: var(--color-text);
  }
  :where(m-command-palette [data-command-item] > span) { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
  :where(m-command-palette [data-command-item] > svg) { inline-size: 1rem; block-size: 1rem; flex: none; color: var(--color-text-muted); }
  :where(m-command-palette [data-command-item] small) { display: block; color: var(--color-text-muted); font-size: var(--text-xs); }
  :where(m-command-palette [data-command-item] kbd) { font: .6875rem var(--font-mono); color: var(--color-text-muted); }
  :where(m-command-palette [data-command-item]):is(:disabled, [aria-disabled="true"]) { opacity: .45; cursor: not-allowed; }
  :where(m-command-palette > footer) {
    padding: var(--space-xs) calc(var(--space-xs) + var(--space-sm)); border-block-start: 1px solid var(--color-border);
    font-size: var(--text-2xs); color: var(--color-text-muted);
  }
  :where(m-command-palette [data-command-empty]) { margin: 0; padding: var(--space-lg); color: var(--color-text-muted); font-size: var(--text-md); }
  /* Native button display rules must not override the hidden state. */
  :where(m-command-palette) [hidden] { display: none; }
  /* A command is already a complete surface; don't add dialog body padding. */
  :where(dialog > m-command-palette) { border: 0; padding: 0; font-size: inherit; }
  /* --- m-menu: authored action popovers, optionally enhanced by menu.js --- */
  /* Enhancement marks context surfaces before a touch starts. Native callout
     and text selection compete with long press; leave ordinary markup alone.
     For selectable content, use a separate More button instead of a context surface. */
  :where([data-m-menu-context]) {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
  :where([data-m-menu-context] :is(input, textarea, select, a[href], [contenteditable]:not([contenteditable="false"]))) {
    -webkit-touch-callout: default;
    -webkit-user-select: text;
    user-select: text;
  }
  :where(m-menu) {
    --menu-gap: var(--space-2xs);
    row-gap: var(--menu-gap); /* resolved length for enhancement positioning */
    background: var(--color-surface-overlay); color: var(--color-text);
    border: 1px solid var(--color-border); border-radius: var(--radius-md);
    padding: var(--space-2xs); inline-size: var(--menu-width, 14rem); font-size: var(--text-md);
    /* align is an HTML presentational hint (text-align) on any element;
       here it only places the menu (menu.js), so captions stay start. */
    text-align: start;
  }
  :where(m-menu:not([popover])) { display: block; }
  :where(m-menu[data-m-menu-enhanced]) {
    position: fixed; inset: auto; margin: 0; position-area: none;
    left: var(--m-menu-x, 0px); top: var(--m-menu-y, 0px);
    max-inline-size: calc(100vw - 1rem); max-block-size: calc(100dvh - 1rem);
    overflow: auto;
  }
  /* The container receives pointer-open focus; item focus supplies keyboard feedback. */
  :where(m-menu[data-m-menu-enhanced]):focus { outline: none; }
  :where(m-menu > button, m-menu > a) {
    display: flex; align-items: center; justify-content: flex-start; gap: var(--space-sm); inline-size: 100%;
    min-block-size: var(--control-height); block-size: auto; padding: var(--space-xs);
    border: 0; background: transparent; color: var(--color-text);
    border-radius: var(--radius-sm); font-size: var(--text-md); font-weight: 400;
    text-align: start; text-decoration: none;
  }
  :where(m-menu > button > span:first-of-type, m-menu > a > span:first-of-type) { flex: 1; }
  /* Match native button hover specificity; enhanced menus use focus as the pointer target. */
  :where(m-menu[data-m-menu-enhanced] > button, m-menu[data-m-menu-enhanced] > a):hover:not(:disabled, [aria-disabled="true"]):where(:not(:focus, [aria-expanded="true"])) {
    background: transparent;
  }
  :where(m-menu > button, m-menu > a):is(:focus, [aria-expanded="true"]) {
    background: var(--menu-active-background, color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay)));
    outline: 0;
  }
  :where(m-menu:not([data-m-menu-enhanced]) > button, m-menu:not([data-m-menu-enhanced]) > a):hover {
    background: var(--menu-active-background, color-mix(in oklch, var(--color-text) 8%, var(--color-surface-overlay)));
  }
  :where(m-menu > [data-variant="danger"]) { color: var(--color-danger-text); }
  :where(m-menu > button):is(:disabled, [aria-disabled="true"]), :where(m-menu > a)[aria-disabled="true"] { opacity: .45; }
  :where(m-menu svg) { inline-size: 1rem; block-size: 1rem; flex: none; }
  :where(m-menu kbd) { font: .6875rem var(--font-mono); color: var(--color-text-muted); }
  :where(m-menu > hr) { margin: var(--space-2xs) var(--space-xs); border: 0; border-block-start: 1px solid var(--color-border); }
  :where(m-menu > [data-menu-heading]) { margin: var(--space-xs); font-size: var(--text-2xs); color: var(--color-text-muted); }
  :where(m-menu > [data-menu-back]) { display: none; }
  :where(m-menu) [hidden] { display: none; }
  @media (max-width: 600px) {
    :where(m-menu > button, m-menu > a) { min-block-size: var(--menu-touch-height, 2.75rem); }
    :where(m-menu[data-m-menu-enhanced] > [data-menu-back]) { display: flex; }
    :where(m-menu[data-m-menu-enhanced] > m-menu:popover-open) { visibility: visible; }
    :where(m-menu[data-m-menu-enhanced]:has(> m-menu:popover-open)) { visibility: hidden; }
  }
}

/* ------------------------------------------------------------------ *
 * Layout primitives (CSS-only)
 *
 * Mechanism: attributes only set custom properties; rules read custom
 * properties. `gap="lg"` and `style="--gap: 2.5rem"` are the same thing.
 * ------------------------------------------------------------------ */
@layer mica.layout {
  /* Custom elements default to display:inline; give ours a sane base. */
  m-vstack,
  m-hstack,
  m-zstack,
  m-center,
  m-box,
  m-grid,
  m-sidecar,
  m-switcher,
  m-reel,
  m-frame,
  m-cover {
    display: block;
    box-sizing: border-box;
  }

  /* Shared attribute vocabulary -> custom properties */
  :is(m-vstack, m-hstack, m-grid, m-sidecar, m-switcher, m-reel, m-cover) {
    &[gap="none"] { --gap: 0; }
    &[gap="2xs"]  { --gap: var(--space-2xs); }
    &[gap="xs"]   { --gap: var(--space-xs); }
    &[gap="sm"]   { --gap: var(--space-sm); }
    &[gap="md"]   { --gap: var(--space-md); }
    &[gap="lg"]   { --gap: var(--space-lg); }
    &[gap="xl"]   { --gap: var(--space-xl); }
    &[gap="2xl"]  { --gap: var(--space-2xl); }
  }

  :is(m-vstack, m-hstack) {
    &[align="start"]   { --align: flex-start; }
    &[align="center"]  { --align: center; }
    &[align="end"]     { --align: flex-end; }
    &[align="stretch"] { --align: stretch; }
  }

  /* --- m-vstack: vertical flow with consistent gaps ---------------- */
  m-vstack {
    display: flex;
    flex-direction: column;
    align-items: var(--align, stretch);
    gap: var(--gap, var(--space-md));

    /* the stack owns spacing; preset rhythm yields to gap. Popovers and
       dialogs are skipped: they render in the top layer, where a
       popover's block margin is the anchored gap to its invoker and a
       modal dialog's auto margin centers it. :where() keeps (0,0,1). */
    & > :where(:not([popover], dialog)) { margin-block: 0; }
  }

  /* --- m-hstack: one horizontal row; `wrap` to allow wrapping ------ */
  m-hstack {
    display: flex;
    align-items: var(--align, center);
    justify-content: var(--justify, flex-start);
    gap: var(--gap, var(--space-md));

    &[wrap] { flex-wrap: wrap; }

    & > :where(:not([popover], dialog)) { margin-block: 0; } /* top-layer surfaces keep their margins (see m-vstack) */

    &[justify="start"]   { --justify: flex-start; }
    &[justify="center"]  { --justify: center; }
    &[justify="end"]     { --justify: flex-end; }
    &[justify="between"] { --justify: space-between; }
  }

  /* --- m-zstack: layering; children occupy the same grid cell ------ */
  m-zstack {
    display: grid;
    align-items: var(--align, stretch);
    justify-items: var(--justify, stretch);

    &[align="start"]   { --align: start; }
    &[align="center"]  { --align: center; }
    &[align="end"]     { --align: end; }
    &[align="stretch"] { --align: stretch; }

    &[justify="start"]   { --justify: start; }
    &[justify="center"]  { --justify: center; }
    &[justify="end"]     { --justify: end; }
    &[justify="stretch"] { --justify: stretch; }

    /* every layer shares one cell; paint order is DOM order.
       per-layer placement is just user CSS: place-self on the child. */
    & > * {
      grid-area: 1 / 1;
    }
  }

  /* --- m-center: intrinsic horizontal centering with a measure ----- */
  m-center {
    max-inline-size: var(--max, var(--measure));
    margin-inline: auto;
    padding-inline: var(--gutter, 0);

    &[max="xs"] { --max: var(--size-xs); }
    &[max="sm"] { --max: var(--size-sm); }
    &[max="md"] { --max: var(--size-md); }
    &[max="lg"] { --max: var(--size-lg); }
    &[max="xl"] { --max: var(--size-xl); }

    &[gutter="sm"] { --gutter: var(--space-sm); }
    &[gutter="md"] { --gutter: var(--space-md); }
    &[gutter="lg"] { --gutter: var(--space-lg); }
  }

  /* --- m-box: padding, an inside for content ----------------------- */
  m-box {
    padding: var(--pad, var(--space-md));

    &[pad="none"] { --pad: 0; }
    &[pad="xs"]   { --pad: var(--space-xs); }
    &[pad="sm"]   { --pad: var(--space-sm); }
    &[pad="md"]   { --pad: var(--space-md); }
    &[pad="lg"]   { --pad: var(--space-lg); }
    &[pad="xl"]   { --pad: var(--space-xl); }
  }

  /* --- m-grid: responsive grid, no media queries ------------------- */
  m-grid {
    display: grid;
    grid-template-columns: repeat(
      auto-fit,
      minmax(min(var(--min, var(--size-sm)), 100%), 1fr)
    );
    gap: var(--gap, var(--space-md));

    &[min="xs"] { --min: var(--size-xs); }
    &[min="sm"] { --min: var(--size-sm); }
    &[min="md"] { --min: var(--size-md); }
    &[min="lg"] { --min: var(--size-lg); }
  }

  /* --- m-sidecar: fixed + flexible pair, stacks when narrow -------- */
  m-sidecar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap, var(--space-md));

    /* the sidecar is the first child by default; `side="end"` flips it */
    & > :first-child {
      flex-basis: var(--side-width, var(--size-xs));
      flex-grow: 1;
    }
    & > :last-child {
      flex-basis: 0;
      flex-grow: 999;
      min-inline-size: var(--content-min, 50%);
    }

    /* side="end": the *last* child is the sidecar (no visual reordering) */
    &[side="end"] > :first-child {
      flex-basis: 0;
      flex-grow: 999;
      min-inline-size: var(--content-min, 50%);
    }
    &[side="end"] > :last-child {
      flex-basis: var(--side-width, var(--size-xs));
      flex-grow: 1;
      min-inline-size: auto;
    }

    &[side-width="xs"] { --side-width: var(--size-xs); }
    &[side-width="sm"] { --side-width: var(--size-sm); }
    &[side-width="md"] { --side-width: var(--size-md); }
  }

  /* --- m-switcher: row that switches to a column below a threshold - */
  m-switcher {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap, var(--space-md));

    & > * {
      flex-basis: calc((var(--threshold, var(--size-lg)) - 100%) * 999);
      flex-grow: 1;
    }

    &[threshold="sm"] { --threshold: var(--size-sm); }
    &[threshold="md"] { --threshold: var(--size-md); }
    &[threshold="lg"] { --threshold: var(--size-lg); }
    &[threshold="xl"] { --threshold: var(--size-xl); }
  }

  /* --- m-reel: horizontal scroll with snap ------------------------- */
  m-reel {
    display: flex;
    gap: var(--gap, var(--space-md));
    overflow-x: auto;
    scroll-snap-type: inline proximity;

    & > * {
      flex-shrink: 0;
      scroll-snap-align: start;
    }

    &[snap="none"]      { scroll-snap-type: none; }
    &[snap="mandatory"] { scroll-snap-type: inline mandatory; }
  }

  /* --- m-frame: hold an aspect ratio, crop media to fit ------------ */
  m-frame {
    aspect-ratio: var(--ratio, 16 / 9);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;

    &[ratio="square"] { --ratio: 1; }
    &[ratio="16:9"]   { --ratio: 16 / 9; }
    &[ratio="4:3"]    { --ratio: 4 / 3; }
    &[ratio="3:2"]    { --ratio: 3 / 2; }
    &[ratio="2:1"]    { --ratio: 2 / 1; }
    &[ratio="9:16"]   { --ratio: 9 / 16; }

    /* media fills and crops; anything else just gets centered */
    & > :is(img, video),
    & > picture > img {
      inline-size: 100%;
      block-size: 100%;
      object-fit: cover;
    }
  }

  /* --- m-cover: fill the viewport, center the principal element ---- *
   * The principal element (h1 by default, or mark one child with
   * data-principal) is vertically centered; children before it pin to
   * the top, children after it pin to the bottom.                     */
  m-cover {
    display: flex;
    flex-direction: column;
    min-block-size: var(--min-height, 100svh);
    gap: var(--gap, var(--space-md));
    padding: var(--pad, var(--space-md));

    &[pad="none"] { --pad: 0; }
    &[pad="sm"]   { --pad: var(--space-sm); }
    &[pad="md"]   { --pad: var(--space-md); }
    &[pad="lg"]   { --pad: var(--space-lg); }
    &[pad="xl"]   { --pad: var(--space-xl); }

    & > :where(:not([popover], dialog)) { margin-block: 0; } /* top-layer surfaces keep their margins (see m-vstack) */

    & > :is(h1, [data-principal]) { margin-block: auto; }

    /* An explicit marker wins over the h1 default. */
    &:has(> [data-principal]) > h1:not([data-principal]) { margin-block: 0; }
  }
}
