/* =====================================================================
   nutrition-mcp.com — the site stylesheet

   Served at /styles.css and loaded by every public page: the landing page
   (scripts/gen-index.ts), /tools, /privacy, /terms, the /alternatives hub
   and comparison pages, and the OAuth login page. The header, sheet menu,
   consent banner and footer styled here are rendered by the shared
   nav()/footer() in scripts/site-partials.ts; site.js drives them.

   Direction: soft, rounded, glassy. Urbanist (500–800) for all text,
   Geist Mono for codes, counts and labels. Neutral blue-grey surfaces with
   a green accent, big radii (20–32px), a header made of two floating glass
   pills, and three blurred colour blobs drifting behind the top of each
   page. The nutrient palette (--cal --pro --car --fat --wat --fib --sug
   --caf) is the in-chat widgets' one.

   Theme: tokens live on <body>. With nothing saved the OS setting drives
   them through prefers-color-scheme ("System", stored as the ABSENCE of a
   localStorage key); the header's segmented control stamps
   data-theme="dark" | "light" on <body> (site.js, and THEME_PREPAINT in
   every page head before first paint) and that override wins. The dark
   palette is written out twice — once under the media query, once under
   the attribute — because CSS cannot name a declaration block and apply it
   from two selectors: a new colour lands in all three blocks.

   Layout of this file:
     1. tokens
     2. keyframes
     3. base, shared hooks, reveals
     4. background blobs
     5. header (two pills, nav, live badge, language, theme, Connect)
     6. sheet menu
     7. footer
     8. consent banner
     9. shared primitives (.nm-*) — the catalogue pages are built from
   Page-specific layout lives in each generator's inline <style> (the
   landing page's in scripts/landing-css.ts), built from these tokens and
   primitives; nothing here is scoped to a single page.
   ===================================================================== */

/* =====================================================================
   1. tokens
   ===================================================================== */
body {
    /* surfaces */
    --bg: #f7f7f9;
    --bg2: #eeeef3;
    --panel: #ffffff;
    --glass: rgba(255, 255, 255, 0.66);
    /* ink */
    --ink: #101318;
    --ink2: #4b5260;
    --ink3: #5f6673;
    /* hairlines */
    --line: #e3e4ea;
    --line2: #d2d4dd;
    /* accent. --acc fills (buttons, logo), --acc-txt is accent TEXT on a
       light surface (AA on --bg/--panel/--acc-soft), --acc-ink is text ON
       an --acc fill, --acc-on-dark is the accent on an ink/dark slab. */
    --acc: #15803d;
    --acc-txt: #166534;
    --acc-on-dark: #4ade80;
    --acc-ink: #ffffff;
    --acc-soft: #dcf5e4;
    --glow: rgba(34, 197, 94, 0.55);
    --track: #e8e9ee;
    /* nutrients (the widgets' palette) */
    --cal: #ff9f0a;
    --pro: #8b5cf6;
    --car: #10b981;
    --fat: #f43f7e;
    --wat: #0ea5e9;
    --fib: #0d9488;
    --sug: #84cc16;
    --caf: #a16207;
    /* drinks / fat gold, and the "Add to Claude" button (white label) */
    --gold: #d4a017;
    --claude: #b5532f;
    --claude-ink: #ffffff;
    /* Glyph grade of each nutrient: an icon tinted by its colour, kept
       ≥3:1 (WCAG 1.4.11) on that colour's own 14-18% tint and on every
       surface. The bright tokens above stay for fills, tints and blobs;
       light mode darkens the glyph along the same hue, dark mode can use
       the bright value as is. Icons only — text stays --ink / --acc-txt.
       --on-icon is a glyph sitting ON an --X-icon fill. */
    --cal-icon: #ae6a01;
    --pro-icon: #8454ee;
    --car-icon: #07885d;
    --fat-icon: #db206a;
    --wat-icon: #077eb3;
    --fib-icon: #078379;
    --sug-icon: #568803;
    --caf-icon: #a16207;
    --gold-icon: #9a7201;
    --on-icon: #ffffff;
    /* form-field outline: ≥3:1 on --bg (the field) and --panel (around it) */
    --field-line: #80868f;
    --shadow:
        0 1px 2px rgba(16, 19, 24, 0.04),
        0 30px 70px -30px rgba(16, 19, 24, 0.25);
    /* popover / menu shadow (language menu, docked consent) */
    --shadow-pop: 0 20px 40px -20px rgba(0, 0, 0, 0.35);
    /* closing-CTA ink slab: light inverts to ink; dark stays a panel */
    --cta-bg: #101318;
    --cta-ink: #f7f7f9;
    --tile: var(--panel);
    --pop: var(--acc);
    --pop-ink: var(--acc-ink);
    /* world map: timezone dots share the logo's accent green; land stays neutral
       so the figure out-contrasts the ground in both themes */
    --map-halo: var(--acc);
    --map-halo-op: 0.32;
    --map-halo-lo: 0.12;
    --map-halo-hi: 0.4;
    --map-core: var(--acc);
    --map-land: #b6bdb8;

    /* layout + type (theme-independent) */
    --container: 1160px;
    --gutter: clamp(16px, 4vw, 40px);
    --section-pad: clamp(40px, 6vw, 88px);
    /* sticky header height (14 + 52 + 14) plus breathing room: anchor
       jumps land below it (html scroll-padding-top). */
    --head-h: 90px;
    --font:
        "Urbanist", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
        "Noto Sans", sans-serif;
    --mono:
        "Geist Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    color-scheme: light;
}

