@import url("/styles/design-system.css");
@import url("/styles/primitives.css");

/* ============================================================================
   BASE.CSS — Element-level design system  ·  "EMBER" theme
   Light theme only. Never adapts to device dark mode.

   Theme notes: not a generic #ff0000 red. The ramp is a warm crimson that
   cools into oxblood at the deep end, paired with warm sand-ash neutrals and
   an ember-orange secondary. Surfaces use faint warm tints rather than pure
   white/gray, so the whole UI reads as one tinted family.

   Specificity policy: nearly every element rule is wrapped in :where() so it
   has ZERO specificity. Your app CSS always wins — a bare class like .btn
   overrides any default here without !important.

   Structure:
     00. Tokens              07. Embedded content
     01. Reset / global      08. Tabular data
     02. Document root       09. Forms
     03. Sectioning          10. Interactive / overlays
     04. Text content        11. Web components / attributes
     05. Inline semantics    12. Utilities, a11y, print
     06. Media
   Cascade layers (priority: low -> high)
     tokens     : :root custom properties
     reset      : box-sizing, margin/padding zeroing, global pseudo-elements
     elements   : every bare HTML tag default
     context    : contextual overrides (nav ul, figure img, search input ...)
                  -> MUST outrank `elements`, which is why layers exist here
     components : custom widget layer (.x-pop, .x-trigger, calendar ...)
     utilities  : .visually-hidden and friends
   Your own app CSS is UNLAYERED, so it automatically beats every layer above
   without needing !important.
   ==========================================================================*/

@layer tokens, reset, elements, context, components, utilities;

@layer tokens {
/* ==========================================================================
   00. TOKENS                                                                 */
/* ========================================================================== */
/* ==========================================================================
   FONT METRIC NORMALISATION  -  the real fix for "text is not vertically
   centred".
   Why every previous attempt failed: flex/grid centring centres the LINE
   BOX, not the glyphs. The line box is built from the font file's own
   ascent/descent/line-gap metrics, which are asymmetric - system UI faces
   reserve extra room above the baseline for accents, so the visible letters
   always settle high. No amount of padding, line-height or text-box-trim
   fixes the cause; they only move the symptom around, differently per
   control.
   The cause is fixed by re-declaring the system font with overridden
   metrics. ascent/descent are set to a symmetric pair that brackets the
   real ink, and line-gap is zeroed, so the line box becomes centred on the
   glyphs themselves. Every flex-centred control then centres correctly with
   NO per-component compensation at all.
   Ref: ascent-override / descent-override / line-gap-override (Chrome 87+,
   Firefox 89+, Safari 17+); the classic "fix vertical metrics" transform.
   ========================================================================== */
@font-face {
  font-family: "UI Sans";
  src: local("Segoe UI"), local("Roboto"), local("Helvetica Neue"),
       local("Arial"), local("Liberation Sans"), local("DejaVu Sans");
  ascent-override: 94%;
  descent-override: 23.6%;
  line-gap-override: 0%;
  font-display: swap;
}
@font-face {
  font-family: "UI Sans";
  src: local("Segoe UI Bold"), local("Roboto Bold"), local("Helvetica Neue Bold"),
       local("Arial Bold"), local("Liberation Sans Bold"), local("DejaVu Sans Bold");
  font-weight: 600 900;
  ascent-override: 94%;
  descent-override: 23.6%;
  line-gap-override: 0%;
  font-display: swap;
}
@font-face {
  font-family: "UI Mono";
  src: local("SFMono-Regular"), local("Menlo"), local("Consolas"),
       local("Liberation Mono"), local("DejaVu Sans Mono"), local("Courier New");
  ascent-override: 94%;
  descent-override: 26.8%;
  line-gap-override: 0%;
  font-display: swap;
}

:root {
  color-scheme: light only;

  /* ---- Ember crimson ramp (brand) — warm at the top, oxblood at the base */
  --red-50:  #fdf3f1;
  --red-100: #fbe3df;
  --red-200: #f7c7c0;
  --red-300: #f0a094;
  --red-400: #e4705f;
  --red-500: #d24a37;
  --red-600: #b93521;   /* primary */
  --red-700: #9a2919;
  --red-800: #7c2418;
  --red-900: #63211a;
  --red-950: #380f0b;

  /* ---- Ember orange (secondary accent) ---- */
  --ember-100: #fdeedb;
  --ember-300: #f5be7a;
  --ember-500: #e08b2c;
  --ember-700: #9c5a12;

  /* ---- Warm sand-ash neutrals ---- */
  --gray-0:   #ffffff;
  --gray-25:  #fdfbfa;
  --gray-50:  #faf7f5;
  --gray-100: #f3efec;
  --gray-200: #e8e2de;
  --gray-300: #d6cec9;
  --gray-400: #ab9f99;
  --gray-500: #7e736e;
  --gray-600: #5d5450;
  --gray-700: #453e3b;
  --gray-800: #2c2724;
  --gray-900: #1b1714;

  /* ---- Status (tuned to sit beside crimson) ---- */
  --success:    var(--ds-success);
  --success-bg: var(--ds-success-soft);
  --success-bd: color-mix(in srgb, var(--ds-success) 25%, var(--ds-surface));
  --warning:    var(--ds-warning);
  --warning-bg: var(--ds-warning-soft);
  --danger:     var(--ds-danger);
  --danger-bg:  var(--ds-danger-soft);
  --info:       var(--ds-info);
  --info-bg:    var(--ds-info-soft);

  /* ---- Semantic roles ---- */
  --bg:            var(--ds-surface);
  --bg-body:       var(--ds-background);   /* page is darker than its cards */
  --bg-subtle:     var(--ds-surface-subtle);
  --bg-muted:      var(--ds-surface-subtle);
  --bg-inset:      var(--ds-surface-raised);
  --bg-brand-soft: var(--ds-accent-soft);
  --bg-code:       #fbf6f3;

  /* The quietest text tone, and deliberately not `--gray-500`. The rules below
     pair this role with `--bg-muted` (a disabled control) and `--bg-subtle` (a
     read-only field), and at #7e736e it is 4.02:1 on `--bg-body` and 4.31:1 on
     `--bg-subtle` — under AA for exactly the small text the tone is spent on.
     #726762 is the lightest value that clears 4.5:1 on every surface these
     tokens put text on (5.48 on --bg, 5.14 on --bg-subtle, 4.79 on --bg-muted),
     so the role still sits a step lighter than --fg-muted and there are still
     three tones rather than two. */
  --fg:          var(--ds-text);
  --fg-muted:    var(--ds-muted);
  --fg-subtle:   var(--ds-text-soft);
  --fg-on-brand: #fff8f6;

  --brand:        var(--ds-accent);
  --brand-hover:  color-mix(in srgb, var(--ds-accent) 86%, var(--ds-text));
  --brand-active: color-mix(in srgb, var(--ds-accent) 72%, var(--ds-text));
  --brand-fg:     var(--ds-accent-foreground);

  --border:        var(--ds-border);
  --border-strong: var(--ds-border-strong);
  --border-brand:  color-mix(in srgb, var(--ds-accent) 25%, var(--ds-surface));

  --link:         var(--red-700);
  --link-hover:   var(--red-900);
  --link-visited: #7d2a55;

  --selection-bg: var(--red-200);
  --selection-fg: var(--red-950);

  /* ---- Signature gradients (what makes the theme feel bespoke) ---- */
  --grad-brand: linear-gradient(180deg, var(--red-500) 0%, var(--red-600) 55%, var(--red-700) 100%);
  --grad-brand-hover: linear-gradient(180deg, var(--red-600) 0%, var(--red-700) 55%, var(--red-800) 100%);
  --grad-ember: linear-gradient(90deg, var(--red-600), var(--ember-500));
  --grad-surface: linear-gradient(180deg, var(--gray-0), var(--gray-25));
  --grad-rule: linear-gradient(90deg, transparent, var(--red-200) 15%, var(--red-300) 50%, var(--red-200) 85%, transparent);

  /* ---- Typography ---- */
  --font-sans: var(--ds-font-body);
  --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", serif;
  --font-mono: "UI Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  /* Fluid type scale — clamp(min, rem + vw, max).
     Every step keeps a rem term so browser zoom still works (a pure-vw
     preferred value breaks zoom accessibility).

     NOTHING IN THIS SYSTEM RENDERS BELOW 12px (0.75rem). The bottom two
     steps used to be 10 and 11 — and that band is where almost everything
     small lives: status badges, chat timestamps, day separators, nav counts,
     field "optional" tags, every tracked caps eyebrow, and every hint under
     a field. It is also where the scale contradicted itself: the same kind
     of caption drawn at 10 here and 11 three rules later, so two pills side
     by side differed by a step nobody chose. The bottom of a scale is where
     a designer is most tempted to shave and a reader has the least recourse,
     so the ladder now starts 13 / 13–14 / 14–15 — the two smallest steps sit
     within a pixel of each other at any width: one visual band, one floor.

     THE FLOOR WAS RAISED FROM 12 TO 13. Nothing in the app renders below 13px
     any more. The two smallest steps were the badges, the field hints and the
     card captions — exactly the lines a reader leans in for — so the bottom of
     the scale moved up rather than the reader moving closer.

     `--fs-2xs` stays FLAT rather than joining the fluid steps on purpose: it
     sizes fixed pills, badges and calendar cells that must not wobble with
     the viewport. */
  --fs-2xs: 0.8125rem;
  --fs-xs:   clamp(0.8125rem, 0.79rem + 0.09vw, 0.875rem);
  --fs-sm:   clamp(0.875rem, 0.85rem + 0.11vw, 0.9375rem);
  --fs-base: clamp(0.9375rem, 0.91rem + 0.14vw, 1rem);
  --fs-md:   clamp(1rem,      0.96rem + 0.18vw, 1.0625rem);
  --fs-lg:   clamp(1.125rem,  1.07rem + 0.27vw, 1.25rem);
  --fs-xl:   clamp(1.375rem,  1.27rem + 0.5vw,  1.625rem);
  --fs-2xl:  clamp(1.625rem,  1.45rem + 0.9vw,  2.125rem);
  --fs-3xl:  clamp(2rem,      1.7rem + 1.5vw,   2.75rem);
  --fs-4xl:  clamp(2.375rem,  1.9rem + 2.4vw,   3.75rem);

  /* Four line-heights, no more. Every element picks one of these.
     flat = single-line UI controls (the box is the rhythm)
     tight = display headings, snug = dense UI + small headings,
     base = prose. */
  --lh-flat: 1;
  --lh-tight: 1.1; --lh-snug: 1.3; --lh-base: 1.6;

  /* Display weights are SEMIBOLD, not black. Heavy weights at large optical
     sizes read as shouty; modern systems lighten as size increases and let
     negative tracking carry the authority. */
  /* ---- Weight system -------------------------------------------------
     CRITICAL CONSTRAINT: a UI font stack is only guaranteed two real
     faces - Regular and Bold. Measured in this environment: 300/400/500
     all render identically (530px for the same string) and 600/700/800
     all render identically (568px). Anything between them is SYNTHESISED
     or snapped, it is not a distinct weight.

     So the system exposes exactly TWO semantic weights and every token
     resolves to one of them. This removes the class of bug where h1 was
     set to 500 (-> Regular) while h3 was 600 (-> Bold), making the
     LARGEST heading render LIGHTER than a smaller one.

     Hierarchy is therefore expressed with SIZE, COLOUR and TRACKING -
     which are continuous and always render - and weight is used only as
     a binary emphasis switch.
     -------------------------------------------------------------------- */
  --fw-normal: 400;    /* -> Regular face */
  --fw-medium: 400;    /* alias: no distinct medium exists; do not fake it */
  --fw-semi:   700;    /* -> Bold face */
  --fw-bold:   700;    /* -> Bold face */

  /* Headings: ALL headings are bold. Size and tracking carry the ladder. */
  --fw-display: 700;   /* h1-h6, one value, no inversion possible */
  --fw-title:   700;

  /* Optical tracking: the larger the type, the tighter it should sit. */
  --tracking-4xl: -0.005em;
  --tracking-3xl: -0.003em;
  --tracking-2xl: 0em;
  --tracking-xl:  0em;
  --tracking-tight: 0em;
  --tracking-wide: 0.035em;

  /* ---- Space ---- */
  --sp-0: 0; --sp-1: .25rem; --sp-2: .5rem; --sp-3: .75rem;
  --sp-4: 1rem; --sp-5: 1.5rem; --sp-6: 2rem; --sp-7: 3rem; --sp-8: 4rem;

  /* ---- Radii ---- */
  /* Rounder than before. Tight 3-5px corners are the single clearest
     "dated" tell; current systems sit at 8px for controls and 14-20px for
     surfaces. Kept on a consistent ramp so nesting still works. */
  /* Set by base.js when a popover needs an arrow / a scrollbar is measured.
     Declared here so the cascade has a real initial value instead of relying
     on every call site remembering a var() fallback. */
  --arrow-x: 1rem;
  --scrollbar-w: 0px;
  --r-xs: 5px; --r-sm: 8px; --r-md: 10px; --r-lg: 16px; --r-xl: 22px; --r-full: 999px;
  /* Concentric radius: inner = outer - gap (clamped at 0px). A nested box that
     reuses the parent's radius bulges at the corners. */
  --r-inner: max(0px, calc(var(--r-lg) - var(--sp-2)));

  /* ---- Elevation: warm-tinted shadows, never neutral black ---- */
  /* ---- Elevation: ONE shadow, scaled ----------------------------------
     Every surface in the app uses the same light: a single source, slightly
     above, casting straight down. Each level is the SAME three-part recipe
     (contact + main mass + ambient diffusion) with the geometry scaled up
     together, which is what makes a set of shadows feel like one system
     rather than six unrelated effects.
     The tint is the brand's darkest brown-red, not black - a shadow picks up
     the colour of the surface it falls on, and pure black on a warm page
     reads as grey sludge. Opacities stay low (.03-.08) and are layered;
     "one heavy shadow" is the thing that looks cheap.
     --------------------------------------------------------------------- */
  --sh-color: 56, 15, 11;
  --sh-xs:
    0 1px 1px rgba(var(--sh-color), .04),
    0 1px 2px rgba(var(--sh-color), .04);
  --sh-sm:
    0 1px 1px rgba(var(--sh-color), .035),
    0 2px 3px rgba(var(--sh-color), .035),
    0 4px 6px rgba(var(--sh-color), .03);
  --sh-md:
    0 1px 2px rgba(var(--sh-color), .035),
    0 3px 6px rgba(var(--sh-color), .035),
    0 8px 14px rgba(var(--sh-color), .035),
    0 16px 26px rgba(var(--sh-color), .025);
  --sh-lg:
    0 2px 4px rgba(var(--sh-color), .035),
    0 6px 12px rgba(var(--sh-color), .035),
    0 14px 26px rgba(var(--sh-color), .035),
    0 28px 48px rgba(var(--sh-color), .03),
    0 48px 80px rgba(var(--sh-color), .025);
  --sh-xl:
    0 2px 6px rgba(var(--sh-color), .04),
    0 8px 18px rgba(var(--sh-color), .04),
    0 20px 40px rgba(var(--sh-color), .04),
    0 40px 72px rgba(var(--sh-color), .035),
    0 72px 120px rgba(var(--sh-color), .03);
  --sh-inset: inset 0 1px 2px rgba(var(--sh-color), .06);
  --sh-raised: inset 0 1px 0 rgba(255, 255, 255, .22), 0 1px 2px rgba(var(--sh-color), .18);

  /* ---- Focus ----
     Mouse clicks get NO halo — just a quiet border tint. Keyboard focus gets
     a soft 2px low-alpha glow, never a hard saturated slab. */
  --ring-w: 2px;
  --ring-color: rgba(185, 53, 33, .18);
  --ring: 0 0 0 var(--ring-w) var(--ring-color);
  --ring-soft: 0 0 0 1px rgba(185, 53, 33, .10);
  --ring-offset: 0 0 0 2px var(--bg), 0 0 0 4px var(--ring-color);

  /* ---- Motion ---- */

  /* ---- Layout ---- */
  --measure: 72ch;
  --container: 1920px;
  /* Every control and every menu row that belongs to a control reads from
     ONE size token, which is why a select and its dropdown now match. */
  --fs-control: var(--fs-sm);
  /* One control geometry across the platform plane: ordinary forms are 44px,
     compact controls are 36px, and premium authentication stays 48px. */
  --control-h: var(--ds-control-height);
  --control-h-sm: var(--ds-control-height-sm);
  --control-h-lg: 3rem;
  --field-bg: var(--ds-surface);
  --field-border: var(--ds-border-strong);
  --field-radius: var(--ds-radius-sm);
  --field-pad-x: .7rem;
  --field-pad-y: .5rem;
  /* Shared interaction metrics; portal/native controls and the React workspace
     consume the same vocabulary, with compact and company overrides preserved. */
  --ui-control-height: var(--ds-control-height);
  --ui-control-height-compact: var(--ds-control-height-sm);
  --ui-control-height-auth: var(--control-h-lg);
  --ui-control-font-size: var(--fs-control);
  --ui-control-line-height: 1.25rem;
  --ui-control-radius: var(--ds-radius-sm);
  --ui-control-pad-x: .75rem;
  --ui-option-min-height: 2.25rem;
  --btn-pad-x: 1rem;
  --btn-gap: .5rem;
  --bar-h: .5rem;
  --bar-track: var(--gray-200);
  --icon-inset: .625rem;   /* where a field icon sits from the edge */
  --icon-size: 1rem;
  --field-pad-icon: calc(var(--icon-inset) + var(--icon-size) + .5rem);

  /* ---- Tooltip -----------------------------------------------------------
     The bubble a control grows on hover and on focus (§22 at the bottom of
     this file). VALUES ONLY — the rules that draw the bubble never say a
     colour or a size, so a page re-skins every tooltip by overriding these
     tokens rather than by copying the rules. `public/styles/app.css` does
     exactly that for its app.

     Light and warm rather than the near-black slab this widget used to draw:
     an overlay in this system is a white pane with a warm edge (`.x-pop`),
     and the bubble now belongs to that family — with the brand's bar down its
     leading edge, the same bar the app's marks wear. */
  --tip-bg: var(--gray-0);
  --tip-fg: var(--gray-800);
  --tip-border: var(--red-200);
  --tip-accent: var(--brand);
  --tip-radius: var(--r-md);
  --tip-shadow: var(--sh-md);
  --tip-size: var(--fs-xs);
  --tip-gap: var(--sp-2);

  /* ---- Inline SVG icon set --------------------------------------------
     One drawing spec for every glyph so they read as a family:
     24x24 grid, 1.75 stroke, round caps AND round joins, no fills.
     Thin round-capped strokes are what separates a current line-icon
     set from the heavy 2.4-weight marks this file used before.
     -------------------------------------------------------------------- */
  --i-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");
  --i-chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --i-chevron-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 6 6 6-6 6'/%3E%3C/svg%3E");
  --i-calendar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='3'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E");
  --i-clock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7v5l3.5 2'/%3E%3C/svg%3E");
  --i-spinner: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237e736e' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 10 4-4 4 4M8 14l4 4 4-4'/%3E%3C/svg%3E");
  --i-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237e736e' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");
  --i-check-brand: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E");
  --i-check-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E");
  --i-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7'/%3E%3C/svg%3E");
  --i-info: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 11.5v5M12 7.6v.4'/%3E%3C/svg%3E");
  --i-warn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z'/%3E%3Cpath d='M12 9v4.5M12 17.2v.3'/%3E%3C/svg%3E");
  --i-external: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3Cpath d='M15 3h6v6M10 14 21 3'/%3E%3C/svg%3E");
  --i-download: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3'/%3E%3C/svg%3E");
  --i-link: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1'/%3E%3Cpath d='M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1'/%3E%3C/svg%3E");
  --i-plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E");
  --i-trash: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7h16M10 11v6M14 11v6'/%3E%3Cpath d='M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13M9 7V4h6v3'/%3E%3C/svg%3E");
  --i-send: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 3 10.5 13.5M21 3l-6.5 18-4-8-8-4z'/%3E%3C/svg%3E");
  --i-refresh: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-2.6-6.4M21 3v6h-6'/%3E%3C/svg%3E");
  --i-user: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='4'/%3E%3Cpath d='M4 21a8 8 0 0 1 16 0'/%3E%3C/svg%3E");
  --i-arrow-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23b93521' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15M13 6l6 6-6 6'/%3E%3C/svg%3E");
  --i-quote: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e8a294' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 8H6a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1c0 2-1 3-2 3M19 8h-3a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2h1c0 2-1 3-2 3'/%3E%3C/svg%3E");
}

/* Hard lock — device/browser dark preference is explicitly ignored. */
@media (prefers-color-scheme: dark) { :root { color-scheme: light only; } }

} /* end tokens */

