/* ==========================================================================
   KilgoreAI — design tokens
   Single source of truth for /chat/, / (landing) and /api-docs.
   Load this BEFORE any page stylesheet.

   BREAKPOINTS — NOT tokens, because @media cannot read var() and
   @custom-media was dropped in Safari 16.4. They are a shared scale you must
   type by hand; there is no way to share them in a custom property. Every page
   sheet uses exactly these four:

     400px  narrow phones (up to an iPhone SE)
     640px  phones        — dropdowns become bottom sheets, sidebar grids collapse
     880px  the fold      — EVERY two-column layout becomes one column
     1180px wide desktop  — the chat sidebar narrows

   Rules that use them:
   - `any-pointer: coarse` (never bare `pointer`) for tap targets. A touchscreen
     laptop with a trackpad reports `pointer: fine`, so a `pointer: coarse` rule
     silently never fires on it and 44px targets collapse back to their icon
     size. Reserve bare `pointer: fine` for hover styling only.
   - Fixed pixel widths on popovers go through min(), e.g.
     min(300px, calc(100vw - 2 * var(--sp-6))) — a literal min-width is an
     overflow at 320px.
   ========================================================================== */

/* ============ fonts (self-hosted, OFL — static/fonts/LICENSE-geist*.txt) ==== */

@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-latin.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-vietnamese.woff2") format("woff2-variations");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9,
    U+20AB;
}
@font-face {
  font-family: "Geist Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-latin-ext.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-latin.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-vietnamese.woff2") format("woff2-variations");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1,
    U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9,
    U+20AB;
}
@font-face {
  font-family: "Geist Mono Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/chat/fonts/geist-mono-latin-ext.woff2") format("woff2-variations");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============ scales (theme-independent) ============ */