/* Script fonts. Urbanist is Latin-only. /uk chains Mulish after it (loaded
   only on that page — localeFontLinks() in scripts/site-partials.ts): Latin
   runs stay Urbanist, Cyrillic glyphs come from Mulish, and Geist Mono has
   Cyrillic already. /ja downloads nothing extra: Latin runs stay Urbanist /
   Geist Mono and kana/kanji fall through to the best system Japanese font
   (Hiragino on Apple, Yu Gothic / Meiryo on Windows, Noto CJK on Linux and
   Android), named before system-ui so a non-Japanese OS locale still picks a
   Japanese face rather than a Chinese one.
   Scoped to `html[lang] body`, not `html[lang]`: the token block above
   declares --font/--mono on body itself, which would shadow a value body
   only inherited from html. */
html[lang="uk"] body {
    --font:
        "Urbanist", "Mulish", system-ui, -apple-system, BlinkMacSystemFont,
        "Segoe UI", "Noto Sans", sans-serif;
}
html[lang="ja"] body {
    --font:
        "Urbanist", "Hiragino Sans", "Hiragino Kaku Gothic ProN",
        "Yu Gothic UI", "Yu Gothic", YuGothic, Meiryo, "Noto Sans JP",
        "Noto Sans CJK JP", system-ui, sans-serif;
    --mono:
        "Geist Mono", "Hiragino Sans", "Hiragino Kaku Gothic ProN",
        "Yu Gothic UI", "Yu Gothic", YuGothic, Meiryo, "Noto Sans JP",
        "Noto Sans CJK JP", ui-monospace, SFMono-Regular, "SF Mono", Menlo,
        monospace;
}
/* Japanese has no spaces, so headings wrap per character and can split a
   word (できる at 390px on /ja/tools). `auto-phrase` (Chrome/Edge 119+) breaks
   at phrase boundaries; browsers without it drop the declaration and keep
   `normal`, which never breaks inside a Latin word. `line-break: strict`
   additionally keeps small kana and prolonged-sound marks off a line start. */
html[lang="ja"] :is(h1, h2, h3, .nm-h1) {
    word-break: normal;
    word-break: auto-phrase;
    line-break: strict;
}

/* Dark palette — copy 1 of 2, the OS path. */
@media (prefers-color-scheme: dark) {
    body:not([data-theme="light"]) {
        --bg: #0b0d12;
        --bg2: #12151c;
        --panel: #161a22;
        --glass: rgba(22, 26, 34, 0.66);
        --ink: #f2f3f6;
        --ink2: #b4bac6;
        --ink3: #8b92a1;
        --line: #232833;
        --line2: #2f3542;
        --acc: #4ade80;
        --acc-txt: #4ade80;
        --acc-on-dark: #4ade80;
        --acc-ink: #062a14;
        --acc-soft: #14301f;
        --glow: rgba(74, 222, 128, 0.55);
        --track: #242935;
        --cal: #ffab2e;
        --pro: #a78bfa;
        --car: #34d399;
        --fat: #fb7199;
        --wat: #38bdf8;
        --fib: #14b8a6;
        --sug: #a3e635;
        --caf: #d4a56a;
        --gold: #e0b43a;
        --claude: #b5532f;
        --claude-ink: #ffffff;
        --cal-icon: #ffab2e;
        --pro-icon: #a78bfa;
        --car-icon: #34d399;
        --fat-icon: #fb7199;
        --wat-icon: #38bdf8;
        --fib-icon: #14b8a6;
        --sug-icon: #a3e635;
        --caf-icon: #d4a56a;
        --gold-icon: #e0b43a;
        --on-icon: #0b0d12;
        --field-line: #69717f;
        --shadow:
            0 1px 2px rgba(0, 0, 0, 0.4), 0 30px 70px -30px rgba(0, 0, 0, 0.8);
        --shadow-pop: 0 20px 40px -20px rgba(0, 0, 0, 0.7);
        --cta-bg: #161a22;
        --cta-ink: #f2f3f6;
        --map-halo: var(--acc);
        --map-halo-op: 0.55;
        --map-halo-lo: 0.28;
        --map-halo-hi: 0.75;
        --map-core: var(--acc);
        --map-land: #3a463f;
        color-scheme: dark;
    }
}
/* Dark palette — copy 2 of 2, the explicit toggle. Keep identical. */
body[data-theme="dark"] {
    --bg: #0b0d12;
    --bg2: #12151c;
    --panel: #161a22;
    --glass: rgba(22, 26, 34, 0.66);
    --ink: #f2f3f6;
    --ink2: #b4bac6;
    --ink3: #8b92a1;
    --line: #232833;
    --line2: #2f3542;
    --acc: #4ade80;
    --acc-txt: #4ade80;
    --acc-on-dark: #4ade80;
    --acc-ink: #062a14;
    --acc-soft: #14301f;
    --glow: rgba(74, 222, 128, 0.55);
    --track: #242935;
    --cal: #ffab2e;
    --pro: #a78bfa;
    --car: #34d399;
    --fat: #fb7199;
    --wat: #38bdf8;
    --fib: #14b8a6;
    --sug: #a3e635;
    --caf: #d4a56a;
    --gold: #e0b43a;
    --claude: #b5532f;
    --claude-ink: #ffffff;
    --cal-icon: #ffab2e;
    --pro-icon: #a78bfa;
    --car-icon: #34d399;
    --fat-icon: #fb7199;
    --wat-icon: #38bdf8;
    --fib-icon: #14b8a6;
    --sug-icon: #a3e635;
    --caf-icon: #d4a56a;
    --gold-icon: #e0b43a;
    --on-icon: #0b0d12;
    --field-line: #69717f;
    --shadow:
        0 1px 2px rgba(0, 0, 0, 0.4), 0 30px 70px -30px rgba(0, 0, 0, 0.8);
    --shadow-pop: 0 20px 40px -20px rgba(0, 0, 0, 0.7);
    --cta-bg: #161a22;
    --cta-ink: #f2f3f6;
    --map-halo: var(--acc);
    --map-halo-op: 0.55;
    --map-halo-lo: 0.28;
    --map-halo-hi: 0.75;
    --map-core: var(--acc);
    --map-land: #3a463f;
    color-scheme: dark;
}