@layer reset {
/* ==========================================================================
   01. RESET / GLOBAL                                                         */
/* ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

/* ==========================================================================
   CURSOR & SELECTION MODEL  (app-like, not document-like)
   Browsers default to `cursor: auto`, which becomes an I-beam over ANY text.
   That reads like a document. Apps show an arrow everywhere and only offer
   the I-beam where text is genuinely editable or meant to be selected.
   Strategy: arrow on <body>, `inherit` on everything, then opt specific
   elements back in. Content regions stay selectable for copy/paste.
   ========================================================================== */
html { cursor: default; }
body { cursor: default; }
/* Inherit rather than `auto`, so no element silently reverts to an I-beam.
   html/body above are unwrapped on purpose: they must out-rank this rule to
   anchor the inheritance chain (`:where()` is zero-specificity, so a later
   zero-specificity rule would otherwise reset them to `inherit`/`auto`). */
:where(*) { cursor: inherit; }

/* --- Text entry: the ONLY place an I-beam belongs --- */
:where(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="image"])),
:where(textarea),
:where([contenteditable="true"]),
:where([contenteditable=""]) { cursor: text; }

/* --- Selection model ---
   Chrome-like: UI furniture is not selectable, prose is. */
:where(body) { -webkit-user-select: none; user-select: none; }
:where(p, h1, h2, h3, h4, h5, h6, li, dd, dt, td, th, caption, figcaption,
       blockquote, pre, code, samp, kbd, var, address, small, cite, q,
       article, section, main, output, time, span, em, strong, mark, abbr,
       sub, sup, label, legend, summary, details, [contenteditable]) {
  -webkit-user-select: text;
  user-select: text;
}
/* Controls and chrome never select */
:where(button, select, nav, [role="button"], [role="listbox"], [role="option"],
       .x-pop, .x-trigger, .x-opt, .x-cal, .x-time, ::-webkit-scrollbar) {
  -webkit-user-select: none;
  user-select: none;
}
:where(input, textarea, [contenteditable]) {
  -webkit-user-select: auto;
  user-select: auto;
}
/* Coarse pointers (touch) have no cursor at all - don't fight the platform */
@media (pointer: coarse) {
  :where(body) { -webkit-user-select: auto; user-select: auto; }
}

:where(*) {
  margin: 0;
  padding: 0;
  border: 0 solid var(--border);
  background-repeat: no-repeat;
  -webkit-tap-highlight-color: rgba(185, 53, 33, .16);
}

::selection { background: var(--selection-bg); color: var(--selection-fg); }
::target-text { background: var(--red-100); color: var(--red-950); }
:where(*)::marker { color: var(--red-500); }
::placeholder { color: var(--fg-subtle); opacity: 1; }
::file-selector-button { font: inherit; }
::backdrop { background: rgba(56, 15, 11, .42); }

/* ---- Scrollbars : "floating pill" ----
   Design notes (why it looks the way it does):
   - The thumb is a rounded pill INSET inside a wider track. That is done with
     a transparent border + `background-clip: padding-box`: the border
     reserves space the background never paints into, so the pill floats in a
     gutter instead of filling it edge to edge.
   - Colour is deliberately LIGHTER than the buttons (--red-300/400, not the
     --red-600 brand). A scrollbar is passive chrome; it must never compete
     with a primary action for attention.
   - The track is a faint hairline pill, not a grey slab.
   - Hover thickens the pill by shrinking the transparent border, mimicking
     the overlay scrollbars in modern desktop OSes.
   - `scrollbar-gutter: stable` reserves the space up front so content never
     reflows the moment it overflows.                                        */
:root {
  --sb-size: 14px;          /* full track width */
  --sb-pad: 4px;            /* transparent gutter around the pill */
  --sb-pad-hover: 3px;      /* thinner gutter = thicker pill on hover */
  --sb-thumb: var(--red-300);
  --sb-thumb-hover: var(--red-400);
  --sb-thumb-active: var(--red-500);
  /* An opaque track. `transparent` lets the browser's own scrollbar surface
     show through in Firefox, and that surface follows the OS theme - the
     same root cause as the dark WebKit gutter. */
  --sb-track: var(--gray-100);
  --sb-rail: rgba(185, 53, 33, .07);
  --sb-min: 42px;           /* never shrink below a grabbable size */
}

html { scrollbar-gutter: stable; }

/* Standard properties - Firefox and any engine WITHOUT the webkit pseudos.
   Guarded on purpose: in Chromium, `scrollbar-width: thin` switches the
   scrollbar to the built-in thin renderer and OVERRIDES the width set on
   ::-webkit-scrollbar, which would silently discard the pill design below.
   So the standard props are only applied where the pseudos do not exist. */
@supports not selector(::-webkit-scrollbar) {
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--sb-thumb) var(--sb-track);
  }
}

/* WebKit/Blink detail layer */
::-webkit-scrollbar {
  width: var(--sb-size);
  height: var(--sb-size);
  /* NOT `transparent`. A transparent scrollbar lets the UA's own scrollbar
     surface show through, and that surface follows the OS theme - which is
     how a dark bar appeared on a light-only page. An explicit opaque colour
     is the only way to keep the gutter light regardless of device theme. */
  background-color: var(--bg-body);
}
::-webkit-scrollbar-track {
  background: var(--sb-rail);
  border: calc(var(--sb-pad) + 1px) solid transparent;
  background-clip: padding-box;
  border-radius: var(--r-full);
}
::-webkit-scrollbar-thumb {
  min-height: var(--sb-min);
  min-width: var(--sb-min);
  background: var(--sb-thumb);
  background-clip: padding-box;      /* keeps the pill inset */
  border: var(--sb-pad) solid transparent;
  border-radius: var(--r-full);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--sb-thumb-hover);
  background-clip: padding-box;
  border-width: var(--sb-pad-hover);
}
::-webkit-scrollbar-thumb:active {
  background: var(--sb-thumb-active);
  background-clip: padding-box;
  border-width: var(--sb-pad-hover);
}
::-webkit-scrollbar-corner { background-color: var(--bg-body); }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

/* Compact rails for small inner panels */
:where(.x-pop, pre, .x-time-col, [data-scroll="compact"]) {
  --sb-size: 10px;
  --sb-pad: 3px;
  --sb-pad-hover: 2px;
  --sb-min: 28px;
}

/* Dark surfaces: pale the pill so it reads against the dark field */
:where(pre[data-dark], [data-surface="dark"]) {
  --sb-thumb: rgba(255, 255, 255, .22);
  --sb-thumb-hover: rgba(255, 255, 255, .34);
  --sb-thumb-active: rgba(255, 255, 255, .45);
  --sb-rail: rgba(255, 255, 255, .06);
}

/* ---- Focus ---- */
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: var(--r-xs); }
:focus:not(:focus-visible) { outline: none; }

} /* end reset */

@layer elements {
/* ==========================================================================
   02. DOCUMENT ROOT                                                          */
/* ========================================================================== */
:where(html) {
  font-family: var(--font-sans);
  font-size: 100%;
  line-height: var(--lh-base);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  tab-size: 2;
  scroll-behavior: auto;
  scroll-padding-top: var(--sp-5);
  /* The scrollbar gutter is painted from the CANVAS, which the root element
     supplies. It must therefore be the page colour, not the card colour, or
     the gutter reads as a white stripe beside a darker page. */
  background-color: var(--bg-body);
  color-scheme: light only;
  accent-color: var(--brand);
  caret-color: var(--brand);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

:where(body) {
  min-height: 100svh;
  /* The page sits a shade darker than the cards on it. That contrast is what
     lets the elevation ramp read at all - a white card on a white page has
     nothing to lift away from. */
  background-color: var(--bg-body);
  color-scheme: light only;   /* restated: some engines read it off <body> */
  color: var(--fg);
  font-size: var(--fs-base);
  font-weight: var(--fw-normal);
  line-height: var(--lh-base);
  overflow-wrap: break-word;
}

/* Never-rendered elements */
head, title, base, link, meta, style, script, datalist, source, track, param
  { display: none !important; }
template { display: none !important; }

:where(noscript) {
  display: block;
  padding: var(--sp-3) var(--sp-4);
  background: var(--danger-bg);
  border: 1px solid var(--border-brand);
  border-radius: var(--r-md);
  color: var(--red-800);
  font-size: var(--fs-sm);
}

/* ========================================================================== */
/* 03. SECTIONING                                                             */
/* ========================================================================== */

/* ---- header : STATIC by default. Opt in to sticky with [data-sticky]. ---- */
:where(header) {
  display: block;
  padding: var(--sp-4);
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
/* Opt-in sticky header */

/* ---- nav ---- */
:where(nav) { display: block; border-bottom: 0; box-shadow: none; }

/* ---- main / section / article / aside / footer ---- */
:where(main) {
  display: block; width: 100%; max-width: var(--container);
  margin-inline: auto; padding: var(--sp-6) var(--sp-5);
}
/* Sections are surfaces: same card treatment, same single elevation. */
:where(section) {
  display: block;
  padding: var(--sp-5);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
}
:where(section) > :first-child { margin-top: 0; }
:where(section) > :last-child { margin-bottom: 0; }

:where(article) {
  display: block;
  padding: var(--sp-5);
  background: var(--grad-surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
}
:where(article) > :first-child { margin-top: 0; }
:where(article) > :last-child { margin-bottom: 0; }
/* An <article>'s own footer sits flush: the article already pads the box, so
   the footer only needs a hairline rule and tight breathing room. */
:where(article) > footer {
  margin-top: var(--sp-4);
  padding: var(--sp-3) 0 0;
  border-top: 1px solid var(--border);
  background: none;
}

:where(aside) {
  display: block;
  /* Inline padding is tighter than block padding: the 4px accent bar already
     reads as left inset, so a full --sp-4 on top of it pushed the text far
     off the rule. The icon gap supplies the rest. */
  padding: var(--sp-3) var(--sp-4);
  padding-inline-start: var(--sp-3);
  /* A callout is a block in a flow and needs to clear whatever follows it.
     With no bottom margin it sat welded to the next field's label. */
  margin-block-end: var(--sp-4);
  background: var(--bg-brand-soft);
  border-inline-start: 4px solid var(--brand);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--red-900);
  font-size: var(--fs-sm);
}
:where(aside) > :last-child { margin-bottom: 0; }

/* ---- callout tones ----
   The base callout is brand-red because that is the house accent, but the
   element is also how this system reports SUCCESS and WARNING. Rendering
   "You have been signed out" in the danger palette tells the user something
   went wrong when nothing did, so a tone repaints the whole callout — bar,
   surface and text — not just the glyph. There is no `data-tone="error"`:
   an untoned callout is already the red one. */
:where(aside[data-tone="ok"]) {
  background: var(--success-bg);
  border-inline-start-color: var(--success);
  color: #12452c;
}
:where(aside[data-tone="warn"]) {
  background: var(--warning-bg);
  border-inline-start-color: var(--ember-500);
  color: var(--warning);
}

:where(footer) {
  display: block; padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--border);
  color: var(--fg-muted); font-size: var(--fs-sm);
}

/* ==========================================================================
   OPTICAL CENTRING - cap-height trim
   The font-face metric override above makes (ascent - capHeight) == descent,
   so a line box is cap-centred in theory. In practice the engine ROUNDS
   ascent/descent to whole pixels, which can leave a half-pixel bias.
   `text-box: trim-both cap alphabetic` removes the question entirely: it
   trims the line box to exactly cap-top..baseline, so `align-items:center`
   is centring the letters themselves rather than a box with leading in it.
   Chrome 133+/Safari 18.2+; Firefox falls back to the metric override,
   which is already correct to within a rounding pixel.
   Applied ONLY to single-line UI controls - never to prose, where the
   descender space is wanted for multi-line rhythm.
   ========================================================================== */
@supports (text-box: trim-both cap alphabetic) {
  :where(button, input[type="submit"], input[type="reset"], input[type="button"],
         .x-trigger, .x-opt, .x-cal-day, .x-cal-nav,
         summary, output, nav a) {
    text-box: trim-both cap alphabetic;
  }
}

/* ---- headings ---- */
:where(h1, h2, h3, h4, h5, h6) {
  margin: 0 0 var(--sp-3);
  color: var(--gray-900);
  font-weight: var(--fw-display);
  font-variation-settings: "wght" var(--fw-display);  /* same token: cannot diverge */
  font-optical-sizing: auto;
  line-height: var(--lh-tight);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
:where(* + h1, * + h2, * + h3, * + h4, * + h5, * + h6) { margin-top: var(--sp-6); }
:where(h1) {
  font-size: var(--fs-4xl);
  /* Large optical sizes need LESS weight, not more. Was 800. */
  font-weight: var(--fw-title);
  font-variation-settings: "wght" var(--fw-display);
  letter-spacing: var(--tracking-4xl);
  line-height: 1.05;
  color: var(--gray-900);
}
:where(h2) {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-title);
  font-variation-settings: "wght" var(--fw-display);
  letter-spacing: var(--tracking-3xl);
  /* No underline. A rule under every h2 was decoration masquerading as
     structure: it fired even when the h2 was the first line of a card that
     already had its own border, producing a double line. Separation is the
     job of the section's own spacing and surface, not the heading. Opt in
     with <h2 data-rule> where a divider is genuinely wanted. */
  padding-bottom: 0;
}
:where(h2[data-rule]) {
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--border);
}
:where(h3) { font-size: var(--fs-2xl); letter-spacing: var(--tracking-2xl); }
:where(h4) { font-size: var(--fs-xl); letter-spacing: var(--tracking-xl); }
:where(h5) { font-size: var(--fs-lg); font-weight: var(--fw-display); letter-spacing: var(--tracking-tight); }
:where(h6) {
  font-size: var(--fs-sm); font-weight: var(--fw-display); color: var(--brand-fg);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}

:where(hgroup) { display: block; margin-bottom: var(--sp-5); }
:where(hgroup) > * { margin-bottom: var(--sp-1); }
:where(hgroup) > p { color: var(--fg-muted); font-size: var(--fs-lg); }

:where(address) {
  display: block; margin-bottom: var(--sp-4);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-subtle);
  border-inline-start: 3px solid var(--border-brand);
  border-radius: var(--r-sm);
  font-style: normal; line-height: var(--lh-snug); color: var(--fg-muted);
}

