:root {
    /* Measured, not guessed -- .site-header's real rendered height
       (34px logo + 22px/17px nav links + their padding). Every
       calc(100dvh - <header>) below must reference this, not a
       hardcoded number, or it silently drifts out of sync the next
       time header content changes. */
    --header-height: 99px;
    --black: #141414;
    --white: #FFFFFF;
    --smoke: #E7E7E7;
    --night: #141414;
    --focus: #137CEC;
    --black-a10: rgba(0, 0, 0, 0.02);
    --black-a9: rgba(0, 0, 0, 0.04);
    --black-a8: rgba(0, 0, 0, 0.06);
    --black-a7: rgba(0, 0, 0, 0.08);
    --black-a6: rgba(0, 0, 0, 0.1);
    --black-a5: rgba(0, 0, 0, 0.12);
    --black-a4: rgba(0, 0, 0, 0.14);
    --black-a3: rgba(0, 0, 0, 0.16);
    --black-a2: rgba(0, 0, 0, 0.2);
    --black-a1: rgba(0, 0, 0, 0.4);
    --black-a0: rgba(0, 0, 0, 0.45);
    --black-base: rgba(0, 0, 0, 0.5);
    --black-b0: rgba(0, 0, 0, 0.55);
    --black-b1: rgba(0, 0, 0, 0.6);
    --black-b2: rgba(0, 0, 0, 0.74);
    --black-b3: rgba(0, 0, 0, 0.77);
    --black-b4: rgba(0, 0, 0, 0.79);
    --black-b5: rgba(0, 0, 0, 0.81);
    --black-b6: rgba(0, 0, 0, 0.83);
    --black-b7: rgba(0, 0, 0, 0.85);
    --black-b8: rgba(0, 0, 0, 0.87);
    --black-b9: rgba(0, 0, 0, 0.89);
    --black-b10: rgba(0, 0, 0, 0.9);
    --white-a10: rgba(255, 255, 255, 0.02);
    --white-a9: rgba(255, 255, 255, 0.04);
    --white-a8: rgba(255, 255, 255, 0.06);
    --white-a7: rgba(255, 255, 255, 0.08);
    --white-a6: rgba(255, 255, 255, 0.1);
    --white-a5: rgba(255, 255, 255, 0.12);
    --white-a4: rgba(255, 255, 255, 0.14);
    --white-a3: rgba(255, 255, 255, 0.16);
    --white-a2: rgba(255, 255, 255, 0.2);
    --white-a1: rgba(255, 255, 255, 0.4);
    --white-a0: rgba(255, 255, 255, 0.45);
    --white-base: rgba(255, 255, 255, 0.5);
    --white-b0: rgba(255, 255, 255, 0.55);
    --white-b1: rgba(255, 255, 255, 0.6);
    --white-b2: rgba(255, 255, 255, 0.74);
    --white-b3: rgba(255, 255, 255, 0.77);
    --white-b4: rgba(255, 255, 255, 0.79);
    --white-b5: rgba(255, 255, 255, 0.81);
    --white-b6: rgba(255, 255, 255, 0.83);
    --white-b7: rgba(255, 255, 255, 0.85);
    --white-b8: rgba(255, 255, 255, 0.87);
    --white-b9: rgba(255, 255, 255, 0.89);
    --white-b10: rgba(255, 255, 255, 0.9);
    --gray-a10: #FAFAFA;
    --gray-a9: #F5F5F5;
    --gray-a8: #F0F0F0;
    --gray-a7: #EBEBEB;
    --gray-a6: #E5E5E5;
    --gray-a5: #E0E0E0;
    --gray-a4: #DBDBDB;
    --gray-a3: #D6D6D6;
    --gray-a2: #CCCCCC;
    --gray-a1: #999999;
    --gray-a0: #8C8C8C;
    --gray-base: #808080;
    --gray-b0: #737373;
    --gray-b1: #666666;
    --gray-b2: #434343;
    --gray-b3: #3A3A3A;
    --gray-b4: #353535;
    --gray-b5: #303030;
    --gray-b6: #2C2C2C;
    --gray-b7: #272727;
    --gray-b8: #222222;
    --gray-b9: #1D1D1D;
    --gray-b10: #191919;
    --indigo-a10: #F6F6FF;
    --indigo-a9: #ECECFF;
    --indigo-a8: #E3E3FF;
    --indigo-a7: #DCDCFF;
    --indigo-a6: #D5D5FF;
    --indigo-a5: #CBCBFF;
    --indigo-a4: #C4C4FF;
    --indigo-a3: #B8B8FF;
    --indigo-a2: #A9A9FF;
    --indigo-a1: #9999FF;
    --indigo-a0: #8080FF;
    --indigo-base: #2020F3;
    --indigo-b0: #1E1EC6;
    --indigo-b1: #1C1CB0;
    --indigo-b2: #1A1A83;
    --indigo-b3: #191978;
    --indigo-b4: #19196D;
    --indigo-b5: #181862;
    --indigo-b6: #181857;
    --indigo-b7: #161641;
    --indigo-b8: #161635;
    --indigo-b9: #15152A;
    --indigo-b10: #15151F;
    --red-a10: #FFF5F5;
    --red-a9: #FFEAEA;
    --red-a8: #FFDFDF;
    --red-a7: #FFD7D7;
    --red-a6: #FFCFCF;
    --red-a5: #FFC4C4;
    --red-a4: #FFBCBC;
    --red-a3: #FFB0B0;
    --red-a2: #FF9D9D;
    --red-a1: #FF7B7B;
    --red-a0: #FF6060;
    --red-base: #DC1818;
    --red-b0: #C10A0A;
    --red-b1: #AE0909;
    --red-b2: #781616;
    --red-b3: #6E1616;
    --red-b4: #641616;
    --red-b5: #5A1515;
    --red-b6: #501515;
    --red-b7: #3C1515;
    --red-b8: #321515;
    --red-b9: #281414;
    --red-b10: #1E1414;
    --blue-a10: #F4F9FF;
    --blue-a9: #E9F2FF;
    --blue-a8: #DEECFF;
    --blue-a7: #D6E6FF;
    --blue-a6: #CDE2FF;
    --blue-a5: #C3DBFF;
    --blue-a4: #BAD7FF;
    --blue-a3: #ACCFFF;
    --blue-a2: #99C4FF;
    --blue-a1: #76AEFF;
    --blue-a0: #5A9FFF;
    --blue-base: #0062EB;
    --blue-b0: #0051C4;
    --blue-b1: #004AB0;
    --blue-b2: #0A3B80;
    --blue-b3: #0B3775;
    --blue-b4: #0C336A;
    --blue-b5: #0D2F5F;
    --blue-b6: #0E2B55;
    --blue-b7: #10243F;
    --blue-b8: #112034;
    --blue-b9: #121C2A;
    --blue-b10: #13181F;
    --green-a10: #F4FBF7;
    --green-a9: #E9F8EC;
    --green-a8: #DEF4E4;
    --green-a7: #D6F1DC;
    --green-a6: #CDEFD6;
    --green-a5: #C2EBCC;
    --green-a4: #BAE8C5;
    --green-a3: #ADE3B9;
    --green-a2: #99DDAB;
    --green-a1: #75D18C;
    --green-a0: #5AC876;
    --green-base: #0F802B;
    --green-b0: #106A26;
    --green-b1: #116024;
    --green-b2: #124A20;
    --green-b3: #12451E;
    --green-b4: #123F1D;
    --green-b5: #123A1C;
    --green-b6: #13341B;
    --green-b7: #132A19;
    --green-b8: #132417;
    --green-b9: #141F16;
    --green-b10: #141915;
    --yellow-a10: #FFFDF7;
    --yellow-a9: #FFFCF1;
    --yellow-a8: #FFF3CD;
    --yellow-a7: #FFF0BF;
    --yellow-a6: #FFECAF;
    --yellow-a5: #FFEAA5;
    --yellow-a4: #FFE89C;
    --yellow-a3: #FFE592;
    --yellow-a2: #FFE388;
    --yellow-a1: #FFE17E;
    --yellow-a0: #FFDF74;
    --yellow-base: #FFD138;
    --yellow-b0: #CB3300;
    --yellow-b1: #AF2C00;
    --yellow-b2: #7E3B24;
    --yellow-b3: #723622;
    --yellow-b4: #663221;
    --yellow-b5: #5B2E1F;
    --yellow-b6: #4F2A1D;
    --yellow-b7: #43251B;
    --yellow-b8: #372119;
    --yellow-b9: #2C1D18;
    --yellow-b10: #201916;
    --backdrop: hsla(0, 0%, 0%, 0.45);
    --border-shadow: rgba(0, 0, 0, 0.25);
    --bg-base: var(--white);
    --bg-raised: var(--white);
    --bg-overlay: var(--white);
    --bg-input: var(--white);
    --bg-input-on: var(--black);
    --bg-input-off: var(--black-a5);
    --bg-input-focus: var(--white);
    --bg-input-disabled: var(--black-a8);
    --fg-placeholder: var(--black-base);
    --fg-input-on: var(--white);
    --border-input: var(--black-a5);
    --border-focus: var(--focus);
    --border-input-focus: var(--focus);
    --fg-primary-accent: var(--indigo-base);
    --fg-primary-body: var(--indigo-b0);
    --bg-primary-section: var(--indigo-a9);
    --bg-primary-surface: var(--indigo-a8);
    --bg-primary-state: var(--indigo-a6);
    --bg-primary-accent: var(--indigo-base);
    --bg-primary-accent-hover: var(--indigo-b0);
    --border-primary-default: var(--indigo-a6);
    --border-primary-strong: var(--indigo-a3);
    --border-primary-accent: var(--indigo-base);
    --fg-info-accent: var(--blue-base);
    --fg-info-body: var(--blue-b0);
    --bg-info-section: var(--blue-a9);
    --bg-info-surface: var(--blue-a8);
    --bg-info-state: var(--blue-a6);
    --bg-info-accent: var(--blue-base);
    --bg-info-accent-hover: var(--blue-b0);
    --border-info-default: var(--blue-a6);
    --border-info-strong: var(--blue-a3);
    --border-info-accent: var(--blue-base);
    --fg-negative-accent: var(--red-base);
    --fg-negative-body: var(--red-b0);
    --bg-negative-section: var(--red-a9);
    --bg-negative-surface: var(--red-a8);
    --bg-negative-state: var(--red-a6);
    --bg-negative-accent: var(--red-base);
    --bg-negative-accent-hover: var(--red-b0);
    --border-negative-default: var(--red-a6);
    --border-negative-strong: var(--red-a3);
    --border-negative-accent: var(--red-base);
    --fg-positive-accent: var(--green-base);
    --fg-positive-body: var(--green-b0);
    --bg-positive-section: var(--green-a9);
    --bg-positive-surface: var(--green-a8);
    --bg-positive-state: var(--green-a6);
    --bg-positive-accent: var(--green-base);
    --bg-positive-accent-hover: var(--green-b0);
    --border-positive-default: var(--green-a6);
    --border-positive-strong: var(--green-a3);
    --border-positive-accent: var(--green-base);
    --fg-notice-accent: var(--yellow-b0);
    --fg-notice-body: var(--yellow-b1);
    --bg-notice-section: var(--yellow-a9);
    --bg-notice-surface: var(--yellow-a8);
    --bg-notice-state: var(--yellow-a6);
    --bg-notice-accent: var(--yellow-base);
    --bg-notice-accent-hover: var(--yellow-a0);
    --border-notice-default: var(--yellow-a6);
    --border-notice-strong: var(--yellow-a3);
    --border-notice-accent: var(--yellow-b0);
    --fg-neutral-accent: var(--black);
    --fg-neutral-body: var(--gray-b6);
    --fg-neutral-subtle: var(--gray-b1);
    --fg-neutral-minimal: var(--gray-b0);
    --fg-neutral-muted: var(--gray-base);
    --bg-neutral-base: var(--gray-a10);
    --bg-neutral-section: var(--gray-a9);
    --bg-neutral-surface: var(--gray-a8);
    --bg-neutral-state: var(--gray-a6);
    --bg-neutral-accent: var(--black);
    --bg-neutral-accent-hover: var(--gray-b3);
    --border-neutral-subtle: var(--gray-a8);
    --border-neutral-default: var(--gray-a6);
    --border-neutral-strong: var(--gray-a3);
    --border-neutral-accent: var(--black);
    --fg-inverse-accent: var(--white);
    --fg-inverse-body: var(--gray-a3);
    --fg-inverse-subtle: var(--gray-a1);
    --fg-inverse-minimal: var(--gray-a0);
    --fg-inverse-muted: var(--gray-base);
    --bg-inverse-base: var(--gray-b10);
    --bg-inverse-section: var(--gray-b9);
    --bg-inverse-surface: var(--gray-b8);
    --bg-inverse-state: var(--gray-b6);
    --bg-inverse-accent: var(--white);
    --bg-inverse-accent-hover: var(--gray-a3);
    --border-inverse-subtle: var(--gray-b8);
    --border-inverse-default: var(--gray-b6);
    --border-inverse-strong: var(--gray-b3);
    --border-inverse-accent: var(--white);
    --fg-dark-accent: var(--black);
    --fg-dark-body: var(--black-b6);
    --fg-dark-subtle: var(--black-b1);
    --fg-dark-minimal: var(--black-b0);
    --fg-dark-muted: var(--black-base);
    --bg-dark-base: var(--black-a10);
    --bg-dark-section: var(--black-a9);
    --bg-dark-surface: var(--black-a8);
    --bg-dark-state: var(--black-a6);
    --bg-dark-accent: var(--black);
    --bg-dark-accent-hover: var(--black-b3);
    --border-dark-subtle: var(--black-a8);
    --border-dark-default: var(--black-a6);
    --border-dark-strong: var(--black-a3);
    --border-dark-accent: var(--black);
    --fg-light-accent: var(--white);
    --fg-light-body: var(--white-b6);
    --fg-light-subtle: var(--white-b1);
    --fg-light-minimal: var(--white-b0);
    --fg-light-muted: var(--white-base);
    --bg-light-base: var(--white-a10);
    --bg-light-section: var(--white-a9);
    --bg-light-surface: var(--white-a8);
    --bg-light-state: var(--white-a6);
    --bg-light-accent: var(--white);
    --bg-light-accent-hover: var(--white-b3);
    --border-light-subtle: var(--white-a8);
    --border-light-default: var(--white-a6);
    --border-light-strong: var(--white-a3);
    --border-light-accent: var(--white);
    --fg-black-accent: var(--black);
    --fg-black-body: var(--black-b6);
    --fg-black-subtle: var(--black-b1);
    --fg-black-minimal: var(--black-b0);
    --fg-black-muted: var(--black-base);
    --bg-black-base: var(--black-a10);
    --bg-black-section: var(--black-a9);
    --bg-black-surface: var(--black-a8);
    --bg-black-state: var(--black-a6);
    --bg-black-accent: var(--black);
    --bg-black-accent-hover: var(--black-b3);
    --border-black-subtle: var(--black-a8);
    --border-black-default: var(--black-a6);
    --border-black-strong: var(--black-a3);
    --border-black-accent: var(--black);
    --fg-white-accent: var(--white);
    --fg-white-body: var(--white-b6);
    --fg-white-subtle: var(--white-b1);
    --fg-white-minimal: var(--white-b0);
    --fg-white-muted: var(--white-base);
    --bg-white-base: var(--white-a10);
    --bg-white-section: var(--white-a9);
    --bg-white-surface: var(--white-a8);
    --bg-white-state: var(--white-a6);
    --bg-white-accent: var(--white);
    --bg-white-accent-hover: var(--white-b3);
    --border-white-subtle: var(--white-a8);
    --border-white-default: var(--white-a6);
    --border-white-strong: var(--white-a3);
    --border-white-accent: var(--white);
    --black: #000;
    --bg-onahau: #C6EDFE;
    --bg-drover: #FAF7AE;
    --bg-pear: #E0FB49;
    --border-onahau: #C6EDFE;
    --font-body: Inter, -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
    --font-heading: inherit;
    --font-logo: Manuale, Georgia, "Times New Roman", serif;
    --font-mono: monospace;
    --body-font-size: var(--text-size-body);
    --body-line-height: 1.5;
    --body-color: var(--fg-dark-body);
    --text-size-display: clamp(18px, 2vw, 24px);
    --text-size-lead: clamp(18px, 2vw, 20px);
    --text-size-large: 18px;
    --text-size-body: 16px;
    --text-size-label: 14px;
    --text-size-small: 12px;
    --text-size-micro: 11px;
    --text-size-detail: 13px;
    --link-line: underline;
    --link-color: var(--fg-info-body);
    --link-hover-color: var(--fg-negative-body);
    --heading-weight: 700;
    --heading-leading: 1.2;
    --heading-tracking: -0.02em;
    --heading-size-h0: clamp(42px, 5vw, 60px);
    --heading-size-h1: clamp(36px, 5vw, 48px);
    --heading-size-h2: clamp(28px, 4vw, 40px);
    --heading-size-h3: clamp(22px, 3.5vw, 32px);
    --heading-size-h4: clamp(20px, 3vw, 24px);
    --heading-size-h5: clamp(18px, 2.5vw, 20px);
    --heading-size-h6: clamp(16px, 2.5vw, 16px);
    --weight-regular: 400;
    --weight-medium: 500;
    --weight-semibold: 600;
    --weight-bold: 700;
    --weight-extrabold: 800;
    --weight-heavy: 900;
    --rounded-full: 9999px;
    --rounded-sm: 3px;
    --rounded: 6px;
    --rounded-lg: 9px;
    --rounded-xl: 12px;
    --spacing-1: clamp(3px, 0.5vw, 4px);
    --spacing-2: clamp(6px, 1vw, 8px);
    --spacing-3: clamp(9px, 1.5vw, 12px);
    --spacing-4: clamp(12px, 2vw, 16px);
    --spacing-5: clamp(16px, 2.5vw, 20px);
    --spacing-6: clamp(18px, 3vw, 24px);
    --spacing-8: clamp(24px, 4vw, 32px);
    --spacing-10: clamp(30px, 5vw, 40px);
    --spacing-12: clamp(36px, 6vw, 48px);
    --spacing-15: clamp(45px, 7.4vw, 60px);
    --spacing-20: clamp(60px, 10vw, 80px);
    --container-xxl: 1280px;
    --container-xl: 1280px;
    --container-lg: 968px;
    --container-md: 808px;
    --container-sm: 712px;
    --prose-width: 68ch;
    --shadow-sm: 0 0 1px 0 var(--border-shadow), 0 1px 1px -0.5px rgba(0, 0, 0, 0.07), 0 3px 3px -1.5px rgba(0, 0, 0, 0.07);
    --control-size-md: 40px;
    --control-size-lg: 48px;
    --button-padding-md: 12px;
    --button-padding-lg: 20px;
    --input-padding-md: 10px;
    --button-font-size: var(--text-size-label);
    --button-font-weight: var(--weight-medium);
    --button-border-radius: var(--rounded);
    --button-height: var(--control-size-md);
    --badge-font-size: var(--text-size-small);
    --badge-font-weight: var(--weight-medium);
    --badge-padding: 0.5em 0.6em;
    --badge-border-radius: var(--rounded-sm);
    --input-font-size: var(--text-size-label);
    --input-border-radius: var(--rounded);
    --input-height: var(--control-size-md);
    --snippet-border-radius: var(--rounded);
}