/* =====================================================================
   2. keyframes (names as in the design)
   ===================================================================== */
@keyframes nm-blink {
    0%,
    49% {
        opacity: 1;
    }
    50%,
    100% {
        opacity: 0;
    }
}
@keyframes nm-rise {
    from {
        opacity: 0;
        transform: translateY(14px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}
@keyframes nm-dot {
    0%,
    80%,
    100% {
        transform: translateY(0);
        opacity: 0.5;
    }
    40% {
        transform: translateY(-4px);
        opacity: 1;
    }
}
@keyframes nm-pulse {
    0%,
    100% {
        box-shadow: 0 0 0 0 var(--glow);
    }
    70% {
        box-shadow: 0 0 0 9px transparent;
    }
}
@keyframes nm-drift {
    0%,
    100% {
        transform: translate(0, 0);
    }
    50% {
        transform: translate(24px, -20px);
    }
}
@keyframes nm-tzpulse {
    0%,
    100% {
        opacity: var(--map-halo-lo);
        transform: scale(0.8);
    }
    50% {
        opacity: var(--map-halo-hi);
        transform: scale(1.6);
    }
}
@keyframes nm-ring {
    from {
        stroke-dashoffset: 37.7;
    }
    to {
        stroke-dashoffset: 0;
    }
}
@keyframes nm-msg {
    from {
        opacity: 0;
        transform: translateY(16px) scale(0.98);
        filter: blur(3px);
    }
    60% {
        filter: blur(0);
    }
    to {
        opacity: 1;
        transform: none;
        filter: none;
    }
}
@keyframes nm-chipup {
    0% {
        transform: translateY(10px);
        opacity: 0;
    }
    100% {
        transform: none;
        opacity: 1;
    }
}
@keyframes nm-chip {
    0% {
        transform: scale(0.6);
        opacity: 0;
    }
    40% {
        transform: scale(1.15);
        opacity: 1;
    }
    100% {
        transform: scale(1);
    }
}
@keyframes nm-arrive {
    0%,
    60% {
        box-shadow:
            0 0 0 3px color-mix(in srgb, var(--acc) 60%, transparent),
            0 0 0 12px color-mix(in srgb, var(--acc) 18%, transparent),
            var(--shadow);
    }
    100% {
        box-shadow:
            0 0 0 3px color-mix(in srgb, var(--acc) 30%, transparent),
            0 0 0 12px transparent,
            var(--shadow);
    }
}

/* =====================================================================
   3. base, shared hooks, reveals
   ===================================================================== */
*,
*::before,
*::after {
    box-sizing: border-box;
}
html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    /* Anchor jumps (#install, /tools#wrong-day) land below the sticky
       header instead of under it. */
    scroll-padding-top: var(--head-h, 90px);
}
html,
body {
    margin: 0;
    padding: 0;
}
body {
    position: relative;
    min-height: 100vh;
    /* clip, not hidden: hidden would make <body> the scroll container and
       break position: sticky on the header. The blobs are what would
       otherwise poke out sideways. */
    overflow-x: clip;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font);
    font-size: 17px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}
/* Element defaults at zero specificity, so any single class wins. */
:where(h1, h2, h3, h4, p, ol, ul, pre, figure, blockquote) {
    margin: 0;
}
:where(img, svg) {
    max-width: 100%;
    display: block;
}
:where(a) {
    color: inherit;
    text-decoration: none;
}
:where(a):hover {
    color: var(--acc-txt);
}
:where(button) {
    font: inherit;
    color: inherit;
}
:where(code) {
    font-family: var(--mono);
}
::selection {
    background: color-mix(in srgb, var(--acc) 28%, transparent);
}
/* Wins over any display: set by a class — the sheet menu, the nav badge
   and the stars count all ship [hidden] and are un-hidden by script. */
[hidden] {
    display: none !important;
}
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--acc);
    outline-offset: 3px;
}
main,
.footer {
    position: relative;
    z-index: 1;
}
/* Phones: no visible page scrollbar (design). Touch devices overlay it
   anyway; this only matters for a narrow desktop window. */
@media (max-width: 699px) {
    html {
        scrollbar-width: none;
    }
    html::-webkit-scrollbar,
    body::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
    }
}

.vh {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}
/* Skip link: the first tab stop on every page. */
.skip {
    position: fixed;
    top: 10px;
    left: 16px;
    z-index: 100;
    padding: 10px 16px;
    background: var(--ink);
    color: var(--bg);
    border-radius: 999px;
    font-weight: 700;
    transform: translateY(-200%);
    transition: transform 0.2s var(--ease-out);
}
.skip:focus-visible {
    transform: none;
    color: var(--bg);
}

/* [data-reveal] elements start hidden only once site.js has confirmed it
   is running (html.js) — without script nothing is ever hidden. */
html.js [data-reveal] {
    opacity: 0;
    transform: translateY(18px);
    transition:
        opacity 0.7s ease,
        transform 0.8s var(--ease-out);
}
html.js [data-reveal].in {
    opacity: 1;
    transform: none;
}
html.js [data-reveal="stagger"] {
    opacity: 1;
    transform: none;
}
html.js [data-reveal="stagger"] > * {
    opacity: 0;
    transform: translateY(14px);
    transition:
        opacity 0.6s ease,
        transform 0.7s var(--ease-out);
}
html.js [data-reveal="stagger"].in > * {
    opacity: 1;
    transform: none;
}
html.js [data-reveal="stagger"].in > :nth-child(2) {
    transition-delay: 0.08s;
}
html.js [data-reveal="stagger"].in > :nth-child(3) {
    transition-delay: 0.16s;
}
html.js [data-reveal="stagger"].in > :nth-child(4) {
    transition-delay: 0.24s;
}
html.js [data-reveal="stagger"].in > :nth-child(5) {
    transition-delay: 0.32s;
}
html.js [data-reveal="stagger"].in > :nth-child(6) {
    transition-delay: 0.4s;
}
html.js [data-reveal="stagger"].in > :nth-child(n + 7) {
    transition-delay: 0.48s;
}