/* ========================================================================== */
/* 04. TEXT CONTENT                                                           */
/* ========================================================================== */
:where(p) { margin: 0 0 var(--sp-4); text-wrap: pretty; }
:where(p:last-child) { margin-bottom: 0; }

:where(hr) { height: 1px; margin: var(--sp-6) 0; border: 0; background: var(--grad-rule); }

/* ---- pre / code : LIGHT themed surface, warm tint (no black block) ---- */
:where(pre) {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4);
  overflow: auto;
  max-width: 100%;
  background: var(--bg-code);
  background-image: linear-gradient(180deg, var(--gray-25), var(--bg-code));
  color: var(--gray-800);
  border: 1px solid var(--red-100);
  border-inline-start: 3px solid var(--red-300);
  border-radius: var(--r-md);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  line-height: 1.65;
  tab-size: 2;
  box-shadow: var(--sh-inset);
}

:where(blockquote) {
  margin: 0 0 var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--red-50);
  border-inline-start: 4px solid var(--brand);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--red-950);
  font-size: var(--fs-md);
  font-style: italic;
}
:where(blockquote) > :last-child { margin-bottom: 0; }

/* ---- lists ---- */
:where(ol, ul) {
  margin: 0 0 var(--sp-4); padding-inline-start: var(--sp-5);
  line-height: var(--lh-snug);      /* was inheriting body 1.6 - too airy */
}
:where(ol) { list-style: decimal; }
:where(ul) { list-style: disc; }
:where(li) { margin-bottom: 2px; padding-inline-start: var(--sp-1); line-height: var(--lh-snug); }
:where(li)::marker { color: var(--red-500); font-weight: var(--fw-semi); }
:where(ul[role="list"], ol[role="list"]) { list-style: none; padding-inline-start: 0; }
:where(menu) { margin: 0 0 var(--sp-4); padding-inline-start: var(--sp-5); list-style: disc; line-height: var(--lh-snug); }

:where(dl) {
  display: grid; grid-template-columns: minmax(8rem, max-content) 1fr;
  gap: var(--sp-2) var(--sp-4);
  margin: 0 0 var(--sp-4); padding: var(--sp-4);
  background: var(--bg-subtle); border: 1px solid var(--border); border-radius: var(--r-md);
}
:where(dt) { font-weight: var(--fw-semi); color: var(--brand-fg); }
:where(dd) { margin: 0; color: var(--fg-muted); }

:where(figure) {
  margin: 0 0 var(--sp-5); padding: var(--sp-3);
  background: var(--bg-subtle); border: 1px solid var(--border); border-radius: var(--r-lg);
}
:where(figcaption) {
  margin-top: var(--sp-2); color: var(--fg-muted);
  font-size: var(--fs-sm); line-height: var(--lh-snug); text-align: center;
}

:where(div) { display: block; }

:where(search) {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
/* The field flexes, the button keeps its intrinsic size and never wraps off */

/* ========================================================================== */
/* 05. INLINE SEMANTICS                                                       */
/* ========================================================================== */
:where(a) {
  color: var(--link); font-weight: var(--fw-medium);
  text-decoration: underline; text-decoration-thickness: 1px;
  text-underline-offset: .18em; text-decoration-color: var(--red-300);
  border-radius: var(--r-xs);
}
:where(a:hover) { color: var(--link-hover); text-decoration-color: currentColor; text-decoration-thickness: 2px; }
:where(a:active) { color: var(--red-950); }
:where(a:visited) { color: var(--link-visited); }

:where(a:not([href])) { color: var(--fg-muted); text-decoration: none; cursor: default; }

:where(em, i) { font-style: italic; }
:where(strong) { font-weight: var(--fw-semi); color: var(--gray-900); }
:where(b) { font-weight: var(--fw-semi); }
:where(b) { font-weight: var(--fw-semi); }
:where(small) { font-size: var(--fs-xs); color: var(--fg-muted); line-height: var(--lh-snug); }

:where(s) { text-decoration: line-through; text-decoration-color: var(--red-400); color: var(--fg-subtle); }
:where(del) {
  text-decoration: line-through; text-decoration-color: var(--red-500);
  background: var(--red-50); color: var(--red-800); padding: 0 .15em; border-radius: var(--r-xs);
}
:where(ins) {
  text-decoration: none; background: var(--success-bg); color: var(--success);
  padding: 0 .15em; border-radius: var(--r-xs); box-shadow: inset 0 -1px 0 currentColor;
}
:where(u) { text-decoration: underline; text-underline-offset: .15em; }
:where(mark) {
  padding: .08em .3em; background: var(--red-100); color: var(--red-950);
  border-radius: var(--r-xs); font-weight: var(--fw-medium);
}

:where(code) {
  padding: .12em .38em;
  background: var(--red-50); border: 1px solid var(--red-100); border-radius: var(--r-xs);
  color: var(--red-800); font-family: var(--font-mono); font-size: var(--fs-sm); word-break: break-word;
}
:where(kbd) {
  display: inline-block; min-width: 1.6em; padding: .15em .45em;
  background: linear-gradient(180deg, var(--gray-0), var(--gray-100));
  border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: var(--r-sm);
  color: var(--gray-800); font-family: var(--font-mono); font-size: var(--fs-xs); font-weight: var(--fw-semi);
  line-height: 1.4; text-align: center; box-shadow: 0 1px 0 rgba(56, 15, 11, .10);
}
:where(samp) {
  padding: .12em .38em; background: var(--gray-100); border-radius: var(--r-xs);
  color: var(--gray-800); font-family: var(--font-mono); font-size: var(--fs-sm);
}
:where(var) { font-family: var(--font-mono); font-style: italic; color: var(--red-700); font-size: var(--fs-sm); }

:where(sub, sup) { font-size: .72em; line-height: 0; position: relative; vertical-align: baseline; }
:where(sup) { top: -.5em; }
:where(sub) { bottom: -.25em; }

:where(abbr) { text-decoration: none; }
:where(abbr[title]) { text-decoration: underline dotted var(--red-400); text-underline-offset: .22em; cursor: help; }
:where(cite) { font-style: italic; color: var(--fg-muted); }
:where(q) { quotes: "“" "”" "‘" "’"; font-style: italic; color: var(--red-800); }
:where(q)::before { content: open-quote; }
:where(q)::after { content: close-quote; }
:where(dfn) { font-style: italic; font-weight: var(--fw-semi); color: var(--brand-fg); border-bottom: 1px dashed var(--border-brand); }
:where(time, data) { font-variant-numeric: tabular-nums; }
:where(time) { color: var(--fg-muted); }
:where(span) { font: inherit; color: inherit; }
:where(bdi) { unicode-bidi: isolate; }
:where(bdo) { unicode-bidi: bidi-override; }
:where(ruby) { ruby-position: over; }
:where(rt) { font-size: var(--fs-2xs); color: var(--fg-muted); }
:where(rp) { display: none; }

/* ========================================================================== */
/* 06. MEDIA                                                                  */
/* ========================================================================== */
:where(img, svg, video, canvas, audio, iframe, embed, object) { display: block; max-width: 100%; }

/* No image-level placeholder fill: transparent logos, diagrams and icons must
   show their actual parent surface instead of an opaque rounded rectangle.
   Components that require a skeleton should style their own wrapper. */
:where(img) {
  height: auto; border-radius: var(--r-md);
  background: transparent;
  font-style: italic; color: var(--fg-muted); font-size: var(--fs-sm);
  vertical-align: middle; object-fit: cover;
}
:where(picture) { display: block; }
/* Icon-in-text alignment: the canonical fix is a -0.125em baseline shift.
   `vertical-align: middle` centres on the x-height and always rides high. */
:where(svg) { fill: currentColor; }
:where(svg:not([width]):not([height])) {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;   /* sits on the text baseline */
  flex: none;
}
/* Inside flex contexts (buttons, nav) the shift is unnecessary */
:where(video) { width: 100%; background: var(--gray-900); border-radius: var(--r-md); box-shadow: var(--sh-sm); }
:where(audio) { width: 100%; min-height: 40px; border-radius: var(--r-full); }
:where(map) { display: inline; }
:where(area) { cursor: pointer; }

/* ========================================================================== */
/* 07. EMBEDDED CONTENT                                                       */
/* ========================================================================== */
:where(iframe, embed, object) {
  width: 100%; min-height: 240px; background: var(--bg-subtle);
  border: 1px solid var(--border); border-radius: var(--r-md);
}
:where(object) { min-height: 0; }
:where(canvas) {
  background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: var(--r-md); max-width: 100%;
}
:where(math) { font-family: var(--font-serif); font-size: var(--fs-base); }

/* ========================================================================== */
/* 08. TABULAR DATA                                                           */
/* ========================================================================== */
:where(table) {
  width: 100%; margin: 0 0 var(--sp-5);
  border-collapse: separate; border-spacing: 0;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--r-lg);
  overflow: hidden; font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums; box-shadow: var(--sh-sm); text-indent: 0;
}
:where(caption) {
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-subtle); border-bottom: 1px solid var(--border);
  color: var(--fg-muted); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-align: start; caption-side: top;
}
:where(thead) { background: var(--red-50); }
:where(thead th[aria-sort])::after {
  content: "↕"; margin-inline-start: .4em; opacity: .55; font-size: .9em;
}
:where(thead th[aria-sort="ascending"])::after { content: "↑"; opacity: 1; }
:where(thead th[aria-sort="descending"])::after { content: "↓"; opacity: 1; }
:where(tbody tr:nth-child(even)) { background: var(--gray-25); }
:where(tbody tr:hover) { background: var(--red-50); }
:where(tbody tr[aria-selected="true"]) { background: var(--red-100); box-shadow: inset 3px 0 0 var(--brand); }
:where(tfoot) { background: var(--bg-subtle); font-weight: var(--fw-semi); }
:where(th, td) {
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border);
  text-align: start; vertical-align: middle;
}
:where(th) { font-weight: var(--fw-semi); color: var(--gray-800); }
:where(tbody tr:last-child > td, tbody tr:last-child > th) { border-bottom: 0; }
:where(td[align="right"], th[align="right"]) { text-align: right; }

/* ========================================================================== */
/* 09. FORMS                                                                  */
/* ========================================================================== */
:where(form) { display: block; }

:where(fieldset) {
  margin: 0 0 var(--sp-5); padding: var(--sp-5);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  min-inline-size: auto;
}
:where(fieldset:disabled) { opacity: .6; background: var(--bg-muted); }
:where(legend) {
  padding: 0 var(--sp-2); margin-inline-start: calc(var(--sp-2) * -1);
  color: var(--brand-fg); font-size: var(--fs-sm); font-weight: var(--fw-semi);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
:where(label) {
  display: inline-block; margin-bottom: var(--sp-1);
  color: var(--gray-800); font-size: var(--fs-sm);
  font-weight: var(--fw-medium); line-height: var(--lh-snug);
}
:where(label:has(> input[type="checkbox"]), label:has(> input[type="radio"])) {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  margin-bottom: 0; cursor: pointer; font-weight: var(--fw-normal);
}
:where(label:has(> :disabled)) { cursor: not-allowed; color: var(--fg-subtle); }

:where(input, textarea, select, button, optgroup, option) {
  font-family: inherit; font-size: var(--fs-base); line-height: inherit; color: inherit;
}

/* ---- Shared field surface. Zero specificity, so per-type rules below
        (also zero specificity) win purely by source order. ------------- */
:where(input, textarea, select) {
  display: block; width: 100%;
  height: var(--control-h); min-height: var(--control-h);
  padding-block: 0;                 /* height + line-height centres the text */
  padding-inline: var(--field-pad-x);
  line-height: calc(var(--control-h) - 2px);
  background-color: var(--field-bg); color: var(--fg);
  border: 1px solid var(--field-border); border-radius: var(--field-radius);
  box-shadow: var(--sh-inset);
appearance: none;
}
/* Types that must NOT inherit the text-field box */
:where(input[type="checkbox"], input[type="radio"], input[type="range"],
       input[type="color"], input[type="file"], input[type="image"],
       input[type="submit"], input[type="reset"], input[type="button"]) {
  width: auto; height: auto; line-height: normal;
  box-shadow: none; appearance: auto;
}

:where(input:hover:not(:disabled), textarea:hover:not(:disabled), select:hover:not(:disabled)) {
  border-color: var(--red-300);
}
/* NOTE: :focus-visible intentionally matches TEXT FIELDS even on mouse click
   (browser heuristic), so it cannot be used to suppress a click ring here.
   Text fields therefore never get a halo at all - focus is communicated by
   a 1px border colour change plus the caret. Buttons/links still get a ring
   via the global :focus-visible rule, where the heuristic works as expected. */
:where(input:focus, textarea:focus, select:focus) {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--sh-inset);        /* same depth as rest state: no jump */
  background-color: var(--bg);
}
/* Opt in to a glow only if you want it */
:where(input[data-ring]:focus, textarea[data-ring]:focus, select[data-ring]:focus) {
  box-shadow: var(--ring);
}
/* Text fields opt OUT of the global :focus-visible outline entirely - their
   focus affordance is the border + caret. Matches the global rule's
   specificity so it actually wins. */
input:focus-visible,
textarea:focus-visible,
select:focus-visible { outline: none; }
/* ...but the non-text controls still need a visible keyboard ring */
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible,
input[type="range"]:focus-visible,
input[type="file"]:focus-visible,
input[type="color"]:focus-visible,
input[type="submit"]:focus-visible,
input[type="reset"]:focus-visible,
input[type="button"]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
:where(input:disabled, textarea:disabled, select:disabled) {
  background-color: var(--bg-muted); color: var(--fg-subtle);
  border-color: var(--border); box-shadow: none; cursor: not-allowed;
}
:where(input:read-only:not([type="checkbox"]):not([type="radio"]), textarea:read-only) {
  background-color: var(--bg-subtle); color: var(--fg-muted);
}
:where(input:user-invalid, textarea:user-invalid, select:user-invalid) {
  border-color: var(--red-600); box-shadow: var(--sh-inset);
}
/* No green. A valid field is the NORMAL state - colouring it green made the
   border change for no user-visible reason and clashed with the red system.
   Only errors are called out. */
:where(input:autofill) {
  -webkit-text-fill-color: var(--fg);
  box-shadow: 0 0 0 100px var(--red-50) inset;
  border-color: var(--red-200);
}

/* ---- Icon-bearing fields: icon sits in reserved padding, never overlaps --- */
:where(input[type="search"]) {
  padding-inline-start: var(--field-pad-icon);
  background-image: var(--i-search);
  background-size: var(--icon-size) var(--icon-size);
  background-position: var(--icon-inset) center;
}
:where(input[data-combobox]) {
  padding-inline-end: 2.3rem;
  background-image: var(--i-chevron-down);
  background-position: right .7rem center;
  background-size: 1rem;
}
:where(input[data-combobox][aria-expanded="true"]) { border-color: var(--brand); }