:root {
  /* type — every step carries its own tracking + leading */
  --fs-display: 46px;   --lh-display: 1.01;  --tr-display: -0.04em;
  --fs-h1: 30px;        --lh-h1: 1.1;        --tr-h1: -0.03em;
  --fs-h2: 20px;        --lh-h2: 1.2;        --tr-h2: -0.025em;
  --fs-lg: 17px;        --lh-lg: 1.25;       --tr-lg: -0.02em;
  --fs-h3: 15.5px;      --lh-h3: 1.3;        --tr-h3: -0.015em;
  --fs-h4: 13.5px;      --lh-h4: 1.4;
  --fs-body: 15px;      --lh-body: 1.6;      --tr-body: 0;
  --fs-sm: 13.5px;      --lh-sm: 1.5;
  --fs-xs: 12px;        --lh-xs: 1.45;
  --fs-micro: 11px;     --lh-micro: 1.4;     --tr-micro: 0.02em;
  --fs-label: 10.5px;                        --tr-label: 0.09em;
  --fs-nano: 9.5px;                          /* uppercase status pills only */
  --lh-code: 1.65;      /* code blocks want more air than prose */
  --tr-badge: 0.04em;   /* uppercase mono verb badges */
  --wt-regular: 400; --wt-medium: 500; --wt-semi: 600; --wt-bold: 700;
  --measure: 65ch;
  --measure-tight: 56ch;      /* deck copy / subtitles */

  /* spacing — 4px base, plus two named optical half-steps so the
     sub-4px values stop being sprinkled as literals */
  --sp-05: 2px; --sp-1-5: 6px; --sp-2-5: 10px; --sp-3-5: 14px;
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px; --sp-5: 20px;
  --sp-6: 24px; --sp-8: 32px; --sp-10: 40px; --sp-12: 48px;   --sp-16: 64px;
  --sp-18: 72px;
  --sp-20: 80px;
  --content-w: 800px;
  --doc-w: 900px;
  --landing-w: 1080px;
  --sidebar-w: 264px;
  --rail-w: 172px;            /* docs table-of-contents rail */
  --modal-w: 460px;           /* consent gate / single-column dialogs */
  --modal-w-lg: 560px;        /* two-column dialogs (profile, share, key reveal) */
  --tap: 44px;                /* WCAG 2.5.5 minimum touch target */

  /* safe-area — one definition for every sheet. env() resolves at the use
     site, so this is 0px on devices with no cutout and max() needs no
     fallback value. Any padding or offset that touches a screen edge must
     go through max(var(--sp-N), calc(var(--saX) + var(--sp-M))) — a bare
     var(--sp-N) clips under the notch / home indicator. */
  --sat: env(safe-area-inset-top);
  --sar: env(safe-area-inset-right);
  --sab: env(safe-area-inset-bottom);
  --sal: env(safe-area-inset-left);

  /* radius — --r-2xs is for hairline markers (scroll thumbs, 3px accent bars),
     not a general step. 50% circles stay literal. */
  --r-2xs: 2px;
  --r-xs: 5px; --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-xl: 22px; --r-pill: 999px;

  /* z-index — named layers. Toast sits above modals on purpose. */
  --z-rail: 5;                /* fixed ad rails hug the content layer */
  --z-anchor: 90;             /* mobile bottom ad — under the jump button */
  --z-interstitial: 650;      /* fullscreen landing ad — over modals, under consent */
  --z-inlayer: 1; --z-inlayer-top: 2; --z-jump: 100;
  --z-dropdown: 200;
  --z-scrim: 300;
  --z-sidebar: 310;
  --z-modal: 400;
  --z-lightbox: 500;
  --z-drop: 600;
  --z-toast: 700;
  --z-consent: 800;  /* first-visit privacy gate — above everything */
  --z-ambient: 2;   /* voice/call waveform, under messages so text stays readable */

  /* Voice-mode ambient: the waveform draws the two sides of the conversation
     in different colours — mic input vs the AI reading its reply back.
     These MUST be literal colours, not var() chains: app.js reads them with
     getComputedStyle and hands the string straight to ctx.fillStyle, which
     does not resolve custom properties. */
  --ambient-user: #d97757;
  --ambient-ai: #46a758;
  --ambient-idle: transparent;

  /* motion — three interaction speeds plus two entrance speeds. Entrances are
     deliberately slower than any hover/press: they play once, on arrival. */
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --dur-fast: 0.12s;
  --dur: 0.18s;
  --dur-slow: 0.28s;
  --dur-reveal: 0.5s;         /* scroll-reveal fade + rise */
  --dur-enter: 0.8s;          /* first-paint hero entrance */
  --stagger-step: 0.08s;      /* multiplied by index for sequenced reveals */

  /* typefaces */
  --font: "Geist Variable", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --mono: "Geist Mono Variable", ui-monospace, "Cascadia Mono", "SF Mono", Consolas, monospace;
}

/* ============ theme: warm (default) ============ */
:root,
body[data-theme="warm"] {
  --bg: #1d1d1b;
  --bg-elev: #242422;
  --bg-elev-2: #2b2b29;
  --bg-hover: #2e2e2c;
  --border: #343432;
  --border-strong: #42423f;
  --text: #f0efec;
  --text-dim: #a9a7a0;
  --text-faint: #949188;
  --accent: #d97757;
  --accent-strong: #e08667;
  --accent-rgb: 217 119 87;
  --accent-soft: rgb(var(--accent-rgb) / 0.12);
  --accent-faint: rgb(var(--accent-rgb) / 0.04);
  --accent-border: rgb(var(--accent-rgb) / 0.28);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.55);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #2a2a27;
  --ok: #46a758;
  --ok-rgb: 70 167 88;
  --warn: #f5a524;
  --warn-rgb: 245 165 36;
  --err: #e5484d;
  --err-strong: #ff6369;
  --err-rgb: 229 72 77;
  --err-soft: rgb(var(--err-rgb) / 0.12);
  --err-border: rgb(var(--err-rgb) / 0.5);
  --err-bubble: rgb(var(--err-rgb) / 0.06);
  --err-bubble-border: rgb(var(--err-rgb) / 0.3);
  --err-code-bg: rgb(var(--err-rgb) / 0.12);
  --code-bg: #1a1a18;
  --code-head-bg: #1f1f1d;
  --code-inline-bg: rgb(255 255 255 / 0.06);
  --code-btn-hover: #55554f;
  --scroll-thumb: #3a3a37;
  --scroll-thumb-hover: #4a4a46;
  --btn-disabled-bg: #3a3a37;
  --on-accent: #1d1d1b;
  --logo-plate: #f2f1ee;
  --logo-plate-dark: #1d1d1b;
  --lb-bg: rgb(12 10 8 / 0.93);
  --scrim: rgb(12 10 8 / 0.6);
  --shadow-rgb: 20 16 12;
}