/* Dark values apply two ways: automatically via prefers-color-scheme
   (unless the manual toggle below has forced light), or unconditionally
   via [data-theme="dark"] once someone clicks "dark" in that toggle
   (src/view/layout.php sets/clears the attribute + persists the choice
   to localStorage). "System" (the default) means no attribute is set
   at all, so only the media query applies -- exactly the old behavior.
   The two selectors below intentionally repeat the same declarations
   (plain CSS has no mixin to share them) -- keep them in sync. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg-base: var(--night);
        --bg-raised: var(--gray-b10);
        --bg-input: var(--night);
        --border-input: var(--white-a5);
        --fg-neutral-accent: var(--smoke);
        --fg-neutral-body: var(--gray-a3);
        --bg-neutral-base: var(--gray-b10);
        --bg-neutral-section: var(--gray-b9);
        --bg-neutral-surface: var(--gray-b8);
        --bg-neutral-state: var(--gray-b6);
        --bg-neutral-accent: var(--smoke);
        --bg-neutral-accent-hover: var(--gray-a3);
        /* .button's background flips light in dark mode (--bg-neutral-
           accent above), but its text color wasn't following -- white
           text on a near-white button was unreadable. Only consumer of
           --fg-inverse-accent is .button, so this is safe to flip. */
        --fg-inverse-accent: var(--black);
        --border-neutral-subtle: var(--gray-b8);
        --border-neutral-default: var(--gray-b6);
        --border-neutral-strong: var(--gray-b3);
        --border-neutral-accent: var(--smoke);
        --fg-dark-accent: var(--smoke);
        --fg-dark-body: var(--white-b6);
        --fg-dark-subtle: var(--white-b1);
        --fg-info-body: var(--blue-a0);
        --bg-info-section: var(--blue-b9);
        --fg-negative-body: var(--red-a0);
        --bg-input-on: var(--smoke);
        --fg-input-on: var(--black);
    }
}