:where(input[type="search"])::-webkit-search-cancel-button {
  appearance: none; width: .85rem; height: .85rem; cursor: pointer;
  background: var(--i-close) center / contain no-repeat; opacity: .6;
}
:where(input[type="search"])::-webkit-search-cancel-button:hover { opacity: 1; }

/* ---- Number: real stepper buttons ----
   The old approach painted a static glyph and laid an invisible native
   spinner on top of it. That was unreliable (the native control is tiny and
   sits hard against the text) so JS now wraps the input in .x-num and
   renders two real buttons. The native spinner is removed outright. */
:where(input[type="number"]) {
  padding-inline-end: var(--sp-3);
  background-image: none;
  -moz-appearance: textfield;
  appearance: textfield;
}
:where(input[type="number"])::-webkit-outer-spin-button,
:where(input[type="number"])::-webkit-inner-spin-button {
  appearance: none; -webkit-appearance: none; margin: 0; display: none;
}

/* Wrapper injected by base.js */
:where(.x-num) { position: relative; display: block; width: 100%; }
:where(.x-num) > input[type="number"] { width: 100%; padding-inline-end: 2.1rem; }

:where(.x-num-btns) {
  position: absolute;
  /* Inset from the field edge so the column FLOATS inside the input instead
     of being welded to its border. Removing the full-height divider rule and
     the hard-cornered box is what separates this from a 2005 spinner. */
  top: 4px; bottom: 4px; right: 4px;
  width: 1.55rem;
  box-sizing: border-box;
  display: grid; grid-template-rows: 1fr 1fr; gap: 2px;
  padding: 0;
  border: 0;                      /* no divider line */
  border-radius: var(--r-xs);
  background: none;               /* no grey slab */
  overflow: hidden;
  opacity: 1;
  pointer-events: auto;
}

/* The shared field-metrics block gives every <button> a 38px height and a
   min-width. Inside the stepper column that made the two buttons overflow
   their container, so the box is reset explicitly here. */
:where(.x-num-btns) > .x-num-btn {
  appearance: none; -webkit-appearance: none;
  border: 0; margin: 0; padding: 0;
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-width: 0; max-width: none;
  height: 100%; min-height: 0; max-height: none;
  box-sizing: border-box;
  background: var(--bg-subtle);
  color: var(--fg-muted);
  box-shadow: none; font-size: inherit; line-height: 1;
  cursor: pointer;
  border-radius: var(--r-xs);
}
/* Chevrons drawn as real SVG strokes with round caps - the old rotated
   CSS-border triangles rendered as hairline wedges that aliased badly and
   never matched the round-capped icon set used everywhere else. */
.x-num-btns > .x-num-btn::before {
  content: "";
  width: .7em; height: .7em;
  background: currentColor;
  -webkit-mask: var(--i-chevron-down) no-repeat center / .7em .7em;
  mask: var(--i-chevron-down) no-repeat center / .7em .7em;
}
.x-num-btns > .x-num-btn[data-step="up"]::before { rotate: 180deg; }
.x-num-btns > .x-num-btn:hover {
  background: var(--red-100);
  color: var(--brand-fg);
}
.x-num-btns > .x-num-btn:active { background: var(--red-200); color: var(--red-900); }
:where(.x-num) > input:disabled ~ .x-num-btns { display: none; }

/* ---- Date & time: custom picker glyph in a reserved gutter ---- */
:where(input[type="date"], input[type="datetime-local"], input[type="month"], input[type="week"]) {
  padding-inline-end: 2.4rem;
  background-image: var(--i-calendar);
  background-size: 1.05rem;
  background-position: right .65rem center;
}
:where(input[type="time"]) {
  padding-inline-end: 2.4rem;
  background-image: var(--i-clock);
  background-size: 1.05rem;
  background-position: right .65rem center;
}
/* base.js draws a themed calendar/time panel, so the native OS indicator is
   removed completely. With data-native (or no JS) it stays clickable. */
:where(input[data-x-picker])::-webkit-calendar-picker-indicator { display: none; }
:where(input[data-x-picker]) { cursor: pointer; }

/* Fallback when JS is absent: invisible-but-clickable native indicator
   sitting exactly over our themed glyph. */
:where(input[type="date"], input[type="time"], input[type="datetime-local"],
       input[type="month"], input[type="week"])::-webkit-calendar-picker-indicator {
  width: 1.15rem; height: 1.15rem;
  margin: 0; padding: 0;
  margin-inline-end: -1.45rem;   /* pull into the gutter over our icon */
  opacity: 0; cursor: pointer;
}
:where(input[type="date"]:disabled, input[type="time"]:disabled,
       input[type="datetime-local"]:disabled) { background-image: none; }
/* Date sub-field polish */
::-webkit-datetime-edit { padding: 0; }
::-webkit-datetime-edit-fields-wrapper { padding: 0; }
::-webkit-datetime-edit-text { color: var(--fg-subtle); padding: 0 .1em; }
/* The ACTIVE segment of a date/time field is painted by the engine with the
   OS selection colour (Chrome blue) inside the input's shadow DOM.

   Probed empirically - only ONE selector reaches it:
     input::-webkit-datetime-edit-month-field          -> WORKS
     ...-month-field:focus                             -> never matches
     input::selection / ::selection                    -> never matches
   The segment is never itself :focus (the INPUT holds focus), and the paint
   is not a real ::selection, so the highlight has to be set on the unfocused
   part and re-stated while the input is focused. */
::-webkit-datetime-edit-year-field,
::-webkit-datetime-edit-month-field,
::-webkit-datetime-edit-day-field,
::-webkit-datetime-edit-hour-field,
::-webkit-datetime-edit-minute-field,
::-webkit-datetime-edit-second-field,
::-webkit-datetime-edit-millisecond-field,
::-webkit-datetime-edit-ampm-field,
::-webkit-datetime-edit-week-field {
  padding: 0 .12em;
  border-radius: var(--r-xs);
  color: var(--fg);
  caret-color: var(--brand);
}
/* Only the segment holding the caret may highlight. Probed against Chromium:
     :selected      -> no match
     :active        -> no match
     :focus         -> no match (the INPUT owns focus, not the part)
     :focus-within  -> MATCHES, and only for the caret's own segment
   so :focus-within is the one correct hook here. */
::-webkit-datetime-edit-year-field:focus-within,
::-webkit-datetime-edit-month-field:focus-within,
::-webkit-datetime-edit-day-field:focus-within,
::-webkit-datetime-edit-hour-field:focus-within,
::-webkit-datetime-edit-minute-field:focus-within,
::-webkit-datetime-edit-second-field:focus-within,
::-webkit-datetime-edit-millisecond-field:focus-within,
::-webkit-datetime-edit-ampm-field:focus-within,
::-webkit-datetime-edit-week-field:focus-within {
  background-color: var(--red-100);
  color: var(--red-900);
  outline: none;
}

/* ---- Checkbox / radio / switch ---- */
:where(input[type="checkbox"], input[type="radio"]) {
  appearance: none; -webkit-appearance: none;
  flex: none; width: 1.15em; height: 1.15em; min-height: 0; margin: 0; padding: 0;
  background: var(--gray-0); border: 1.5px solid var(--border-strong);
  box-shadow: var(--sh-xs); cursor: pointer;
  display: inline-grid; place-content: center;
}
:where(input[type="checkbox"]) { border-radius: var(--r-xs); }
:where(input[type="radio"]) { border-radius: var(--r-full); }
:where(input[type="checkbox"]:hover, input[type="radio"]:hover) { border-color: var(--red-400); background: var(--red-50); }
:where(input[type="checkbox"])::before {
  content: ""; width: .8em; height: .8em;background: var(--i-check) center / contain no-repeat;
}
:where(input[type="radio"])::before {
  content: ""; width: .5em; height: .5em; border-radius: 50%;background: var(--fg-on-brand);
}
:where(input[type="checkbox"]:checked, input[type="radio"]:checked, input[type="checkbox"]:indeterminate) {
  background: var(--grad-brand); border-color: var(--red-700); box-shadow: var(--sh-raised);
}
/* A CHECKED box shows a tick; an INDETERMINATE box shows a dash. These were
   sharing one rule that flattened the glyph to a 2px bar, so a checked box
   rendered identically to an indeterminate one - the tick never appeared. */
:where(input[type="checkbox"]:checked:not([role="switch"]))::before {
  width: .8em; height: .8em;
  border-radius: 0;
  background: var(--fg-on-brand);
  -webkit-mask: var(--i-check-mark) no-repeat center / .8em .8em;
  mask: var(--i-check-mark) no-repeat center / .8em .8em;
}
:where(input[type="checkbox"]:indeterminate:not([role="switch"]))::before {
  background: var(--fg-on-brand);
  -webkit-mask: none; mask: none;
  height: 2px; width: .6em; border-radius: 1px;
}
:where(input[type="checkbox"]:disabled, input[type="radio"]:disabled) {
  background: var(--bg-muted); border-color: var(--border); cursor: not-allowed;
}
:where(input[type="checkbox"]:checked:disabled, input[type="radio"]:checked:disabled) {
  background: var(--gray-400); border-color: var(--gray-400); box-shadow: none;
}
:where(input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible) {
  outline: none; box-shadow: var(--ring);
}
:where(input[type="checkbox"][role="switch"]) {
  width: 2.3em; height: 1.3em; border-radius: var(--r-full);
  place-content: center start; padding: 2px; background: var(--gray-200); border-color: var(--gray-300);
}
:where(input[type="checkbox"][role="switch"])::before {
  width: 1em; height: 1em; border-radius: 50%; background: var(--gray-0);
box-shadow: var(--sh-sm);
}
:where(input[type="checkbox"][role="switch"]:checked) {
  background: var(--grad-brand);
  place-content: center end;      /* knob slides to the far end */
}
/* the knob is a plain disc in every state - never a tick or a dash */
:where(input[type="checkbox"][role="switch"])::before,
:where(input[type="checkbox"][role="switch"]:checked)::before,
:where(input[type="checkbox"][role="switch"]:indeterminate)::before {
  width: 1em; height: 1em;
  border-radius: 50%;
  background: var(--gray-0);
  -webkit-mask: none; mask: none;
  box-shadow: var(--sh-sm);
}

/* ---- Range : fill is driven by --_fill (set by base.js) ---- */
:where(input[type="range"]) {
  appearance: none; -webkit-appearance: none;
  display: block; width: 100%;
  height: 1.25rem; min-height: 0; padding: 0; margin: 0;
  background: transparent; border: 0; box-shadow: none;
  cursor: pointer;
  --_fill: 50%;
}
/* WebKit track + progress fill */
:where(input[type="range"])::-webkit-slider-runnable-track {
  height: 6px; border-radius: var(--r-full);
  background:
    linear-gradient(90deg, var(--red-600) 0 var(--_fill), transparent var(--_fill) 100%),
    var(--gray-200);
  box-shadow: var(--sh-inset);
  border: 0;
}
:where(input[type="range"])::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none;
  width: 16px; height: 16px;
  margin-top: -5px;                 /* (track 6px - thumb 16px) / 2 */
  border-radius: 50%;
  background: var(--grad-brand);
  border: 2px solid var(--gray-0);
  box-shadow: 0 1px 3px rgba(56,15,11,.3);
}
/* Firefox */
:where(input[type="range"])::-moz-range-track {
  height: 6px; border-radius: var(--r-full); background: var(--gray-200); border: 0;
}
:where(input[type="range"])::-moz-range-progress {
  height: 6px; border-radius: var(--r-full); background: var(--red-600);
}
:where(input[type="range"])::-moz-range-thumb {
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--red-600); border: 2px solid var(--gray-0);
  box-shadow: 0 1px 3px rgba(56,15,11,.3);
}
:where(input[type="range"]:focus-visible)::-webkit-slider-thumb {
  box-shadow: 0 0 0 4px var(--ring-color);
}
:where(input[type="range"]:focus-visible)::-moz-range-thumb {
  box-shadow: 0 0 0 4px var(--ring-color);
}
:where(input[type="range"]:disabled) { cursor: not-allowed; opacity: .6; }
:where(input[type="range"]:disabled)::-webkit-slider-thumb { background: var(--gray-400); }
:where(input[type="range"]:disabled)::-webkit-slider-runnable-track {
  background: linear-gradient(90deg, var(--gray-400) 0 var(--_fill), transparent var(--_fill) 100%), var(--gray-200);
}

/* ---- Color / file / image / hidden ---- */
:where(input[type="color"]) {
  width: 3rem; height: var(--control-h); min-height: var(--control-h); line-height: normal; padding: 3px;
  background: var(--gray-0); border: 1px solid var(--field-border);
  border-radius: var(--r-md); cursor: pointer;
}
:where(input[type="color"])::-webkit-color-swatch-wrapper { padding: 0; }
:where(input[type="color"])::-webkit-color-swatch { border: 0; border-radius: var(--r-sm); }
:where(input[type="color"])::-moz-color-swatch { border: 0; border-radius: var(--r-sm); }

:where(input[type="file"]) {
  display: flex; align-items: center; width: 100%;
  height: auto; min-height: var(--control-h);
  padding: var(--sp-2); line-height: normal;
  font-size: var(--fs-sm); color: var(--fg-muted);
  background: var(--bg-subtle); border: 1px dashed var(--border-strong);
  border-radius: var(--r-md); cursor: pointer;
}
:where(input[type="file"]:hover) { border-color: var(--red-400); background: var(--red-50); }
:where(input[type="file"])::file-selector-button {
  margin-inline-end: var(--sp-3); padding: var(--sp-2) var(--sp-3);
  background: var(--grad-brand); color: var(--fg-on-brand);
  border: 0; border-radius: var(--r-sm);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer;
}
:where(input[type="file"])::file-selector-button:hover { filter: brightness(.92); }
:where(input[type="image"]) { border: 1px solid var(--border); border-radius: var(--r-md); cursor: pointer; }
input[type="hidden"] { display: none !important; }

/* ---- Textarea ---- */
:where(textarea) {
  height: auto; min-height: 6rem;
  padding-block: var(--sp-3); padding-inline: var(--field-pad-x);
  line-height: var(--lh-base);
  resize: vertical; field-sizing: content;
}

/* ---- Select ---- */
:where(select) {
  padding-inline-end: 2.3rem;
  background-image: var(--i-chevron-down);
  background-position: right .7rem center;
  background-size: 1rem;
  cursor: pointer;
}
:where(select[multiple], select[size]:not([size="1"])) {
  background-image: none; padding: var(--sp-1); min-height: 6rem;
}
:where(option) {
  min-block-size: var(--ui-option-min-height);
  padding: var(--sp-2);
  background: var(--bg);
  color: var(--fg);
  font-size: var(--ui-control-font-size);
  font-weight: var(--fw-normal);
}
:where(option:checked) { background: var(--red-100); color: var(--red-900); font-weight: var(--fw-medium); }
:where(option:disabled) { color: var(--fg-subtle); }
:where(optgroup) { font-weight: var(--fw-semi); color: var(--brand-fg); font-style: normal; }

/* ==========================================================================
   OPTICAL TEXT CENTERING
   `align-items: center` centres the line box, which includes invisible
   half-leading that is asymmetric above cap-height vs below the baseline.
   The glyphs therefore render ~0.5-1px high in every control. Fix:
     2. margin-block: calc(0.5cap - 0.5lh)   (fallback, wide support)
   ========================================================================== */

/* ---- Buttons : unified metrics, true optical centering ----
   line-height:1 + flex centering + equal padding = text sits dead center.
   Height is driven by padding so multi-line never breaks alignment. */
:where(button, input[type="submit"], input[type="reset"], input[type="button"]) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--btn-gap);
  height: var(--control-h);
  min-height: var(--control-h);
  padding-block: 0;
  padding-inline: var(--btn-pad-x);
  line-height: 1;
  background: var(--grad-brand);
  color: var(--fg-on-brand);
  border: 1px solid var(--red-700);
  border-radius: var(--r-md);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  letter-spacing: .01em;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: var(--sh-raised);
}
/* Icons inside buttons never stretch or shift the baseline */

/* Sibling buttons get automatic spacing — no more touching edges */
:where(button + button,
       button + input[type="submit"], button + input[type="reset"], button + input[type="button"],
       input[type="submit"] + button, input[type="reset"] + button, input[type="button"] + button,
       input[type="submit"] + input, input[type="reset"] + input, input[type="button"] + input) {
  margin-inline-start: var(--sp-2);
}