/* HTTP verb colours — one set per theme so the docs badges stay legible.
   Dark themes share a palette; `paper` overrides it below. */
:root,
body[data-theme="warm"],
body[data-theme="midnight"],
body[data-theme="amoled"] {
  --verb-get: #6fc276;         --verb-get-border: #2f5a36;    --verb-get-bg: rgb(111 194 118 / 0.08);
  --verb-post: #e8a85f;        --verb-post-border: #6b4a20;   --verb-post-bg: rgb(232 168 95 / 0.08);
  --verb-put: #c79ae8;         --verb-put-border: #4d2f6b;    --verb-put-bg: rgb(199 154 232 / 0.08);
  --verb-patch: #7fb0e8;       --verb-patch-border: #274a75;  --verb-patch-bg: rgb(127 176 232 / 0.08);
  --verb-delete: #e87a7f;      --verb-delete-border: #6b272b; --verb-delete-bg: rgb(232 122 127 / 0.08);
}

/* ============ theme: midnight (cool dark) ============ */
body[data-theme="midnight"] {
  --bg: #0f1216;
  --bg-elev: #151a20;
  --bg-elev-2: #1b2128;
  --bg-hover: #1e252d;
  --border: #232b34;
  --border-strong: #2e3945;
  --text: #e8ecf1;
  --text-dim: #9aa7b4;
  --text-faint: #8896a4;
  --accent: #4c9eea;
  --ambient-user: #4c9eea;
  --ambient-ai: #46a758;
  --accent-strong: #6fb3f2;
  --accent-rgb: 76 158 234;
  --accent-soft: rgb(var(--accent-rgb) / 0.14);
  --accent-faint: rgb(var(--accent-rgb) / 0.05);
  --accent-border: rgb(var(--accent-rgb) / 0.32);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.6);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #1a2027;
  --err-strong: #ff6369;
  --err-soft: rgb(var(--err-rgb) / 0.14);
  --err-bubble: rgb(var(--err-rgb) / 0.07);
  --err-bubble-border: rgb(var(--err-rgb) / 0.35);
  --err-code-bg: rgb(var(--err-rgb) / 0.14);
  --code-bg: #0b0e12;
  --code-head-bg: #11151a;
  --code-inline-bg: rgb(255 255 255 / 0.07);
  --code-btn-hover: #3d4a58;
  --scroll-thumb: #2a3440;
  --scroll-thumb-hover: #3a4755;
  --btn-disabled-bg: #262f39;
  --on-accent: #0b1117;
  --lb-bg: rgb(4 8 14 / 0.93);
  --scrim: rgb(4 8 14 / 0.62);
  --shadow-rgb: 4 8 14;
}

/* ============ theme: amoled (pure black) ============ */
body[data-theme="amoled"] {
  --bg: #000000;
  --bg-elev: #0a0a0a;
  --bg-elev-2: #141414;
  --bg-hover: #181818;
  --border: #1c1c1c;
  --border-strong: #2a2a2a;
  --text: #f2f2f2;
  --text-dim: #9b9b9b;
  /* #7f7f7f sat at 4.35:1 over the composer's own surface (#1a1a18), under
     the 4.5 WCAG AA floor for 11px text. #8a8a8a clears it at 5.05:1 and
     still reads fainter than --text-dim, so the hierarchy holds. */
  --text-faint: #8a8a8a;
  --accent: #d97757;
  --ambient-user: #d97757;
  --ambient-ai: #46a758;
  --accent-strong: #e08667;
  --accent-soft: rgb(var(--accent-rgb) / 0.14);
  --accent-faint: rgb(var(--accent-rgb) / 0.05);
  --accent-border: rgb(var(--accent-rgb) / 0.3);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.6);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #101010;
  --err-strong: #ff6369;
  --err-soft: rgb(var(--err-rgb) / 0.15);
  --err-bubble: rgb(var(--err-rgb) / 0.08);
  --err-bubble-border: rgb(var(--err-rgb) / 0.4);
  --err-code-bg: rgb(var(--err-rgb) / 0.16);
  --code-bg: #080808;
  --code-head-bg: #101010;
  --code-inline-bg: rgb(255 255 255 / 0.08);
  --code-btn-hover: #3a3a3a;
  --scroll-thumb: #222222;
  --scroll-thumb-hover: #333333;
  --btn-disabled-bg: #1e1e1e;
  --on-accent: #000000;
  --lb-bg: rgb(0 0 0 / 0.95);
  --scrim: rgb(0 0 0 / 0.7);
  --shadow-rgb: 0 0 0;
}

