/* ==========================================================================
 * graffiti.css — the Graffiti design system. Single source of truth for
 * colour, type, spacing and every component on the site.
 * --------------------------------------------------------------------------
 * Hand-authored on purpose. There is no Node toolchain in this project, so a
 * compiled Tailwind bundle could never be rebuilt and could never grow a
 * light theme (no `dark:` variants were ever compiled into it). One plain
 * stylesheet is smaller, has no build step, and makes light/dark a token swap.
 *
 * HOW TO CHANGE THE BRAND
 * Edit §1 (raw ramps) or §2 (semantic tokens). Nothing below §3 hardcodes a
 * colour, so a rebrand is a handful of lines here and no template edits.
 *
 * THE FOUR RULES (see CLAUDE.md > Branding — these are not negotiable):
 *   1. Dark text on brand, never white. Brand fills carry --brand-ink.
 *   2. Pink never carries state alone. It is decoration and emphasis only;
 *      under deuteranopia it collapses toward the orange.
 *   3. Severity separates by treatment, not hue. Destructive is
 *      white-on-solid-red; brand is always dark-on-bright.
 *   4. Brand colour is not status colour. "Healthy" is --live, always.
 *
 * LIGHT MODE ADDS A FIFTH:
 *   5. A brand FILL and brand TEXT are different tokens. #FF5A1F on white is
 *      ~3:1 — fine behind dark ink, unusable as type. --brand is the fill,
 *      --brand-text is the readable one, and it darkens in light mode.
 * ========================================================================== */

/* ==========================================================================
 * §1  RAW PALETTE — the physical cans. Referenced only by §2.
 * ========================================================================== */

:root {
  /* Safety Orange — the brand */
  --o-300: #FFA37D;
  --o-400: #FF7A47;
  --o-500: #FF5A1F;
  --o-600: #E84711;
  --o-700: #AE3208;   /* light-mode brand TEXT: clears 4.5:1 even on a washed surface */

  /* Fluoro Pink — the second can */
  --p-300: #FF8FC4;
  --p-400: #FF5FAD;
  --p-500: #FF2D95;
  --p-600: #E5117C;
  --p-700: #A80B59;

  /* Ink that sits ON a bright fill */
  --ink-on-brand: #1A0600;
  --ink-on-pink:  #2B0014;

  /* Neutral ground. Deliberately hue-neutral: two warm brights need a ground
     with no cast of its own, or both look muddy. */
  --n-0:   #FFFFFF;
  --n-50:  #F4F4F4;
  --n-100: #E8E8E8;
  --n-200: #DCDCDC;
  --n-300: #C4C4C4;
  --n-400: #A8A8A8;
  --n-500: #888888;
  --n-600: #656565;
  --n-700: #525252;
  --n-750: #313131;
  --n-800: #1F1F1F;
  --n-850: #161616;
  --n-900: #131313;
  --n-950: #0A0A0A;
  --n-1000: #050505;

  /* Status. Emerald survives with exactly one job. */
  --status-live:      #10B981;
  --status-live-soft: #34D399;
  --status-live-dark: #047354;

  /* Warning — pure yellow, remapped off amber. An orange brand beside an
     amber warning is not a distinction. */
  --y-400: #FACC15;
  --y-500: #EAB308;
  --y-600: #CA8A04;
  --y-700: #915806;

  /* Danger */
  --r-400: #F87171;
  --r-500: #EF4444;
  --r-600: #DC2626;
  --r-700: #B91C1C;

  /* Discord's own blurple. Exempt from the palette — it is their identity,
     not ours, and is kept exact so the button reads as authentic. */
  --discord:       #5865F2;
  --discord-hover: #4752C4;
}

/* ==========================================================================
 * §2  SEMANTIC TOKENS + THEMES
 * --------------------------------------------------------------------------
 * Three states, and the order below is load-bearing:
 *   bare :root          -> DARK. Graffiti's primary experience, and what a
 *                          visitor with no JS and no stated preference gets.
 *   prefers-color-scheme -> light, but only when no explicit choice is stored.
 *   [data-theme=...]     -> an explicit choice, and it wins in both directions.
 * ========================================================================== */

:root {
  color-scheme: dark;

  --bg:          var(--n-950);
  --bg-raised:   var(--n-900);
  --bg-sunken:   var(--n-1000);
  --bg-inset:    var(--n-850);
  --bg-hover:    var(--n-800);

  --ink:         #EDEDED;
  --ink-muted:   var(--n-400);
  --ink-faint:   var(--n-500);
  --ink-invert:  var(--n-950);

  --line:        var(--n-800);
  --line-strong: var(--n-750);

  --brand:       var(--o-500);
  --brand-hover: var(--o-400);
  --brand-ink:   var(--ink-on-brand);
  --brand-text:  var(--o-400);
  --brand-wash:  rgba(255, 90, 31, 0.12);
  --brand-edge:  rgba(255, 90, 31, 0.32);

  --pink:        var(--p-500);
  --pink-ink:    var(--ink-on-pink);
  --pink-text:   var(--p-400);
  --pink-wash:   rgba(255, 45, 149, 0.12);

  --live:        var(--status-live-soft);
  --live-wash:   rgba(16, 185, 129, 0.14);
  --live-edge:   rgba(16, 185, 129, 0.30);

  --warn:        var(--y-400);
  --warn-wash:   rgba(250, 204, 21, 0.12);

  --danger:      var(--r-600);
  --danger-text: var(--r-400);
  --danger-ink:  #FFFFFF;
  --danger-wash: rgba(239, 68, 68, 0.12);

  --focus:       var(--o-400);
  --selection:   rgba(255, 90, 31, 0.28);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.55);
  --shadow-2: 0 10px 30px -12px rgba(0, 0, 0, 0.80);
  --shadow-3: 0 24px 60px -20px rgba(0, 0, 0, 0.90);

  --grain-opacity: 0.018;
  --grain-blend: overlay;
}

/* Light theme, factored out so it is defined once and applied twice. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;

    --bg:          var(--n-50);
    --bg-raised:   var(--n-0);
    --bg-sunken:   var(--n-100);
    --bg-inset:    #EFEFEF;
    --bg-hover:    #E4E4E4;

    --ink:         #111111;
    --ink-muted:   var(--n-700);
    --ink-faint:   var(--n-600);
    --ink-invert:  var(--n-0);

    --line:        var(--n-200);
    --line-strong: var(--n-300);

    --brand-hover: var(--o-600);
    --brand-text:  var(--o-700);
    --brand-wash:  rgba(255, 90, 31, 0.06);
    --brand-edge:  rgba(194, 56, 11, 0.30);

    --pink-text:   var(--p-700);
    --pink-wash:   rgba(255, 45, 149, 0.09);

    --live:        var(--status-live-dark);
    --live-wash:   rgba(4, 120, 87, 0.10);
    --live-edge:   rgba(4, 120, 87, 0.26);

    --warn:        var(--y-700);
    --warn-wash:   rgba(161, 98, 7, 0.10);

    --danger:      var(--r-600);
    --danger-text: var(--r-700);
    --danger-wash: rgba(220, 38, 38, 0.09);

    --focus:       var(--o-600);
    --selection:   rgba(255, 90, 31, 0.24);

    --shadow-1: 0 1px 2px rgba(16, 16, 16, 0.08);
    --shadow-2: 0 10px 30px -14px rgba(16, 16, 16, 0.22);
    --shadow-3: 0 24px 60px -22px rgba(16, 16, 16, 0.28);

    --grain-opacity: 0.024;
    --grain-blend: multiply;
  }
}

:root[data-theme="light"] {
  color-scheme: light;

  --bg:          var(--n-50);
  --bg-raised:   var(--n-0);
  --bg-sunken:   var(--n-100);
  --bg-inset:    #EFEFEF;
  --bg-hover:    #E4E4E4;

  --ink:         #111111;
  --ink-muted:   var(--n-700);
  --ink-faint:   var(--n-600);
  --ink-invert:  var(--n-0);

  --line:        var(--n-200);
  --line-strong: var(--n-300);

  --brand-hover: var(--o-600);
  --brand-text:  var(--o-700);
  --brand-wash:  rgba(255, 90, 31, 0.06);
  --brand-edge:  rgba(194, 56, 11, 0.30);

  --pink-text:   var(--p-700);
  --pink-wash:   rgba(255, 45, 149, 0.09);

  --live:        var(--status-live-dark);
  --live-wash:   rgba(4, 120, 87, 0.10);
  --live-edge:   rgba(4, 120, 87, 0.26);

  --warn:        var(--y-700);
  --warn-wash:   rgba(161, 98, 7, 0.10);

  --danger:      var(--r-600);
  --danger-text: var(--r-700);
  --danger-wash: rgba(220, 38, 38, 0.09);

  --focus:       var(--o-600);
  --selection:   rgba(255, 90, 31, 0.24);

  --shadow-1: 0 1px 2px rgba(16, 16, 16, 0.08);
  --shadow-2: 0 10px 30px -14px rgba(16, 16, 16, 0.22);
  --shadow-3: 0 24px 60px -22px rgba(16, 16, 16, 0.28);

  --grain-opacity: 0.024;
  --grain-blend: multiply;
}

/* ==========================================================================
 * §3  TYPE, SPACE, MOTION
 * ========================================================================== */