:where(button:hover, input[type="submit"]:hover, input[type="reset"]:hover, input[type="button"]:hover) {
  background: var(--grad-brand-hover);
  box-shadow: 0 2px 6px rgba(56,15,11,.18);
}
:where(button:active, input[type="submit"]:active, input[type="reset"]:active, input[type="button"]:active) {
  background: var(--red-800);
box-shadow: inset 0 2px 4px rgba(56,15,11,.28);
}
:where(button:focus-visible, input[type="submit"]:focus-visible,
       input[type="reset"]:focus-visible, input[type="button"]:focus-visible) {
  outline: none; box-shadow: var(--ring-offset);
}
:where(button:disabled, input[type="submit"]:disabled, input[type="reset"]:disabled, input[type="button"]:disabled) {
  background: var(--gray-200); border-color: var(--gray-300); color: var(--fg-subtle);
  cursor: not-allowed; box-shadow: none; transform: none;
}

/* Size variants */
:where(button[data-size="sm"], input[data-size="sm"]) {
  height: var(--control-h-sm); min-height: var(--control-h-sm);
  padding-inline: var(--sp-3); font-size: var(--fs-xs); border-radius: var(--r-sm);
}
:where(button[data-size="lg"], input[data-size="lg"]) {
  height: var(--control-h-lg); min-height: var(--control-h-lg);
  padding-inline: var(--sp-5); font-size: var(--fs-base);
}
:where(button[data-block]) { display: flex; width: 100%; }
/* Icon-ONLY buttons are square. This must not match a labelled button such
   as data-icon="send", which is a label WITH an icon - that was collapsing
   every labelled button to a 38px square and clipping its text. */
:where(button[data-icon=""], button[data-icon-only]) {
  width: var(--control-h); padding-inline: 0; flex: none; border-radius: var(--r-md);
}

/* Variants derived from semantics */
:where(button[type="reset"], input[type="reset"]) {
  background: var(--bg); color: var(--brand-fg);
  border-color: var(--border-strong); box-shadow: var(--sh-xs);
}
:where(button[type="reset"]:hover, input[type="reset"]:hover) {
  background: var(--red-50); border-color: var(--red-300);
}
:where(button[type="button"], input[type="button"]) {
  background: var(--grad-surface); color: var(--gray-800);
  border-color: var(--border-strong); box-shadow: var(--sh-xs);
}
:where(button[type="button"]:hover, input[type="button"]:hover) {
  background: var(--bg-subtle); border-color: var(--red-300); color: var(--brand-fg);
}
:where(button[data-variant="ghost"]) {
  background: transparent; border-color: transparent;
  color: var(--brand-fg); box-shadow: none;
}
:where(button[data-variant="ghost"]:hover) { background: var(--red-50); border-color: transparent; }
:where(button[data-variant="danger"]) {
  background: linear-gradient(180deg, var(--red-600), var(--red-800));
  border-color: var(--red-900); color: var(--fg-on-brand);
}
:where(button[aria-pressed="true"]) {
  background: var(--red-100); border-color: var(--red-300);
  color: var(--red-800); box-shadow: var(--sh-inset);
}
/* Button groups */

/* ---- Output / progress / meter : ONE shared bar system ----
   All three share height, radius, track color and inset shadow so they
   never look like three different widgets. */
:where(output) {
  display: inline-flex; align-items: center;
  min-height: var(--control-h-sm);
  padding: 0 var(--sp-3);
  background: var(--red-50);
  border: 1px solid var(--red-100);
  border-radius: var(--r-sm);
  color: var(--red-800);
  font-family: var(--font-mono); font-size: var(--fs-sm);
  font-weight: var(--fw-semi); font-variant-numeric: tabular-nums;
  line-height: 1;
}

:where(progress, meter) {
  appearance: none; -webkit-appearance: none;
  display: block;
  width: 100%;
  height: var(--bar-h);
  margin: 0;
  border: 0;
  border-radius: var(--r-full);
  background: var(--bar-track);
  box-shadow: var(--sh-inset);
  overflow: hidden;
  color: var(--brand);
}
/* -- progress -- */
:where(progress)::-webkit-progress-bar {
  background: var(--bar-track); border-radius: var(--r-full); box-shadow: var(--sh-inset);
}
:where(progress)::-webkit-progress-value {
  background: var(--grad-ember);
  border-radius: var(--r-full);
}
:where(progress)::-moz-progress-bar { background: var(--grad-ember); border-radius: var(--r-full); }
:where(progress:indeterminate) {
  background: var(--bar-track);
  background-image: repeating-linear-gradient(-45deg,
      var(--red-300) 0 10px, var(--red-100) 10px 20px);
  background-size: 200% 100%;
}
:where(progress:indeterminate)::-webkit-progress-bar { background: transparent; }
:where(progress:indeterminate)::-moz-progress-bar { background: transparent; }
/* -- meter : identical geometry to progress -- */
:where(meter)::-webkit-meter-inner-element { border-radius: var(--r-full); }
:where(meter)::-webkit-meter-bar {
  background: var(--bar-track); border: 0; border-radius: var(--r-full); box-shadow: var(--sh-inset);
}
:where(meter)::-webkit-meter-optimum-value { background: var(--success); border-radius: var(--r-full); }
:where(meter)::-webkit-meter-suboptimum-value { background: var(--ember-500); border-radius: var(--r-full); }
:where(meter)::-webkit-meter-even-less-good-value { background: var(--red-600); border-radius: var(--r-full); }
:where(meter)::-moz-meter-bar { border-radius: var(--r-full); }
:where(meter:-moz-meter-optimum)::-moz-meter-bar { background: var(--success); }
:where(meter:-moz-meter-sub-optimum)::-moz-meter-bar { background: var(--ember-500); }
:where(meter:-moz-meter-sub-sub-optimum)::-moz-meter-bar { background: var(--red-600); }

/* Bar size variants */
:where(progress[data-size="lg"], meter[data-size="lg"]) { height: calc(var(--bar-h) * 1.8); }
:where(progress[data-size="sm"], meter[data-size="sm"]) { height: calc(var(--bar-h) * .6); }

/* ========================================================================== */
/* 10. INTERACTIVE / OVERLAYS                                                 */
/* ========================================================================== */
:where(details) {
  margin: 0 0 var(--sp-3); background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden;
}
:where(details:hover) { border-color: var(--red-200); }
:where(details[open]) { box-shadow: var(--sh-sm); border-color: var(--red-200); }
:where(summary) {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-subtle); color: var(--gray-800);
  font-weight: var(--fw-semi); font-size: var(--fs-sm);
  cursor: pointer; user-select: none; list-style: none;
}
:where(summary)::-webkit-details-marker { display: none; }
:where(summary)::marker { content: ""; }
:where(summary)::before {
  content: ""; flex: none; width: .55em; height: .55em;
  border-right: 2px solid var(--brand); border-bottom: 2px solid var(--brand);
  transform: rotate(-45deg);}

/* ---- dialog: hidden unless open ---- */
:where(dialog) {
  max-width: min(92vw, 34rem); max-height: 85vh; margin: auto;
  padding: var(--sp-5); background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--r-xl);
  box-shadow: var(--sh-xl); overflow: hidden auto;
}
dialog:not([open]) { display: none !important; }
:where(dialog)::backdrop { background: rgba(56, 15, 11, .45); backdrop-filter: blur(2px); }
:where(dialog) > :last-child { margin-bottom: 0; }

/* ---- popover: MUST stay hidden until invoked ---- */
[popover] { display: none; }
[popover]:popover-open { display: block; }
:where([popover]) {
  position: fixed; inset: auto; margin: auto;
  width: fit-content; max-width: min(92vw, 26rem);
  padding: var(--sp-4);
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--border-brand); border-radius: var(--r-lg);
  box-shadow: var(--sh-lg);
  overflow: auto;
}
:where([popover]) > :last-child { margin-bottom: 0; }
:where([popover])::backdrop { background: rgba(56, 15, 11, .22); }
/* Fallback for engines without :popover-open */
@supports not selector(:popover-open) {
  [popover]:not(.is-open) { display: none; }
  [popover].is-open { display: block; }
}

/* ========================================================================== */
/* 11. WEB COMPONENTS / ATTRIBUTE DEFAULTS                                    */
/* ========================================================================== */
:where(slot) { display: contents; }
:where(fencedframe) { display: block; border: 1px solid var(--border); border-radius: var(--r-md); }
:where(marquee) { display: block; color: var(--brand-fg); }
:where([contenteditable="true"]) {
  padding: var(--sp-3); background: var(--bg);
  border: 1px dashed var(--border-strong); border-radius: var(--r-md); min-height: 3rem;
}
:where([contenteditable="true"]:focus) {
  outline: none; border-color: var(--brand); border-style: solid; box-shadow: var(--ring);
}
[hidden] { display: none !important; }
:where([inert]) { opacity: .55; user-select: none; pointer-events: none; }
:where(a, button, summary, label, select, [role="button"]) { touch-action: manipulation; }

/* --- 12. UTILITIES, A11Y, PRINT --- */
.visually-hidden:not(:focus):not(:active) {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

@media print {
  :where(body) { background: #fff; color: #000; }
  nav, footer, button, input[type="submit"] { display: none !important; }
  :where(a)::after { content: " (" attr(href) ")"; font-size: .85em; }
  :where(article, table, pre) { break-inside: avoid; box-shadow: none; }
}

} /* end elements */

@layer context {
/* ==========================================================================
   CONTEXTUAL OVERRIDES
   Rules targeting an element *inside a context* (nav ul, figure > img,
   pre code). They live in a layer ABOVE `elements`, so a generic tag rule
   can never override them regardless of source order. This is the
   root-cause fix for the <nav> rendering list bullets and link underlines:
   :where(nav ul) and :where(ul) both had zero specificity, so whichever
   came last in the file won.
   ========================================================================== */

/* ---- nav ---- */
:where(nav) ul, :where(nav) ol, :where(nav) menu {
  list-style: none; margin: 0; padding-inline-start: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1);
}
:where(nav) li { margin: 0; padding-inline-start: 0; list-style: none; display: block; }
:where(nav) li::marker { content: ""; font-size: 0; }
:where(nav) a {
  display: inline-flex; align-items: center;
  /* line-height:1 so the link's own box is glyph-sized; the nav's inherited
     1.6 body leading was what pushed these links off-centre. */
  line-height: 1;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--fg-muted); font-weight: var(--fw-medium);
  text-decoration: none;
}
:where(nav) a:hover { background: var(--red-50); color: var(--brand-fg); text-decoration: none; }
:where(nav) a:active { background: var(--red-100); }
:where(nav) a:visited { color: var(--fg-muted); }
:where(nav) a[aria-current] {
  color: var(--brand-fg); background: var(--red-50);
}
:where(nav) a::after, :where(nav) a::before { content: none; }

/* ---- header / footer placement ---- */
:where(body > header) { position: static; background: var(--grad-surface); box-shadow: var(--sh-xs); }
:where(header[data-sticky]) {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: saturate(1.5) blur(10px);
}
:where(body > footer) { background: var(--bg-subtle); margin-top: var(--sp-7); }
:where(article + article) { margin-top: var(--sp-5); }

/* ---- figure children (concentric radius) ---- */
:where(figure) > img, :where(figure) > picture > img,
:where(figure) > svg, :where(figure) > video, :where(figure) > canvas {
  display: block; width: 100%;
  border-radius: max(0px, calc(var(--r-lg) - var(--sp-3)));
}
:where(figure) > pre, :where(figure) > table, :where(figure) > blockquote { margin-bottom: 0; }
:where(picture) > img { width: 100%; }

/* ---- inline children ---- */
:where(pre) code { padding: 0; background: none; border: 0; color: inherit; font-size: inherit; }
:where(blockquote) cite {
  display: block; margin-top: var(--sp-2);
  color: var(--red-800); font-size: var(--fs-sm); font-style: normal; font-weight: var(--fw-medium);
}
:where(kbd) kbd { border: 0; box-shadow: none; background: none; padding: 0; min-width: 0; }

/* ---- nested lists ---- */
:where(ol) ol { list-style: lower-alpha; }
:where(ol) ol ol { list-style: lower-roman; }
:where(ul) ul { list-style: circle; }
:where(ul) ul ul { list-style: square; }
:where(ol) ol, :where(ol) ul, :where(ul) ul, :where(ul) ol { margin-block: var(--sp-2); }

/* ---- search shell: concentric radius, identical in every state ---- */
:where(search) > input {
  flex: 1 1 auto; width: auto; min-width: 0;
  border-radius: var(--r-inner);
}
:where(search) > input:hover,
:where(search) > input:focus,
:where(search) > input:active { border-radius: var(--r-inner); }
:where(search) > button { flex: 0 0 auto; border-radius: var(--r-inner); }
:where(search) > label { flex: none; margin-bottom: 0; }

/* ---- table parts ---- */
:where(thead) th {
  position: sticky; top: 0; z-index: 1;
  background: var(--red-50); color: var(--red-800);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  white-space: nowrap; box-shadow: inset 0 -1px 0 var(--red-200);
}
:where(tbody) tr:nth-child(even) { background: var(--gray-25); }
:where(tbody) tr:hover { background: var(--red-50); }
:where(tbody) tr[aria-selected="true"] { background: var(--red-100); box-shadow: inset 3px 0 0 var(--brand); }
:where(tbody) tr:last-child > td, :where(tbody) tr:last-child > th { border-bottom: 0; }
:where(tfoot) td, :where(tfoot) th { border-top: 2px solid var(--border-strong); color: var(--gray-800); }
:where(th[scope="row"]) { background: var(--gray-25); color: var(--brand-fg); }

/* ---- details / summary ---- */
:where(details) > :not(summary) { padding-inline: var(--sp-4); }
:where(details) > summary + * { padding-top: var(--sp-3); margin-top: 0; }
:where(details) > :last-child { padding-bottom: var(--sp-4); }
:where(details[open]) > summary { border-bottom: 1px solid var(--border); }
:where(details[open]) > summary::before { transform: rotate(45deg); }
:where(summary):hover { background: var(--red-50); color: var(--brand-fg); }

/* ---- icons inside flex controls need no baseline shift ---- */
:where(button) > svg, :where(button) > img { flex: none; width: 1.05em; height: 1.05em; vertical-align: 0; }
:where(summary) > svg, :where(.x-opt) > svg, :where(.x-trigger) > svg { vertical-align: 0; }
/* Dialog action row: a real footer. It is separated from the body by a rule
   that bleeds to the dialog's edges (negative inline margin cancels the
   dialog padding), so the buttons read as a distinct commit bar rather than
   floating in the corner. */
:where(dialog) > form[method="dialog"] {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: var(--sp-5) calc(var(--sp-5) * -1) calc(var(--sp-5) * -1);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--border);
  background: var(--bg-subtle);
  border-end-start-radius: inherit;
  border-end-end-radius: inherit;
}
:where(dialog) > form[method="dialog"] > button { margin: 0; flex: 0 0 auto; }
/* A ghost button next to a solid one needs the visual weight of a border to
   stop it reading as plain text. */
:where(dialog) > form[method="dialog"] > button[data-variant="ghost"] {
  border-color: var(--border);
  background: var(--bg);
}
:where(dialog) > form[method="dialog"] > button[data-variant="ghost"]:hover {
  background: var(--red-50); border-color: var(--red-200);
}

/* ---- segmented button group ---- */
:where([role="group"]) { display: inline-flex; }
:where([role="group"]) > button { border-radius: 0; margin-inline-start: -1px; }
:where([role="group"]) > button:first-child {
  border-start-start-radius: var(--r-md); border-end-start-radius: var(--r-md); margin-inline-start: 0;
}
:where([role="group"]) > button:last-child {
  border-start-end-radius: var(--r-md); border-end-end-radius: var(--r-md);
}
/* --- Interactive controls: pointer --- */
:where(a[href]), :where(button), :where(summary), :where(select),
:where(label[for]), :where(option),
:where([role="button"]), :where([role="option"]), :where([role="tab"]),
:where([role="menuitem"]), :where([role="link"]),
:where(input[type="checkbox"]), :where(input[type="radio"]),
:where(input[type="submit"]), :where(input[type="reset"]),
:where(input[type="button"]), :where(input[type="image"]),
:where(input[type="file"]), :where(input[type="color"]),
:where(.x-opt), :where(.x-trigger), :where(.x-cal-day), :where(.x-cal-nav) {
  cursor: pointer;
}

/* --- State cursors --- */
:where(:disabled), :where([aria-disabled="true"]), abbr[title], [role="tooltip"] { cursor: help; }
:where(a[href^="mailto:"]), :where(a[href^="tel:"]) { cursor: pointer; }