/* The "this page is machine-translated" disclosure (translationNotice()
   in site-partials.ts): neutral, not accent-branded — a disclosure, not an
   action. .translation-notice-band wraps it where it sits between two
   full-bleed sections (the landing page). */
.translation-notice {
    padding: 12px 18px;
    border-radius: 18px;
    background: var(--bg2);
    border: 1px solid var(--line);
}
.translation-notice p {
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--ink2);
}
.translation-notice a {
    color: var(--acc-txt);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
    white-space: nowrap;
}
.translation-notice-band {
    position: relative;
    z-index: 1;
    max-width: var(--container);
    margin: 0 auto;
    padding: 0 var(--gutter) clamp(24px, 4vw, 40px);
}

/* =====================================================================
   4. background blobs — blobs() in site-partials.ts, emitted by nav()
   ===================================================================== */
.nm-blobs {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: var(--blobs-h, 1100px);
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
}
.nm-blobs span {
    position: absolute;
    border-radius: 50%;
    filter: blur(120px);
}
.nm-blobs .b1 {
    left: 8%;
    top: -160px;
    width: 620px;
    height: 620px;
    background: var(--car);
    opacity: 0.16;
    animation: nm-drift 16s ease-in-out infinite;
}
.nm-blobs .b2 {
    right: 4%;
    top: -120px;
    width: 560px;
    height: 560px;
    background: var(--pro);
    opacity: 0.14;
    animation: nm-drift 20s 2s ease-in-out infinite reverse;
}
.nm-blobs .b3 {
    left: 38%;
    top: 420px;
    width: 520px;
    height: 520px;
    background: var(--cal);
    opacity: 0.12;
    animation: nm-drift 18s 1s ease-in-out infinite;
}
.nm-blobs::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, transparent 60%, var(--bg));
}
/* The shorter, fainter set /tools, /alternatives and login use (blobs("compact")). */
.nm-blobs-compact {
    height: var(--blobs-h, 900px);
}
.nm-blobs-compact .b1 {
    left: 4%;
    top: -180px;
    width: 560px;
    height: 560px;
    opacity: 0.15;
}
.nm-blobs-compact .b2 {
    right: 6%;
    top: -140px;
    width: 520px;
    height: 520px;
    opacity: 0.13;
}
.nm-blobs-compact .b3 {
    left: 42%;
    top: 300px;
    width: 460px;
    height: 460px;
    opacity: 0.1;
}
.nm-blobs-compact::after {
    background: linear-gradient(to bottom, transparent 55%, var(--bg));
}

/* =====================================================================
   5. header — two glass pills (nav() in site-partials.ts)
   ===================================================================== */
.site-head {
    position: sticky;
    top: 0;
    z-index: 20;
    padding: 14px var(--gutter);
}
.head-inner {
    max-width: var(--container);
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
}
.head-bar,
.head-tools {
    height: 52px;
    display: flex;
    align-items: center;
    background: var(--glass);
    -webkit-backdrop-filter: blur(18px) saturate(160%);
    backdrop-filter: blur(18px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: var(--shadow);
}
.head-bar {
    flex: 1;
    min-width: 0;
    gap: 6px;
    padding: 0 10px 0 20px;
}
.head-tools {
    flex: none;
    gap: 4px;
    padding: 0 7px;
}
@media (max-width: 699px) {
    .head-tools {
        display: none;
    }
}

.brand {
    flex: none;
    display: flex;
    align-items: center;
    gap: 7px;
    font-weight: 800;
    font-size: 17px;
    letter-spacing: -0.02em;
    white-space: nowrap;
    color: var(--ink);
}
.brand:hover {
    color: var(--ink);
}
.nm-logo {
    display: block;
    flex: none;
    color: var(--acc);
}
.brand .nm-logo {
    width: 28px;
    height: 28px;
}

/* Primary nav. Hidden below 1060px (the hamburger takes over), and also
   above it whenever site.js finds it overflowing its pill (html.nav-tight:
   translated labels run long). */
.head-nav {
    position: relative;
    display: none;
    align-items: center;
    margin-left: auto;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
}
.head-nav::-webkit-scrollbar {
    display: none;
}
.head-nav a {
    position: relative;
    z-index: 1;
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 10px;
    border-radius: 999px;
    color: var(--ink2);
    transition: color 0.4s ease 0.05s;
}
.head-nav a:hover {
    color: var(--ink2);
    /* 0.85, not lower: --ink2 must stay ≥4.5:1 on the glass pill */
    opacity: 0.85;
}
.head-nav a.active,
.head-nav a[aria-current="page"] {
    color: var(--bg);
    opacity: 1;
}
/* The sliding ink pill. site.js sets --ind-x / --ind-w / --ind-o on
   .head-nav; .ind-ready (after the first placement) enables the slide. */
.nav-ind {
    position: absolute;
    left: 0;
    top: 50%;
    height: 32px;
    margin-top: -16px;
    width: var(--ind-w, 0px);
    transform: translateX(var(--ind-x, 0px));
    opacity: var(--ind-o, 0);
    border-radius: 999px;
    background: var(--ink);
    pointer-events: none;
}
.head-nav.ind-ready .nav-ind {
    transition:
        transform 0.55s var(--ease-out),
        width 0.55s var(--ease-out),
        opacity 0.35s ease;
}
/* Without script nothing positions the pill: the current page's link
   wears it statically. */
html:not(.js) .head-nav a[aria-current="page"] {
    background: var(--ink);
}

/* Live-stats badge: an inline "+N" pill after the label (the "+" is CSS so
   the digits stay plain). Painted by site.js; hidden at 0. */
.nav-badge {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border-radius: 999px;
    background: var(--acc-soft);
    color: var(--acc-txt);
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: 0;
}
.nav-badge-n::before {
    content: "+";
}
.nav-badge.capped .nav-badge-n::before {
    content: none;
}
.nav-badge.pop {
    animation: nm-chip 0.45s var(--ease-out);
}

/* Hamburger, at the right end of the left pill. */
.menu-btn {
    position: relative;
    flex: none;
    margin-left: auto;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    font-size: 17px;
    transition:
        background 0.25s,
        color 0.25s;
}
.menu-btn:hover {
    background: var(--bg2);
}
.menu-btn[aria-expanded="true"] {
    background: var(--ink);
    color: var(--bg);
}
.menu-btn .mb-close,
.menu-btn[aria-expanded="true"] .mb-open {
    display: none;
}
.menu-btn[aria-expanded="true"] .mb-close {
    display: inline;
}
/* The hamburger's decorative copy of the badge: a quiet dot (the count is
   read from the Live stats row inside the sheet). */
.menu-btn .nav-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
    background: var(--acc);
    box-shadow: 0 0 0 2px var(--panel);
}
.menu-btn .nav-badge-n::before {
    content: none;
}
.menu-btn[aria-expanded="true"] .nav-badge {
    display: none;
}