:root {
  --font-display: 'Archivo', 'Inter', ui-sans-serif, system-ui, sans-serif;
  --font-body: 'Inter', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: ui-monospace, 'SFMono-Regular', 'JetBrains Mono', Menlo, monospace;

  /* Fluid scale. Every size is viewport-aware, so nothing is a shrunk desktop. */
  --text-xs:  clamp(0.75rem,  0.735rem + 0.07vw, 0.8125rem);
  --text-sm:  clamp(0.8125rem, 0.79rem + 0.11vw, 0.875rem);
  --text-base: clamp(0.9375rem, 0.91rem + 0.14vw, 1rem);
  --text-md:  clamp(1.0625rem, 1.01rem + 0.27vw, 1.1875rem);
  --text-lg:  clamp(1.1875rem, 1.10rem + 0.42vw, 1.4375rem);
  --text-xl:  clamp(1.4375rem, 1.28rem + 0.78vw, 1.9375rem);
  --text-2xl: clamp(1.75rem,  1.47rem + 1.40vw, 2.75rem);
  --text-3xl: clamp(2.25rem,  1.70rem + 2.75vw, 4rem);
  --text-4xl: clamp(2.75rem,  1.80rem + 4.75vw, 5.75rem);

  --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
  --sp-5: 1.5rem;   --sp-6: 2rem;     --sp-7: 2.5rem;   --sp-8: 3rem;
  --sp-9: 4rem;     --sp-10: 5rem;    --sp-11: 6.5rem;  --sp-12: 8rem;

  /* Restrained radii. Street signage and stickers, not pill-shaped SaaS. */
  --r-xs: 3px;  --r-sm: 5px;  --r-md: 8px;  --r-lg: 14px;  --r-pill: 999px;

  --wrap: 74rem;
  --wrap-narrow: 44rem;
  --wrap-wide: 88rem;
  --measure: 68ch;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast: 140ms;
  --dur: 260ms;
  --dur-slow: 560ms;

  --nav-h: 3.75rem;
}

/* ==========================================================================
 * §4  RESET + BASE
 * ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + var(--sp-5));
  /* The canvas colour is taken from the root element. Leaving <html>
     transparent and colouring only <body> means the browser falls back to its
     own white canvas for any moment the page is not fully painted -- which is
     what produced the white flash between navigations. */
  background-color: var(--bg);
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

::selection { background: var(--selection); color: var(--ink); }

img, svg, video, canvas { display: block; max-width: 100%; height: auto; }

input, button, textarea, select { font: inherit; color: inherit; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); }

p { text-wrap: pretty; }

a { color: var(--brand-text); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--brand); }

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

hr { border: 0; border-top: 1px solid var(--line); }

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

/* Scrollbars */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--r-pill); }
*::-webkit-scrollbar-thumb:hover { background: var(--ink-faint); }

/* `hidden` means the element is not there. Any component rule that sets
   `display` outclasses the UA sheet's `[hidden] { display: none }` by source
   order alone -- .field__hint's `display: block` was un-hiding a "Saved"
   message permanently -- so this is one of the few places !important is the
   correct tool rather than a shortcut. Two bespoke `.x[hidden]` rules elsewhere
   in this file exist because of exactly that, and are now redundant. */
[hidden] { display: none !important; }


/* ==========================================================================
 * §5  UTILITIES — a deliberately tiny set. Not a utility framework.
 * ========================================================================== */

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: absolute; top: 0; left: 0; z-index: 100;
  transform: translateY(-120%);
  background: var(--brand); color: var(--brand-ink);
  font-weight: 700; padding: var(--sp-3) var(--sp-5);
  border-radius: 0 0 var(--r-md) 0;
  transition: transform var(--dur-fast) var(--ease);
}
.skip-link:focus { transform: translateY(0); color: var(--brand-ink); }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--sp-5); }
.wrap-narrow { max-width: var(--wrap-narrow); }
.wrap-wide { max-width: var(--wrap-wide); }

@media (min-width: 48rem) { .wrap { padding-inline: var(--sp-6); } }

.measure { max-width: var(--measure); }
.tabular { font-variant-numeric: tabular-nums; }
.no-wrap { white-space: nowrap; }

.section { padding-block: var(--sp-9); }
@media (min-width: 48rem) { .section { padding-block: var(--sp-11); } }
.section--tight { padding-block: var(--sp-8); }
.section--sunken { background: var(--bg-sunken); }
.section--raised { background: var(--bg-raised); }
.section--edged { border-block: 1px solid var(--line); }

.stack > * + * { margin-top: var(--sp-4); }
.stack-sm > * + * { margin-top: var(--sp-2); }
.stack-lg > * + * { margin-top: var(--sp-6); }

.cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }
.cluster--center { justify-content: center; }
.cluster--between { justify-content: space-between; }

.text-muted { color: var(--ink-muted); }
.text-faint { color: var(--ink-faint); }
.text-brand { color: var(--brand-text); }
.text-live { color: var(--live); }
.text-danger { color: var(--danger-text); }

/* ==========================================================================
 * §6  BRAND TREATMENTS
 * --------------------------------------------------------------------------
 * All hue- and shape-independent, so they survive a palette or icon change.
 * Grain and marks are preferred over glow — the soft blurred blob look is the
 * most generic thing a dark UI can do.
 * ========================================================================== */

/* The fade — a blend between two adjacent cans. This is the one place a
   gradient is earned: it is the subject's own technique. */
.mark-fill {
  background: linear-gradient(135deg, var(--o-400) 0%, var(--o-500) 38%, var(--p-500) 100%);
  color: var(--ink-on-brand);
}

.mark-text {
  background: linear-gradient(115deg, var(--o-400) 0%, var(--o-500) 40%, var(--p-500) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* Sticker slap — a mark applied by hand, not a centred favicon. */
.slap { transform: rotate(-4deg); }
.slap-hover { transition: transform var(--dur) var(--ease); }
.group:hover .slap-hover,
a:hover > .slap-hover { transform: rotate(-4deg) scale(1.06); }

/* Marker swipe behind a headline word. Replaces gradient text. */
.swipe {
  display: inline-block;
  background: linear-gradient(100deg, var(--o-500) 0%, var(--p-500) 100%);
  color: var(--ink-on-brand);
  padding: 0 0.12em;
  transform: rotate(-1.4deg) skewX(-5deg);
}
.swipe > * { display: inline-block; transform: skewX(5deg); }

/* Sticker / tape label — a physical mark, used for eyebrows and badges. */
.sticker {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.4em 0.8em;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xs);
  background: var(--bg-raised);
  color: var(--ink-muted);
}
.sticker--brand { background: var(--brand); color: var(--brand-ink); border-color: transparent; }
.sticker--wash { background: var(--brand-wash); color: var(--brand-text); border-color: var(--brand-edge); }
.sticker--pink { background: var(--pink); color: var(--pink-ink); border-color: transparent; }
.sticker--live { background: var(--live-wash); color: var(--live); border-color: var(--live-edge); }
.sticker--warn { background: var(--warn-wash); color: var(--warn); border-color: transparent; }
.sticker--danger { background: var(--danger-wash); color: var(--danger-text); border-color: transparent; }
.sticker--tilt { transform: rotate(-2deg); }

/* Grain — a fine paper tooth over a section. ~400 bytes, no image request. */
.grain { position: relative; isolation: isolate; }
.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--grain-opacity);
  mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='96' height='96'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.9' numOctaves='1' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}

/* Hand-drawn rule — a marker stroke used to divide editorial sections. */
.rule-mark {
  height: 3px;
  width: 3.5rem;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--o-500), var(--p-500));
}

/* A single accent word, underlined the way you'd underline it on paper. */
.underline-mark {
  background-image: linear-gradient(90deg, var(--o-500), var(--p-500));
  background-repeat: no-repeat;
  background-size: 100% 0.18em;
  background-position: 0 88%;
  padding-inline: 0.04em;
}

/* ==========================================================================
 * §7  BUTTONS
 * ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 650;
  line-height: 1.2;
  padding: 0.72rem 1.15rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: none;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.btn:disabled:active, .btn[aria-disabled="true"]:active { transform: none; }
.btn svg { width: 1.05em; height: 1.05em; flex: none; }

/* Rule 1: dark ink on brand, never white. */
.btn--brand { background: var(--brand); color: var(--brand-ink); }
.btn--brand:hover { background: var(--brand-hover); color: var(--brand-ink); }

.btn--ink { background: var(--ink); color: var(--bg); }
.btn--ink:hover { background: var(--ink-muted); color: var(--bg); }

.btn--ghost { border-color: var(--line-strong); color: var(--ink); }
.btn--ghost:hover { background: var(--bg-inset); border-color: var(--ink-faint); color: var(--ink); }

.btn--quiet { color: var(--ink-muted); }
.btn--quiet:hover { background: var(--bg-inset); color: var(--ink); }

/* Rule 3: destructive is white-on-solid-red. That treatment, not the hue, is
   what separates it from the brand. */
.btn--danger { background: var(--danger); color: var(--danger-ink); }
.btn--danger:hover { background: var(--r-700); color: var(--danger-ink); }

.btn--lg { font-size: var(--text-md); padding: 0.95rem 1.6rem; border-radius: var(--r-lg); }
.btn--sm { font-size: var(--text-xs); padding: 0.45rem 0.75rem; }
.btn--icon { padding: 0.55rem; border-radius: var(--r-md); }
.btn--block { display: flex; width: 100%; }

/* ==========================================================================
 * §8  SURFACES
 * ========================================================================== */

.card {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
}
.card--flat { background: none; }
.card--inset { background: var(--bg-inset); }
.card--pad-lg { padding: var(--sp-6); }
.card--pad-sm { padding: var(--sp-4); }