:root[data-theme="dark"] {
    --bg-base: var(--night);
    --bg-raised: var(--gray-b10);
    --bg-input: var(--night);
    --border-input: var(--white-a5);
    --fg-neutral-accent: var(--smoke);
    --fg-neutral-body: var(--gray-a3);
    --bg-neutral-base: var(--gray-b10);
    --bg-neutral-section: var(--gray-b9);
    --bg-neutral-surface: var(--gray-b8);
    --bg-neutral-state: var(--gray-b6);
    --bg-neutral-accent: var(--smoke);
    --bg-neutral-accent-hover: var(--gray-a3);
    --fg-inverse-accent: var(--black);
    --border-neutral-subtle: var(--gray-b8);
    --border-neutral-default: var(--gray-b6);
    --border-neutral-strong: var(--gray-b3);
    --border-neutral-accent: var(--smoke);
    --fg-dark-accent: var(--smoke);
    --fg-dark-body: var(--white-b6);
    --fg-dark-subtle: var(--white-b1);
    --fg-info-body: var(--blue-a0);
    --bg-info-section: var(--blue-b9);
    --fg-negative-body: var(--red-a0);
    --bg-input-on: var(--smoke);
    --fg-input-on: var(--black);
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    background: var(--bg-base);
    color: var(--body-color);
    font-family: var(--font-body);
    font-size: var(--body-font-size);
    line-height: var(--body-line-height);
    /* Shared with body::before's height and .page's top padding, so
       real content always starts clear of the fixed fade overlay --
       otherwise it renders underneath it and looks faded by default,
       even before any scrolling happens. */
    --top-fade-height: 7.4em;
}

body::before {
    /* 37signals' actual technique: a separate fade overlay, not the
       header's own background (the header has none -- see above).
       position:fixed removes it from body's flex flow, so it doesn't
       affect header/main/footer layout. z-index sits below the
       header (100) so the nav text stays crisp on top, but above
       normal page content. */
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: var(--top-fade-height);
    /* Fades over (almost) the whole height, then stays fully
       transparent for the last stretch -- 37signals' own ratio. */
    background: linear-gradient(180deg, var(--bg-base) 0, transparent 90%);
    pointer-events: none;
    z-index: 90;
}

@media (min-width: 64em) and (hover: hover) and (pointer: fine) {
    body {
        --top-fade-height: max(22.2vh, 5.4em);
    }
}

a {
    color: var(--link-color);
    text-decoration: none;
}

a:hover {
    color: var(--link-hover-color);
    text-decoration: underline;
}

h1, h2, h3 {
    font-family: var(--font-heading);
    font-weight: var(--heading-weight);
    line-height: var(--heading-leading);
    letter-spacing: var(--heading-tracking);
    color: var(--fg-neutral-accent);
    text-wrap: balance;
    /* Anchor jumps (e.g. #about-foundry) would otherwise land right
       under body::before's fixed fade overlay at the top. */
    scroll-margin-top: var(--top-fade-height);
}

h1 {
    font-size: var(--heading-size-h1);
    margin: 0 0 var(--spacing-3);
}

h2 {
    font-size: var(--heading-size-h3);
    margin: var(--spacing-12) 0 var(--spacing-3);
}

h3 {
    font-size: var(--heading-size-h5);
    margin: var(--spacing-8) 0 var(--spacing-2);
}

p {
    margin: 0 0 var(--spacing-4);
    max-width: var(--prose-width);
}

.hero-actions, .tokens, .card p, .footer-inner p {
    max-width: none;
}

ul {
    padding-left: 1.25em;
    max-width: var(--prose-width);
}

ul.card-grid {
    max-width: none;
}

/* layout */