@media (min-width: 1060px) {
    .head-nav {
        display: flex;
    }
    .menu-btn {
        display: none;
    }
    html.nav-tight .head-nav {
        display: none;
    }
    html.nav-tight .menu-btn {
        display: grid;
    }
}

/* Right pill: GitHub, language, theme, Connect. */
.icon-btn {
    display: grid;
    place-items: center;
    flex: none;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    font-size: 17px;
    transition: background 0.2s;
}
.icon-btn:hover {
    background: var(--bg2);
    color: var(--ink);
}

.lang-switch {
    position: relative;
}
/* Also styles the login page's {{LANG_SWITCHER}}: renderLangSwitcher in
   src/oauth.ts emits the same icon + code summary and the same name/code
   menu items as nav(). */
.lang-switch summary {
    list-style: none;
    width: auto;
    height: 38px;
    padding: 0 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: 999px;
    color: var(--ink);
    cursor: pointer;
    font-family: var(--mono);
    font-size: 12px;
    user-select: none;
}
.lang-switch summary::-webkit-details-marker {
    display: none;
}
.lang-switch summary:hover,
.lang-switch[open] summary {
    background: var(--bg2);
}
.lang-switch summary .fa-language {
    font-size: 14px;
}
.lang-menu {
    position: absolute;
    right: 0;
    top: 46px;
    z-index: 45;
    min-width: 180px;
    padding: 6px;
    display: grid;
    gap: 2px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 20px;
    box-shadow: var(--shadow-pop);
    animation: nm-rise 0.2s both;
}
.lang-menu a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 8px 10px;
    border-radius: 12px;
    font-size: 14px;
    color: var(--ink);
}
.lang-menu a:hover,
.lang-menu a[aria-current="page"] {
    background: var(--bg2);
    color: var(--ink);
}
.lang-menu a[aria-current="page"] {
    font-weight: 700;
}
.lang-menu-code {
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink3);
}

/* Theme: a 3-button segmented group (System / Light / Dark). site.js keeps
   aria-pressed in sync on every [data-theme-set], here and in the sheet. */
.theme-seg {
    display: flex;
    gap: 2px;
    padding: 3px;
    background: var(--bg2);
    border-radius: 999px;
}
.theme-seg button {
    width: 28px;
    height: 28px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--ink2);
    cursor: pointer;
    font-size: 11px;
    transition:
        background 0.2s,
        color 0.2s;
}
.theme-seg button:hover {
    color: var(--ink);
}
.theme-seg button[aria-pressed="true"] {
    background: var(--ink);
    color: var(--bg);
}

.head-cta {
    flex: none;
    height: 38px;
    display: inline-flex;
    align-items: center;
    padding: 0 14px;
    background: var(--ink);
    color: var(--bg);
    border-radius: 999px;
    font-weight: 700;
    font-size: 14px;
    white-space: nowrap;
    transition:
        background 0.2s,
        color 0.2s;
}
.head-cta:hover {
    background: var(--acc);
    color: var(--acc-ink);
}

/* =====================================================================
   6. sheet menu — full screen, under the header (z 19 < 20) so the
      hamburger stays on top. site.js un-hides it, then sets data-open on
      the next frame so the transition runs; --menu-top is the header's
      offset when the consent banner pushes it down.
   ===================================================================== */
.site-menu {
    position: fixed;
    inset: 0;
    z-index: 19;
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding: calc(96px + var(--menu-top, 0px)) 20px
        calc(24px + env(safe-area-inset-bottom, 0px));
    background: var(--bg);
    overflow-y: auto;
    overscroll-behavior: contain;
    opacity: 0;
    transform: translateY(-12px);
    transition:
        opacity 0.25s ease,
        transform 0.35s var(--ease-out);
}
.site-menu[data-open] {
    opacity: 1;
    transform: none;
}
body.menu-open {
    overflow: hidden;
}
/* The banner sits above the header in the flow, so while the sheet is open
   it is taken out: otherwise the header (and the sheet's rows under it)
   would start below an invisible strip. The page behind shifts, unseen
   under the sheet, and comes back on close. */