.card-link {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.card-link:hover {
  border-color: var(--brand-edge);
  transform: translateY(-2px);
  color: inherit;
}

.panel {
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
  background: var(--bg-inset);
}
.panel__body { padding: var(--sp-5); }

.status-dot {
  /* inline-block, not inline: this is a <span>, and an inline box ignores
     width/height -- it painted as a thin coloured rectangle anywhere it was not
     inside a flex container, which is every use outside a .identity row. */
  display: inline-block;
  vertical-align: middle;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--r-pill);
  background: var(--ink-faint);
  flex: none;
}
.status-dot--live { background: var(--live); box-shadow: 0 0 0 3px var(--live-wash); }
.status-dot--warn { background: var(--warn); box-shadow: 0 0 0 3px var(--warn-wash); }
.status-dot--danger { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-wash); }

/* ==========================================================================
 * §9  SITE CHROME — nav + footer
 * ========================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
@supports not (backdrop-filter: blur(1px)) { .nav { background: var(--bg); } }

.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-height: var(--nav-h);
}

.nav__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-right: auto;
}
.nav__glyph {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-sm);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.05rem;
  box-shadow: var(--shadow-1);
}

.nav__links { display: none; align-items: center; gap: var(--sp-1); }
@media (min-width: 60rem) { .nav__links { display: flex; } }

.nav__link {
  display: inline-block;
  padding: 0.45rem 0.7rem;
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  font-weight: 550;
  color: var(--ink-muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.nav__link:hover { color: var(--ink); background: var(--bg-inset); }
.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link[aria-current="page"]::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 3px;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--o-500), var(--p-500));
}

.nav__actions { display: flex; align-items: center; gap: var(--sp-2); }
.nav__cta { display: none; }
@media (min-width: 30rem) { .nav__cta { display: inline-flex; } }

.nav__toggle { display: inline-flex; }
@media (min-width: 60rem) { .nav__toggle { display: none; } }

.nav__mobile {
  display: none;
  border-top: 1px solid var(--line);
  background: var(--bg);
  padding-block: var(--sp-3);
}
.nav__mobile[data-open="true"] { display: block; }
@media (min-width: 60rem) { .nav__mobile { display: none !important; } }
.nav__mobile .nav__link {
  display: block;
  padding: var(--sp-3) var(--sp-2);
  font-size: var(--text-md);
  font-weight: 600;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
}
.nav__mobile .nav__link:last-of-type { border-bottom: 0; }
.nav__mobile .nav__link[aria-current="page"]::after { width: 2rem; }

/* Account menu */
.menu { position: relative; }
.menu__trigger {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0.3rem 0.5rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}
.menu__trigger:hover { background: var(--bg-inset); }
.menu__avatar { width: 1.9rem; height: 1.9rem; border-radius: var(--r-pill); border: 1px solid var(--line-strong); }
.menu__id { display: none; text-align: left; line-height: 1.15; }
@media (min-width: 40rem) { .menu__id { display: block; } }
.menu__name { font-size: var(--text-sm); font-weight: 650; }
.menu__tier {
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.menu__tier--paid { color: var(--warn); }
.menu__tier--dev { color: var(--danger-text); }
.menu__chevron { transition: transform var(--dur-fast) var(--ease); color: var(--ink-faint); }
.menu__trigger[aria-expanded="true"] .menu__chevron { transform: rotate(180deg); }

.menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 50;
  min-width: 12rem;
  padding: var(--sp-2);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-3);
}
.menu__panel[hidden] { display: none; }
.menu__item {
  display: block;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
}
.menu__item:hover { background: var(--bg-inset); color: var(--ink); }
.menu__item--dev { color: var(--warn); font-weight: 650; }
.menu__item--danger { color: var(--danger-text); }
.menu__item--danger:hover { background: var(--danger-wash); color: var(--danger-text); }
.menu__sep { height: 1px; margin: var(--sp-2) var(--sp-1); background: var(--line); }

/* Theme toggle — one button, two icons, CSS decides which is visible. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: none;
  color: var(--ink-muted);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.theme-toggle:hover { color: var(--ink); border-color: var(--line-strong); }
.theme-toggle svg { grid-area: 1 / 1; width: 1.05rem; height: 1.05rem; }
.theme-toggle .icon-sun { display: none; }
.theme-toggle .icon-moon { display: block; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .theme-toggle .icon-sun { display: block; }
  :root:not([data-theme="dark"]) .theme-toggle .icon-moon { display: none; }
}
:root[data-theme="light"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }

/* Footer */
.footer {
  margin-top: auto;
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
  padding-block: var(--sp-8) var(--sp-6);
}
.footer__grid {
  display: grid;
  gap: var(--sp-7);
  grid-template-columns: 1fr;
}
@media (min-width: 40rem) { .footer__grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 64rem) { .footer__grid { grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--sp-6); } }

.footer__col-title {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--sp-3);
}
.footer__link {
  display: block;
  padding-block: 0.3rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
}
.footer__link:hover { color: var(--brand-text); }
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
  font-size: var(--text-xs);
  color: var(--ink-faint);
}

/* ==========================================================================
 * §10  PAGE PATTERNS — hero, stats, feature clusters
 * ========================================================================== */

.hero { position: relative; padding-block: var(--sp-9) var(--sp-8); overflow: hidden; }
@media (min-width: 48rem) { .hero { padding-block: var(--sp-11) var(--sp-10); } }

.hero__title {
  font-size: var(--text-4xl);
  line-height: 0.94;
  letter-spacing: -0.035em;
  max-width: 16ch;
}
.hero__sub {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--ink-muted);
  max-width: 22ch;
}
.hero__lede { font-size: var(--text-md); color: var(--ink-muted); max-width: 54ch; }

/* Stat strip */
.stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
@media (min-width: 48rem) { .stats { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 72rem) { .stats--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } }

.stat { background: var(--bg-raised); padding: var(--sp-5) var(--sp-4); text-align: center; }
.stat__value {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stat__label {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

/* Editorial split — asymmetric on purpose, not a centred card. */
.split {
  display: grid;
  gap: var(--sp-6);
  align-items: start;
}
@media (min-width: 64rem) {
  .split { grid-template-columns: 5fr 7fr; gap: var(--sp-9); }
  .split--flip > :first-child { order: 2; }
  .split--even { grid-template-columns: 1fr 1fr; }
}

.section-head { max-width: 60ch; }
.section-head__title { font-size: var(--text-2xl); margin-top: var(--sp-3); }
.section-head__lede { margin-top: var(--sp-4); color: var(--ink-muted); font-size: var(--text-md); }

/* Feature clusters */
.cluster-grid { display: grid; gap: var(--sp-5); }
@media (min-width: 48rem) { .cluster-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 76rem) { .cluster-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.feature-group { display: flex; flex-direction: column; }
.feature-group__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 2px solid var(--ink);
  margin-bottom: var(--sp-4);
}
.feature-group__title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 800;
  letter-spacing: 0.02em;
}
.feature-list { list-style: none; padding: 0; display: grid; gap: var(--sp-3); }
.feature-item { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); align-items: start; }
.feature-item__dot {
  width: 0.4rem; height: 0.4rem; margin-top: 0.55rem;
  border-radius: var(--r-pill); background: var(--brand); flex: none;
}
.feature-item__name { display: block; font-weight: 650; font-size: var(--text-sm); }
.feature-item__desc {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--text-sm);
  color: var(--ink-muted);
  line-height: 1.5;
}

/* Numbered editorial list — used by the protection section */
.steps { list-style: none; padding: 0; display: grid; gap: var(--sp-6); counter-reset: step; }
.step { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-4); counter-increment: step; }
.step::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 900;
  line-height: 1;
  color: var(--brand-text);
  font-variant-numeric: tabular-nums;
}
.step__title { font-family: var(--font-display); font-size: var(--text-md); font-weight: 800; }
.step__body { margin-top: var(--sp-2); color: var(--ink-muted); font-size: var(--text-sm); }

/* Profile switch — the modularity section */
.profiles { display: grid; gap: var(--sp-4); }
@media (min-width: 56rem) { .profiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.profile__name { font-family: var(--font-display); font-weight: 800; font-size: var(--text-md); }
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) 0;
  border-bottom: 1px dashed var(--line);
  font-size: var(--text-sm);
}
.toggle-row:last-child { border-bottom: 0; }
.toggle-chip {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.15em 0.5em;
  border-radius: var(--r-xs);
  background: var(--bg-inset);
  color: var(--ink-faint);
}
.toggle-chip[data-on="true"] { background: var(--brand); color: var(--brand-ink); }

/* CTA band */
.cta-band {
  position: relative;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: var(--bg-raised);
  padding: var(--sp-8) var(--sp-5);
  text-align: center;
  overflow: hidden;
}
@media (min-width: 48rem) { .cta-band { padding: var(--sp-10) var(--sp-8); } }

/* ==========================================================================
 * §11  DOCUMENTATION
 * ========================================================================== */

.docs { display: block; padding-block: var(--sp-6) var(--sp-9); }
@media (min-width: 64rem) {
  .docs { display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: var(--sp-8); align-items: start; }
}

.docs__nav { margin-bottom: var(--sp-6); }
@media (min-width: 64rem) {
  .docs__nav {
    position: sticky;
    top: calc(var(--nav-h) + var(--sp-4));
    max-height: calc(100vh - var(--nav-h) - var(--sp-8));
    overflow-y: auto;
    margin-bottom: 0;
  }
}

.docs__nav-toggle {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-raised);
  font-weight: 650;
  font-size: var(--text-sm);
  cursor: pointer;
}
@media (min-width: 64rem) { .docs__nav-toggle { display: none; } }
.docs__nav-toggle .menu__chevron { transition: transform var(--dur-fast) var(--ease); }
.docs__nav-toggle[aria-expanded="true"] .menu__chevron { transform: rotate(180deg); }