:where(input[type="range"]) { cursor: ew-resize; }
:where(input[type="range"]:active) { cursor: grabbing; }
:where(input[type="range"]:disabled) { cursor: not-allowed; }
:where(:disabled), :where([aria-disabled="true"]), :where(fieldset:disabled *) {
  cursor: not-allowed;
}
} /* end context */

@layer components {
/* ==========================================================================
   13. CUSTOM WIDGET LAYER
   Native <select> popups, date-picker calendars and <datalist> suggestion
   lists are rendered by the OS/browser and CANNOT be styled with CSS. The
   markup below is enhanced by base.js, which builds real DOM replacements
   that carry the Ember theme. Everything degrades to the native control if
   JS is unavailable.
   ========================================================================== */

/* ---- Shared floating surface for every dropdown/menu/calendar ---- */
:where(.x-pop) {
  position: absolute;
  z-index: 1000;
  width: max-content;
  min-width: 0;
  max-width: min(92vw, 22rem);
  max-height: 16rem;
  overflow: auto;
  overscroll-behavior: contain;
  padding: var(--sp-1);
  background: var(--bg);
  border: 1px solid var(--border-brand);
  border-radius: var(--r-md);
  box-shadow: var(--sh-lg);
  opacity: 0;
transform-origin: top center;
pointer-events: none;
}
:where(.x-pop[data-open]) { opacity: 1; transform: none; pointer-events: auto; }
:where(.x-pop[data-placement="top"]) { transform-origin: bottom center; }

/* ---- Option rows (select, datalist, any menu) ---- */
:where(.x-opt) {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  color: var(--fg);
  font-size: var(--fs-sm);
  line-height: 1.3;
  cursor: pointer;
  user-select: none;
  scroll-margin: var(--sp-1);
}
:where(.x-opt:hover), :where(.x-opt[data-active]) {
  background: var(--red-50);
  color: var(--brand-fg);
}
:where(.x-opt[data-selected]) {
  background: var(--red-100);
  color: var(--red-900);
  font-weight: var(--fw-semi);
}
:where(.x-opt[data-selected])::after {
  content: "";
  margin-inline-start: auto;
  width: .85em; height: .85em;
  background: var(--i-check-brand) center / contain no-repeat;
}
:where(.x-opt[aria-disabled="true"]) {
  color: var(--fg-subtle); cursor: not-allowed; background: none;
}
:where(.x-optgroup) {
  padding: var(--sp-2) var(--sp-3) var(--sp-1);
  color: var(--brand-fg);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
:where(.x-empty) {
  padding: var(--sp-3);
  color: var(--fg-subtle);
  font-size: var(--fs-sm);
  text-align: center;
}

/* ---- Custom select trigger (mirrors the native field exactly) ---- */
:where(.x-select) { position: relative; display: block; width: 100%; }
:where(.x-select > select) { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
:where(.x-trigger) {
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* reset the button base's centering */
  gap: var(--sp-2);
  font-weight: var(--fw-normal); /* reset the button base's 600 */
  letter-spacing: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  height: var(--control-h);
  width: 100%;
  min-height: var(--control-h);
  padding: var(--field-pad-y) 2.3rem var(--field-pad-y) var(--field-pad-x);
  background: var(--field-bg);
  color: var(--fg);
  border: 1px solid var(--field-border);
  border-radius: var(--field-radius);
  box-shadow: var(--sh-inset);
  font-size: var(--fs-base);
  text-align: start;
  cursor: pointer;
}
:where(.x-trigger:hover) { border-color: var(--red-300); background: var(--field-bg); box-shadow: var(--sh-inset); }
:where(.x-trigger:focus-visible) { outline: none; border-color: var(--brand); box-shadow: var(--ring); }
:where(.x-trigger[aria-expanded="true"]) { border-color: var(--brand); box-shadow: var(--ring-soft); }
:where(.x-trigger)::after {
  content: "";
  position: absolute;
  inset-inline-end: var(--icon-inset);
  width: 1rem; height: 1rem;
  background: var(--i-chevron-down) center / contain no-repeat;
pointer-events: none;
}
:where(.x-trigger[aria-expanded="true"])::after { transform: rotate(180deg); }
:where(.x-placeholder) { color: var(--fg-subtle); }

/* ---- Calendar (date picker) : compact, modern, 2-line header ---- */
:where(.x-cal) {
  --cell: 2rem;
  /* 7 cells + the grid gaps + the panel padding. Setting an explicit floor
     stops the header's month dropdown from clipping "September". */
  min-width: calc(var(--cell) * 7 + var(--sp-3) * 2 + 6px);
  width: max-content;
  max-width: none;
  padding: var(--sp-3);
  max-height: none;
  overflow: visible;
  border-radius: var(--r-lg);
}
:where(.x-cal-head) {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--sp-1);
  margin-bottom: var(--sp-2);
}
/* Month + year as real controls, not static text */
:where(.x-cal-sel) {
  min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: var(--sp-1);
}
/* Month names are long ("September"); give that select the slack and keep
   the year select to its intrinsic width so neither clips. */
:where(.x-cal-sel) > select:first-child { flex: 1 1 auto; }
:where(.x-cal-sel) > select + select { flex: 0 0 auto; }
:where(.x-cal-sel) > select {
  appearance: none; -webkit-appearance: none;
  height: 1.9rem; min-height: 0;
  width: auto; max-width: none; min-width: 0;
  text-overflow: ellipsis;
  padding: 0 1.45rem 0 var(--sp-2);
  border: 1px solid transparent; border-radius: var(--r-sm);
  background-color: transparent;
  background-image: var(--i-chevron-down);
  background-repeat: no-repeat;
  background-position: right var(--sp-2) center;
  background-size: .7rem;
  color: var(--gray-900); font-size: var(--fs-sm); font-weight: var(--fw-normal);
  line-height: 1.9rem;
  cursor: pointer;
}
/* The OS renders the open list, but the closed control and its option rows
   are ours. */
:where(.x-cal-sel) > select > option {
  background: var(--bg); color: var(--fg);
  font-size: var(--fs-sm); font-weight: var(--fw-normal);
  padding: var(--sp-2) var(--sp-3);
}
:where(.x-cal-sel) > select > option:checked {
  background: var(--red-100); color: var(--red-900); font-weight: var(--fw-semi);
}
:where(.x-cal-sel) > select:hover { background-color: var(--red-50); border-color: var(--red-200); }
:where(.x-cal-sel) > select:focus { border-color: var(--brand); background-color: var(--bg); }

:where(.x-cal-nav) {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.85rem; height: 1.85rem; flex: none; padding: 0;
  background: transparent; color: var(--brand-fg);
  border: 1px solid transparent; border-radius: var(--r-sm);
  font: inherit; font-size: var(--fs-sm); line-height: 1;
  cursor: pointer; box-shadow: none;
}
:where(.x-cal-nav)::before {
  content: ""; width: .5em; height: .5em;
  border-top: 2px solid currentColor; border-right: 2px solid currentColor;
}
:where(.x-cal-nav[data-dir="prev"])::before { transform: rotate(-135deg); margin-left: 2px; }
:where(.x-cal-nav[data-dir="next"])::before { transform: rotate(45deg); margin-right: 2px; }
:where(.x-cal-nav:hover) { background: var(--red-50); border-color: var(--red-200); }
:where(.x-cal-nav:active) { background: var(--red-100); }

:where(.x-cal-grid) {
  display: grid;
  grid-template-columns: repeat(7, var(--cell));
  gap: 1px;
}
:where(.x-cal-dow) {
  display: flex; align-items: center; justify-content: center;
  height: 1.6rem;
  font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  color: var(--fg-subtle); text-transform: uppercase;
  letter-spacing: .04em;
}
:where(.x-cal-day) {
  display: flex; align-items: center; justify-content: center;
  width: var(--cell); height: var(--cell);
  padding: 0; margin: 0;
  background: none; border: 0; box-shadow: none;
  border-radius: var(--r-sm);
  color: var(--gray-800);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-normal);
  font-variant-numeric: tabular-nums; letter-spacing: normal;
  cursor: pointer;
}
:where(.x-cal-day:hover) { background: var(--red-50); color: var(--brand-fg); }
:where(.x-cal-day[data-outside]) { color: var(--gray-400); }
:where(.x-cal-day[data-weekend]) { color: var(--red-700); }
:where(.x-cal-day[data-outside][data-weekend]) { color: var(--red-300); }
/* today = a dot under the number, not a heavy ring */
:where(.x-cal-day[data-today]) { font-weight: var(--fw-semi); position: relative; }
:where(.x-cal-day[data-today])::after {
  content: ""; position: absolute; bottom: 3px; left: 50%; translate: -50% 0;
  width: 3px; height: 3px; border-radius: 50%; background: var(--brand);
}
:where(.x-cal-day[data-selected]) {
  background: var(--grad-brand); color: var(--fg-on-brand);
  font-weight: var(--fw-semi); box-shadow: var(--sh-raised);
}
:where(.x-cal-day[data-selected])::after { background: var(--fg-on-brand); }
:where(.x-cal-day:focus-visible) { outline: 2px solid var(--brand); outline-offset: -2px; }
:where(.x-cal-day:disabled) { color: var(--gray-300); cursor: not-allowed; background: none; }

:where(.x-cal-foot) {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2);
  margin-top: var(--sp-2); padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
}
:where(.x-cal-foot) button {
  height: 1.75rem; min-height: 0; padding-inline: var(--sp-3);
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  background: transparent; color: var(--fg-muted);
  border: 1px solid transparent; border-radius: var(--r-sm);
  box-shadow: none; cursor: pointer;
}
:where(.x-cal-foot) button:hover { background: var(--bg-muted); color: var(--gray-900); }
:where(.x-cal-foot) button[data-accent] { color: var(--brand-fg); font-weight: var(--fw-semi); }
:where(.x-cal-foot) button[data-accent]:hover { background: var(--red-50); }

/* ---- Time picker : scroll columns that never collapse ---- */
:where(.x-time) {
  display: flex;
  align-items: stretch;
  gap: 0;
  width: max-content;
  max-width: none;
  max-height: none;
  padding: 0;
  overflow: hidden;
  border-radius: var(--r-lg);
}
:where(.x-time-col) {
  flex: 0 0 auto;          /* must not shrink - this clipped the minutes */
  width: 3.5rem;
  min-width: 3.5rem;
  height: 100%;
  display: flex; flex-direction: column; gap: 1px;
  padding: var(--sp-1);
  overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain;
  scroll-snap-type: y proximity;
  scrollbar-width: none;            /* internal columns: no rails */
}
:where(.x-time-col) + :where(.x-time-col) { border-inline-start: 1px solid var(--border); }
/* Time columns are a centred grid of numbers. The generic .x-opt selected
   state appends a check icon with `margin-inline-start:auto`, which pushed
   the number off-centre to the left. In a time column the selected state is
   shown by the filled pill alone, so the check is removed and centring is
   restored. */
:where(.x-time-col) > .x-opt {
  justify-content: center;
  position: relative;
  padding: var(--sp-1) 0;
  font-variant-numeric: tabular-nums;
  scroll-snap-align: center;
  border-radius: var(--r-sm);
}
:where(.x-time-col) > .x-opt[data-selected]::after { content: none; display: none; }
:where(.x-time-col) > .x-opt[data-selected] {
  background: var(--brand); color: var(--fg-on-brand); font-weight: var(--fw-semi);
}
:where(.x-time-col) > .x-opt[data-selected]:hover { background: var(--red-700); color: var(--fg-on-brand); }

:where(.x-time-head) {
  display: flex;
  padding: var(--sp-2) 0;
  background: var(--bg-subtle);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-2xs); font-weight: var(--fw-semi);
  color: var(--fg-subtle); text-transform: uppercase; letter-spacing: .05em;
}
:where(.x-time-head) > span {
  flex: 0 0 auto; width: 3.5rem; text-align: center;
}
:where(.x-time-wrap) { display: flex; flex-direction: column; width: max-content; }
:where(.x-time-body) {
  display: flex;
  height: 11.5rem;        /* bounded height = columns actually scroll */
  min-height: 0;
  overflow: hidden;
}

/* ---- Scroll lock applied to <html> while a modal is open ---- */
:where(html[data-scroll-lock]) {
  overflow: hidden;
  /* padding compensates for the removed scrollbar so layout never jumps */
  padding-inline-end: var(--scrollbar-w, 0px);
}

/* ---- Dialog & popover motion ---- */
:where(dialog) {
  opacity: 0;}
:where(dialog[open]) { opacity: 1; transform: none; }
@starting-style { :where(dialog[open]) { opacity: 0;} }

/* Popover: anchored to its trigger by base.js, not centered in the viewport */
:where([popover]) {
  position: absolute;
  inset: auto;
  margin: 0;
  opacity: 0;
}
:where([popover]:popover-open) { opacity: 1; transform: none; }
@starting-style { :where([popover]:popover-open) { opacity: 0;} }
/* Arrow */
:where([popover][data-anchored])::before {
  content: "";
  position: absolute;
  width: 10px; height: 10px;
  background: var(--bg);
  border-inline-start: 1px solid var(--border-brand);
  border-block-start: 1px solid var(--border-brand);
  transform: rotate(45deg);
  top: -6px;
  inset-inline-start: var(--arrow-x, 1rem);
}
:where([popover][data-placement="top"])::before {
  top: auto; bottom: -6px; transform: rotate(225deg);
}

/* Native-anchor enhancement where supported */
@supports (anchor-name: --a) {
  :where([popover][data-anchored]) { position-try-fallbacks: flip-block; }
}
} /* end components */

/* ==========================================================================
   14. TYPOGRAPHIC CONSISTENCY
   Two rules, applied last, that make size and leading predictable.

   (1) Controls and the menus that belong to them share ONE size token.
       A <select> and its dropdown, an <input> and its datalist, a date
       field and the calendar are the same control in two states - if the
       popup renders at a different size than the field, the widget looks
       broken. This is why the audit found a dropdown at a different size
       than its own input.

   (2) Single-line UI text gets --lh-flat (1). Leading is vertical rhythm
       BETWEEN lines; on a one-line label there is no second line, so any
       value above 1 is just off-centre padding. Multi-line content keeps
       real leading.
   ========================================================================== */
@layer utilities {
  /* Accessibility skip link: invisible during normal pointer/touch use,
     revealed only when keyboard focus reaches it. */
  .skip-link {
    position: fixed;
    inset-block-start: 0;
    inset-inline-start: var(--sp-4);
    z-index: 1000;
    transform: translateY(calc(-100% - var(--sp-4)));
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--bg);
    color: var(--link);
    box-shadow: var(--sh-sm);
  }
  .skip-link:focus,
  .skip-link:focus-visible {
    transform: translateY(var(--sp-3));
  }

  /* (1) one size for every control surface */
  button, input, select, textarea, optgroup, option,
  .x-trigger, .x-opt, .x-pop, .x-cal, .x-time,
  .x-cal-day, .x-cal-nav, .x-cal-sel > select, .x-time-col > .x-opt {
    font-size: var(--fs-control);
    font-family: inherit;
  }
  /* textarea is multi-line: it keeps prose leading */
  textarea { line-height: var(--lh-base); }

  /* (2) flat leading for single-line UI */
  button, .x-trigger, .x-opt, .x-cal-day, .x-cal-nav, .x-num-btn,
  select, output, legend, .x-time-head > span {
    line-height: var(--lh-flat);
  }
  /* Text inputs centre their own inner editor against the CONTENT box, so a
     flat line-height collapses that box and the caret rides the top edge.
     They keep a line-height equal to the control's inner height instead. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]) {
    line-height: normal;
  }

  nav a { line-height: var(--lh-flat); }

  /* Dense UI text that can wrap keeps a snug, consistent leading */
  label, summary, caption, figcaption, th, td, small, .x-pop {
    line-height: var(--lh-snug);
  }

  /* Prose is the only place with generous leading */
  p, li, dd, dt, blockquote, address { line-height: var(--lh-base); }

  /* Inline elements inside prose must NOT invent their own leading - they
     sit on the parent's line and have to ride its rhythm, or a line
     containing <code> ends up taller than the lines around it. */
  code, samp, kbd, var, cite, abbr, mark, small, time, q, b, i, em, strong,
  a, span, sub, sup, del, ins, s, u, dfn, data, bdi, bdo, ruby {
    line-height: inherit;
  }
  sub, sup { line-height: 0; }

  /* Inline code-ish runs: one size, no em compounding */
  code, samp, kbd, var { font-size: var(--fs-sm); }
  pre code, pre samp { font-size: inherit; }
}