/* ============ theme: paper (light) ============
   Light done as a real composition, not an inverted dark: a deeper cream
   stage so warm-white surfaces genuinely elevate, one saturated rust accent,
   borders with actual presence, and shadows tinted warm-dark instead of grey. */
body[data-theme="paper"] {
  --bg: #f4f1ea;
  --bg-elev: #fffefb;
  --bg-elev-2: #ebe6dc;
  --bg-hover: #f0ece4;
  --border: #d9d2c4;
  --border-strong: #beb5a2;
  --text: #211e19;
  --text-dim: #5a554a;
  --text-faint: #6f6a5e;
  --accent: #bf4d26;
  --ambient-user: #bf4d26;
  --ambient-ai: #2f9e44;
  --accent-strong: #a63e1c;
  --accent-rgb: 191 77 38;
  --accent-soft: rgb(var(--accent-rgb) / 0.1);
  --accent-faint: rgb(var(--accent-rgb) / 0.04);
  --accent-border: rgb(var(--accent-rgb) / 0.25);
  --accent-border-strong: rgb(var(--accent-rgb) / 0.5);
  --accent-focus-ring: rgb(var(--accent-rgb) / 0.28);
  --user-bg: #eae4d8;
  --ok: #2f9e44;
  --ok-rgb: 47 158 68;
  --warn: #b45309;
  --warn-rgb: 180 83 9;
  --err: #dc2626;
  --err-strong: #b91c1c;
  --err-rgb: 220 38 38;
  --err-soft: rgb(var(--err-rgb) / 0.1);
  --err-border: rgb(var(--err-rgb) / 0.45);
  --err-bubble: rgb(var(--err-rgb) / 0.05);
  --err-bubble-border: rgb(var(--err-rgb) / 0.3);
  --err-code-bg: rgb(var(--err-rgb) / 0.1);
  --code-bg: #eeeae1;
  --code-head-bg: #e6e1d5;
  --code-inline-bg: rgb(0 0 0 / 0.06);
  --code-btn-hover: #d6cfbf;
  --scroll-thumb: #c4bcae;
  --scroll-thumb-hover: #ada492;
  --btn-disabled-bg: #ded7c9;
  --on-accent: #ffffff;
  --logo-plate: #e9e6e1;
  --logo-plate-dark: #26241f;
  --lb-bg: rgb(31 30 28 / 0.9);
  --scrim: rgb(60 48 38 / 0.42);
  --shadow-rgb: 74 62 45;

  /* Glass needs near-opaque surfaces in light mode — the translucent recipe
     tuned for dark themes reads as a smudge over cream. */
  --glass-bg: color-mix(in srgb, var(--bg-elev) 90%, transparent);

  --verb-get: #1a6b33;    --verb-get-border: #a8d4b2;    --verb-get-bg: rgb(26 107 51 / 0.07);
  --verb-post: #8a4c07;   --verb-post-border: #e0c193;   --verb-post-bg: rgb(138 76 7 / 0.07);
  --verb-put: #5b2d82;    --verb-put-border: #d0b8e4;    --verb-put-bg: rgb(91 45 130 / 0.07);
  --verb-patch: #16457f;  --verb-patch-border: #a9c6e6;  --verb-patch-bg: rgb(22 69 127 / 0.07);
  --verb-delete: #9b1c1c; --verb-delete-border: #e5b4b4; --verb-delete-bg: rgb(155 28 28 / 0.07);
}