.docs__nav-list { list-style: none; padding: 0; margin-top: var(--sp-3); }
.docs__nav-list[hidden] { display: none; }
@media (min-width: 64rem) { .docs__nav-list { display: block !important; margin-top: 0; } }

.docs__nav-title {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: var(--sp-3);
  display: none;
}
@media (min-width: 64rem) { .docs__nav-title { display: block; } }

.docs__nav-link {
  display: block;
  padding: 0.45rem var(--sp-3);
  border-left: 2px solid var(--line);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-decoration: none;
}
.docs__nav-link:hover { color: var(--ink); border-left-color: var(--line-strong); background: var(--bg-inset); }
.docs__nav-link[aria-current="page"] {
  color: var(--brand-text);
  border-left-color: var(--brand);
  font-weight: 650;
  background: var(--brand-wash);
}

.docs__main { min-width: 0; }
.docs__foot {
  display: grid;
  gap: var(--sp-3);
  margin-top: var(--sp-9);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--line);
}
@media (min-width: 40rem) { .docs__foot { grid-template-columns: 1fr 1fr; } }
.docs__step {
  display: block;
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--dur) var(--ease);
}
.docs__step:hover { border-color: var(--brand-edge); color: inherit; }
.docs__step--next { text-align: right; grid-column: -2 / -1; }
.docs__step-label {
  display: block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.docs__step-title { display: block; margin-top: 0.2rem; font-weight: 650; color: var(--brand-text); }

/* Long-form prose */
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--sp-4); }
.prose h2 {
  font-size: var(--text-xl);
  margin-top: var(--sp-8);
  padding-top: var(--sp-2);
  scroll-margin-top: calc(var(--nav-h) + var(--sp-5));
}
.prose h3 { font-size: var(--text-md); margin-top: var(--sp-6); scroll-margin-top: calc(var(--nav-h) + var(--sp-5)); }
.prose p, .prose li { color: var(--ink-muted); }
.prose strong { color: var(--ink); font-weight: 650; }
.prose ul, .prose ol { padding-left: 1.15rem; display: grid; gap: var(--sp-2); }
.prose li::marker { color: var(--brand-text); }
.prose code {
  padding: 0.12em 0.38em;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--bg-inset);
  color: var(--ink);
}
.prose pre {
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-inset);
  overflow-x: auto;
  font-size: var(--text-sm);
  line-height: 1.55;
}
.prose pre code { padding: 0; border: 0; background: none; }
.prose blockquote {
  padding-left: var(--sp-4);
  border-left: 3px solid var(--brand);
  color: var(--ink-muted);
}
.prose table { width: 100%; }
.prose figure { margin: 0; }
.prose .table-scroll { overflow-x: auto; }

/* Collapsible questions at the foot of a documentation page. Answers to
   questions someone does not have yet push the instructions off the screen, so
   they fold. Closed is the resting state and it has to read as a list. */
.faq {
  padding: var(--sp-4);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-raised);
}
.prose .faq + .faq { margin-top: var(--sp-3); }
.faq > summary {
  cursor: pointer;
  font-weight: 650;
  color: var(--ink);
  /* The marker is the only affordance a closed row has, so it keeps its
     default triangle rather than being styled away. */
  list-style-position: outside;
}
.faq > summary::marker { color: var(--brand-text); }
.faq > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
.faq[open] > summary { margin-bottom: var(--sp-3); }
.faq__body > * + * { margin-top: var(--sp-3); }

/* ==========================================================================
 * §12  DATA + FORMS
 * ========================================================================== */

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table th, .table td { padding: var(--sp-3) var(--sp-4); text-align: left; }
.table thead th {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table tbody tr { border-bottom: 1px solid var(--line); }
.table tbody tr:last-child { border-bottom: 0; }
.table tbody tr:hover { background: var(--bg-inset); }
.table--fixed { table-layout: fixed; }

.field { display: block; }
.field__label { display: block; font-size: var(--text-sm); font-weight: 650; margin-bottom: var(--sp-2); }
.field__hint { display: block; font-size: var(--text-xs); color: var(--ink-faint); margin-top: var(--sp-2); }

.input, .select, .textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: var(--bg-inset);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-faint); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-faint); }
.input:focus, .select:focus, .textarea:focus { border-color: var(--brand); }
.input:disabled, .select:disabled, .textarea:disabled { opacity: 0.55; cursor: not-allowed; }
.textarea { min-height: 6rem; resize: vertical; }
.select {
  appearance: none;
  padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.05rem center, right 0.8rem center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

/* Switch — a real checkbox underneath, so it is keyboard and screen-reader native. */
.switch { display: inline-flex; align-items: center; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  position: relative;
  width: 2.6rem;
  height: 1.5rem;
  border-radius: var(--r-pill);
  background: var(--bg-inset);
  border: 1px solid var(--line-strong);
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.switch__track::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0.18rem;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: var(--r-pill);
  background: var(--ink-faint);
  transform: translateY(-50%);
  transition: transform var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.switch input:checked + .switch__track { background: var(--brand); border-color: var(--brand); }
.switch input:checked + .switch__track::after { transform: translate(1.06rem, -50%); background: var(--brand-ink); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--focus); outline-offset: 2px; }
.switch input:disabled + .switch__track { opacity: 0.5; cursor: not-allowed; }

/* Modal — dialog element, so focus trap and Esc are the platform's job. */
.modal {
  width: min(34rem, calc(100vw - 2rem));
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-raised);
  color: var(--ink);
  box-shadow: var(--shadow-3);
}
.modal::backdrop { background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(3px); }
.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
}
.modal__body { padding: var(--sp-5); }
.modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--line);
  background: var(--bg-inset);
}

/* Progress bar — used by the leaderboard */
.bar {
  display: block;
  height: 0.4rem;
  border-radius: var(--r-pill);
  background: var(--bg-inset);
  overflow: hidden;
}
.bar__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-pill);
  background: linear-gradient(90deg, var(--o-500), var(--o-400));
}

/* ==========================================================================
 * §13  MOTION
 * --------------------------------------------------------------------------
 * Everything here is an enhancement. The reduced-motion block below is the
 * single switch that turns all of it off, and every animated element must
 * render correctly in its final state without JS.
 * ========================================================================== */

/*
 * No @view-transition here on purpose. Cross-document view transitions look
 * nice, but the browser rejects the transition promise whenever one is
 * skipped -- an ordinary occurrence on fast navigation -- and that surfaces as
 * an uncaught AbortError in the console on a page that has done nothing wrong.
 * Not worth a permanently noisy console for a sub-second flourish.
 */

@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes spin { to { transform: rotate(360deg); } }

.reveal { animation: rise var(--dur-slow) var(--ease) both; }
.reveal-1 { animation-delay: 60ms; }
.reveal-2 { animation-delay: 140ms; }
.reveal-3 { animation-delay: 220ms; }
.reveal-4 { animation-delay: 300ms; }

/* JS marks the document so scroll-reveal only hides content when it can also
   show it again. Without JS these rules never apply and everything is visible. */
[data-reveal-ready] .on-scroll { opacity: 0; transform: translateY(16px); }
[data-reveal-ready] .on-scroll.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-slow) var(--ease), transform var(--dur-slow) var(--ease);
}

.spin { animation: spin 1s linear infinite; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal-ready] .on-scroll { opacity: 1; transform: none; }
}

/* ==========================================================================
 * §14  LANDING-PAGE COMPOSITIONS
 * --------------------------------------------------------------------------
 * Pieces that exist once, on the home page. Kept here rather than in a
 * <style> block so there is still exactly one stylesheet to reason about.
 * ========================================================================== */

/* Sticker wall — the hero's visual. Module names as slapped labels: it shows
   the breadth of the product without a screenshot or an illustration. */
.tagwall { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: flex-start; }
.tagwall__item {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: 0.01em;
  padding: 0.45em 0.75em;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xs);
  background: var(--bg-raised);
  color: var(--ink-muted);
  box-shadow: var(--shadow-1);
  transition: transform var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.tagwall__item:nth-child(3n+1) { transform: rotate(-2.5deg); }
.tagwall__item:nth-child(3n+2) { transform: rotate(1.5deg); }
.tagwall__item:nth-child(4n+3) { transform: rotate(-0.8deg); }
.tagwall__item:hover { transform: rotate(0) scale(1.04); color: var(--ink); border-color: var(--line-strong); }
.tagwall__item--brand { background: var(--brand); color: var(--brand-ink); border-color: transparent; }
.tagwall__item--brand:hover { color: var(--brand-ink); }
.tagwall__item--pink { background: var(--pink); color: var(--pink-ink); border-color: transparent; }
.tagwall__item--pink:hover { color: var(--pink-ink); }
.tagwall__item--outline { background: none; }

/* Dashboard abstraction — a drawing of the settings UI, not a screenshot of
   it. Nothing here claims to be a control that exists; it is a diagram. */