/* ==========================================================================
   15. ICONS
   Icons are ADDITIVE and AUTOMATIC. Everything here is a ::before/::after
   pseudo-element, so an element's real text is never replaced, never
   hidden from a screen reader, and still copies as plain text.

   The point of this layer is that icons appear WITHOUT touching markup:
   a submit button in a search form gets a magnifier, a [type=email] field
   gets an envelope, an external link gets an out-arrow. Meaning is read
   from the semantics already in the HTML.
   ========================================================================== */
@layer components {

  /* ---------- shared glyph recipe ---------- */
  :where([data-icon])::before,
  :where(a[target="_blank"], a[download])::after,
  :where(aside, blockquote)::before {
    content: "";
    display: inline-block;
    flex: none;
    inline-size: 1em;
    block-size: 1em;
    background: no-repeat center / contain;
    vertical-align: -0.125em;   /* baseline-correct; never `middle` */
  }

  /* ---------- automatic, semantic icons ---------- */
  /* search forms */
  :where(form[role="search"], search) button[type="submit"],
  :where(form[role="search"], search) input[type="submit"] {
    display: inline-flex; align-items: center; gap: .5em;
  }
  :where(form[role="search"], search) button[type="submit"]::before {
    content: ""; flex: none; inline-size: 1em; block-size: 1em;
    background: var(--i-search) no-repeat center / contain;
    vertical-align: -0.125em;
    filter: brightness(0) invert(1);      /* white on the solid button */
  }

  /* links that leave the page or pull a file */
  :where(a[target="_blank"])::after {
    background-image: var(--i-external);
    margin-inline-start: .35em;
    inline-size: .78em; block-size: .78em;
    opacity: .7;
}
    :where(a[download]):not([target="_blank"])::after {
    background-image: var(--i-download);
    margin-inline-start: .35em;
    inline-size: .82em; block-size: .82em;
    opacity: .75;
  }
  :where(a[target="_blank"]:hover)::after { opacity: 1; translate: 1px -1px; }
  :where(a[download]:hover)::after { opacity: 1; translate: 0 1px; }

  /* callouts carry a tone glyph.
     NOT flex. A callout is authored as `<strong>Title.</strong> detail text`:
     an element followed by a BARE TEXT NODE. `display:flex` turns those into
     two separate flex items, so the title got its own shrink-to-fit column
     and wrapped one word per line beside the detail — the single worst
     rendering bug on the auth pages.
     The glyph is therefore taken out of flow and the box reserves a gutter
     for it. The message then stays ONE continuous run of inline content, so
     any mix of elements and bare text wraps as the prose it is. */
  :where(aside) {
    display: block;
    position: relative;
    padding-inline-start: calc(var(--sp-3) + 1.15em + var(--sp-2));
  }
  /* Masked, not drawn: the glyph then inherits whatever colour the tone set
     on the callout, so a success callout cannot end up with a red tick in it. */
  :where(aside)::before {
    background: currentColor;
    -webkit-mask: var(--i-info) no-repeat center / contain;
    mask: var(--i-info) no-repeat center / contain;
    inline-size: 1.15em; block-size: 1.15em;
    position: absolute;
    inset-block-start: calc(var(--sp-3) + .1em);
    inset-inline-start: var(--sp-3);
  }
  :where(aside[data-tone="warn"])::before {
    -webkit-mask-image: var(--i-warn); mask-image: var(--i-warn);
  }
  :where(aside[data-tone="ok"])::before {
    -webkit-mask-image: var(--i-check-brand); mask-image: var(--i-check-brand);
  }

  /* pull-quotes get a quote mark instead of a bare indent */
  :where(blockquote) { position: relative; }
  :where(blockquote)::before {
    background-image: var(--i-quote);
    position: absolute;
    inset-block-start: var(--sp-3);
    inset-inline-start: var(--sp-3);
    inline-size: 1.5em; block-size: 1.5em;
    opacity: .5;
    pointer-events: none;
  }

  /* Required fields are marked, not relabelled.
     The second selector covers a WRAPPED control (any app that puts its
     input inside a field surface, which is a standard pattern): the
     label's next sibling is then the wrapper, not the input, so the original
     `+ input:required` stopped matching and required fields silently lost
     their mark — while an unwrapped one beside it kept its own, which is the
     worst version of the bug. */
  :where(label:has(+ input:required, + select:required, + textarea:required))::after,
  :where(label:has(+ * > input:required, + * > select:required, + * > textarea:required))::after,
  :where(label[data-required])::after {
    content: "*";
    margin-inline-start: .2em;
    color: var(--brand);
    font-weight: var(--fw-semi);
  }

  /* ---------- opt-in slot: data-icon="name" ---------- */
  :where([data-icon]) { display: inline-flex; align-items: center; gap: .5em; }
  :where([data-icon=""])::before, :where([data-icon]:not([data-icon=""]))::before { margin: 0; }
  :where([data-icon="search"])::before   { background-image: var(--i-search); }
  :where([data-icon="calendar"])::before { background-image: var(--i-calendar); }
  :where([data-icon="clock"])::before    { background-image: var(--i-clock); }
  :where([data-icon="check"])::before    { background-image: var(--i-check-brand); }
  :where([data-icon="info"])::before     { background-image: var(--i-info); }
  :where([data-icon="warn"])::before     { background-image: var(--i-warn); }
  :where([data-icon="link"])::before     { background-image: var(--i-link); }
  :where([data-icon="plus"])::before     { background-image: var(--i-plus); }
  :where([data-icon="trash"])::before    { background-image: var(--i-trash); }
  :where([data-icon="send"])::before     { background-image: var(--i-send); }
  :where([data-icon="refresh"])::before  { background-image: var(--i-refresh); }
  :where([data-icon="user"])::before     { background-image: var(--i-user); }
  :where([data-icon="download"])::before { background-image: var(--i-download); }
  :where([data-icon="external"])::before { background-image: var(--i-external); }
  :where([data-icon="next"])::before     { background-image: var(--i-arrow-right); }

  /* On a SOLID button the glyph must invert to stay visible. The variant
     exclusions are load-bearing: a ghost/link button is type="submit" too
     (the resend-code button is exactly that), and inverting its brand-red
     glyph painted white-on-white — a button that rendered with an invisible
     icon and a hole where the mark should be. Invert only where the
     background is actually solid. */
  :where(button[type="submit"], button[data-variant="primary"],
         button[data-variant="danger"])[data-icon]:not([data-variant="ghost"]):not([data-variant="link"])::before {
    filter: brightness(0) invert(1);
  }

  /* An icon-only button is square. It is identified by an EMPTY data-icon
     plus an aria-label - never by :has(), which cannot test for text nodes
     and so matched every labelled button and collapsed it to a square. */
  :where(button[data-icon=""][aria-label]),
  :where(button[data-icon-only]) {
    aspect-ratio: 1;
    padding-inline: 0;
    justify-content: center;
    min-inline-size: var(--control-h);
  }
  :where(button[data-icon=""][aria-label])::before {
    margin: 0;
    background-image: var(--i-plus);   /* empty slot defaults to "add" */
  }
  /* a square icon button can still name its glyph via data-icon-only */
  :where(button[data-icon-only="user"])::before     { background-image: var(--i-user); }
  :where(button[data-icon-only="trash"])::before    { background-image: var(--i-trash); }
  :where(button[data-icon-only="close"])::before    { background-image: var(--i-close); }
  :where(button[data-icon-only="refresh"])::before  { background-image: var(--i-refresh); }
  :where(button[data-icon-only])::before {
    content: ""; inline-size: 1em; block-size: 1em; margin: 0;
    background: no-repeat center / contain;
  }

  /* inline <svg> children inherit colour + optical size automatically */
  :where(button, a, .x-trigger, summary, label) > svg {
    inline-size: 1.15em; block-size: 1.15em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
    vertical-align: -0.125em;
  }
}

/* ==========================================================================
   16. WEIGHT DISCIPLINE
   The stack has exactly two faces, Regular and Bold, so weight is a BINARY
   and must be spent deliberately. The rule applied here:

     Regular  = every resting surface. Body copy, option rows, table cells,
                field values, closed control labels, placeholder chrome.
     Bold     = headings, and the single selected/active item in a group.

   Menus are the place this went wrong: a dropdown is a LIST OF PEERS, so
   every row must rest at the same weight and only the chosen row may go
   bold. Previously the calendar's month select rendered Bold while its own
   option rows rendered Regular, so the same control disagreed with itself.
   ========================================================================== */
@layer utilities {
  /* --- resting state: one weight across every menu and field surface --- */
  .x-pop, .x-opt, .x-cal, .x-cal-day, .x-cal-sel > select, .x-cal-sel > select > option,
  .x-time, .x-time-col > .x-opt, .x-trigger,
  select, option, optgroup, input, textarea, td, output, .x-num-btn {
    font-weight: var(--fw-normal);
  }

  /* --- chosen item in a list of peers: the one place bold is earned --- */
  .x-opt[data-selected],
  .x-opt[aria-selected="true"],
  .x-cal-day[data-selected],
  .x-time-col > .x-opt[data-selected],
  option:checked,
  .x-cal-sel > select > option:checked {
    font-weight: var(--fw-semi);
  }

  /* Today is a hint, not a selection: mark it with colour, not weight, so it
     cannot compete with the actual selected day. */
  .x-cal-day[data-today]:not([data-selected]) {
    font-weight: var(--fw-normal);
    color: var(--brand-fg);
  }

  /* --- structural labels stay bold: they are headings for their region --- */
  th, caption, legend, dt, summary, .x-time-head > span, .x-cal-dow {
    font-weight: var(--fw-semi);
  }

  /* --- buttons: actions are emphatic, but a ghost/secondary is not --- */
  button, input[type="submit"], input[type="reset"], input[type="button"] {
    font-weight: var(--fw-semi);
  }
  button[data-variant="ghost"], button[data-variant="link"],
  .x-cal-nav, .x-cal-foot button {
    font-weight: var(--fw-normal);
  }

  /* --- inline emphasis --- */
  strong, b { font-weight: var(--fw-semi); }
  /* A link takes the weight of whatever it sits in: bold inside a heading,
     regular inside prose. `inherit` is only correct when the parent is not
     itself bold for another reason, so prose links are pinned explicitly. */
  p a, li a, dd a, td a, blockquote a, address a, figcaption a, small a,
  label a, .x-pop a { font-weight: var(--fw-normal); }
  h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; }
  nav a { font-weight: var(--fw-normal); }
  nav a[aria-current] { font-weight: var(--fw-semi); }
}

/* ==========================================================================
   17. EMPTY STATES, STATUS & MICRO-INTERACTION
   Research-backed gaps this system was missing.

   An empty state is the most-designed surface in a modern product and the
   one most often left blank. NN/g's rule: say what belongs here, why it is
   empty, and give a starting VERB. So :where(.x-empty) ships a glyph, a
   title, a line of help and a slot for a CTA - never a bare "No data".

   Motion: current UIs confirm state with short, spring-eased movement.
   Everything here is <=320ms, transform/opacity only (compositor-friendly),
   and every single one is disabled under prefers-reduced-motion.
   ========================================================================== */
@layer components {

  /* ---------- empty state ---------- */
  :where(.x-empty) {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    padding: var(--sp-7) var(--sp-5);
    text-align: center;
    color: var(--fg-muted);
    background:
      radial-gradient(120% 80% at 50% 0%, var(--red-50), transparent 70%),
      var(--bg);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r-lg);
  }
  :where(.x-empty)::before {
    content: "";
    inline-size: 2.5rem; block-size: 2.5rem;
    margin-block-end: var(--sp-1);
    background: var(--i-search) no-repeat center / contain;
    opacity: .55;
  }
  :where(.x-empty[data-icon="calendar"])::before { background-image: var(--i-calendar); }
  :where(.x-empty[data-icon="user"])::before     { background-image: var(--i-user); }
  :where(.x-empty[data-icon="warn"])::before     { background-image: var(--i-warn); }
  :where(.x-empty) > :where(h1,h2,h3,h4,h5,h6) {
    margin: 0; font-size: var(--fs-md); color: var(--gray-900);
  }
  :where(.x-empty) > p { margin: 0; max-inline-size: 42ch; font-size: var(--fs-sm); }
  :where(.x-empty) > :where(button, a) { margin-block-start: var(--sp-2); }

  /* ---------- status pill ---------- */
  :where(.x-badge) {
    display: inline-flex; align-items: center; gap: .4em;
    padding: .2em .65em;
    border-radius: var(--r-full);
    background: var(--red-50);
    color: var(--brand-fg);
    border: 1px solid var(--red-100);
    font-size: var(--fs-xs);
    font-weight: var(--fw-semi);
    line-height: var(--lh-flat);
  }
  :where(.x-badge)::before {
    content: ""; inline-size: .45em; block-size: .45em;
    border-radius: var(--r-full); background: currentColor;
  }
  :where(.x-badge[data-tone="ok"]) { background: var(--success-bg); color: var(--success); border-color: var(--success-bd); }
  :where(.x-badge[data-tone="mute"]) { background: var(--bg-subtle); color: var(--fg-muted); border-color: var(--border); }

  /* ---------- skeleton loading ---------- */
  :where(.x-skeleton) {
    background: linear-gradient(90deg, var(--gray-100) 25%, var(--gray-50) 37%, var(--gray-100) 63%);
    background-size: 400% 100%;
    border-radius: var(--r-sm);
color: transparent !important;
    min-block-size: 1em;
  }
}

@layer utilities {
  /* ---------- micro-interaction ---------- */
  /* Buttons acknowledge a press rather than just recolouring. */

  /* Cards lift very slightly on hover - depth, not decoration. */
  :where(article, section):hover { box-shadow: var(--sh-md); }

  /* Menus and dialogs enter with a small spring. */
  /* Honour the OS setting: kill all of it. */
}

/* ==========================================================================
   18. NATIVE SELECTION COLOURS  +  PRESSED-STATE INTEGRITY
   ========================================================================== */
@layer utilities {

  /* ------------------------------------------------------------------
     The blue.
     JS only replaces single <select>s. A multiple/size>1 select stays a
     REAL list box, and a real list box paints its chosen rows with the
     OS accent - Chrome's rgb(25,103,210). It is not inherited from this
     stylesheet, so no amount of styling .x-opt could ever reach it.

     In-page list boxes (multiple / size>1) are ordinary DOM, so they CAN
     be restyled - unlike a dropdown POPUP, which is OS-drawn. The blue is
     killed three ways because engines disagree on which one they honour.
     ------------------------------------------------------------------ */
  /* NOTE: no `scrollbar-color` here. In Chromium any scrollbar-color/width
     on an element switches it to the built-in renderer and DISCARDS the
     ::-webkit-scrollbar pill design, so this box would get a different
     scrollbar from the rest of the app. The standard properties live in a
     single `@supports not selector(::-webkit-scrollbar)` guard near the top
     of the file; that is the ONLY place they may be declared. */
  select[multiple], select[size]:not([size="1"]) {
    accent-color: var(--brand);
    /* UA ships `overflow-y: scroll`, which reserves a permanent rail even when
       every row fits. `auto` shows one only when it is actually needed. */
    overflow-y: auto;
    /* A list box is a FIELD, so it needs the same inner gutter as every other
       field. Without it the first row sat hard against the border and its
       highlight bled edge-to-edge, which is why this control looked unlike
       the inputs above and below it. Block padding is halved because the row
       padding supplies the rest. */
    padding: var(--sp-1) calc(var(--field-pad-x) - 2px);
    block-size: auto;
  }
  /* `size` counts ROWS, and the engine sizes the box from the UA row height.
     Adding padding+margin made each row 32px inside a box reserved for ~23px,
     so 4 options overflowed a size=4 list and produced a scrollbar. Keep rows
     compact so the declared size still fits. */
  select[multiple] option, select[size]:not([size="1"]) option {
    /* 2px inline padding keeps the selected pill clear of the gutter edge
       while the wrapper padding above provides the real inset. */
    padding: 2px var(--sp-2);
    border-radius: var(--r-xs);
    margin-block: 0;
    color: var(--fg);
    background-color: var(--bg);
  }
  /* :checked is the reliable hook for a chosen row in a list box. */
  /* Chromium repaints a selected row's TEXT white to contrast the accent it
     intended to draw. Setting only the background leaves white-on-pink, so
     the text colour must be forced in the same rule. A mid-tone fill is used
     so the label stays legible whichever way the engine resolves it. */
  select[multiple] option:checked,
  select[size]:not([size="1"]) option:checked {
    background: var(--red-100) !important;
    background-image: linear-gradient(var(--red-100), var(--red-100)) !important;
    color: var(--red-900) !important;
    -webkit-text-fill-color: var(--red-900) !important;   /* beats forced paint */
    font-weight: var(--fw-semi);
  }
  select[multiple]:focus option:checked,
  select[size]:not([size="1"]):focus option:checked {
    background: var(--red-200) !important;
    background-image: linear-gradient(var(--red-200), var(--red-200)) !important;
    color: var(--red-950) !important;
    -webkit-text-fill-color: var(--red-950) !important;
  }
  select[multiple] option:hover, select[size]:not([size="1"]) option:hover {
    background-image: linear-gradient(var(--red-50), var(--red-50)) !important;
  }

  /* The calendar's month/year selects are also native and were unstyled. */
  .x-cal-sel > select option:checked {
    background-image: linear-gradient(var(--red-100), var(--red-100)) !important;
    color: var(--red-900) !important;
    -webkit-text-fill-color: var(--red-900) !important;
  }

  /* Text selection + tap highlight anywhere in the app stay on-brand. */
  ::selection { background: var(--red-100); color: var(--red-950); }
  ::target-text { background: var(--red-100); }

  /* ------------------------------------------------------------------
     Pressed state.
     A solid button paints its fill with a GRADIENT (background-image).
     The :active rule only set background-color, and a background-image
     always paints ON TOP of a background-color - so the dark press colour
     was hidden behind the resting gradient and the button looked light.
     Every state must therefore reset background-image too.
     ------------------------------------------------------------------ */
  :where(button, input[type="submit"], input[type="reset"], input[type="button"],
         [role="button"]):active:not(:disabled) {
    background-image: none;
  }
  button[type="submit"]:active:not(:disabled),
  button[data-variant="primary"]:active:not(:disabled),
  input[type="submit"]:active:not(:disabled),
  dialog form[method="dialog"] button[type="submit"]:active:not(:disabled) {
    background-image: none !important;
    background-color: var(--red-800) !important;
    color: var(--fg-on-brand) !important;
    box-shadow: inset 0 2px 4px rgba(56, 15, 11, .28);
  }
  button[data-variant="danger"]:active:not(:disabled) {
    background-image: none !important;
    background-color: var(--red-900) !important;
    color: var(--fg-on-brand) !important;
  }
  /* Keep the label and its icon white for the whole press. */
  button[type="submit"]:active:not(:disabled)::before,
  button[data-variant="primary"]:active:not(:disabled)::before,
  button[data-variant="danger"]:active:not(:disabled)::before {
    filter: brightness(0) invert(1);
  }
}