body.menu-open .consent {
    display: none !important;
}
.menu-nav {
    display: grid;
}
.menu-nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 60px;
    border-bottom: 1px solid var(--line);
    font-size: 26px;
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.15;
    color: var(--ink);
}
.menu-nav a:hover,
.menu-nav a.active,
.menu-nav a[aria-current="page"] {
    color: var(--acc-txt);
}
.menu-nav a > span {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.menu-nav .fa-arrow-right {
    flex: none;
    font-size: 15px;
    color: var(--ink3);
}
.menu-nav .nav-badge {
    padding: 3px 9px;
    font-size: 13px;
    letter-spacing: 0;
}
.menu-group {
    display: grid;
    gap: 10px;
}
.menu-group-label {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink2);
}
.menu-langs {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
}
.menu-langs a {
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--line);
    border-radius: 14px;
    font-family: var(--mono);
    font-size: 14px;
    color: var(--ink);
}
.menu-langs a:hover {
    color: var(--ink);
    border-color: var(--line2);
}
.menu-langs a[aria-current="page"] {
    background: var(--bg2);
    border-color: var(--line2);
    font-weight: 600;
}
.menu-theme {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    padding: 4px;
    background: var(--bg2);
    border-radius: 999px;
}
.menu-theme button {
    height: 40px;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 8px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--ink2);
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.menu-theme button[aria-pressed="true"] {
    background: var(--ink);
    color: var(--bg);
}
.menu-foot {
    margin-top: auto;
    display: grid;
    gap: 10px;
}
.menu-gh {
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 1px solid var(--line2);
    border-radius: 999px;
    font-weight: 700;
    font-size: 16px;
    color: var(--ink);
}
.menu-gh:hover {
    color: var(--ink);
    background: var(--bg2);
}
.menu-gh .fa-github {
    font-size: 18px;
}
.menu-gh-stars {
    font-family: var(--mono);
    font-size: 13px;
    font-weight: 500;
    color: var(--ink2);
}
.menu-gh-stars .fa-star {
    font-size: 10px;
    margin-right: 4px;
}
.menu-cta {
    height: 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    background: var(--ink);
    color: var(--bg);
    border-radius: 999px;
    font-weight: 700;
    font-size: 17px;
}
.menu-cta:hover {
    color: var(--acc-ink);
    background: var(--acc);
}
.menu-cta .fa-arrow-right {
    font-size: 13px;
}

/* =====================================================================
   7. footer
   ===================================================================== */
.footer {
    border-top: 1px solid var(--line);
    background: var(--bg2);
}
.footer-inner {
    max-width: var(--container);
    margin: 0 auto;
    padding: clamp(32px, 4vw, 48px) var(--gutter);
    display: grid;
    gap: 22px;
}
.footer-top {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 18px;
}
.footer-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 800;
    font-size: 20px;
    letter-spacing: -0.02em;
    color: var(--ink);
}
.footer-brand:hover {
    color: var(--ink);
}
.footer-brand .nm-logo {
    width: 34px;
    height: 34px;
}
.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0 18px;
    font-size: 15px;
    font-weight: 600;
    color: var(--ink2);
}
.footer-links a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
}
.footer-links a:hover {
    color: var(--acc-txt);
}
.footer-links a[aria-current="page"] {
    color: var(--ink);
}
/* GitHub star count beside the footer's GitHub link (filled by site.js). */
.footer-stars {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 6px;
    font-family: var(--mono);
    font-size: 12.5px;
    font-weight: 500;
}
.footer-stars .fa-star {
    font-size: 10px;
}
/* "Cookie settings" is a <button> (it opens the consent banner, it goes
   nowhere) that must read as one more footer link. */
.footer-link-btn {
    -webkit-appearance: none;
    appearance: none;
    min-height: 40px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
}
.footer-link-btn:hover {
    color: var(--acc-txt);
}
.footer-note {
    margin: 0;
    padding-top: 18px;
    border-top: 1px solid var(--line);
    font-size: 13px;
    color: var(--ink3);
}

/* =====================================================================
   8. consent banner — a glass card in the flow above the header (nav()),
      docked to the bottom edge when reopened from the footer's "Cookie
      settings" (html[data-consent-reopen], site.js). Shown only while the
      head's loader has stamped html[data-consent="ask"], before first
      paint, so nothing shifts. Accept and Reject are deliberately the same
      button: equal weight, so neither choice is the easier one.
   ===================================================================== */