.mock {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-raised);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}
.mock__bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  background: var(--bg-inset);
}
.mock__dot { width: 0.5rem; height: 0.5rem; border-radius: var(--r-pill); background: var(--line-strong); }
.mock__body { display: grid; grid-template-columns: 7rem minmax(0, 1fr); min-height: 15rem; }
.mock__side { border-right: 1px solid var(--line); padding: var(--sp-3); display: grid; gap: var(--sp-2); align-content: start; }
.mock__tab {
  font-size: var(--text-xs);
  font-weight: 650;
  color: var(--ink-faint);
  padding: 0.35rem 0.5rem;
  border-radius: var(--r-xs);
}
.mock__tab[data-active="true"] { background: var(--brand-wash); color: var(--brand-text); }
.mock__main { padding: var(--sp-4); display: grid; gap: var(--sp-3); align-content: start; }
.mock__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--line);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}
.mock__row:last-child { border-bottom: 0; }
.mock__switch {
  width: 1.9rem; height: 1.05rem; border-radius: var(--r-pill);
  background: var(--bg-inset); border: 1px solid var(--line-strong); position: relative; flex: none;
}
.mock__switch::after {
  content: ""; position: absolute; top: 50%; left: 0.12rem;
  width: 0.7rem; height: 0.7rem; border-radius: var(--r-pill);
  background: var(--ink-faint); transform: translateY(-50%);
}
.mock__switch[data-on="true"] { background: var(--brand); border-color: var(--brand); }
.mock__switch[data-on="true"]::after { background: var(--brand-ink); transform: translate(0.82rem, -50%); }
.mock__field { height: 1.5rem; flex: 1; max-width: 8rem; border: 1px solid var(--line-strong); border-radius: var(--r-xs); background: var(--bg-inset); }

/* Quiet key/value list, used by the custom-bots section. */
.spec { display: grid; gap: var(--sp-3); }
.spec__row { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr); gap: var(--sp-3); font-size: var(--text-sm); }
.spec__key { color: var(--ink-faint); font-weight: 650; }
@media (max-width: 30rem) { .spec__row { grid-template-columns: 1fr; gap: var(--sp-1); } }

/* Two-up card grid — the documentation index and anywhere else a short list
   of links needs more room than a bullet. */
.card-grid { display: grid; gap: var(--sp-4); }
@media (min-width: 44rem) { .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ==========================================================================
 * §15  APP PAGES
 * --------------------------------------------------------------------------
 * The signed-in dashboard: server picker, fleet, developer console. Same
 * tokens and same components as the public site — the two halves of the
 * product are deliberately not styled separately.
 * ========================================================================== */

.page { padding-block: var(--sp-7) var(--sp-9); }
.page__head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-bottom: var(--sp-5);
  margin-bottom: var(--sp-6);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 48rem) {
  .page__head { flex-direction: row; align-items: flex-end; justify-content: space-between; }
}
.page__title { font-size: var(--text-xl); }
.page__sub { margin-top: var(--sp-2); font-size: var(--text-sm); color: var(--ink-muted); }
.page__tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); }