.site-header {
    flex-shrink: 0;
    position: sticky;
    top: 0;
    z-index: 100;
    /* No background color of its own -- body::before is the *only*
       fade layer (37signals' actual setup: their header has no
       separate background either). A second gradient here would force
       a plateau in body::before to avoid a seam, eating into its fade
       height for no reason. Sticky (not fixed) so it still reserves
       its own space in normal flow; nav text stays legible on its
       own z-index regardless of what's behind it. backdrop-filter is
       independent of background-color -- it still blurs whatever
       scrolls underneath even with no tint of its own. */
    background: none;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.site-header::after {
    /* backdrop-filter on the header itself has a hard edge at the
       header's own bottom border -- content passing underneath jumps
       from fully blurred to fully sharp in one pixel row. This strip
       sits right below the header and re-blurs the same content with
       a mask-image fading from opaque (top, seamless with the header's
       own blur) to transparent (bottom, reveals sharp content), so the
       transition reads as a gradient instead of a line. */
    content: '';
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: 24px;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    mask-image: linear-gradient(to bottom, black, transparent);
    -webkit-mask-image: linear-gradient(to bottom, black, transparent);
    pointer-events: none;
}

.site-header nav {
    max-width: var(--container-xl);
    margin: 0 auto;
    padding: var(--spacing-6) var(--spacing-5);
    display: flex;
    gap: var(--spacing-8);
    align-items: center;
}

.site-header .brand {
    font-family: var(--font-logo);
    font-size: 34px;
    font-weight: 600;
    letter-spacing: 1px;
    color: var(--fg-neutral-accent);
    text-decoration: none;
}

.site-header nav a:not(.brand) {
    font-family: var(--font-logo);
    font-size: 17px;
    font-weight: 500;
    letter-spacing: 1px;
}

.site-header nav a:not(.brand):not(.button) {
    color: var(--fg-neutral-body);
    text-decoration: none;
}

.site-header nav a:not(.brand):not(.button):hover {
    color: var(--fg-neutral-accent);
}

.site-header nav .nav-right {
    /* Pushes itself (and everything after it in source order, i.e.
       .theme-toggle, .nav-cta) to the right, grouping all three
       together -- .brand stays alone on the left. */
    margin-left: auto;
}

.nav-cta {
    /* Muted/outline in the header specifically (unlike the filled
       .button default, or other .button-secondary uses elsewhere) --
       matches .theme-toggle's pill shape so the two sit together as a
       visually related pair. */
    border-radius: var(--rounded-full);
}

/* nav-burger: hidden entirely above 640px (nav-right/theme-toggle/
   nav-cta just show inline as normal) -- see the mobile override below
   for what it actually does. */

.nav-burger {
    display: none;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--fg-neutral-accent);
    cursor: pointer;
}

.nav-burger svg {
    width: 22px;
    height: 22px;
}

@media (max-width: 640px) {
    /* Below 640px: brand, theme-toggle, and the burger are the only
       things that stay in the top row (nav-right/nav-cta have no
       visible width here at all, so the row naturally closes up
       around them without any explicit reordering). Clicking the
       burger (src/view/layout.php) toggles .nav-open on <nav>, which
       reveals nav-right/nav-cta again as full-width rows wrapped onto
       a new line below -- order:10 keeps them there regardless of
       their actual position in the DOM. */
    .site-header nav {
        flex-wrap: wrap;
    }

    .nav-burger {
        display: inline-flex;
    }

    .site-header nav .nav-right,
    .site-header nav .nav-cta {
        display: none;
        order: 10;
        width: 100%;
        margin-left: 0;
    }

    .site-header nav.nav-open .nav-right,
    .site-header nav.nav-open .nav-cta {
        display: block;
        margin-top: var(--spacing-3);
    }
}

/* theme-toggle: System/Light/Dark segmented control (src/view/
   layout.php has the markup + wiring script). Purely decorative
   without JS -- prefers-color-scheme alone still governs the page in
   that case, same as before this existed. */

.theme-toggle {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    /* Extra room from the "Foundry" nav link to its left, beyond the
       nav's own default gap -- keeps the toggle visually grouped with
       "Get in touch" (to its right) instead of the text nav links.
       margin-right pulls the other side back in the opposite
       direction, closer than the nav's default gap, so the toggle
       reads as paired with the button rather than evenly spaced from
       both neighbors. */
    margin-left: var(--spacing-4);
    margin-right: calc(var(--spacing-5) - var(--spacing-8));
    background: var(--bg-neutral-section);
    border-radius: var(--rounded-full);
}

.theme-toggle button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: var(--rounded-full);
    background: transparent;
    color: var(--fg-neutral-muted);
    cursor: pointer;
}

.theme-toggle button svg {
    width: 16px;
    height: 16px;
}

.theme-toggle button:hover {
    color: var(--fg-neutral-accent);
}

.theme-toggle button[aria-pressed="true"] {
    background: var(--bg-raised);
    color: var(--fg-neutral-accent);
    box-shadow: 0 1px 2px var(--black-a7);
}

.page {
    flex: 1;
    display: flex;
    flex-direction: column;
    /* flex: 1 alone only grants .page whatever's left after the
       header/footer's own height. This min-height guarantees the
       full viewport-minus-header allocation regardless, so the
       golden-ratio split below actually has real space to distribute.
       --header-height is a measured constant, not computed -- there's
       no JS on this site and no pure-CSS way to read a sibling's
       rendered (content-driven) height, so this needs re-measuring by
       hand if .site-header's own content/size ever changes. */
    min-height: calc(100dvh - var(--header-height));
    max-width: var(--container-xl);
    width: 100%;
    margin: 0 auto;
    /* No top padding -- every page's content now either starts with
       .page-section (which owns its own top spacing) or is a stub
       page (which sets its own top padding directly, see stub.php's
       .stub-content). A shared top padding here just meant every
       .page-section had to cancel it back out with a negative margin. */
    padding: 0 var(--spacing-5) var(--spacing-20);
    box-sizing: border-box;
}

.stub-content {
    /* Stub pages (About us, Updates, Policies, ...) don't use
       .page-section, so they need their own top spacing now that
       .page itself has none. */
    padding-top: var(--spacing-10);
}

.about-intro {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-8);
    align-items: start;
}

.about-intro-col:last-child {
    /* The descriptive paragraph reads better bottom-aligned against
       the (usually taller) heading column next to it, instead of
       starting flush with the kicker at the top. */
    align-self: end;
}

@media (max-width: 640px) {
    .about-intro {
        grid-template-columns: 1fr;
        gap: var(--spacing-5);
    }
}

/* /about's map section -- deliberately not a real embedded map (no
   Maps SDK/API key, no external tile requests -- same "no third-party
   dependencies" stance as the rest of the site). A static photo
   (assets/img/about.jpg) as a CSS background fills the box, with
   the address card layered on top. aspect-ratio close to the
   source photo's own 16:9 keeps background-size: cover from
   cropping/zooming in much.*/
.about-map {
    position: relative;
    margin-top: var(--spacing-20);
    min-width: 480px;
    aspect-ratio: 16 / 9;
    border-radius: var(--rounded-xl);
    overflow: hidden;
    background: var(--bg-neutral-section) url("/assets/img/about.jpg") center / cover no-repeat;
}

.about-map-card {
    /* Fixed black/white regardless of page theme, same reasoning as
       .closing-cta .button -- a card meant to read like a printed
       label sitting on top of the map, not a themed UI panel. Centered
       on both axes over the dot-grid box, not anchored to an edge --
       its own 17:8 is deliberately wider/flatter than the outer box's
       16:9, so it reads as a distinct plate rather than a smaller copy
       of the same frame. aspect-ratio needs a definite width to
       compute height from, hence the explicit width (not just
       max-width); the mobile override below switches to a
       left/right-driven width instead. */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 320px;
    max-width: calc(100% - var(--spacing-10) * 2);
    aspect-ratio: 17 / 8;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--spacing-6);
    border-radius: var(--rounded-lg);
    background: var(--black);
    color: var(--white);
    box-sizing: border-box;
}

.about-map-card p {
    margin: 0 0 var(--spacing-2);
}

.about-map-card p:last-child {
    margin-bottom: 0;
}

.about-map-card p.about-map-card-name {
    /* No gap to the address line right below -- name and address read
       as one block, only the link after them gets breathing room. */
    margin-bottom: 0;
    font-weight: var(--weight-bold);
}

.about-map-card a {
    color: var(--white);
}

@media (max-width: 640px) {
    .about-map {
        min-width: 0;
        aspect-ratio: 4 / 5;
    }

    .about-map-card {
        left: var(--spacing-5);
        right: var(--spacing-5);
        transform: translateY(-50%);
        width: auto;
        max-width: none;
    }
}

.page-section {
    /* Base case (any .page-section that isn't the actual hero, e.g. the
       "About Foundry" section): just a flat, fixed top gap -- no
       centering attempt. min-height still lets tall content grow past
       one viewport and push later content down normally. */
    min-height: calc(100dvh - var(--header-height));
    padding-top: 45px;
    /* Anchor ids (#about-foundry, #tool) live on .page-section itself, not
       the inner .page-section-content -- otherwise an anchor jump lands at
       .page-section-content's own position, skipping past this gap entirely
       and landing deeper into the page than the visual layout implies.
       Only needs to clear the sticky header, since .page-section's own
       top already starts right at the header's bottom edge. */
    scroll-margin-top: var(--header-height);
}