/* ==========================================================================
   19. NO MOTION
   Motion is switched off for the whole system, by request - not merely
   shortened. Every `transition`, `animation`, `@keyframes` and hover/active
   `transform` was deleted at its source above; this block is the backstop so
   nothing can reintroduce movement later, including author CSS loaded after
   this file and UA-driven smooth scrolling.

   State is still communicated - colour, border, shadow and weight all change
   instantly on hover/active/focus. Only the ANIMATION between states is gone.
   ========================================================================== */
*, *::before, *::after, :root {
  transition: none !important;
  transition-property: none !important;
  animation: none !important;
  scroll-behavior: auto !important;
  view-transition-name: none !important;
}
html:focus-within { scroll-behavior: auto !important; }
@media (prefers-reduced-motion: no-preference) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ==========================================================================
   20. FIELD SURFACE FIXES
   ========================================================================== */
@layer utilities {

  /* ---- SEARCH ------------------------------------------------------
     Full anatomy per the established pattern: landmark, label, leading
     magnifier, field, clear control, keyboard hint, submit.

     Decisions that matter:
     - The WRAPPER is the control surface; the input inside is naked. One
       border, one focus ring - not a box beside a box.
     - The leading magnifier is decorative and pointer-transparent so it can
       never block a click or collide with the placeholder.
     - Chromium's ::-webkit-search-cancel-button is unstyleable beyond
       hiding, missing in Firefox and has NO accessible name, so it is
       suppressed and a real <button> is used instead.
     - The clear button appears only once text exists, via
       :not(:placeholder-shown) - pure CSS, no input listener.
     - A "/" hint is shown only while the field is empty and unfocused.
     -------------------------------------------------------------------- */
  search, form[role="search"] {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    inline-size: 100%;
    max-inline-size: 34rem;
    background: var(--bg);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-md);
    box-shadow: var(--sh-xs);
    padding: 4px 4px 4px var(--sp-3);
  }
  search:hover, form[role="search"]:hover { border-color: var(--red-200); }
  search:focus-within, form[role="search"]:focus-within {
    border-color: var(--brand);
    box-shadow: var(--sh-inset);
  }

  /* leading magnifier - decorative, never intercepts the pointer */
  search::before, form[role="search"]::before {
    content: "";
    flex: none;
    inline-size: 1.05em;
    block-size: 1.05em;
    background: var(--i-search) no-repeat center / contain;
    opacity: .5;
    pointer-events: none;
  }
  search:focus-within::before, form[role="search"]:focus-within::before { opacity: 1; }

  /* the field is naked: the wrapper is the visible control */
  search > input[type="search"], form[role="search"] > input[type="search"],
  search > input[type="text"],   form[role="search"] > input[type="text"] {
    flex: 1 1 auto;
    min-inline-size: 0;
    border: 0 !important;
    background: none !important;
    background-image: none !important;   /* no second magnifier */
    box-shadow: none !important;
    outline: none !important;
    padding-inline: 0 !important;
    block-size: auto;
  }
  /* suppress the UA cancel widget in favour of a real, labelled button */
  search input[type="search"]::-webkit-search-cancel-button,
  search input[type="search"]::-webkit-search-decoration,
  form[role="search"] input[type="search"]::-webkit-search-cancel-button,
  form[role="search"] input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none; appearance: none; display: none;
  }

  /* clear (×) - only once the user has typed */
  search button[data-clear], form[role="search"] button[data-clear] {
    flex: none;
    display: none;
    place-items: center;
    inline-size: 1.5rem; block-size: 1.5rem;
    min-inline-size: 0; min-block-size: 0;
    padding: 0; margin: 0;
    border: 0;
    border-radius: var(--r-full);
    background: var(--gray-100);
    box-shadow: none;
    cursor: pointer;
  }
  search button[data-clear]::before, form[role="search"] button[data-clear]::before {
    content: "";
    inline-size: .7em; block-size: .7em;
    background: var(--fg-muted);
    -webkit-mask: var(--i-close) no-repeat center / contain;
    mask: var(--i-close) no-repeat center / contain;
  }
  search button[data-clear]:hover, form[role="search"] button[data-clear]:hover {
    background: var(--red-100);
  }
  search button[data-clear]:hover::before { background: var(--brand); }
  /* the sibling combinator is why the clear button must FOLLOW the input */
  search input:not(:placeholder-shown) ~ button[data-clear],
  form[role="search"] input:not(:placeholder-shown) ~ button[data-clear] { display: grid; }

  /* keyboard hint - hidden as soon as the field is used */
  search kbd[data-hint], form[role="search"] kbd[data-hint] {
    flex: none;
    padding: .15em .45em;
    font-size: var(--fs-2xs);
    line-height: 1.5;
    color: var(--fg-subtle);
    background: var(--bg-subtle);
    border: 1px solid var(--border);
    border-radius: var(--r-xs);
    box-shadow: none;
    pointer-events: none;
  }
  search:focus-within kbd[data-hint],
  form[role="search"]:focus-within kbd[data-hint],
  search input:not(:placeholder-shown) ~ kbd[data-hint],
  form[role="search"] input:not(:placeholder-shown) ~ kbd[data-hint] { display: none; }

  /* The bar already has a leading magnifier, so the submit must not carry a
     second one - two magnifiers on one bar is the dated look being fixed. */
  search > button[type="submit"]::before,
  form[role="search"] > button[type="submit"]::before { content: none; }

  /* submit sits inside the bar, concentric with it */
  search > button[type="submit"], form[role="search"] > button[type="submit"] {
    flex: none;
    align-self: stretch;
    /* inner = outer - (border + padding) = 10 - (1 + 4) = 5px = --r-xs */
    border-radius: var(--r-xs);
    padding-inline: var(--sp-4);
    margin: 0;
  }

  /* ---- a button must never show two glyphs ----
     data-icon draws a ::before AND the author may pass an inline <svg>.
     If a real <svg> is present, the pseudo glyph is suppressed. */
  button:has(> svg)::before,
  a:has(> svg)::before,
  .x-trigger:has(> svg)::before { content: none !important; }

  /* ---- focus must not stick ----
     :focus stays on a control after the pointer leaves if the element keeps
     DOM focus, which made borders look stuck. Resting/hover colour is stated
     explicitly so the field always returns to it. */
  :where(input, textarea, select):not(:focus):not(:focus-visible) {
    border-color: var(--border-strong);
  }
  :where(input, textarea, select):not(:focus):hover { border-color: var(--red-200); }
}

/* ==========================================================================
   21. CHOICE CONTROLS - layout
   The controls themselves were fine; their ARRANGEMENT was the problem.
   Checkboxes and radios were inline in a <p>, so they wrapped mid-group,
   the label text sat unevenly against the box, and hit targets were only as
   tall as the glyph. Fixes:
     - each option is a flex row with a fixed gap and a real hit target
     - groups stack in a column (or wrap as a row) instead of running on
     - the label is clickable across its whole width, not just the glyph
     - <input type=color> is a swatch, not a full-width field
   ========================================================================== */
@layer components {

  /* one option = glyph + text on a shared baseline, whole row clickable */
  label:has(> input[type="checkbox"]),
  label:has(> input[type="radio"]) {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    padding-block: var(--sp-1);
    padding-inline: 0;
    cursor: pointer;
    line-height: var(--lh-snug);
    -webkit-user-select: none; user-select: none;
  }
  label:has(> input[type="checkbox"]:disabled),
  label:has(> input[type="radio"]:disabled) { cursor: not-allowed; color: var(--fg-subtle); }

  /* a run of options becomes a real group with consistent rhythm */
  p:has(> label > input[type="checkbox"]),
  p:has(> label > input[type="radio"]) {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-5);
    margin-block: var(--sp-3);
  }
  /* stacked variant for long option text */
  [data-options="stack"] { flex-direction: column; align-items: flex-start; gap: var(--sp-1); }

  /* the switch reads as a control, so it gets a little more room */
  label:has(> input[role="switch"]) { gap: var(--sp-3); }

  /* colour is a swatch, not a field: size it to the glyph */
  :where(input[type="color"]) {
    inline-size: 3rem;
    block-size: 2.25rem;
    padding: 3px;
    border-radius: var(--r-sm);
    cursor: pointer;
  }
  :where(input[type="color"])::-webkit-color-swatch { border: 0; border-radius: 3px; }
  :where(input[type="color"])::-webkit-color-swatch-wrapper { padding: 0; }
  :where(input[type="color"])::-moz-color-swatch { border: 0; border-radius: 3px; }

  /* range needs breathing room from its label, not a full-bleed bar */
  :where(input[type="range"]) { max-inline-size: 22rem; }
}

/* ==========================================================================
   22. TOOLTIPS
   A short word on a control that has no room for one: a glyph in a toolbar, a
   mark in a bar. The words come from the control's own `data-tip`, so there is
   one copy of what it means — the one the accessible name is read from — and
   this draws a copy of it rather than asking for a second element and a script
   to position it.

   CSS-ONLY, ON PURPOSE. No JS, no wrapper, no focus trap: the bubble is an
   `::after`, so it appears on hover and on keyboard focus by itself and a page
   with no script still has every tooltip it was given. Generated content is not
   in the accessibility tree, so a reader who cannot see it loses nothing — the
   control's name says the same thing.

   `data-tip` puts the bubble under the control, centred on it. Add
   `data-tip-align="end"` for a control against the right edge of the window,
   where a centred bubble would hang off the screen — one in a top bar, say.

   HOW IT IS DRAWN, and where to change it: every value the bubble uses is a
   `--tip-*` token declared with the rest of them at the top of this file, so
   a page re-skins the bubble by overriding a token — never by copying these
   rules. The rules below decide only the SHAPE of the thing: where it sits,
   when it appears, and how it arrives.
   ========================================================================== */
@layer components {

  :where([data-tip]) { position: relative; }

  :where([data-tip])::after {
    content: attr(data-tip);
    position: absolute;
    z-index: 1000;
    inset-block-start: calc(100% + var(--tip-gap));
    inset-inline-start: 50%;
    /* Rests a few pixels low and rises into place when it is asked for, rather
       than fading in where it lands (see the motion block at the end). */
    translate: -50% 4px;
    max-inline-size: min(16rem, 80vw);
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--tip-border);
    /* The brand's bar down the leading edge — the same bar the app's marks
       wear — which is what makes a floating chip read as one of these pages
       rather than as any overlay. */
    border-inline-start: 3px solid var(--tip-accent);
    border-radius: var(--tip-radius);
    background: var(--tip-bg);
    color: var(--tip-fg);
    box-shadow: var(--tip-shadow);
    font-size: var(--tip-size);
    font-weight: var(--fw-medium);
    /* Snug, not flat: a bubble whose words wrap onto a second line needs air
       between them, and `flat` (1) made a two-line tip read as one smudge. */
    line-height: var(--lh-snug);
    letter-spacing: var(--tracking-wide);
    text-align: start;
    /* An absolutely-positioned box shrinks to its text, so a short word is one
       line without saying `nowrap`; a longer one wraps at the cap above instead
       of running off the screen. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
  }

  :where([data-tip-align="end"])::after {
    inset-inline-start: auto;
    inset-inline-end: 0;
    translate: 0 4px;
  }

  /* Reached for, not sat there: the bubble is worth nothing until somebody is
     wondering what the control does. Both of the ways somebody asks — a pointer
     and a keyboard — are the same rule, and both rise the same way. */
  :where([data-tip]:hover)::after,
  :where([data-tip]:focus-visible)::after {
    opacity: 1;
    visibility: visible;
    translate: -50% 0;
  }

  /* Written AFTER the centred rule on purpose: every rule here has zero
     specificity (`:where`), so the order they appear in is the whole answer
     when two of them match — and an end-aligned bubble must rise straight up
     rather than slide sideways into place. */
  :where([data-tip-align="end"]:hover)::after,
  :where([data-tip-align="end"]:focus-visible)::after { translate: 0 0; }

  @media (prefers-reduced-motion: no-preference) {
    :where([data-tip])::after {
      transition: opacity .15s ease, translate .15s ease, visibility .15s;
    }
  }
}

/* Shared, CSP-safe navigation progress for browser links and SPA routes.
   This is intentionally navigation-only, never a background API spinner. */
#racopaes-navigation-feedback {
  position: fixed;
  z-index: 2147483000;
  inset: 0 0 auto;
  pointer-events: none;
  color: var(--workspace-text, var(--ds-text, #252525));
  font: 600 12px/1.4 system-ui, sans-serif;
}
#racopaes-navigation-feedback::before {
  content: "";
  display: block;
  width: 100%;
  height: 3px;
  background: var(--workspace-accent, var(--ds-accent, #2766a4));
  transform-origin: left;
  animation: racopaes-nav-progress 1.1s ease-in-out infinite;
}
/* The page-opening caption is suspended directly beneath the progress
   line. Its own text, not only the capsule, is centered in the viewport. */
#racopaes-navigation-feedback > span {
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: min(220px, calc(100vw - 20px));
  min-height: 52px;
  max-width: calc(100vw - 20px);
  margin: 0 auto;
  padding: 10px 20px 18px;
  text-align: center;
  background: var(--workspace-surface, var(--ds-surface, #fff));
  border: 1px solid var(--workspace-border, var(--ds-border, #ddd));
  border-top: 0;
  border-radius: 0 0 50% 50% / 0 0 85% 85%;
  box-shadow: 0 9px 24px #00000012;
}
@keyframes racopaes-nav-progress {
  0% { transform: scaleX(.12); opacity: .65; }
  60% { transform: scaleX(.78); opacity: 1; }
  100% { transform: scaleX(1); opacity: .55; }
}
@media (prefers-reduced-motion: reduce) {
  #racopaes-navigation-feedback::before { animation: none; }
}

/* The ordinary portal and operator action buttons provide immediate feedback
   during real async work, without showing a global spinner for background reads. */
:where(button.button)[aria-busy="true"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  cursor: progress;
}
:where(button.button)[aria-busy="true"]::after {
  content: "";
  display: inline-block;
  flex: none;
  inline-size: .78rem;
  block-size: .78rem;
  border: 1.5px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: racopaes-action-spinner 650ms linear infinite;
}
@keyframes racopaes-action-spinner { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  :where(button.button)[aria-busy="true"]::after { animation-duration: 1400ms; }
}