.consent {
    display: none;
    position: relative;
    z-index: 21;
    padding: 14px var(--gutter) 0;
}
html[data-consent="ask"] .consent:not([hidden]) {
    display: block;
}
.consent-inner {
    max-width: var(--container);
    margin: 0 auto;
    padding: 12px 12px 12px 22px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 20px;
    background: var(--glass);
    -webkit-backdrop-filter: blur(18px) saturate(160%);
    backdrop-filter: blur(18px) saturate(160%);
    border: 1px solid var(--line);
    border-radius: 28px;
    box-shadow: var(--shadow);
    font-size: 14px;
    line-height: 1.5;
    color: var(--ink2);
}
.consent-text {
    flex: 1 1 360px;
    margin: 0;
    text-wrap: pretty;
}
.consent-title {
    font-weight: 700;
    color: var(--ink);
}
.consent-text a {
    color: var(--acc-txt);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.consent-actions {
    flex: none;
    display: flex;
    gap: 8px;
}
.consent-btn {
    height: 38px;
    padding: 0 18px;
    border: 1px solid var(--line2);
    border-radius: 999px;
    background: transparent;
    color: var(--ink);
    cursor: pointer;
    font: inherit;
    font-weight: 700;
    white-space: nowrap;
    transition: background 0.2s;
}
.consent-btn:hover {
    background: var(--bg2);
}
@media (max-width: 559px) {
    .consent-inner {
        padding: 14px;
        border-radius: 22px;
    }
    .consent-actions {
        flex: 1 1 100%;
    }
    .consent-btn {
        flex: 1 1 0;
        min-width: 0;
    }
}
html[data-consent-reopen] .consent {
    position: fixed;
    left: 50%;
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
    transform: translateX(-50%);
    z-index: 40;
    width: min(1120px, calc(100vw - 32px));
    padding: 0;
}
html[data-consent-reopen] .consent-inner {
    padding: 14px 14px 14px 22px;
    box-shadow: var(--shadow), var(--shadow-pop);
    animation: nm-rise 0.3s both;
}
@media print {
    .consent {
        display: none !important;
    }
}

/* =====================================================================
   9. shared primitives (.nm-*) — build pages from these, not new CSS.
      Literal values are the design's.
   ===================================================================== */

/* ---- layout ---- */
/* .nm-section is width + gutters + the vertical rhythm. */
.nm-section {
    position: relative;
    z-index: 1;
    max-width: var(--container);
    margin: 0 auto;
    padding: var(--section-pad) var(--gutter);
}

/* ---- type ---- */
.nm-eyebrow {
    margin: 0 0 12px;
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--acc-txt);
}
/* Mono label (counts, codes, small captions). */
.nm-label-mono {
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    color: var(--ink3);
}
.nm-h1 {
    margin: 0;
    font-weight: 800;
    font-size: clamp(42px, 5.6vw, 78px);
    line-height: 1;
    letter-spacing: -0.045em;
    text-wrap: balance;
}
.nm-h2 {
    margin: 0;
    font-weight: 800;
    font-size: clamp(32px, 4.4vw, 58px);
    line-height: 1;
    letter-spacing: -0.04em;
    text-wrap: balance;
}
.nm-lead {
    margin: 0;
    max-width: 54ch;
    font-size: clamp(17px, 1.6vw, 20px);
    line-height: 1.55;
    color: var(--ink2);
    text-wrap: pretty;
}
.nm-sub {
    margin: 0;
    max-width: 44ch;
    color: var(--ink2);
    text-wrap: pretty;
}
/* Inline text link inside prose. */
.nm-link {
    color: var(--acc-txt);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.nm-link:hover {
    color: var(--acc-txt);
    text-decoration-thickness: 2px;
}

/* ---- surfaces ---- */
.nm-card {
    position: relative;
    background: var(--panel);
    border: 1px solid var(--line);
    border-radius: 28px;
    box-shadow: var(--shadow);
}
.nm-card-lg {
    border-radius: 32px;
}
/* The ink slab (closing CTA): reads --cta-bg / --cta-ink, not --ink/--bg,
   so dark mode gets a panel instead of a floodlight. */
.nm-ink {
    position: relative;
    overflow: hidden;
    background: var(--cta-bg);
    color: var(--cta-ink);
    border: 1px solid var(--line);
    border-radius: 32px;
}
.nm-ink .nm-eyebrow {
    color: var(--acc-on-dark);
}

/* ---- colour roles: one class sets --c (fills, tints, blobs) and --c-icon
   (the glyph drawn on that tint, see the *-icon tokens). Anything that sets
   --c inline sets --c-icon beside it. ---- */
.nm-c-acc {
    --c: var(--acc);
    --c-icon: var(--acc);
}
.nm-c-cal {
    --c: var(--cal);
    --c-icon: var(--cal-icon);
}
.nm-c-pro {
    --c: var(--pro);
    --c-icon: var(--pro-icon);
}
.nm-c-car {
    --c: var(--car);
    --c-icon: var(--car-icon);
}
.nm-c-fat {
    --c: var(--fat);
    --c-icon: var(--fat-icon);
}
.nm-c-wat {
    --c: var(--wat);
    --c-icon: var(--wat-icon);
}
.nm-c-fib {
    --c: var(--fib);
    --c-icon: var(--fib-icon);
}
.nm-c-sug {
    --c: var(--sug);
    --c-icon: var(--sug-icon);
}
.nm-c-caf {
    --c: var(--caf);
    --c-icon: var(--caf-icon);
}

/* Icon tile: a rounded square tinted by --c. */
.nm-tile {
    flex: none;
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    border-radius: 15px;
    background: color-mix(in srgb, var(--c, var(--acc)) 14%, var(--panel));
    color: var(--c-icon, var(--acc));
    font-size: 18px;
}
.nm-tile-md {
    width: 38px;
    height: 38px;
    border-radius: 12px;
    font-size: 15px;
}
/* Soft colour glow inside a card (position: relative + overflow: hidden
   on the card). */
.nm-blob {
    position: absolute;
    right: -60px;
    top: -60px;
    width: 200px;
    height: 200px;
    border-radius: 50%;
    background: var(--c, var(--acc));
    opacity: 0.14;
    filter: blur(50px);
    pointer-events: none;
}
/* A small colour dot (legend, list bullet). */
.nm-dot {
    display: inline-block;
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c, var(--acc));
}
/* "Live" dot that breathes. */
.nm-pulse-dot {
    display: inline-block;
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--acc);
    animation: nm-pulse 2s infinite;
}