.page-content > .page-section:first-child {
    /* The actual hero -- simple flex centering instead of the fixed
       top gap above (overridden here). .page no longer has its own
       top padding, so no cancellation margin is needed here either. */
    padding-top: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.page-content > .page-section:first-child .page-section-content {
    /* Flex-centers within .page-section's own box -- but that box starts
       at the header's bottom edge, not the true viewport top, so
       there's still some space above (header + centering) than below
       (centering alone). Only the real hero needs this; other
       .page-section sections use a flat top gap with no centering to
       correct for. */
    margin-top: -5%;
}

.page-section h1 {
    /* Full container width read as too wide typographically for a
       big display headline -- narrower measure, wraps to two lines
       instead of stretching thin across the whole page. */
    max-width: 600px;
}

.page-section .lead {
    max-width: 46ch;
}

/* Short pages (nothing tall enough to fill the viewport) settle at a
   golden-ratio point instead of sitting glued to the top. Real divs,
   not ::before/::after -- some browsers don't grow generated-content
   pseudo-elements reliably as flex items. .page-content is a plain
   block, not itself a flex item's *child* flex container, so none of
   this touches how the actual page content sizes. The moment real
   content is tall enough to fill the space itself, the spacers have
   nothing left to grow into and this has no effect -- normal
   top-aligned flow, same as any other page. */

.page-spacer-top {
    flex: 0.618 0 0;
}

.page-spacer-bottom {
    flex: 1 0 0;
}

.page-content {
    flex: 0 0 auto;
}

/* kicker badge, e.g. above a page's h1 */

.kicker {
    display: inline-block;
    background: var(--bg-info-section);
    color: var(--fg-info-body);
    font-size: var(--badge-font-size);
    font-weight: var(--badge-font-weight);
    padding: var(--badge-padding);
    border-radius: var(--badge-border-radius);
    margin-bottom: var(--spacing-4);
}

/* alternating gray section, e.g. a feature block */

.section {
    /* No horizontal padding/border-radius/margin -- now that .section
       itself has no background (the card inside it carries the gray,
       see .section .card), a padded/rounded box around invisible edges
       just reads as unexplained indentation instead of a boxed
       section. Its own top/bottom margin is gone too: wherever
       .section is used, it's inside .page-section, which already owns
       top spacing (padding-top) -- .section's margin was stacking on
       top of that, adding confusing, redundant space. This class now
       exists only for the .section .card selector below. */
}

/* buttons */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: var(--button-height);
    padding: 0 var(--button-padding-lg);
    background: var(--bg-neutral-accent);
    color: var(--fg-inverse-accent);
    font-size: var(--button-font-size);
    font-weight: var(--button-font-weight);
    border: none;
    border-radius: var(--button-border-radius);
    cursor: pointer;
    text-decoration: none;
}

.button:hover {
    background: var(--bg-neutral-accent-hover);
    color: var(--fg-inverse-accent);
    text-decoration: none;
}

.button-secondary {
    background: transparent;
    color: var(--fg-neutral-accent);
    border: 1px solid var(--border-neutral-default);
}

.button-secondary:hover {
    background: var(--bg-neutral-section);
    color: var(--fg-neutral-accent);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-3);
    align-items: center;
    margin: var(--spacing-5) 0;
}

.lead {
    font-size: var(--text-size-lead);
    color: var(--fg-neutral-body);
    text-wrap: balance;
}

.caption {
    font-size: var(--text-size-small);
    color: var(--fg-neutral-muted);
}

/* tool panel -- a boxed, app-like container for a live demo */

.tool-panel {
    border: 1px solid var(--border-neutral-default);
    border-radius: var(--rounded-xl);
    padding: var(--spacing-8) var(--spacing-6);
    margin: 0;
    background: var(--bg-raised);
    box-shadow: var(--shadow-sm);
}

.tool-panel-header {
    font-size: var(--text-size-small);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fg-neutral-muted);
    margin: 0 0 var(--spacing-5);
    padding-bottom: var(--spacing-3);
    border-bottom: 1px solid var(--border-neutral-subtle);
}

/* tool-with-examples: the tool panel and its examples list are two
   INDEPENDENT elements side by side -- not two panes of one shared
   frame (that was the previous design, reverted: examples read as
   part of the tool's own border, when it should sit next to the tool
   instead). */
.tool-with-examples {
    display: grid;
    grid-template-columns: 1.618fr 1fr;
    gap: var(--spacing-6);
    align-items: start;
    margin: var(--spacing-6) 0;
}

.examples-panel {
    border-radius: var(--rounded-xl);
    padding: var(--spacing-6);
    background: var(--bg-raised);
}

@media (max-width: 640px) {
    .tool-with-examples {
        grid-template-columns: 1fr;
        gap: var(--spacing-6);
    }
}

/* demo form */

form.demo {
    margin: 0;
}

form.demo label {
    display: block;
    font-size: var(--label-font-size);
    font-weight: var(--label-font-weight);
    margin-bottom: var(--spacing-2);
}

form.demo input[type="text"] {
    width: 100%;
    height: var(--input-height);
    font-family: var(--font-mono);
    font-size: var(--input-font-size);
    padding: 0 var(--input-padding-md);
    border: 1px solid var(--border-input);
    border-radius: var(--input-border-radius);
    background: var(--bg-input);
    color: var(--body-color);
}

form.demo input[type="text"]:focus {
    outline: none;
    border-color: var(--border-input-focus);
}

form.demo .field-row {
    display: flex;
    gap: var(--spacing-4);
    align-items: flex-end;
}

form.demo .field-name {
    flex: 1;
    min-width: 0;
}

form.demo .field-country {
    width: 5.5em;
}

form.demo select.input-country {
    width: 100%;
    height: var(--input-height);
    font-family: var(--font-mono);
    font-size: var(--input-font-size);
    padding: 0 var(--input-padding-md);
    padding-right: calc(var(--input-padding-md) * 2 + 10px);
    border: 1px solid var(--border-input);
    border-radius: var(--input-border-radius);
    background-color: var(--bg-input);
    color: var(--body-color);
    /* Flat chevron instead of the browser's native (OS-specific,
       skeuomorphic on some platforms) dropdown arrow -- appearance:none
       strips that chrome entirely, so the arrow has to be painted back
       on manually via background-image. #808080 is hardcoded (a plain
       background-image can't reference a CSS custom property) but
       reads fine against both --bg-input values (near-white/near-black). */
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23808080' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--input-padding-md) center;
    /* .field-country's narrow fixed width clips the closed box down to
       roughly the leading "XX" code -- the dropdown list itself isn't
       width-constrained the same way, so it still shows the full
       "XX — Name" option text once opened. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

form.demo select.input-country:focus {
    outline: none;
    border-color: var(--border-input-focus);
}

.submit-row {
    /* margin-top lives here, not on the button itself -- a margin on
       just one flex item would grow its margin box and throw off
       align-items: center between the button and the spinner next to
       it (which has no margin of its own). */
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    margin: var(--spacing-3) 0 0;
}

.spinner {
    /* Hidden by default -- #tool's _tool.php script adds/relies on the
       swap() fetch to toggle #tool.loading, since a real network
       round-trip happens even though the form still degrades to a
       plain full-page GET without JS (no spinner needed in that case,
       the browser's own loading indicator covers it). */
    display: none;
    width: 18px;
    height: 18px;
    border: 2px solid var(--border-neutral-default);
    border-top-color: var(--fg-neutral-accent);
    border-radius: var(--rounded-full);
    animation: spinner-rotate 0.6s linear infinite;
}

#tool.loading .spinner {
    display: inline-block;
}

@keyframes spinner-rotate {
    to {
        transform: rotate(360deg);
    }
}

/* contact-layout: the /contact page itself -- no separate hero above
   the form, a direct two-column split (copy left, form right) instead,
   both living in the page's one .page-section. */

.contact-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-12);
    align-items: start;
    width: 100%;
}

.contact-info h1 {
    max-width: none;
}

.checklist {
    list-style: none;
    padding: 0;
    margin: var(--spacing-6) 0 0;
    max-width: none;
}

.checklist li {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    padding: var(--spacing-2) 0;
    color: var(--fg-neutral-body);
}

.checklist li::before {
    content: "\2713";
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    border-radius: var(--rounded-full);
    background: var(--bg-neutral-section);
    color: var(--fg-neutral-accent);
    font-size: var(--text-size-small);
}

.contact-form-label {
    font-weight: var(--weight-semibold);
    margin-bottom: var(--spacing-4);
}

@media (max-width: 780px) {
    .contact-layout {
        grid-template-columns: 1fr;
        gap: var(--spacing-8);
    }
}

/* contact-form: the field stack itself, reusing form.demo's input
   look (mono font, same border/radius tokens) without its two-column
   .field-row layout, which is specific to the name+country pair on
   the demo tool. */

.contact-form {
    max-width: 32em;
}