.grid-cards {
  display: grid;
  gap: var(--sp-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

.entity { display: flex; flex-direction: column; }
.entity__head { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.entity__avatar,
.entity__fallback {
  width: 3rem;
  height: 3rem;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  flex: none;
}
.entity__avatar { object-fit: cover; }

/*
  A server on Premium.

  Carried by the card rather than by a badge inside it: a badge in the head
  competed for width with the one thing a server card exists to say, and pushed
  names that fitted perfectly well into their ellipsis. This costs no
  horizontal space at all.

  Deliberately quiet -- a tinted edge, a whisper of wash off the top, and the
  orange->pink fade down the left. That fade is the one gradient the brand
  earns (a blend between two adjacent cans, a real technique), and it is a
  difference in the card's own geometry as well as its hue, so the distinction
  does not rest on colour alone. The fact is also stated in visually-hidden
  text, which costs the layout nothing.

  Brand, never --live: green means online/healthy everywhere else here, and a
  tier is not a state.
*/
.entity--premium {
  position: relative;
  overflow: hidden;
  border-color: var(--brand-edge);
  background:
    linear-gradient(180deg, var(--brand-wash), transparent 45%),
    var(--bg-raised);
}
.entity--premium::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: linear-gradient(180deg, var(--o-400), var(--p-500));
}
.entity__fallback {
  display: grid;
  place-items: center;
  background: var(--bg-inset);
  font-family: var(--font-display);
  font-weight: 800;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.entity__id { min-width: 0; flex: 1; }
/* Both are block: as inline spans they sat on one line whenever the pair
   happened to fit, so the same list showed some cards stacked and some not.
   Block also gives text-overflow something to work with -- ellipsis does
   nothing on an inline box, which is why long server names were being cut
   off mid-word with no ellipsis at all. */
.entity__name {
  display: block;
  font-weight: 700;
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entity__meta {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.entity__foot { margin-top: var(--sp-5); }

/* A short block of explanation attached to a decision — "this is a Premium
   feature", "your setup is kept", "this bot also runs in two other servers".
   Distinct from .empty (which fills a page that has no content) and from a
   .card (which holds controls): a notice is prose about the state you are in.
   Variants carry the same meaning as the stickers, so a warning notice and a
   warning sticker on one page agree. */
.notice {
  border: 1px solid var(--border);
  border-left: 3px solid var(--ink-faint);
  border-radius: var(--radius);
  background: var(--bg-inset);
  padding: var(--sp-4) var(--sp-5);
}
.notice__title { font-weight: 700; margin-bottom: var(--sp-2); }
.notice__body { font-size: var(--text-sm); color: var(--ink-muted); max-width: 68ch; }
.notice__body + p { margin-top: var(--sp-4); }
.notice--brand { border-left-color: var(--brand); }
.notice--warn { border-left-color: var(--warn); }
.notice--danger { border-left-color: var(--danger); }
.notice--live { border-left-color: var(--live); }

/* The identity row at the top of a management page: who is running, and how it
   is doing. Deliberately not .entity, which is a card header. */
.identity {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}
/* The one at the top of a management page, where the bot IS the subject of the
   screen rather than a row in a list. */
.identity--lead { gap: var(--sp-5); }
.entity__avatar--lg,
.entity__fallback--lg { width: 4rem; height: 4rem; font-size: var(--text-lg); }
.identity--lead .identity__name { font-size: var(--text-xl); }
.identity__meta { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.identity__name { font-size: var(--text-lg); font-weight: 750; }
.identity__state { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--text-sm); }
.identity__note { font-size: var(--text-sm); color: var(--ink-muted); }

/* A checklist of setup progress. Each row states a fact, not an instruction. */
.progress { list-style: none; padding: 0; margin: 0; }
.progress > li { display: flex; gap: var(--sp-3); align-items: baseline; padding: var(--sp-2) 0; }
.progress__mark { flex: none; font-weight: 700; }
.progress__mark--done { color: var(--live); }
.progress__mark--pending { color: var(--warn); }

.empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--sp-9) var(--sp-5);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
}
.empty__title { font-weight: 700; }
.empty__body { margin-top: var(--sp-2); font-size: var(--text-sm); color: var(--ink-faint); max-width: 44ch; margin-inline: auto; }

.search { position: relative; }
.search__icon {
  position: absolute;
  left: 0.7rem;
  top: 50%;
  transform: translateY(-50%);
  width: 1rem;
  height: 1rem;
  color: var(--ink-faint);
  pointer-events: none;
}
.search .input { padding-left: 2.25rem; }

/* Inline log viewer — fleet and developer consoles. */
.logbox {
  margin: 0;
  padding: var(--sp-4);
  max-height: 22rem;
  overflow: auto;
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-size: var(--text-xs);
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--ink-muted);
}

/* Segmented control — sort toggles and other small either/or choices. */
.segment {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg-inset);
}
.segment button {
  padding: 0.35rem 0.7rem;
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  font-size: var(--text-xs);
  font-weight: 650;
  color: var(--ink-muted);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.segment button:hover { color: var(--ink); }
.segment button[aria-pressed="true"] { background: var(--brand); color: var(--brand-ink); }

/* Rank chips. The number is always present, so the colour is decoration and
   never the only thing telling you which place someone came. */
.rank {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--r-pill);
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
}
.rank--first { color: var(--ink-on-brand); }
.rank--podium { background: var(--ink); color: var(--bg); }

.lb-name { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.lb-avatar { width: 2.1rem; height: 2.1rem; border-radius: var(--r-pill); object-fit: cover; border: 1px solid var(--line-strong); flex: none; }
.lb-user { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-value { font-weight: 700; font-variant-numeric: tabular-nums; margin-bottom: 0.35rem; }
.bar__fill--alt { background: linear-gradient(90deg, var(--p-500), var(--p-400)); }

/* Tabs — a real tablist, so arrow keys and screen readers work. */
.tabs {
  display: flex;
  gap: var(--sp-1);
  margin-bottom: var(--sp-6);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
.tabs button {
  padding: 0.7rem 1rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  font-size: var(--text-sm);
  font-weight: 650;
  color: var(--ink-muted);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.tabs button:hover { color: var(--ink); }
.tabs button[aria-selected="true"] { color: var(--brand-text); border-bottom-color: var(--brand); }

/* ==========================================================================
 * §16  SETTINGS SCREEN
 * --------------------------------------------------------------------------
 * The per-guild settings page (dashboard/templates/settings.html) had its own
 * ~480-line design system in a scoped <style> block, keyed to Tailwind's slate
 * palette and dark-only. The structure was sound, so it moved here as-is and
 * its local variables were re-pointed at the semantic tokens in §2 — which is
 * what makes the page theme-aware without touching its markup or its 760 lines
 * of behaviour in static/js/settings.js.
 *
 * Local names are kept (--panel, --text, --accent...) so the rules below still
 * read the way they were written. They are scoped to .settings-shell rather
 * than :root so they cannot collide with the global tokens.
 * ========================================================================== */

.settings-shell {
  --panel:        var(--bg-raised);
  --panel-raised: var(--bg-inset);
  --panel-hover:  var(--bg-hover);
  --border:       var(--line);
  --border-soft:  var(--line);
  --text:         var(--ink);
  --text-dim:     var(--ink-muted);
  --text-faint:   var(--ink-faint);

  --accent:       var(--brand);
  --accent-text:  var(--brand-text);
  --accent-hover: var(--brand-hover);
  --accent-dim:   var(--brand-wash);
  --accent-ring:  color-mix(in oklab, var(--brand) 32%, transparent);

  --premium:      var(--warn);
  --premium-dim:  var(--warn-wash);
  --premium-edge: color-mix(in oklab, var(--warn) 34%, transparent);

  --dev:          var(--pink-text);
  --dev-dim:      var(--pink-wash);
  --dev-edge:     color-mix(in oklab, var(--pink) 30%, transparent);

  --s-danger:      var(--danger-text);
  --s-danger-dim:  var(--danger-wash);
  --s-danger-edge: color-mix(in oklab, var(--danger) 34%, transparent);

  /* Discord blurple, kept exact so the panel preview reads as authentic. */
  --indigo: var(--discord);

  --radius: var(--r-lg);
  --radius-sm: var(--r-md);

  background: transparent;
  color: var(--text);
  font-family: var(--font-body);
}
.settings-shell * { box-sizing: border-box; }
.settings-shell a { color: inherit; }

/* ---------- page head ---------- */
.settings-shell .page-head {
  max-width: 1180px;
  margin: 0 auto 4px;
  padding: 24px 28px 20px;
  border-bottom: 1px solid var(--border-soft);
}
.settings-shell .back-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 11px; border-radius: var(--r-md);
  border: 1px solid var(--border); background: var(--panel-raised);
  color: var(--text-dim); font-size: 12px; font-weight: 700;
  text-decoration: none; margin-bottom: 14px;
  transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}
.settings-shell .back-link:hover { background: var(--panel-hover); color: var(--text); border-color: var(--line-strong); }
.settings-shell .back-link svg { width: 13px; height: 13px; flex: none; }
.settings-shell .sidebar-guild-name {
  font-family: var(--font-display);
  font-size: 22px; font-weight: 800; letter-spacing: -0.02em;
  margin: 0 0 10px; overflow-wrap: break-word;
}
.settings-shell .sidebar-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.settings-shell .bot-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px 2px 7px; border-radius: var(--r-pill);
  background: var(--panel-raised); border: 1px solid var(--border);
  font-size: 11px; font-weight: 600; color: var(--text);
}
.settings-shell .bot-pill i { width: 6px; height: 6px; border-radius: 50%; display: inline-block; }

/* ---------- layout ---------- */
.settings-shell .layout { display: flex; align-items: flex-start; max-width: 1180px; margin: 0 auto; padding: 24px 28px 140px; }
.settings-shell .sidebar { width: 230px; flex: none; position: sticky; top: calc(var(--nav-h) + 12px); margin-right: 28px; }
.settings-shell .sidebar-toggle { display: none; }
.settings-shell .sidebar-list { display: flex; flex-direction: column; gap: 4px; }
.settings-shell .sidebar-label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-faint); font-weight: 700; padding: 0 12px 8px;
}
.settings-shell .tab-btn {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border-radius: 10px;
  border: 1px solid transparent; background: none; color: var(--text-dim);
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  text-align: left; cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.settings-shell .tab-btn .tab-icon { font-size: 15px; width: 20px; text-align: center; flex: none; }
.settings-shell .tab-btn:hover { background: var(--panel-hover); color: var(--text); }
.settings-shell .tab-btn.active {
  position: relative;
  background: var(--accent-dim); color: var(--text);
  border-color: var(--brand-edge);
}
.settings-shell .tab-btn.active::before {
  content: ''; position: absolute; left: -1px; top: 8px; bottom: 8px;
  width: 3px; border-radius: 3px; background: var(--accent);
}
.settings-shell .sidebar-divider { height: 1px; background: var(--border-soft); margin: 8px 4px; }

.settings-shell .content { flex: 1; min-width: 0; }
.settings-shell .tab-panel { display: none; }
.settings-shell .tab-panel.active { display: block; animation: rise .18s var(--ease) both; }

.settings-shell .module-box { margin-bottom: 22px; }
.settings-shell .module-box:last-child { margin-bottom: 0; }
.settings-shell .module-head { margin-bottom: 14px; }
.settings-shell .module-head h3 {
  font-family: var(--font-display);
  font-size: 21px; margin: 0 0 6px; font-weight: 800;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.settings-shell .module-head.module-sub h3 { font-size: 16px; }
.settings-shell .module-head p { margin: 0; color: var(--text-dim); font-size: 13.5px; max-width: 640px; line-height: 1.5; }
.settings-shell .tab-head { margin-bottom: 20px; }
.settings-shell .tab-head h2 {
  font-family: var(--font-display);
  font-size: 22px; margin: 0 0 4px; font-weight: 800;
  display: flex; align-items: center; gap: 10px;
}

.settings-shell .settings-list { background: var(--panel); border: 1px solid var(--border-soft); border-radius: var(--radius); }
.settings-shell .setting-item {
  position: relative; display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 16px 20px; border-bottom: 1px solid var(--border-soft);
}
.settings-shell .setting-item:first-child { border-radius: var(--radius) var(--radius) 0 0; }
.settings-shell .setting-item:last-child { border-bottom: none; border-radius: 0 0 var(--radius) var(--radius); }
.settings-shell .setting-info { min-width: 0; max-width: 62%; }
.settings-shell .setting-info label {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  font-size: 14px; font-weight: 700; color: var(--text); cursor: default;
}
.settings-shell .setting-info .description { display: block; margin-top: 4px; font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }
.settings-shell .setting-input { flex: none; display: flex; align-items: center; }

/* A textarea reads badly squeezed into the narrow right-hand column — stack it
   full width instead, label above and the box spanning the whole row. */
.settings-shell .setting-item.setting-item-textarea { flex-direction: column; align-items: stretch; gap: 12px; }
.settings-shell .setting-item.setting-item-textarea .setting-info { max-width: 100%; }
.settings-shell .setting-item.setting-item-textarea .setting-input { width: 100%; flex-direction: column; align-items: stretch; }
.settings-shell .textarea-input { width: 100%; min-height: 100px; resize: vertical; font-family: inherit; line-height: 1.5; padding: 11px 12px; }
.settings-shell .textarea-count { align-self: flex-end; margin-top: 6px; font-size: 11px; font-weight: 600; color: var(--text-faint); }
.settings-shell .textarea-count.near-limit { color: var(--premium); }
.settings-shell .textarea-count.at-limit { color: var(--s-danger); }

/* ---------- badges ---------- */
.settings-shell .badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 6px; border-radius: var(--r-pill);
  font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em;
}
.settings-shell .badge svg { width: 11px; height: 11px; fill: none; }
.settings-shell .badge-recommended svg { fill: currentColor; }
.settings-shell .badge-premium { color: var(--premium); background: var(--premium-dim); border: 1px solid var(--premium-edge); }
.settings-shell .badge-dev { color: var(--dev); background: var(--dev-dim); border: 1px solid var(--dev-edge); }
.settings-shell .badge-beta { color: var(--text-dim); background: var(--panel-hover); border: 1px solid var(--border); }
.settings-shell .badge-recommended { color: var(--accent-text); background: var(--accent-dim); border: 1px solid var(--brand-edge); }
.settings-shell .badge-coming-soon { color: var(--text-dim); background: var(--panel-hover); border: 1px solid var(--border); }

/* ---------- tooltip ---------- */
.settings-shell .info-icon,
.settings-shell .danger-icon { display: inline-flex; width: 14px; height: 14px; color: var(--text-faint); cursor: help; position: relative; flex: none; }
.settings-shell .info-icon svg,
.settings-shell .danger-icon svg { width: 14px; height: 14px; }
.settings-shell .info-icon:hover { color: var(--accent-text); }
.settings-shell .info-icon:focus-visible { color: var(--accent-text); }
.settings-shell .danger-icon { color: var(--s-danger); cursor: default; }
.settings-shell .info-icon::after {
  content: attr(data-tooltip);
  position: absolute; left: 50%; bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  width: max-content; max-width: 230px;
  /* Inverted against the page so it reads as an overlay in either theme. */
  background: var(--ink); color: var(--bg);
  font-size: 11.5px; font-weight: 500; line-height: 1.5;
  padding: 8px 10px; border-radius: 7px;
  box-shadow: var(--shadow-3);
  opacity: 0; pointer-events: none; z-index: 50;
  transition: opacity .12s ease, transform .12s ease;
  text-transform: none; letter-spacing: normal;
}
.settings-shell .info-icon:hover::after,
.settings-shell .info-icon:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---------- locked / coming soon ---------- */
.settings-shell .setting-item.is-locked { background: linear-gradient(90deg, var(--premium-dim), transparent 40%); }
.settings-shell .setting-item.is-locked .setting-input { opacity: .55; filter: grayscale(.15); }
.settings-shell .setting-item.is-locked input,
.settings-shell .setting-item.is-locked select,
.settings-shell .setting-item.is-locked .gsel-trigger-locked { cursor: not-allowed; }
.settings-shell .lock-note { position: absolute; right: 20px; bottom: -1px; transform: translateY(100%); display: none; }
.settings-shell .setting-item.is-locked,
.settings-shell .setting-item.is-coming-soon { flex-wrap: wrap; }
.settings-shell .setting-item.is-locked .lock-note,
.settings-shell .setting-item.is-coming-soon .lock-note {
  display: flex; align-items: center; gap: 6px;
  position: static; transform: none; width: 100%;
  margin-top: 10px; padding: 9px 12px; border-radius: var(--r-md);
  background: var(--premium-dim); border: 1px solid var(--premium-edge);
  color: var(--premium); font-size: 12px; font-weight: 600;
}
.settings-shell .lock-note svg { width: 13px; height: 13px; flex: none; }
.settings-shell .setting-item.is-coming-soon { background: linear-gradient(90deg, var(--bg-hover), transparent 40%); }
.settings-shell .setting-item.is-coming-soon .setting-input { opacity: .5; filter: grayscale(.4); }
.settings-shell .setting-item.is-coming-soon .lock-note { background: var(--panel-hover); border-color: var(--border); color: var(--text-dim); }
.settings-shell .module-box.module-coming-soon .module-head h3 { color: var(--text-dim); }

/* ---------- visible_if / enabled_if, resolved by settings.js after first paint ---------- */
.settings-shell .setting-item.setting-item-hidden { display: none; }
.settings-shell .setting-item.is-cond-disabled .setting-input { opacity: .5; }
.settings-shell .setting-item.is-cond-disabled input,
.settings-shell .setting-item.is-cond-disabled select,
.settings-shell .setting-item.is-cond-disabled button { cursor: not-allowed; }
.settings-shell .gsel.gsel-cond-disabled .gsel-trigger { cursor: not-allowed; }
.settings-shell .module-box.module-premium { position: relative; }
.settings-shell .module-box.module-premium .module-head h3 { color: var(--text); }

/* ---------- inputs ---------- */
.settings-shell .field-input {
  background: var(--panel-raised); border: 1px solid var(--border); color: var(--text);
  padding: 9px 12px; border-radius: var(--r-md); font-size: 13.5px; font-family: inherit;
  min-width: 200px; transition: border-color .12s ease, box-shadow .12s ease;
}
.settings-shell .field-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.settings-shell .field-input:disabled { opacity: .6; cursor: not-allowed; }
.settings-shell .number-field { display: flex; align-items: center; gap: 8px; }
.settings-shell .number-input { min-width: 110px; text-align: center; }
.settings-shell .number-cap { font-size: 11px; color: var(--text-faint); font-weight: 600; white-space: nowrap; }
.settings-shell .number-unit { font-size: 12.5px; color: var(--text-dim); font-weight: 700; white-space: nowrap; }

.settings-shell select.native-select {
  appearance: none; -webkit-appearance: none; cursor: pointer;
  min-width: 180px; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 17px center, right 12px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.settings-shell select.native-select:disabled { cursor: not-allowed; }

/* ---------- toggle ---------- */
.settings-shell .toggle { position: relative; display: inline-flex; cursor: pointer; }
.settings-shell .toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.settings-shell .toggle-track {
  width: 42px; height: 24px; border-radius: var(--r-pill);
  background: var(--panel-raised); border: 1px solid var(--border);
  display: block; position: relative;
  transition: background-color .15s ease, border-color .15s ease;
}
.settings-shell .toggle-thumb {
  position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--text-faint); transition: transform .15s ease, background-color .15s ease;
}
.settings-shell .toggle input:checked + .toggle-track { background: var(--accent); border-color: var(--accent); }
.settings-shell .toggle input:checked + .toggle-track .toggle-thumb { transform: translateX(18px); background: var(--brand-ink); }
.settings-shell .toggle input:focus-visible + .toggle-track { outline: 2px solid var(--focus); outline-offset: 2px; }
.settings-shell .toggle-locked { cursor: not-allowed; }

/* ---------- searchable select (gsel) ---------- */
.settings-shell .gsel { position: relative; width: 260px; }
.settings-shell .gsel-trigger {
  width: 100%; display: flex; align-items: center; gap: 9px; padding: 9px 11px;
  background: var(--panel-raised); border: 1px solid var(--border); border-radius: var(--r-md);
  color: var(--text); font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.settings-shell .gsel-trigger:hover { border-color: var(--line-strong); }
.settings-shell .gsel.open .gsel-trigger { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.settings-shell .gsel-icon { flex: none; width: 15px; height: 15px; color: var(--text-faint); display: flex; }
.settings-shell .gsel-icon svg { width: 15px; height: 15px; }
.settings-shell .gsel-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.settings-shell .gsel-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.settings-shell .gsel-chevron { flex: none; width: 14px; height: 14px; color: var(--text-faint); transition: transform .15s ease; }
.settings-shell .gsel-chevron svg { width: 14px; height: 14px; }
.settings-shell .gsel.open .gsel-chevron { transform: rotate(180deg); }
.settings-shell .gsel-trigger-locked { opacity: .7; cursor: not-allowed; }

/* Undocked default. settings.js portals the panel to <body> on open and
   switches it to position:fixed, which is what stops an ancestor's overflow
   from ever clipping it. */
.gsel-panel {
  display: none; position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; width: 100%;
  background: var(--bg-inset); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow-3); overflow: hidden;
}
.gsel-panel.gsel-portal { display: block; position: fixed; z-index: 2000; }
.gsel-search-wrap { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border-bottom: 1px solid var(--line); }
.gsel-search-icon { width: 14px; height: 14px; color: var(--ink-faint); flex: none; }
.gsel-search-icon svg { width: 14px; height: 14px; }
.gsel-search { flex: 1; background: transparent; border: none; color: var(--ink); font-family: inherit; font-size: 13px; }
.gsel-search:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.gsel-options { max-height: 220px; overflow-y: auto; padding: 4px; }
.gsel-option {
  display: flex; align-items: center; gap: 9px; padding: 8px 9px; border-radius: 6px;
  font-size: 13px; font-weight: 600; color: var(--ink); cursor: pointer;
}
.gsel-option:hover, .gsel-option.hl { background: var(--bg-hover); }
.gsel-option.selected { color: var(--brand-text); }
.gsel-option .gsel-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.gsel-option input[type="checkbox"] { accent-color: var(--brand); width: 14px; height: 14px; flex: none; }
.gsel-empty { padding: 14px 12px; font-size: 12.5px; color: var(--ink-faint); text-align: center; }

/* ---------- empty state ---------- */
.settings-shell .empty-state {
  text-align: center; padding: 60px 24px; color: var(--text-dim);
  background: var(--panel); border: 1px dashed var(--border); border-radius: var(--radius);
}
.settings-shell .empty-state h3 { color: var(--text); margin: 0 0 6px; }

/* ---------- save bar ---------- */
.settings-shell .save-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; justify-content: center; pointer-events: none;
  padding: 16px 28px;
  background: linear-gradient(180deg, transparent, var(--bg) 70%);
  transform: translateY(100%); opacity: 0;
  transition: transform .22s var(--ease), opacity .22s ease;
}
.settings-shell .save-bar.visible { transform: translateY(0); opacity: 1; pointer-events: auto; }
.settings-shell .save-bar-inner {
  width: 100%; max-width: 1180px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 16px; box-shadow: var(--shadow-2);
}
.settings-shell .save-hint { font-size: 12.5px; color: var(--premium); font-weight: 700; display: flex; align-items: center; gap: 7px; }
.settings-shell .save-hint svg { width: 14px; height: 14px; }
.settings-shell .btn-save {
  appearance: none; border: none; cursor: pointer; font-family: inherit;
  background: var(--accent); color: var(--brand-ink); font-weight: 800; font-size: 14px;
  padding: 11px 22px; border-radius: 9px; transition: background-color .12s ease, transform .12s ease;
}
.settings-shell .btn-save:hover { background: var(--brand-hover); }
.settings-shell .btn-save:active { transform: translateY(1px); }
.settings-shell .btn-save:disabled { opacity: .6; cursor: not-allowed; }

/* Toasts are portalled to <body>, so they are not scoped to .settings-shell. */
.toast-stack { position: fixed; bottom: 18px; right: 18px; z-index: 2100; display: flex; flex-direction: column; gap: 10px; width: 300px; }
.toast {
  display: flex; align-items: center; gap: 10px; padding: 12px 16px;
  background: var(--bg-raised); border: 1px solid var(--brand-edge); border-radius: 10px;
  color: var(--ink); font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-3);
  animation: rise .22s var(--ease) both;
}
.toast.error { border-color: color-mix(in oklab, var(--danger) 40%, transparent); }
.toast i { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: none; }
.toast.error i { background: var(--danger); }

/* ---------- tickets tab ---------- */
.settings-shell .ticket-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 24px; }
.settings-shell .ticket-field-label {
  display: block; font-size: 11px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-faint); margin-bottom: 8px;
}
.settings-shell .ticket-textarea {
  width: 100%; background: var(--panel-raised); border: 1px solid var(--border); color: var(--text);
  padding: 12px; border-radius: var(--r-md); font-size: 13.5px; font-family: inherit; height: 96px; resize: vertical;
}
.settings-shell .ticket-textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.settings-shell .ticket-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 6px; }
.settings-shell .deploy-box {
  background: color-mix(in oklab, var(--indigo) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--indigo) 35%, transparent);
  padding: 16px; border-radius: 10px;
}
.settings-shell .deploy-box .ticket-field-label { color: var(--indigo); }
.settings-shell .deploy-row { display: flex; gap: 8px; }
.settings-shell .deploy-row .gsel { width: auto; flex: 1; }
.settings-shell .btn-indigo {
  background: var(--indigo); color: #fff; border: none; font-weight: 800; font-size: 13px;
  padding: 0 18px; border-radius: var(--r-md); cursor: pointer; white-space: nowrap;
  font-family: inherit; transition: background-color .12s ease;
}
.settings-shell .btn-indigo:hover { background: var(--discord-hover); }
.settings-shell .btn-indigo:disabled { opacity: .6; cursor: not-allowed; }
.settings-shell .deploy-status { font-size: 12px; margin-top: 8px; display: none; font-weight: 700; }
.settings-shell .deploy-status.show { display: block; }
.settings-shell .deploy-status.ok { color: var(--accent-text); }
.settings-shell .deploy-status.err { color: var(--s-danger); }
.settings-shell .deploy-status.pending { color: var(--indigo); }