/* ============ elevation — shadows tinted by the theme's own hue ============ */
:root {
  --e1: 0 1px 2px rgb(var(--shadow-rgb) / 0.18);
  --e2: 0 4px 12px rgb(var(--shadow-rgb) / 0.22), 0 1px 2px rgb(var(--shadow-rgb) / 0.16);
  --e3: 0 12px 32px rgb(var(--shadow-rgb) / 0.32), 0 2px 6px rgb(var(--shadow-rgb) / 0.2);
  --e4: 0 20px 48px rgb(var(--shadow-rgb) / 0.4), 0 4px 12px rgb(var(--shadow-rgb) / 0.24);
  /* glassmorphism */
  --glass-bg: color-mix(in srgb, var(--bg-elev) 72%, transparent);
  --glass-border: color-mix(in srgb, var(--border-strong) 60%, transparent);
  --glass-blur: 14px;
  /* Lightbox chrome always sits on the dark --lb-bg scrim, so its buttons are
     white-on-dark in every theme. Declared once instead of per rule. */
  --lb-chrome-bg: rgb(255 255 255 / 0.06);
  --lb-chrome-bg-hover: rgb(255 255 255 / 0.16);
  --lb-chrome-border: rgb(255 255 255 / 0.2);
  --lb-chrome-fg: #fff;
  --lb-chrome-dim: rgb(255 255 255 / 0.7);
  --lb-count-bg: rgb(0 0 0 / 0.4);
  /* Composer geometry, published so the jump button and toast can sit above it
     without re-encoding its rendered height. */
  --composer-h: 88px;
  /* Fixed brand colours — Discord's own palette, identical in every theme, and
     the white that saturated fills (error badges, generated avatars) need
     regardless of the surface under them. */
  --discord: #5865F2;
  --discord-strong: #4752C4;
  --discord-rgb: 88 101 242;
  --on-solid: #fff;
}

/* ============ base reset ============ */
* { box-sizing: border-box; }

::selection { background: var(--accent-soft); color: var(--text); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: var(--r-xs); border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); }
::-webkit-scrollbar-track { background: transparent; }

/* text-size-adjust:100 stops iOS from auto-inflating the root font size when
   a phone rotates to landscape. Without it .main { height: var(--app-h) } and
   the composer stop matching the viewport and the layout overflows sideways. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ============ utility: monospace ============
   Was defined only as `.tbl .mono` / `.model-row .mono` inside admin.html, so
   the same class silently did nothing outside those two scopes. */
.mono { font-family: var(--mono); }

/* ============ utility: screen-reader-only text ============ */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ============ utility: stagger delays for scroll reveals ============ */
/* Was six --stagger custom properties that nothing ever read. This version is
   a real utility: put .stagger on the container and its children sequence
   themselves off --stagger-step, so the rhythm lives in one token. */
.stagger > *:nth-child(1) { transition-delay: 0s; }
.stagger > *:nth-child(2) { transition-delay: calc(var(--stagger-step) * 1); }
.stagger > *:nth-child(3) { transition-delay: calc(var(--stagger-step) * 2); }
.stagger > *:nth-child(4) { transition-delay: calc(var(--stagger-step) * 3); }
.stagger > *:nth-child(5) { transition-delay: calc(var(--stagger-step) * 4); }
.stagger > *:nth-child(6) { transition-delay: calc(var(--stagger-step) * 5); }
.stagger > *:nth-child(7) { transition-delay: calc(var(--stagger-step) * 6); }
.stagger > *:nth-child(n + 8) { transition-delay: calc(var(--stagger-step) * 7); }

/* Single focus contract for the whole product. Never remove an outline
   without putting one back — five places used to do exactly that. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute; left: var(--sp-2); top: var(--sp-2);
  z-index: var(--z-toast);
  transform: translateY(-200%);
  background: var(--bg-elev-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-4);
  font: var(--wt-semi) var(--fs-sm) / 1 var(--font);
  text-decoration: none;
  transition: transform var(--dur) var(--ease);
}
.skip-link:focus-visible { transform: none; }

/* ============ grain overlay — breaks digital flatness, no external asset ==== */
.grain {
  position: fixed; inset: 0; z-index: 1;
  pointer-events: none; opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
body[data-theme="paper"] .grain { opacity: 0.03; mix-blend-mode: multiply; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