.field-decoy {
    /* Honeypot for Contact_controller::on_contact() -- off-screen via
       absolute positioning, not display:none/visibility:hidden, since
       those are the first things a scraper checks for when deciding
       which fields to skip. Real visitors never see or reach it
       (no tab stop, aria-hidden), so it should always arrive empty. */
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.contact-form .field {
    margin-bottom: var(--spacing-5);
}

.contact-form label {
    display: block;
    font-size: var(--label-font-size);
    font-weight: var(--label-font-weight);
    margin-bottom: var(--spacing-2);
}

.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
    width: 100%;
    font-family: var(--font-mono);
    font-size: var(--input-font-size);
    padding: var(--input-padding-md);
    border: 1px solid var(--border-input);
    border-radius: var(--input-border-radius);
    background: var(--bg-input);
    color: var(--body-color);
}

.contact-form input[type="text"],
.contact-form input[type="email"] {
    height: var(--input-height);
    padding: 0 var(--input-padding-md);
}

.contact-form textarea {
    resize: vertical;
}

.contact-form input:focus,
.contact-form textarea:focus {
    outline: none;
    border-color: var(--border-input-focus);
}

.contact-form .field .warning {
    display: block;
    margin-top: var(--spacing-2);
    font-size: var(--text-size-label);
}

.examples-label {
    font-size: var(--text-size-label);
    font-weight: var(--weight-medium);
    color: var(--fg-neutral-body);
    margin-bottom: var(--spacing-2);
}

ul.examples {
    list-style: none;
    padding: 0;
    margin: 0;
    max-width: none;
}

ul.examples li {
    border-bottom: 1px solid var(--border-neutral-subtle);
}

ul.examples li:last-child {
    border-bottom: none;
}

ul.examples a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-3);
    padding: var(--spacing-2) 0;
    color: var(--fg-neutral-body);
    font-family: var(--font-mono);
    font-size: var(--text-size-detail);
    text-decoration: none;
}

ul.examples a .arrow {
    color: var(--fg-neutral-muted);
    flex-shrink: 0;
}

ul.examples a:hover {
    color: var(--fg-info-body);
}

ul.examples a:hover .arrow {
    color: var(--fg-info-body);
}

/* benefit-list: a "we help you" style benefit list (icon + one-line
   outcome), scannable in a way a full card grid isn't -- used for the
   "Use cases" section instead of another card-grid. */

ul.benefit-list {
    list-style: none;
    padding: 0;
    margin: 0;
    max-width: none;
}

ul.benefit-list li {
    display: flex;
    align-items: baseline;
    gap: var(--spacing-3);
    padding: var(--spacing-3) 0;
    border-bottom: 1px solid var(--border-neutral-subtle);
    color: var(--fg-neutral-body);
}

ul.benefit-list li:last-child {
    border-bottom: none;
}

.benefit-icon {
    flex-shrink: 0;
}

/* did-you-mean: same "whole line is the click target, arrow on the
   right" affordance as ul.examples a, so re-clicking to adopt a
   suggestion reads the same way as picking an example. */
a.did-you-mean {
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
    color: var(--fg-neutral-body);
    text-decoration: none;
}

a.did-you-mean .arrow {
    color: var(--fg-neutral-muted);
}

a.did-you-mean:hover,
a.did-you-mean:hover .arrow {
    color: var(--fg-info-body);
}

.warning {
    color: var(--fg-notice-body);
}

/* code */

pre {
    background: var(--bg-neutral-section);
    border: 1px solid var(--border-neutral-default);
    border-radius: var(--snippet-border-radius);
    padding: var(--spacing-4);
    overflow-x: auto;
    font-family: var(--font-mono);
    font-size: var(--text-size-detail);
    line-height: 1.5;
}

code {
    font-family: var(--font-mono);
}

/* parse result -- human-readable first, raw JSON tucked behind <details> */

.result {
    border-top: 1px dashed var(--border-neutral-default);
    padding-top: var(--spacing-5);
    margin-top: var(--spacing-5);
}

.result-name {
    font-size: var(--heading-size-h5);
    font-weight: var(--weight-semibold);
    margin-bottom: var(--spacing-3);
}

/* gender-result-table: the minimal result view on /foundry/name-
   intelligence/gender (_tool.php's $minimal mode) -- plain label/value
   rows, no token breakdown, no country chips, no did-you-mean. */

.gender-result-table {
    border-collapse: collapse;
}

.gender-result-table th,
.gender-result-table td {
    text-align: left;
    padding: var(--spacing-2) var(--spacing-4) var(--spacing-2) 0;
    border-bottom: 1px solid var(--border-neutral-subtle);
}

.gender-result-table th {
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--text-size-small);
}

.gender-result-table td {
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-accent);
}

.tokens {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
    margin-bottom: var(--spacing-4);
}

.token {
    position: relative;
    display: inline-block;
    font: inherit;
    font-size: var(--badge-font-size);
    font-family: var(--font-mono);
    padding: var(--badge-padding);
    border: none;
    border-radius: var(--badge-border-radius);
    background: var(--bg-neutral-section);
    color: var(--fg-neutral-body);
    cursor: pointer;
}

.token-title, .token-honorific, .token-salutation {
    background: var(--bg-info-section);
    color: var(--fg-info-body);
}

.token-given_name, .token-initial {
    background: var(--bg-positive-section);
    color: var(--fg-positive-body);
}

.token-family_name, .token-patronymic {
    background: var(--bg-primary-section);
    color: var(--fg-primary-body);
}

.token-nobility_title, .token-associated_name {
    background: var(--bg-notice-section);
    color: var(--fg-notice-body);
}

.token-info {
    display: none;
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: var(--spacing-2);
    padding: var(--spacing-2) var(--spacing-3);
    border-radius: var(--rounded-sm);
    background: var(--bg-inverse-base);
    color: var(--fg-inverse-body);
    font-family: var(--font-body);
    font-size: var(--text-size-small);
    font-weight: var(--weight-regular);
    white-space: nowrap;
    z-index: 100;
}

.token:hover .token-info,
.token:focus .token-info,
.token:focus-visible .token-info {
    display: block;
}

.confidence {
    font-weight: var(--weight-medium);
    margin-bottom: var(--spacing-3);
}

.confidence-high { color: var(--fg-positive-body); }
.confidence-medium { color: var(--fg-notice-body); }
.confidence-low { color: var(--fg-negative-body); }

.warnings {
    color: var(--fg-notice-body);
    font-size: var(--text-size-label);
}

@media (prefers-color-scheme: dark) {
    /* --fg-positive-body/--fg-notice-body deliberately don't flip
       globally (see .token-given_name etc. above -- they're paired with
       a same-family background that also never flips, e.g.
       --bg-positive-section, so both stay dark-on-light regardless of
       page theme). But .confidence-high/.confidence-medium/.warnings
       use these as plain text directly on the page background, with no
       background of their own -- dark green/amber text on an otherwise
       dark page is nearly unreadable. Override just these standalone
       usages instead of the shared custom properties. */
    :root:not([data-theme="light"]) .confidence-high { color: var(--green-a0); }
    :root:not([data-theme="light"]) .confidence-medium,
    :root:not([data-theme="light"]) .warnings,
    :root:not([data-theme="light"]) .warning { color: var(--yellow-a0); }
}

:root[data-theme="dark"] .confidence-high { color: var(--green-a0); }
:root[data-theme="dark"] .confidence-medium,
:root[data-theme="dark"] .warnings,
:root[data-theme="dark"] .warning { color: var(--yellow-a0); }

.detail {
    font-size: var(--text-size-label);
    color: var(--fg-neutral-body);
}

/* country-note: a curated naming-convention fact on a country landing
   page (src/data/countries.php's 'note' field) -- deliberately its own
   labeled box, not a second hero paragraph, so it reads as a distinct
   fact rather than blending into the hero copy. */

.country-note {
    border: 1px solid var(--border-neutral-subtle);
    border-radius: var(--rounded-xl);
    background: var(--bg-neutral-section);
    padding: var(--spacing-5) var(--spacing-6);
    margin: var(--spacing-6) 0;
}

.country-note-label {
    font-size: var(--text-size-small);
    font-weight: var(--weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fg-neutral-muted);
    margin-bottom: var(--spacing-2);
}

.country-note p:last-child {
    margin-bottom: 0;
}

/* naming-conventions: the richer showcase-country write-up
   (src/data/country_deep_dives.php) -- language/script intro, one
   block per suffix/prefix pattern, a closing note tying it back to
   how Foundry actually handles it. */

.naming-conventions {
    border: 1px solid var(--border-neutral-subtle);
    border-radius: var(--rounded-xl);
    background: var(--bg-raised);
    padding: var(--spacing-6);
    margin: var(--spacing-6) 0;
}

.naming-conventions-intro {
    color: var(--fg-neutral-body);
}

.naming-pattern {
    padding: var(--spacing-4) 0;
    border-top: 1px solid var(--border-neutral-subtle);
}

.naming-pattern:first-of-type {
    border-top: none;
    padding-top: var(--spacing-2);
}

.naming-pattern-label {
    font-family: var(--font-mono);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-accent);
    margin-bottom: var(--spacing-1);
}