/* Discord's own chrome, reproduced exactly so the preview is honest about what
   members will actually see. Deliberately exempt from the palette. */
.settings-shell .discord-preview { background: #313338; border-radius: 10px; padding: 14px; border: 1px solid var(--border-soft); }
.settings-shell .discord-preview-inner { border-left: 4px solid var(--accent); background: #2b2d31; border-radius: 6px; padding: 14px; }
.settings-shell .discord-preview-inner .p-title { font-weight: 800; color: #fff; font-size: 13.5px; margin: 0 0 6px; }
.settings-shell .discord-preview-inner .p-msg { color: #dbdee1; font-size: 12.5px; white-space: pre-wrap; line-height: 1.5; margin: 0; }
.settings-shell .discord-preview-buttons { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.settings-shell .discord-btn { display: inline-flex; align-items: center; gap: 6px; color: #fff; font-size: 12.5px; font-weight: 600; padding: 6px 12px; border-radius: 4px; }
.settings-shell .discord-btn.empty { color: #949ba4; font-style: italic; font-weight: 500; }

.settings-shell .ticket-panels-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; flex-wrap: wrap; }
.settings-shell .btn-accent-sm {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent); color: var(--brand-ink);
  font-weight: 800; font-size: 12.5px; padding: 9px 16px; border-radius: 9px;
  border: none; cursor: pointer; font-family: inherit; transition: background-color .12s ease;
}
.settings-shell .btn-accent-sm:hover { background: var(--brand-hover); }
.settings-shell .btn-accent-sm:disabled { opacity: .5; cursor: not-allowed; }
.settings-shell .btn-accent-sm svg { width: 13px; height: 13px; }
.settings-shell .limit-banner {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; color: var(--premium);
  background: var(--premium-dim); border: 1px solid var(--premium-edge);
  padding: 8px 12px; border-radius: var(--r-md); margin-bottom: 14px;
}
.settings-shell .limit-banner svg { width: 14px; height: 14px; flex: none; }

.settings-shell .ticket-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.settings-shell .ticket-card {
  background: var(--panel); border: 1px solid var(--border-soft); border-radius: 11px; padding: 16px;
  transition: border-color .12s ease, transform .12s ease;
}
.settings-shell .ticket-card:hover { border-color: var(--brand-edge); transform: translateY(-2px); }
.settings-shell .ticket-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.settings-shell .ticket-card-name { display: flex; align-items: center; gap: 8px; min-width: 0; font-weight: 800; font-size: 14.5px; }
.settings-shell .ticket-card-name span.n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.settings-shell .ticket-style-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; margin-top: 3px; }
.settings-shell .ticket-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.settings-shell .ticket-tag {
  background: var(--panel-raised); border: 1px solid var(--border); color: var(--text-dim);
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 6px;
}
.settings-shell .ticket-card-msg {
  color: var(--text-faint); font-size: 12px; line-height: 1.5; margin: 0 0 12px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.settings-shell .ticket-card-actions { display: flex; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border-soft); }
.settings-shell .ticket-card-actions button {
  font-family: inherit; font-size: 11.5px; font-weight: 800; padding: 8px; border-radius: 7px;
  border: none; cursor: pointer; transition: background-color .12s ease;
}
.settings-shell .ticket-card-actions .edit-btn { flex: 1; background: var(--panel-raised); color: var(--text); }
.settings-shell .ticket-card-actions .edit-btn:hover { background: var(--panel-hover); }
.settings-shell .ticket-card-actions .del-btn { background: var(--s-danger-dim); color: var(--s-danger); padding: 8px 12px; }
.settings-shell .ticket-card-actions .del-btn:hover { background: color-mix(in oklab, var(--danger) 20%, transparent); }
.settings-shell .ticket-empty {
  text-align: center; padding: 44px 20px; border: 1px dashed var(--border);
  border-radius: 11px; color: var(--text-faint); font-size: 13px;
}
.settings-shell .ticket-empty strong { color: var(--accent-text); }

/* ---------- ticket type modal (portalled, so not scoped) ---------- */
.modal-backdrop {
  position: fixed; inset: 0; background: rgba(0, 0, 0, .68); backdrop-filter: blur(3px);
  z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 16px;
  opacity: 0; pointer-events: none; transition: opacity .18s ease;
}
.modal-backdrop.open { opacity: 1; pointer-events: auto; }
.modal-panel {
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 16px;
  width: 100%; max-width: 600px; max-height: 88vh; overflow-y: auto; color: var(--ink);
  transform: translateY(10px) scale(.98); opacity: 0;
  transition: transform .2s ease, opacity .2s ease;
}
.modal-backdrop.open .modal-panel { transform: none; opacity: 1; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px 22px; border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--bg-raised); z-index: 2;
}
.modal-head h3 { margin: 0; font-size: 17px; font-weight: 800; font-family: var(--font-display); }
.modal-close { background: none; border: none; color: var(--ink-faint); cursor: pointer; padding: 4px; display: flex; }
.modal-close:hover { color: var(--ink); }
.modal-close svg { width: 18px; height: 18px; }
.modal-body { padding: 22px; display: flex; flex-direction: column; gap: 18px; }
.modal-error {
  display: none; background: var(--danger-wash);
  border: 1px solid color-mix(in oklab, var(--danger) 34%, transparent);
  color: var(--danger-text); font-size: 12px; font-weight: 700;
  padding: 10px 12px; border-radius: var(--r-md);
}
.modal-error.show { display: block; }
.modal-grid-2 { display: grid; grid-template-columns: 1fr auto; gap: 14px; }
.modal-grid-2-even { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.style-picker { display: flex; gap: 8px; }
.style-dot-btn {
  width: 34px; height: 34px; border-radius: 50%; border: 2px solid transparent;
  cursor: pointer; padding: 0; transition: border-color .12s ease, opacity .12s ease;
}
.style-dot-btn.sel { border-color: var(--ink); }
.style-dot-btn:not(.sel) { opacity: .55; }
.style-dot-btn:hover { opacity: 1; }
.modal-input {
  width: 100%; background: var(--bg-inset); border: 1px solid var(--line); color: var(--ink);
  padding: 10px 12px; border-radius: var(--r-md); font-size: 13.5px; font-family: inherit;
}
.modal-input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 32%, transparent); }
.modal-textarea { min-height: 76px; resize: vertical; }
.modal-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 22px; border-top: 1px solid var(--line);
  position: sticky; bottom: 0; background: var(--bg-raised);
}
.btn-text-danger { background: none; border: none; color: var(--danger-text); font-weight: 800; font-size: 13px; cursor: pointer; font-family: inherit; padding: 8px; }
.btn-text-danger:hover { color: var(--danger); }
.btn-ghost { background: none; border: none; color: var(--ink-muted); font-weight: 700; font-size: 13px; cursor: pointer; font-family: inherit; padding: 10px 16px; }
.btn-ghost:hover { color: var(--ink); }

/* ---------- mobile ---------- */
@media (max-width: 860px) {
  .settings-shell .page-head { padding: 18px 16px 16px; }
  .settings-shell .layout { flex-direction: column; padding: 18px 16px 150px; }
  /* `top` must be reset alongside `position`: left at the sticky offset it
     shifts a position:relative sidebar down over the content below it. */
  .settings-shell .sidebar { position: relative; top: auto; width: 100%; margin: 0 0 18px; }

  /* Current tab as a button; tap to reveal the list beneath it. */
  .settings-shell .sidebar-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
    padding: 13px 14px; border-radius: 12px; border: 1px solid var(--border);
    background: var(--panel); color: var(--text);
    font-family: inherit; font-size: 14.5px; font-weight: 700; cursor: pointer;
  }
  .settings-shell .sidebar-toggle-current { display: flex; align-items: center; gap: 10px; min-width: 0; }
  .settings-shell .sidebar-toggle-current .tab-icon { font-size: 16px; width: 20px; text-align: center; flex: none; }
  .settings-shell .sidebar-toggle-current span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .settings-shell .sidebar-toggle-chevron { width: 16px; height: 16px; flex: none; color: var(--text-dim); transition: transform .15s ease; }
  .settings-shell .sidebar-toggle[aria-expanded="true"] { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
  .settings-shell .sidebar-toggle[aria-expanded="true"] .sidebar-toggle-chevron { transform: rotate(180deg); }

  /* Floating panel rather than an in-flow block, so opening it never shifts
     the page content below. */
  .settings-shell .sidebar-list {
    display: none; flex-direction: column; gap: 2px;
    position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 30;
    background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
    padding: 6px; box-shadow: var(--shadow-3);
    max-height: 60vh; overflow-y: auto;
  }
  .settings-shell .sidebar-list.open { display: flex; }
  .settings-shell .sidebar-label { display: none; }

  /* The sidebar toggle already names the current tab, so the panel heading
     would read it straight back. Keep it for assistive tech, drop it visually. */
  .settings-shell .tab-head {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  .settings-shell .tab-btn.active::before { display: none; }
  .settings-shell .setting-item { flex-direction: column; align-items: flex-start; gap: 12px; }
  .settings-shell .setting-info { max-width: 100%; }
  .settings-shell .gsel,
  .settings-shell .field-input,
  .settings-shell .number-field,
  .settings-shell select.native-select { width: 100%; }
  .settings-shell .setting-input { width: 100%; }
  .settings-shell .ticket-grid,
  .settings-shell .ticket-cards,
  .modal-grid-2-even { grid-template-columns: 1fr; }
  .modal-grid-2 { grid-template-columns: 1fr; }
}