/* ---- pills, chips, tags ---- */
/* Pill: a small rounded label (eyebrow chip above a hero title, counts). */
.nm-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 32px;
    padding: 0 14px;
    border-radius: 999px;
    background: var(--glass);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid var(--line);
    font-size: 13px;
    font-weight: 600;
    color: var(--ink2);
    white-space: nowrap;
}
/* Chip: a selectable filter/category pill (links or labels). */
.nm-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 38px;
    padding: 0 14px;
    border-radius: 999px;
    background: var(--panel);
    border: 1px solid var(--line);
    font-size: 14px;
    font-weight: 600;
    color: var(--ink);
    white-space: nowrap;
    cursor: pointer;
    transition:
        border-color 0.2s,
        background 0.2s,
        color 0.2s;
}
.nm-chip:hover {
    color: var(--ink);
    border-color: var(--line2);
}
.nm-chip[aria-current="true"],
.nm-chip[aria-pressed="true"],
.nm-chip.is-active,
input:checked + .nm-chip {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--bg);
}
/* Count inside a chip. */
.nm-chip-n {
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    color: var(--ink3);
}
.nm-chip[aria-current="true"] .nm-chip-n,
.nm-chip[aria-pressed="true"] .nm-chip-n,
.nm-chip.is-active .nm-chip-n,
input:checked + .nm-chip .nm-chip-n {
    color: inherit;
    opacity: 0.7;
}
/* Tag: tiny mono label (e.g. "read-only", "destructive"). */
.nm-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 22px;
    padding: 0 8px;
    border-radius: 999px;
    background: var(--bg2);
    font-family: var(--mono);
    font-size: 11px;
    font-weight: 500;
    color: var(--ink2);
    white-space: nowrap;
}
.nm-tag-acc {
    background: var(--acc-soft);
    color: var(--acc-txt);
}
/* GitHub star count inside a button (filled by the landing script). */
.nm-stars {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--bg2);
    font-family: var(--mono);
    font-size: 12.5px;
    font-weight: 500;
    color: var(--ink2);
}
.nm-stars i {
    font-size: 10px;
}

/* ---- buttons ---- */
.nm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 54px;
    max-width: 100%;
    padding: 0 26px;
    border: 0;
    border-radius: 999px;
    font: inherit;
    font-weight: 700;
    font-size: 16px;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition:
        background 0.2s,
        color 0.2s,
        border-color 0.2s,
        transform 0.2s,
        filter 0.2s;
}
.nm-btn:active {
    transform: translateY(1px);
}
.nm-btn i {
    font-size: 13px;
}
.nm-btn .fa-github {
    font-size: 18px;
}
/* Accent: the primary call to action, with the green glow. */
.nm-btn-acc {
    background: var(--acc);
    color: var(--acc-ink);
    box-shadow: 0 0 44px -6px var(--glow);
}
.nm-btn-acc:hover {
    color: var(--acc-ink);
    transform: translateY(-2px);
}
/* Ink: turns accent on hover (the header CTA's behaviour). */
.nm-btn-ink {
    background: var(--ink);
    color: var(--bg);
}
.nm-btn-ink:hover {
    background: var(--acc);
    color: var(--acc-ink);
}
/* Glass: secondary action floating over the blobs. */
.nm-btn-glass {
    background: var(--glass);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid var(--line);
    color: var(--ink);
    font-weight: 600;
}
.nm-btn-glass:hover {
    color: var(--ink);
    border-color: var(--line2);
}
/* Ghost: outline on the ink slab (.nm-ink). */
.nm-btn-ghost-dark {
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--cta-ink) 30%, transparent);
    color: var(--cta-ink);
    font-weight: 600;
}
.nm-btn-ghost-dark:hover {
    color: var(--cta-ink);
    border-color: var(--cta-ink);
}
.nm-btn-ghost-dark .nm-stars {
    padding: 0;
    background: transparent;
    color: inherit;
    opacity: 0.8;
}
/* Sizes: base 54px; lg 56. */
.nm-btn-lg {
    height: 56px;
    padding: 0 28px;
    font-size: 17px;
}
/* Phones: CTA buttons go full width (the design's `fw`). */
@media (max-width: 699px) {
    .nm-btn-fw {
        width: 100%;
    }
}
.nm-btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}
/* Round icon button (38px), e.g. a copy or pause control. */
.nm-icon-btn {
    flex: none;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--ink);
    color: var(--bg);
    cursor: pointer;
    font-size: 13px;
    transition:
        background 0.2s,
        color 0.2s;
}
.nm-icon-btn:hover {
    background: var(--acc);
    color: var(--acc-ink);
}
/* .copy-mini (site.js copies data-copy) gets .copied for 1.5s. */
.copy-mini.copied {
    background: var(--acc);
    color: var(--acc-ink);
}

/* ---- accordion (landing FAQ, /tools troubleshooting) ----
   Markup: <details class="nm-faq-row"><summary class="nm-faq-q">
   <span class="nm-faq-n">01</span><span>Question</span>
   <span class="nm-faq-ic"><i class="fa-solid fa-plus"></i></span>
   </summary><div class="nm-faq-a">…</div></details> */
.nm-faq {
    border-top: 1px solid var(--line);
}
.nm-faq-row {
    border-bottom: 1px solid var(--line);
}
.nm-faq-q {
    list-style: none;
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 16px;
    padding: 18px 4px;
    cursor: pointer;
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.3;
}
.nm-faq-q::-webkit-details-marker {
    display: none;
}
.nm-faq-q:hover {
    color: var(--acc-txt);
}
.nm-faq-n {
    font-family: var(--mono);
    font-size: 12px;
    font-weight: 500;
    color: var(--ink3);
}
.nm-faq-ic {
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--bg2);
    color: var(--ink);
    font-size: 12px;
    transition:
        background 0.2s,
        color 0.2s,
        transform 0.3s var(--ease-out);
}
.nm-faq-row[open] .nm-faq-ic {
    background: var(--ink);
    color: var(--bg);
    transform: rotate(45deg);
}
.nm-faq-a {
    padding: 0 4px 22px calc(4px + 2ch + 16px);
    color: var(--ink2);
    animation: nm-rise 0.3s both;
}
.nm-faq-a > * + * {
    margin-top: 10px;
}
.nm-faq-a a {
    color: var(--acc-txt);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
}
@media (max-width: 559px) {
    .nm-faq-q {
        font-size: 16px;
        gap: 12px;
    }
    .nm-faq-a {
        padding-left: 4px;
    }
}

/* ---- reduced motion ---- */
@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;
    }
    html.js [data-reveal],
    html.js [data-reveal="stagger"] > * {
        opacity: 1;
        transform: none;
    }
}