.naming-pattern-meaning {
    color: var(--fg-neutral-body);
}

.naming-pattern-examples {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
    max-width: none;
    margin-bottom: 0;
}

.naming-example {
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    background: var(--bg-neutral-section);
    padding: var(--badge-padding);
    border-radius: var(--badge-border-radius);
}

.naming-conventions-footnote {
    margin: var(--spacing-4) 0 0;
    padding-top: var(--spacing-4);
    border-top: 1px solid var(--border-neutral-subtle);
    font-size: var(--text-size-label);
    color: var(--fg-neutral-muted);
}

/* naming-conventions-rich: the richer SEO-content schema (snippet/
   pillars/affixes/genderNote/stat/faq in country_deep_dives.php) --
   3 rule pillars, an affix table, a gender note, a highlighted
   "data journalism" stat pulled from Foundry's own corpus data
   (src/data/popular_names.php), and a short FAQ. */

.naming-conventions-rich h3 {
    margin-top: var(--spacing-6);
}

.naming-pillars {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--spacing-5);
    margin-bottom: var(--spacing-6);
}

.naming-pillar {
    border: 1px solid var(--border-neutral-subtle);
    border-radius: var(--rounded-lg);
    background: var(--bg-neutral-section);
    padding: var(--spacing-4) var(--spacing-5);
}

.naming-pillar h3 {
    margin-top: 0;
    font-size: var(--text-size-label);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--fg-neutral-accent);
    margin-bottom: var(--spacing-1);
}

.naming-pillar p {
    color: var(--fg-neutral-body);
    margin-bottom: 0;
}

.naming-affixes-table-wrap {
    overflow-x: auto;
    margin: var(--spacing-3) 0 var(--spacing-6);
}

.naming-affixes-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-size-label);
}

.naming-affixes-table th,
.naming-affixes-table td {
    text-align: left;
    padding: var(--spacing-2) var(--spacing-3);
    border-bottom: 1px solid var(--border-neutral-subtle);
    vertical-align: top;
}

.naming-affixes-table th {
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: var(--text-size-small);
}

.naming-affixes-table td:first-child {
    font-family: var(--font-mono);
    color: var(--fg-neutral-accent);
    white-space: nowrap;
}


/* closing-cta: a full-width colored block for the page's one closing
   action (imperavi-style) -- deliberately no social-proof caption
   ("join thousands of developers...") since there's no real customer
   base yet to point to; the honest substitute is a plain
   early-stage note instead. */

.closing-cta {
    /* --yellow-a4, not --bg-notice-section (= --yellow-a9) -- a9 is
       the palest tint in the scale, meant for subtle notice boxes, and
       reads as near-white (#FFFCF1) rather than an actual yellow. This
       block wants the imperavi-style punchy pastel instead. Fixed
       dark-on-light colors throughout too, not the theme-flipping
       --fg-neutral-* tokens -- this yellow doesn't have (or want) a
       dark-mode override, so text here must not flip light either or
       it loses contrast against this box's always-yellow background
       when the rest of the page is in dark mode. */
    background: var(--yellow-a4);
    color: var(--black);
    border-radius: var(--rounded-xl);
    padding: var(--spacing-12) var(--spacing-10);
    margin: var(--spacing-12) 0;
}

.closing-cta-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border: 1px solid var(--black-a5);
    border-radius: var(--rounded-lg);
    font-size: var(--text-size-large);
    color: var(--black);
    margin-bottom: var(--spacing-8);
}

.closing-cta h2 {
    color: var(--black);
    margin: 0 0 var(--spacing-5);
}

.closing-cta .lead {
    color: var(--black-b1);
    margin-bottom: var(--spacing-15);
}

.closing-cta-caption {
    margin: var(--spacing-6) 0 0;
    font-size: var(--text-size-label);
    color: var(--black-a1);
}

/* .button itself flips to a light background in dark mode (so it
   still contrasts against an otherwise-dark page elsewhere) -- but
   this box's background never flips, it's always light yellow, so a
   light-gray dark-mode button on it barely reads as a button at all.
   Pin it back to its light-mode look (dark bg, light text) here,
   regardless of page theme. */
.closing-cta .button {
    background: var(--black);
    color: var(--white);
}

.closing-cta .button:hover {
    background: var(--black-b7);
    color: var(--white);
}

@media (prefers-color-scheme: dark) {
    /* A one-off custom color, not one of the --yellow-* scale tokens --
       none of them are this yellow-green/chartreuse. Matches the exact
       reference color supplied for dark mode (Linear's testimonial
       card), not just "a more saturated yellow" in general. */
    :root:not([data-theme="light"]) .closing-cta {
        background: #D2D957;
    }
}

:root[data-theme="dark"] .closing-cta {
    background: #D2D957;
}

/* stat-callout: a highlighted, colored box for a real, checkable
   number (never a fabricated testimonial/social-proof stand-in) --
   used both for the per-country "data journalism" stat
   (country_deep_dives.php) and for standalone product stats like the
   false-confidence-rate figure on the Name Intelligence hub page. */

.stat-callout {
    border-left: 3px solid var(--border-primary-accent);
    background: var(--bg-primary-section);
    border-radius: 0 var(--rounded-xl) var(--rounded-xl) 0;
    padding: var(--spacing-5) var(--spacing-6);
    margin: var(--spacing-6) 0;
}

.stat-callout-figure {
    font-weight: var(--weight-semibold);
    color: var(--fg-primary-accent);
    margin-bottom: var(--spacing-2);
}

.stat-callout-interpretation {
    color: var(--fg-neutral-body);
    margin-bottom: 0;
}

.naming-faq-item {
    padding: var(--spacing-4) 0;
    border-top: 1px solid var(--border-neutral-subtle);
}

.naming-faq-item:first-of-type {
    border-top: none;
    padding-top: var(--spacing-2);
}

.naming-faq-question {
    font-weight: var(--weight-semibold);
    margin-bottom: var(--spacing-1);
}

.naming-faq-answer {
    color: var(--fg-neutral-body);
    margin-bottom: 0;
}

@media (max-width: 640px) {
    .naming-pillars {
        grid-template-columns: 1fr;
    }

    .closing-cta {
        padding: var(--spacing-8) var(--spacing-6);
        margin: var(--spacing-8) 0;
    }

    .closing-cta .lead {
        margin-bottom: var(--spacing-8);
    }
}

/* country-origin: name_validation.countries, dressed up as flag chips
   -- the first (most likely) country gets an accent chip, the rest
   stay neutral. No probability number shown: the parser doesn't
   return a per-country score, only an ordered list. */

.country-origin {
    margin: 0 0 var(--spacing-4);
}

.country-origin-label {
    font-size: var(--text-size-label);
    color: var(--fg-neutral-body);
    margin-bottom: var(--spacing-2);
}

.country-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-2);
}

.country-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    font-size: var(--badge-font-size);
    font-family: var(--font-mono);
    padding: var(--badge-padding);
    border-radius: var(--badge-border-radius);
    background: var(--bg-neutral-section);
    color: var(--fg-neutral-body);
}

.country-chip-primary {
    background: var(--bg-info-section);
    color: var(--fg-info-body);
    font-weight: var(--weight-semibold);
}

/* popular-names: two ranked lists (given/family) side by side on a
   country landing page -- src/data/popular_names.php. Each row paints
   a background bar (.popular-name-bar, width set inline per item,
   relative to the #1 entry) behind the text for an at-a-glance sense
   of relative frequency, without a separate charting element. */

.popular-names {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-6);
    margin: var(--spacing-6) 0;
}

.popular-names-column {
    flex: 1;
    min-width: 260px;
    border: 1px solid var(--border-neutral-subtle);
    border-radius: var(--rounded-xl);
    padding: var(--spacing-6);
    background: var(--bg-raised);
}

.popular-names-label {
    font-size: var(--text-size-label);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-body);
    margin-bottom: var(--spacing-3);
}

ol.popular-names-list {
    list-style: none;
    counter-reset: popular-name;
    padding-left: 0;
    margin: 0;
    max-width: none;
}

ol.popular-names-list li {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    padding: var(--spacing-2) var(--spacing-3);
    border-radius: var(--rounded-sm);
}

ol.popular-names-list li::before {
    counter-increment: popular-name;
    content: counter(popular-name);
    flex-shrink: 0;
    width: 1.5em;
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    color: var(--fg-neutral-muted);
    text-align: right;
}

.popular-name-bar {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    z-index: 0;
    border-radius: var(--rounded-sm);
    background: var(--bg-info-section);
}

.popular-name-value {
    position: relative;
    z-index: 1;
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.popular-name-pct {
    position: relative;
    z-index: 1;
    color: var(--fg-neutral-muted);
    font-family: var(--font-mono);
    font-size: var(--text-size-small);
    flex-shrink: 0;
}

@media (max-width: 640px) {
    .popular-names {
        flex-direction: column;
    }

    .popular-names-column {
        min-width: 0;
    }
}

/* card grid, e.g. a features or roadmap list */

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--spacing-4);
    margin: var(--spacing-6) 0;
    padding: 0;
    list-style: none;
}

.card-grid-3 {
    grid-template-columns: repeat(3, 1fr);
}

.card-grid-2 {
    grid-template-columns: repeat(2, 1fr);
}

.card-grid-3 .card,
.card-grid-2 .card {
    /* Acts as a *minimum* height, not a fixed one -- a card whose
       content needs more room (e.g. a longer list) still grows past
       16:9 instead of clipping, since nothing here sets an explicit
       conflicting height. */
    aspect-ratio: 16 / 9;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.section .card {
    /* The card itself carries the gray, not the whole .section --
       otherwise the section's own background made everything in it
       (heading, text, card) uniformly gray instead of the card
       reading as a distinct box. */
    background: var(--bg-neutral-section);
}

@media (max-width: 640px) {
    .card-grid-3 {
        grid-template-columns: repeat(2, 1fr);
    }
}

.card {
    border: 1px solid var(--border-neutral-default);
    border-radius: var(--rounded-lg);
    padding: var(--spacing-5);
    /* Grid items default to min-width:auto (their content's intrinsic
       min size), not 0 -- a card with enough text can force its 1fr
       track wider than the grid container, overflowing the whole
       page horizontally. This lets it actually shrink to the track. */
    min-width: 0;
}

.card h4 {
    margin: 0 0 var(--spacing-2);
    font-size: var(--text-size-large);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-accent);
}

.card h4 a {
    /* Otherwise the global a{} link color (blue) wins over the
       inherited heading color -- a rule directly matching the
       element always beats inheritance, regardless of specificity. */
    color: inherit;
    text-decoration: none;
}

.card-link,
.card-link:hover {
    display: block;
    color: inherit;
    text-decoration: none;
}

/* .card's own padding puts empty space *outside* the .card-link
   anchor sitting inside it -- clicks in that ring silently miss the
   link even though the ring looks like part of the card. Move the
   padding onto the anchor itself instead, and stretch it to fill the
   card's full (aspect-ratio'd) height, so the whole visual box is one
   click target. Only applies to cards that actually wrap a link --
   plain/muted cards keep their padding directly. */
.card:has(> .card-link) {
    padding: 0;
}

.card > .card-link {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: var(--spacing-5);
    box-sizing: border-box;
}

.card-link:hover h4 {
    color: var(--fg-neutral-accent-hover, var(--fg-neutral-accent));
}

.badge {
    display: inline-block;
    font-size: var(--text-size-small);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-muted);
    border: 1px solid var(--border-neutral-default);
    border-radius: var(--rounded-full);
    padding: 0 var(--spacing-2);
    vertical-align: middle;
}

.card-product h4 {
    position: relative;
    font-size: var(--heading-size-h2);
}

.card-product h4 .badge {
    /* Raised, top-right of the title -- like a version-number pill
       riding the corner of the word, not sitting inline on its
       baseline. */
    position: relative;
    top: -0.15em;
    margin-left: 4px;
    vertical-align: top;
}

.card.card-product p {
    /* Higher specificity than .card p (same 0-1-1 otherwise, and
       .card p comes later in source) so this actually wins. */
    font-size: var(--text-size-lead);
}

.card-product h4,
.card-product p {
    text-wrap: balance;
}

/* Base CTA treatment for any card-link, e.g. foundry.php's denser
   "Current engine" card (a feature list, not just a teaser blurb, so
   it doesn't want card-product's larger type). */
.card-cta {
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-accent);
    margin-top: var(--spacing-4);
}

.card.card-product p.card-cta {
    /* Higher specificity again to override the rule directly above --
       the CTA line reads as a link, not another paragraph of body
       copy, so it stays at label size regardless. */
    font-size: var(--heading-size-h4);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-accent);
    margin-top: var(--spacing-4);
}

.card-cta .arrow {
    display: inline-block;
    transition: transform 0.15s ease;
}

.card-link:hover .card-cta .arrow {
    transform: translateX(4px);
}

.card p {
    margin: 0;
    color: var(--fg-neutral-body);
    font-size: var(--text-size-label);
}

.card.muted {
    background: var(--bg-neutral-section);
    border-color: transparent;
}

.card.muted h4, .card.muted p {
    color: var(--fg-neutral-muted);
}

/* dashed divider */

.divider {
    border: none;
    border-top: 1px dashed var(--border-neutral-default);
    margin: var(--spacing-10) 0;
}

/* footer */

.site-footer {
    flex-shrink: 0;
    margin-top: var(--spacing-20);
    /* .wordmark is position:fixed, out of normal flow entirely -- the
       page's own scrollable length no longer accounts for it at all.
       This forces just enough extra scroll room (roughly the
       wordmark's own rendered height) so the page keeps scrolling past
       it instead of running out of content right as it appears. */
    margin-bottom: 250px;
}

.footer-inner {
    max-width: var(--container-xl);
    margin: 0 auto;
    padding: var(--spacing-8) var(--spacing-5);
    position: relative;
}

.footer-inner::before {
    /* border-top: dashed gives no control over dash length/thickness
       -- a repeating gradient does. */
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    background-image: linear-gradient(to right, var(--border-neutral-default) 70%, transparent 30%);
    background-size: 16px 2px;
    background-repeat: repeat-x;
}

.footer-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: var(--spacing-8);
}

.footer-columns {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-20);
    margin-bottom: var(--spacing-8);
}

.footer-column {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
    min-width: 140px;
}

.footer-column-header {
    font-size: var(--text-size-small);
    font-weight: var(--weight-semibold);
    color: var(--fg-neutral-muted);
    margin: 0 0 var(--spacing-1);
}

.footer-column a {
    color: var(--fg-neutral-body);
    text-decoration: none;
}

.footer-column a:hover {
    color: var(--fg-neutral-accent);
}

.copyright {
    color: var(--fg-neutral-muted);
    font-size: var(--text-size-small);
    margin: 0;
}

.wordmark {
    /* position:fixed, always at the viewport bottom regardless of
       scroll -- pushed down 40% of its own height via translateY so
       40% of it permanently sits below the viewport edge, cropped.
       No background color of its own -- body::after is the only fade
       layer here, same reasoning as .site-header/body::before.
       backdrop-filter still blurs the footer content scrolling
       underneath it independently of that. */
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    z-index: 100;
    transform: translateY(40%);
    background: none;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    font-size: clamp(72px, 15vw, 200px);
    font-weight: var(--weight-heavy);
    letter-spacing: var(--heading-tracking);
    color: var(--bg-neutral-section);
    text-align: center;
    line-height: 1;
    padding: var(--spacing-8) var(--spacing-5) var(--spacing-6);
    user-select: none;
}

.wordmark::before {
    /* Mirror of .site-header::after -- the wordmark's own top edge is
       where its backdrop-filter starts, so content scrolling into view
       above it would otherwise snap from sharp to blurred in one row.
       Mask fades from opaque (bottom, seamless with the wordmark's own
       blur) to transparent (top, reveals sharp content). */
    content: '';
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    height: 24px;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    mask-image: linear-gradient(to top, black, transparent);
    -webkit-mask-image: linear-gradient(to top, black, transparent);
    pointer-events: none;
}

body::after {
    /* Mirror of body::before, for the wordmark at the bottom edge --
       same separate-overlay/no-plateau reasoning, gradient direction
       and fade ratio flipped since this anchors to the viewport's
       bottom instead of its top. */
    content: "";
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    height: var(--top-fade-height);
    background: linear-gradient(180deg, transparent 10%, var(--bg-base) 100%);
    pointer-events: none;
    z-index: 90;
}

/* mobile */

@media (max-width: 640px) {
    .site-header nav {
        flex-wrap: wrap;
        gap: var(--spacing-3);
    }

    .theme-toggle {
        /* .nav-right normally carries the margin-left: auto that
           pushes the whole right-hand group away from .brand, but it's
           display:none on mobile -- re-anchor the push to whichever
           visible element comes first after .brand, so the logo stays
           flush left and theme-toggle+burger sit flush right together.
           Placed in this later block, not the earlier mobile block
           near .nav-burger's own rules, so it wins over the
           unconditional .theme-toggle margin-left declared above. */
        margin-left: auto;
        margin-right: 0;
    }

    .wordmark {
        /* clamp()'s 15vw hits the 72px floor on phone widths, leaving
           it small with wide side gaps -- a steeper vw share and
           tighter padding instead keeps it large and flush edge-to-edge. */
        font-size: 22vw;
        padding-left: var(--spacing-3);
        padding-right: var(--spacing-3);
    }
}
