/* SITE: the public pages' ground, the paper every marketing, legal, tool and
   auth page is printed on. Every public page loads it; landing.html loads it
   first and landing.css on top. Holds the body and starfield overrides, the nav
   pill and phone header, the letterhead, the reveal system, the papyrus buttons,
   the section grammar, FAQ, the closer and the colophon. */

/* Body overrides (undo variables.css defaults). The descent into night is one
   linear-gradient across the document height, so the dark settles gradually. */
html {
    scroll-behavior: smooth;
    scroll-padding-top: var(--space-22);
    background: #100d09;
    overflow: auto;
    height: auto;
}
/* Nav-target sections carry 120px of top padding, which on a hash jump sits
   under the fixed nav; the negative scroll-margin pulls past it to a ~30px gap. */
#figures, #scene-revisions, #faq { scroll-margin-top: -90px; }
/* The -90px is tuned to the 120px desktop padding; phones carry 72px, so the
   offset drops by that 48px delta or the heading tucks under the nav. */
@media (max-width: 600px) {
    #figures, #scene-revisions, #faq { scroll-margin-top: -42px; }
}
body {
    /* Deep near-black base; body::before adds a static CSS starfield
       on top so stars are visible even when the canvas isn't running. */
    background:
        radial-gradient(ellipse 80% 50% at 50% 0%, rgba(40,34,26,0.55), transparent 70%),
        #100d09;
    color: var(--t1);
    font: 15px/1.6 var(--sans);
    /* Both lines, the way variables.css sets them for the app: with only the
       -webkit- one, Firefox on macOS renders the same row heavier than the editor. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    min-height: 100vh;
    overflow-x: clip;
    height: auto;
    position: relative;
}

/* Static CSS starfield, fixed across the viewport: base density on top of the
   JS-driven canvas stars so the sky never feels empty. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    opacity: 0.95;
    background:
        radial-gradient(1px 1px at 4% 8%,  rgba(252,226,164,0.85), transparent 60%),
        radial-gradient(1px 1px at 12% 18%, rgba(252,226,164,0.78), transparent 60%),
        radial-gradient(1.5px 1.5px at 22% 6%, rgba(248,218,148,0.7), transparent 60%),
        radial-gradient(1px 1px at 32% 22%, rgba(252,226,164,0.6), transparent 60%),
        radial-gradient(1.5px 1.5px at 42% 12%, rgba(252,226,164,0.78), transparent 60%),
        radial-gradient(1px 1px at 52% 4%,  rgba(248,218,148,0.7), transparent 60%),
        radial-gradient(1.5px 1.5px at 62% 26%, rgba(252,226,164,0.72), transparent 60%),
        radial-gradient(1px 1px at 72% 14%, rgba(248,218,148,0.66), transparent 60%),
        radial-gradient(1px 1px at 82% 26%, rgba(252,226,164,0.6), transparent 60%),
        radial-gradient(1.5px 1.5px at 92% 8%, rgba(248,218,148,0.7), transparent 60%),
        radial-gradient(1px 1px at 6% 36%,  rgba(252,226,164,0.55), transparent 60%),
        radial-gradient(1px 1px at 16% 48%, rgba(248,218,148,0.5), transparent 60%),
        radial-gradient(1.5px 1.5px at 28% 42%, rgba(252,226,164,0.65), transparent 60%),
        radial-gradient(1px 1px at 38% 56%, rgba(248,218,148,0.5), transparent 60%),
        radial-gradient(1.5px 1.5px at 48% 38%, rgba(252,226,164,0.6), transparent 60%),
        radial-gradient(1px 1px at 58% 52%, rgba(252,226,164,0.55), transparent 60%),
        radial-gradient(1px 1px at 68% 44%, rgba(248,218,148,0.5), transparent 60%),
        radial-gradient(1.5px 1.5px at 78% 58%, rgba(252,226,164,0.6), transparent 60%),
        radial-gradient(1px 1px at 88% 46%, rgba(248,218,148,0.5), transparent 60%),
        radial-gradient(1px 1px at 96% 38%, rgba(252,226,164,0.55), transparent 60%),
        radial-gradient(1px 1px at 8% 68%,  rgba(252,226,164,0.5), transparent 60%),
        radial-gradient(1.5px 1.5px at 18% 78%, rgba(252,226,164,0.55), transparent 60%),
        radial-gradient(1px 1px at 28% 72%, rgba(248,218,148,0.45), transparent 60%),
        radial-gradient(1px 1px at 38% 88%, rgba(252,226,164,0.5), transparent 60%),
        radial-gradient(1.5px 1.5px at 48% 76%, rgba(248,218,148,0.5), transparent 60%),
        radial-gradient(1px 1px at 58% 92%, rgba(252,226,164,0.45), transparent 60%),
        radial-gradient(1px 1px at 68% 82%, rgba(248,218,148,0.45), transparent 60%),
        radial-gradient(1.5px 1.5px at 78% 68%, rgba(252,226,164,0.55), transparent 60%),
        radial-gradient(1px 1px at 88% 86%, rgba(248,218,148,0.45), transparent 60%),
        radial-gradient(1px 1px at 96% 76%, rgba(252,226,164,0.5), transparent 60%);
}

/* Accent — gold phrase inside headings. Plain `display: inline` so the
   gradient text-clip never makes a box that could crop descenders; the
   right-edge breathing comes from the heading's own 0.18em padding-right. */
.accent {
    font-style: normal;
    background:
        linear-gradient(180deg,
            #faecbf 0%,
            #efcd72 18%,
            #e0b14a 38%,
            var(--accent) 55%,
            #b08125 78%,
            #8e651a 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--accent);
}

/* Skip-to-content link — visually hidden until focused */
.skip-link {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 200;
    background: var(--accent);
    color: var(--chrome-bg);
    padding: var(--space-4) var(--space-7);
    border-radius: var(--radius-sm);
    font: 600 13px var(--sans);
    text-decoration: none;
    transform: translateY(-200%);
    transition: transform 150ms ease;
}
.skip-link:focus {
    transform: translateY(0);
    outline: 2px solid var(--accent-hover);
    outline-offset: 2px;
}

/* "Doodle + sections" background (js/agent-bg.js) — opted in per page via
   body.agent-bg. The page sits on a flat deep lapis-black: no sky gradient,
   no static starfield, just the wandering pens + section boxes behind content. */
/* Middle of the lapis descent. Named, because the full-bleed sections fade
   their own edges out to exactly this ground. */
body.agent-bg { --stage-ground: #1a1610; background: var(--stage-ground); }
body.agent-bg::before { content: none; }
#agent-bg {
    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
    z-index: 0; pointer-events: none;
    /* Own compositor layer and contained paint, so the canvas's per-frame repaint
       never re-rasterizes the content behind it. */
    will-change: transform;
    contain: layout paint style;
}
/* Removed on phones: the pen is only visible in the hero band. agent-bg.js
   early-returns on a display:none canvas, so no animation loop runs. */
@media (max-width: 600px) {
    #agent-bg { display: none; }
}

/* Nav: a floating glass pill, centred by margin:0 auto + width:fit-content
   rather than a transform, so the scroll-driven .nav-hidden translateY is free. */
nav {
    position: fixed;
    top: 16px; left: 0; right: 0;
    margin: 0 auto;
    z-index: 100;
    width: fit-content;
    max-width: calc(100vw - 32px);
    padding: 0 var(--space-4) 0 var(--space-11);
    height: 56px;
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-14);
    background: rgba(22,20,15,0.62);
    backdrop-filter: blur(32px) saturate(1.6);
    -webkit-backdrop-filter: blur(32px) saturate(1.6);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: var(--radius-xl);
    box-shadow:
        0 1px 0 rgba(255,232,180,0.05) inset,
        0 0 0 1px rgba(212,168,68,0.06),
        0 10px 32px -8px rgba(0,0,0,0.45);
    opacity: 0;
    transform: translateY(0);
    transition: opacity 0.8s ease, transform 350ms cubic-bezier(.4,0,.2,1);
    /* Backstop in case JS never adds .show — fades in only opacity so
       the scroll-driven nav-hidden transform keeps working after 4s. */
    animation: nav-fade-in 0.4s 4s forwards;
}
nav.show { opacity: 1; }
nav.nav-hidden { transform: translateY(-160%); }

/* Static pages (body.chrome-static) have no entrance choreography, so the
   opacity:0 + 4s backstop is replaced by a prompt fade-in and the header does
   not arrive late. Reduced motion is handled by the rule below. */
body.chrome-static nav { animation: nav-fade-in 680ms var(--ease) 40ms both; }

@keyframes nav-fade-in {
    to { opacity: 1; }
}

@keyframes ensure-visible {
    to { opacity: 1; transform: none; }
}
.nav-logo {
    font: 500 14px var(--sans); color: var(--t1);
    display: flex; align-items: center; gap: var(--space-5);
    letter-spacing: -0.01em;
    text-decoration: none;            /* it's an <a> home link on every page */
    transition: color 150ms;
}
.nav-logo svg { width: 24px; height: 24px; display: block; transition: transform 180ms ease, filter 180ms ease; }
/* Two-tone wordmark: keep "Cite" steady, brighten "Owl", and lift the owl
 * medallion with a soft gold glow — instead of flattening the whole logo gold. */
.nav-logo:hover { color: var(--t1); }
.nav-logo:hover svg { transform: scale(1.07); filter: drop-shadow(0 1px 5px rgba(var(--accent-rgb), 0.55)); }

/* Brand lockup — a papyrus plaque pinned top-left (a gilt cartouche over the dark
 * hero): the original perched owl in black (papyrus negative-space eyes) + serif
 * wordmark — dark "Cite", brick-red "Owl" (the app citation accent). */
.site-brand {
    position: absolute; top: 22px; left: 24px; z-index: 90;
    display: inline-flex; align-items: center; gap: var(--space-4);
    text-decoration: none;
    padding: var(--space-3) var(--space-8) var(--space-3) var(--space-5);
    background: var(--grad-papyrus);
    border: 1px solid rgba(201,154,62,0.55);
    border-radius: var(--radius-btn);
    box-shadow:
        inset 0 1px 0 rgba(255,250,235,0.55),
        0 10px 26px -12px rgba(0,0,0,0.55),
        0 3px 16px -6px rgba(212,168,68,0.18);
    transition: transform 200ms ease, box-shadow 200ms ease;
    /* settles in like a stamp being placed (backwards fill = hidden during the
       delay, then no forwards fill so :hover transform still works after). */
    animation: plaque-appear 600ms var(--ease) 400ms backwards;
}
/* shared by the landing + footer + auth plaques (auth loads site.css) */
@keyframes plaque-appear {
    from { opacity: 0; transform: translateY(-6px) scale(0.95); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .site-brand, .footer-plaque, .auth-brand, .nav-brand { animation: none !important; }
}
.site-brand-mark { height: 37px; width: auto; display: block; }
.site-brand-name { font: 600 25px/1 var(--serif); letter-spacing: -0.01em; color: #2a1d10; }
/* "Owl" in the app's brick-red (--doc-accent), not gold. */
.site-brand .brand-owl-grad {
    background: none; -webkit-background-clip: border-box; background-clip: border-box;
    -webkit-text-fill-color: var(--doc-accent); color: var(--doc-accent);
}
.site-brand:hover { transform: translateY(-1px); box-shadow: inset 0 1px 0 rgba(255,250,235,0.6), 0 14px 30px -12px rgba(0,0,0,0.55), 0 5px 20px -6px rgba(212,168,68,0.24); }
/* Compact plaque from 900px down, the breakpoint the nav collapses at, so the
   brand and the pill align as a matched pair in opposite corners. */
/* On phones the brand moves INTO the nav pill (see the <=900 nav block below),
   so the standalone top-left plaque is hidden to avoid two brands on screen. */
@media (max-width: 900px) {
    .site-brand { display: none; }
}

/* Landing: nav pill and corner plaque are both hidden (the ONE DOCUMENT block
   at the end of this file) and the brand renders as .doc-masthead. */
.landing-page .site-brand { display: none; }
/* Wordmark ink for the phone pill cap on non-landing pages (the dark
   plaque ink also used by .site-brand-name). */
.nav-brand-name { font: 600 20px/1 var(--serif); letter-spacing: -0.01em; color: #2a1d10; }
.nav-brand-owl { color: var(--doc-accent); }
.nav-links { display: flex; align-items: center; gap: var(--space-12); }
.nav-link {
    text-decoration: none;
    color: var(--t3);
    font: 400 14px var(--sans);
    transition: color 150ms;
}
.nav-link:hover { color: var(--t1); }

/* Brand inside the nav — only used on the phone header (<=900px), where the
   owl + wordmark live in the dark-glass pill. On desktop the brand is the
   top-left .site-brand plaque, so this stays hidden. */
.nav-brand { display: none; }

/* Menu button — hidden on desktop; on the phone header it's the labeled "Menu"
   control (bars + word) centered in the bar. Carries no chrome of its own. */
.nav-hamburger {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    align-items: center;
    padding: 0;
}
.nav-hamburger:focus,
.nav-hamburger:focus-visible { outline: none; }
.nav-hamburger-bars {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.nav-hamburger-bar {
    display: block;
    width: 18px;
    height: 2px;
    background: var(--t1);
    border-radius: 1px;
    transition: transform 150ms ease, opacity 150ms ease;
}
nav.nav-open .nav-hamburger-bar:nth-child(1) { transform: translateY(6px) rotate(45deg); }
nav.nav-open .nav-hamburger-bar:nth-child(2) { opacity: 0; }
nav.nav-open .nav-hamburger-bar:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* Phone / small-tablet header (<=900px): brand plaque, labeled menu and Sign in
   merge into ONE dark-glass object, the links unrolling out of the same sheet.
   .nav-links takes flex-basis:100%; order is CSS, so the DOM stays desktop-first. */
@media (max-width: 900px) {
    nav {
        left: 14px; right: 14px;
        top: 14px;
        margin: 0;
        width: auto;
        height: auto;
        padding: 0 var(--space-6);
        gap: 0;
        flex-wrap: wrap;
        align-items: center;
        justify-content: space-between;   /* brand cap · Menu · Sign in cap */
        background: rgba(22,20,15,0.86);
        overflow: hidden;            /* clips the unroll to the rounded corners */
    }
    /* brand — the papyrus PLAQUE nested inside the dark glass, so the brand keeps
       its cream lockup and the owl reads against a bright surface. */
    .nav-brand {
        display: inline-flex;
        order: 1;
        align-items: center;
        align-self: stretch;          /* fill the pill height -> a flush cap */
        gap: var(--space-4);
        margin-left: -12px;           /* break out of the nav's left padding so it sits flush;
                                         the nav's radius + overflow:hidden clip the left corners */
        text-decoration: none;
        padding: 0 var(--space-7) 0 var(--space-7);
        background: var(--grad-papyrus);
        border-radius: 0 10px 10px 0; /* square left (clipped to the bar corner), rounded into the glass on the right */
        box-shadow: inset 0 1px 0 rgba(255,250,235,0.5), 2px 0 8px -3px rgba(0,0,0,0.4);
    }
    .nav-brand-mark { height: 28px; width: auto; display: block; }
    /* wordmark ink + brick "Owl" come from the unconditional rules above */

    /* Sign in is a flush GOLD cap on the right end — mirrors the brand cap's
       shape (papyrus left, gold right), keeping the CTA hot (gold on dark). */
    .nav-cta {
        order: 3;
        align-self: stretch;
        margin: 0 -12px 0 0;          /* flush to the right edge */
        padding: 0 var(--space-8);
        font-size: 14px;
        border-radius: 10px 0 0 10px; /* rounded into the glass on the left, square right (clipped) */
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), -2px 0 9px -3px rgba(0,0,0,0.4);
    }
    .nav-hamburger {
        display: inline-flex;
        order: 2;                      /* space-between drops it midway between the two caps */
        flex-direction: row;           /* bars + "Menu" word side by side */
        gap: var(--space-4);
        height: 46px;                  /* anchors the pill-row band; the caps stretch to fill it */
    }
    .nav-hamburger-label {
        font: 500 14px var(--sans);
        color: var(--t1);
        letter-spacing: 0.01em;
    }

    /* The links unroll out of the SAME sheet: full-width second line, no chrome
       of its own, height-animated open. The fold-line rides this block's top
       edge, so it auto-positions at the seam whatever the pill row height. */
    .nav-links {
        order: 4;
        position: relative;
        flex-basis: 100%;
        width: 100%;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        max-height: 0;
        opacity: 0;
        overflow: hidden;
        padding: 0;
        pointer-events: none;
        transition: max-height 300ms var(--ease), opacity 160ms ease,
                    padding 300ms var(--ease);
    }
    /* seam between the pill row and the links — the same subtle divider as the
       ones between links, so the first line reads as a normal line, not special. */
    .nav-links::before {
        content: '';
        position: absolute;
        top: 0; left: 0; right: 0;
        height: 1px;
        background: var(--chrome-border-subtle);
    }
    nav.nav-open .nav-links {
        max-height: min(70vh, 520px);
        opacity: 1;
        /* Symmetric end padding: each link carries 12px of its own, so an even 6px
           top and bottom lands ~18px of breathing room at both ends. */
        padding: var(--space-3) 0;
        pointer-events: auto;
    }
    .nav-link {
        padding: var(--space-6) var(--space-1);
        border-bottom: 1px solid var(--chrome-border-subtle);
        font-size: 15px;
        /* In the expanded menu these are the primary tap targets with no hover to
           brighten them, so the desktop pill's --t3 reads as disabled. --t2
           keeps the brand and CTA the brightest elements. */
        color: var(--t2);
    }
    .nav-link:last-of-type { border-bottom: none; }
}

/* ---- Reveal-on-scroll system ----------------------------------------
   Four entrance directions, all driven by IntersectionObserver (.show).
   `data-delay="120"` per item is forwarded by the JS as a CSS variable. ---- */
.reveal,
.reveal-up,
.reveal-left,
.reveal-right,
.reveal-scale {
    opacity: 0;
    /* Two curves on purpose: opacity ramps close to evenly (the page's usual
       fast-start curve reads as a switch flipping), the offset settles on ease-out. */
    transition: opacity 560ms cubic-bezier(.32,.08,.32,1), transform 560ms cubic-bezier(.22,.61,.36,1);
    transition-delay: var(--reveal-delay, 0ms);
    will-change: opacity, transform;
    animation: ensure-visible 0.4s 4s forwards;   /* backstop, see below */
}
/* A fade alone reads as a light switching on, so each direction carries a
   small offset it settles out of. Kept short (~14px) because a reload lands
   mid-page and it has to read as a settle, not as content sliding around. */
.reveal-up { transform: translateY(14px); }
.reveal-left { transform: translateX(-14px); }
.reveal-right { transform: translateX(14px); }
.reveal-scale { transform: scale(0.985); }

.reveal.show,
.reveal-up.show,
.reveal-left.show,
.reveal-right.show,
.reveal-scale.show { opacity: 1; transform: none; }
/* Never the scroll anchor. A transform sets Chrome's disable-anchoring flag and
   only a LAYOUT clears it, so a revealed box anchoring the viewport suppresses
   every compensation for the rest of the visit. */
.reveal, .reveal-up, .reveal-left, .reveal-right, .reveal-scale { overflow-anchor: none; }

/* Phone timing: 560ms is cut for a wheel and a thumb throws the page, so the
   fade runs in half the time and travels less (landing.js pre-rolls too). */
@media (max-width: 900px) {
    .reveal,
    .reveal-up,
    .reveal-left,
    .reveal-right,
    .reveal-scale {
        transition: opacity 340ms cubic-bezier(.32,.08,.32,1),
                    transform 380ms cubic-bezier(.22,.61,.36,1);
    }
    .reveal-up { transform: translateY(9px); }
    .reveal-left { transform: translateX(-9px); }
    .reveal-right { transform: translateX(9px); }
}

/* An element the reader has ALREADY scrolled past lands whole. Set by the
   reveal observer when the page arrives mid-scroll (a restored position, an
   anchor, or a thumb that started before the entrance finished). */
.reveal.reveal-instant,
.reveal-up.reveal-instant,
.reveal-left.reveal-instant,
.reveal-right.reveal-instant,
.reveal-scale.reveal-instant { transition: none; }

/* The backstop makes the page legible if JS never runs, but it is an animation:
   `forwards` pins opacity at 1 and outranks the transition forever after, so it
   is armed only once landing.js has the reveal observers. */
html.reveals-armed .reveal,
html.reveals-armed .reveal-up,
html.reveals-armed .reveal-left,
html.reveals-armed .reveal-right,
html.reveals-armed .reveal-scale { animation: none; }


/* ONE typographic system for every section heading on the page. Modest
   letter-spacing so no glyph clips on the right edge, especially under the
   gradient background-clip on .accent. */
.chapter-heading,
.scene-heading,
.pricing-heading,
.faq-heading,
.cta h2 {
    font: var(--font-section);
    color: var(--t1);
    letter-spacing: var(--track-heading);
    margin: 0 0 var(--space-6);
    max-width: 32ch;
    /* Right padding for gradient text-clip overhang, bottom padding
       so lowercase descenders (g, y, p) don't crop. */
    padding-right: 0.18em;
    padding-bottom: 0.20em;
    overflow: visible;
}
.chapter-desc,
.scene-desc,
.cta p {
    font: var(--font-lead);
    color: var(--t2);
    max-width: 56ch;
    margin: 0;
    letter-spacing: -0.005em;
}

/* CTA & FOOTER */
.cta {
    text-align: center;
    padding: var(--space-26) var(--space-17) var(--space-27);
    position: relative; z-index: 2;
    max-width: 1100px; margin: 0 auto;
}
/* The CTA inherits the shared section-heading / section-description rules
   above. The only CTA-specific styles are centering and the subtitle-to-button
   gap, which is the hero's own 48px. */
.cta h2 {
    max-width: none;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}
/* On the landing page the closer's subline is a section lead; that rule is
   .cta.paper-band--cta p, further down. Here it only centres. */
.cta p {
    margin: 0 auto var(--space-19);
}

footer {
    position: relative; z-index: 2;
    padding: var(--space-22) 0 var(--space-15);
    width: 100%;
    /* night-earth glass with a faint warm afterglow rising from the horizon */
    background:
        radial-gradient(ellipse 72% 100% at 50% 0%, rgba(var(--accent-rgb), 0.06), transparent 60%),
        rgba(10,8,6,0.55);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
}
/* the horizon — the sun's last light resting on the line where night meets ground */
footer::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(var(--accent-rgb), 0.42) 50%, transparent);
}
.footer-wrap {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--space-17);
}
.footer-inner {
    display: grid;
    grid-template-columns: 1.3fr 2fr;
    gap: var(--space-20);
    align-items: start;
    margin-bottom: var(--space-18);
}
.footer-brand { display: flex; flex-direction: column; gap: var(--space-7); align-items: flex-start; }
/* footer brand — the papyrus plaque (warm sign-off in the dark footer) */
.footer-plaque {
    display: inline-flex; align-items: center; gap: var(--space-4); text-decoration: none;
    padding: var(--space-3) var(--space-8) var(--space-3) var(--space-5);
    background: var(--grad-papyrus);
    border: 1px solid rgba(201,154,62,0.55);
    border-radius: var(--radius-btn);
    box-shadow: inset 0 1px 0 rgba(255,250,235,0.55), 0 10px 26px -12px rgba(0,0,0,0.55), 0 3px 16px -6px rgba(212,168,68,0.18);
    transition: transform 200ms ease, box-shadow 200ms ease;
}
.footer-plaque:hover { transform: translateY(-1px); }
.footer-plaque-mark { height: 37px; width: auto; display: block; }
.footer-plaque-name { font: 600 25px/1 var(--serif); letter-spacing: -0.01em; color: #2a1d10; }
.footer-plaque .brand-owl-grad {
    background: none; -webkit-background-clip: border-box; background-clip: border-box;
    -webkit-text-fill-color: var(--doc-accent); color: var(--doc-accent);
}
.footer-tagline {
    font: 400 13px/1.6 var(--sans); color: var(--t3);
    max-width: 260px;
}
.footer-cols {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-15);
}
.footer-col { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-5); }
.footer-col-title {
    font: 600 11px var(--sans); color: var(--t2);
    text-transform: uppercase; letter-spacing: var(--track-eyebrow);
    margin-bottom: var(--space-1);
}
.footer-col a {
    font: 400 13px var(--sans); color: var(--t3);
    text-decoration: none; transition: color 150ms;
    overflow-wrap: anywhere;
}
.footer-col a:hover { color: var(--t1); }
.footer-bottom {
    border-top: 1px solid rgba(255,255,255,0.05);
    padding-top: var(--space-9);
    display: flex; align-items: center; gap: var(--space-4);
    font: 400 12px var(--sans); color: var(--t3); opacity: 0.6;
}
.footer-bottom-sep { color: var(--t3); opacity: 0.5; }
@media (max-width: 800px) {
    .footer-inner { grid-template-columns: 1fr; gap: var(--space-16); }
    .footer-cols { gap: var(--space-12); }
}
@media (max-width: 560px) {
    .footer-cols { grid-template-columns: repeat(2, 1fr); gap: var(--space-14); }
}

/* 901-1000px still shows the full centered link bar and wants a little more
   breathing room. Scoped to the upper range so it cannot clobber the hamburger
   pill's own padding in the <=900 block. */
@media (min-width: 901px) and (max-width: 1000px) {
    nav { padding: 0 var(--space-8); }
}
@media (max-width: 600px) {
    /* The header brand STAMPS in when the nav reveals; on phones .nav-brand shows
       instead of .site-brand. Landing only: on chrome-static pages the nav already
       fades in, and stamping an already-visible brand blinks the header. */
    body:not(.chrome-static) nav.show .nav-brand { animation: plaque-appear 600ms var(--ease) both; }
    .cta { padding: var(--space-18) var(--space-7) var(--space-19); }
    footer { padding-top: var(--space-19); }
    /* Brand plaque and tagline move BELOW the link columns on phones: stacked,
       the bright cream cartouche sat under the gold closing CTA and pulled
       attention off it. */
    .footer-cols { order: 1; }
    .footer-brand { order: 2; }
}
.faq-list {
    display: flex; flex-direction: column;
}
.faq-item {
    border-bottom: 1px solid var(--chrome-border-subtle);
    transition: border-color 200ms var(--ease);
    /* Inherited by ::details-content, which is what lets the answer panel
       animate to and from its natural height. Lives on the item, not the
       section, so the accordion animates in whatever wrapper hosts it. */
    interpolate-size: allow-keywords;
}
.faq-item:first-child { border-top: 1px solid var(--chrome-border-subtle); }
.faq-item:hover { border-bottom-color: rgba(212,168,68,0.25); }
.faq-q {
    list-style: none;
    cursor: pointer;
    padding: var(--space-13) var(--space-2);
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-12);
    font: 400 18px var(--serif); color: var(--t1);
    letter-spacing: -0.01em;
    transition: color 200ms var(--ease);
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q:hover { color: var(--accent); }
.faq-chev {
    flex-shrink: 0; width: 28px; height: 28px;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--accent);
    /* 200 is the family's thinnest cut and came out lighter than a hairline on
       papyrus; 400 puts the plus's stem at the drawn tick's own ~2px weight. */
    font: 400 22px var(--sans);
    transition: transform 300ms var(--ease);
}
.faq-item[open] .faq-chev { transform: rotate(45deg); }
/* Smooth open/close: animate the generated content box from 0 → auto height.
   Browsers without ::details-content just snap (current behaviour). */
.faq-item::details-content {
    height: 0;
    overflow: hidden;
    transition: height 360ms var(--ease), content-visibility 360ms allow-discrete;
}
.faq-item[open]::details-content {
    height: auto;
}
.faq-a {
    padding: 0 var(--space-2) var(--space-14);
    font: 400 15px/1.75 var(--sans); color: var(--t2);
    max-width: 680px;
    transform: translateY(-6px);
    opacity: 0;
    transition: transform 360ms var(--ease), opacity 280ms var(--ease);
}
.faq-item[open] .faq-a {
    transform: none;
    opacity: 1;
}
.faq-a a { color: var(--accent); text-decoration: none; }
.faq-a a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* The FAQ set INSIDE the manuscript (the landing only): §6 is a numbered
   section of the paper, so the column's cut is scoped here. The FLOORS carry the
   phone tuning below, these rules outranking that media query on specificity. */
.doc-sec .faq-q { font-size: clamp(16px, 0.66vw + 12px, 22px); }
.doc-sec .faq-a { font-size: clamp(14px, 0.55vw + 10.7px, 19px); }

/* prefers-reduced-motion: skip the entrance, freeze cursor and scene replay. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    nav,
    .reveal,
    .reveal-up,
    .reveal-left,
    .reveal-right,
    .reveal-scale,
    .hero-stagger,
    .anim-msg,
    .anim-section,
    .mockup .preview-bar,
    .mockup .rev-item,
    .mockup .src-card {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
        animation: none !important;
    }
    .landing-btn-primary { transition: none !important; }
    .landing-btn-primary:hover { transform: none !important; }
    .landing-btn-secondary { transition: none !important; }
    .landing-btn-secondary:hover { transform: none !important; }
    .faq-chev { transition: none !important; }
    .faq-item::details-content { transition: none !important; }
    .faq-a { transition: none !important; transform: none !important; }
}
/* .chapter-heading inherits from the unified rule above.
   Override only the margin/max-width specific to chapter pages. */
.chapter-heading {
    margin: 0;
    max-width: 32ch;
}
.chapter-desc {
    font: var(--font-lead);
    color: var(--t2);
    max-width: 56ch;
    margin: 0 auto;
    letter-spacing: -0.005em;
}

/* MOBILE VERTICAL-SPACING PASS: phone overrides that have to come last in source order to beat the desktop rules above. */
@media (max-width: 600px) {

    /* FAQ reads as a wall on phones: 18px serif questions on 24px padding,
       stacked ~10 deep, every row its own heading. Shrink and tighten. */
    .faq-q { padding: var(--space-8) var(--space-1); font-size: 16px; gap: var(--space-8); }
    .faq-a { padding-bottom: var(--space-11); font-size: 14px; }
}


/* HERO: full-bleed papyrus, no frame and no card. The viewport is the page. */
.paper-hero {
    position: relative;
    z-index: 2;
    /* No min-height: the hero is exactly as tall as the title block it holds. */
    /* Same radial the real doc area uses, so this is the app's paper and
       not a beige rectangle that resembles it. */
    background: radial-gradient(ellipse at 50% 34%, var(--doc-bg-light) 0%, var(--doc-bg) 72%);
    color: var(--td1);
    overflow: hidden;
    display: flex;
    align-items: center;
    padding: calc(var(--space-25) + var(--space-10)) var(--space-17) var(--space-19);
}
/* Grain: the one texture on the page. Without it a 100vh flat fill reads
   as a colour swatch rather than paper. */
.paper-hero::before {
    content: '';
    position: absolute; inset: 0;
    pointer-events: none;
    opacity: 0.5;
    background:
        radial-gradient(1px 1px at 12% 22%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 47% 68%, rgba(90,74,44,0.09), transparent 60%),
        radial-gradient(1px 1px at 78% 34%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 31% 84%, rgba(90,74,44,0.08), transparent 60%),
        radial-gradient(1px 1px at 88% 76%, rgba(90,74,44,0.09), transparent 60%);
    background-size: 180px 180px, 220px 220px, 260px 260px, 200px 200px, 240px 240px;
}

/* ---- The manuscript column ---- */
.paper-hero-doc {
    position: relative; z-index: 2;
    width: 100%;
    max-width: 760px;
    margin: 0 auto;
}

.paper-hero h1 {
    font: var(--font-display);
    /* Capped under the token's 88px so the sentence breaks in TWO lines across the
       column; 74 is the measured ceiling for a 760px column. */
    font-size: clamp(31px, 5.6vw, 74px);
    color: var(--td1);
    letter-spacing: var(--track-heading);
    margin: 0 0 var(--space-9);
    padding: 0 0.06em 0.2em 0;
}
/* On papyrus the gold gradient washes out and, by the palette rule, brick
   is the accent this ground owns. Flat brick, no gradient clip. */
.paper-hero h1 .accent,
.paper-band .accent,
.cta-copy .accent {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--doc-accent);
}
.paper-hero-abstract {
    /* THE SAME LEAD as every section head, to the byte. If this cut changes, change
       it in ONE place: auth.css mirrors it by hand and says so. Live for /pricing,
       which overrides only the margin, so it is not dead code. */
    font: 400 clamp(18px, 0.5vw + 15px, 23px)/1.5 var(--sans);
    letter-spacing: -0.008em;
    color: var(--td2);
    /* 54ch left "so." alone on a third line. Two more characters of
       measure pull the closing clause up and the abstract sets in two. */
    max-width: 58ch;
    margin: 0 0 var(--space-17);
}

/* ---- Papyrus-ground buttons. Brick, per "one red per ground". ---- */
.paper-btn {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--grad-brick-pill, var(--doc-accent));
    color: var(--t1);
    font: 600 15px var(--sans);
    letter-spacing: -0.005em;
    padding: var(--space-8) var(--space-16);
    /* The app's roundness SCALED, not copied: --radius-btn is 8px on ~30px
       controls, a ratio of ~0.27, and 53 x 0.27 = 14. The raw token read almost
       square at this size, and a full pill is a shape the product doesn't wear. */
    border-radius: 14px;
    /* No outline: a 1px black stroke around a brick pill reads as a drawn border
       on paper rather than as the pill's own edge. The inset highlight and the
       drop shadow give it its edge. */
    border: none;
    text-decoration: none;
    box-shadow: 0 1px 0 rgba(255,255,255,0.16) inset, 0 6px 18px -8px rgba(60,20,12,0.7);
    transition: transform 160ms var(--ease-out), box-shadow 160ms var(--ease-out), filter 160ms;
}
.paper-btn:hover { filter: brightness(1.06); transform: translateY(-1px); box-shadow: 0 1px 0 rgba(255,255,255,0.18) inset, 0 10px 26px -10px rgba(60,20,12,0.75); }
.paper-btn:active { transform: translateY(0); }
/* Same ratio at the closer's 62px height: 62 x 0.27 = 17. */
.paper-btn--lg { font-size: 16px; padding: var(--space-10) var(--space-18); border-radius: 17px; }

.paper-link {
    display: inline-flex; align-items: center; gap: var(--space-4);
    color: var(--td3);
    font: 500 14px var(--sans);
    text-decoration: none;
    background: none; border: none; cursor: pointer;
    padding: var(--space-5) 0;
    transition: color 180ms;
}
.paper-link:hover { color: var(--doc-accent); }
.paper-link-arrow { display: inline-block; transition: transform 180ms; }
.paper-link:hover .paper-link-arrow { transform: translateY(2px); }

@media (max-width: 900px) {
    .paper-hero {
        min-height: auto;
        padding: calc(var(--space-25) + var(--space-4)) var(--space-12) var(--space-17);
    }
    .paper-hero h1 { max-width: 100%; }
}


/* THE REVIEW BAND: papyrus, and the only interactive thing on the page. */
.paper-band {
    position: relative; z-index: 2;
    background: radial-gradient(ellipse at 50% 30%, var(--doc-bg-light) 0%, var(--doc-bg) 72%);
    color: var(--td1);
    padding: var(--space-26) var(--space-17);
}

@media (max-width: 900px) {
    .paper-band { padding: var(--space-22) var(--space-12); }
}

/* -- Laptop: the writing surface -- */
/* One scale variable per device drives BOTH the outer box and the inner
   transform, so a narrower screen shrinks the whole thing instead of cropping. */
/* The bezel is part of the device, NOT part of the screen: the outer box is the
   scaled surface PLUS both borders, or border-box eats the interior. */
/* The lid carries a bezel on all four sides, the bottom one being the chin.
   Both borders are added to the height as the sides are added to the width. */
/* THE FRAME IS PART OF THE MACHINE, so it shrinks with it: a flat bezel makes
   the machine fatter the smaller it gets. Every derived height below is a
   multiple of --lap-bez, and the coefficients reproduce the desk tier exactly. */
.landing-page { --lap-s: 0.4375; --ph-s: 0.60;
                --lap-bez: max(4px, 20.6px * var(--lap-s));
                --ph-bez: max(3.5px, 13.3px * var(--ph-s));
                --lap-chin: calc(var(--lap-bez) * 1.7); }
/* The deck: head-on the base shows three surfaces, and the depth is which way
   each faces (the void under the chin, the deck foreshortened to shade, the face
   with one specular line). Heights are multiples of --lap-bez, not --lap-s. */
.landing-page { --lap-deck: calc(var(--lap-bez) * 0.3);
                --lap-void: calc(var(--lap-bez) * 0.75); }

/* With the rails still up the centre column bottoms out near 716px while the
   pair at full scale is 818, and centring slides each device under a rail. */
@media (max-width: 1340px) {
    .landing-page { --lap-s: 0.37; --ph-s: 0.55; }
}
/* Same physical widths as before the surfaces grew: each phone notch holds the
   390 surface at the width the 360 one had. */
@media (max-width: 1000px) {
    .landing-page { --lap-s: 0.345; --ph-s: 0.52; }
}
@media (max-width: 620px) {
    /* The tier trades laptop for phone: at this width the phone is the device the
       visitor is holding, so it keeps the larger share when fitMockups() shrinks. */
    .landing-page { --lap-s: 0.235; --ph-s: 0.48; }
}


/* THE CLOSER: bookends the hero on the same material, bibliography showing. */
.paper-band--cta {
    max-width: none; margin: 0;
    text-align: left;
    padding: 0;
    overflow: hidden;
    display: grid;
    align-items: center;
    /* The band is sized by its own padding, with a floor that keeps it a band. */
    min-height: 42vh;
}
.paper-band--cta > * { grid-area: 1 / 1; }
.cta-copy {
    position: relative; z-index: 2;
    max-width: 1100px; margin: 0 auto; width: 100%;
    padding: var(--space-20) var(--space-17) var(--space-22);
    text-align: center;
}
.cta.paper-band--cta h2 {
    color: var(--td1);
    margin: 0 auto var(--space-6);
    /* One line. The 20ch clamp broke "Start writing your next paper."
       after "next", and a five-word closer split 4/1 read as a typo. */
    max-width: none;
    text-align: center;
}
.cta.paper-band--cta p {
    /* A SECTION LEAD, byte for byte with .doc-sec-lead: every line on this page
       that sells rather than narrates is a lead, and this is the last of them. */
    font: 400 clamp(18px, 0.5vw + 15px, 23px)/1.5 var(--sans);
    letter-spacing: -0.008em;
    color: var(--td2);
    /* No ch cap: the line is 52 characters, and a 46ch measure broke it after
       "or". Centred in a 1100px band it sits on one. */
    max-width: none;
    margin: 0 auto var(--space-17);
    text-align: center;
}
/* The closer's pointer: one static stroke from the headline's last letter onto
   the centred button. Both ends are pinned, so only the run between them moves;
   it stretches rather than scales (non-scaling-stroke) and overflows its box. */
.cta-copy h2 .accent { position: relative; }
/* Drawn at 3 where the annotations are 2.2: this is the page's only dead-flat
   run, and below 2.3 a 1x display drops the antialiased fringe entirely. */
.cta-point {
    position: absolute;
    right: -18px;
    /* The word's own middle: the accent's box is its line box plus the heading's
       descender padding, so 0.69em from its top is where the lowercase letters are. */
    top: calc(0.69em - 6px);
    width: calc(5.118em - 56.4px);
    height: 180px;
    color: var(--doc-accent);
    pointer-events: none;
    opacity: 0.9;
}
.cta-point svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* Desk only, with the drawn overlay: narrower than this the headline, the
   lead and the button stop holding the distances a fixed mark is cut for. */
@media (max-width: 1179px) { .cta-point { display: none; }
}

/* The headline needs to hold its own over the manuscript behind it. */
.cta-copy::before {
    content: '';
    position: absolute; inset: -6% -12%;
    background: radial-gradient(ellipse at 50% 50%, var(--doc-bg-light) 0%, rgba(220,208,176,0.86) 45%, transparent 74%);
    z-index: -1;
    pointer-events: none;
}

@media (max-width: 900px) {
    .paper-band--cta { min-height: 0; }
    .cta-copy { padding: var(--space-19) var(--space-12); }
}

/* Nav crosses papyrus now, where a 0.62 scrim turned the links to mud. */
.landing-page nav { background: rgba(22,20,15,0.88); }


/* THE APP FRAME: fixed rails at both edges, the page scrolling in the column between them, the way the document sits between the app's panels. */
.landing-page {
    --rail-l: clamp(210px, 17vw, 268px);
    --rail-r: clamp(250px, 21vw, 340px);
}

@media (min-width: 1180px) {

    /* The column. Padding rather than a margin so the papyrus bands still
       paint their own full-width ground and only their CONTENT insets. */
    .landing-page main,
    .landing-page footer {
        padding-left: var(--rail-l);
        padding-right: var(--rail-r);
    }
    /* Inside the column the hero sets its own margins. */
    .paper-hero { padding-left: var(--space-19); padding-right: var(--space-19); }
}

/* Nav sits on the COLUMN's midline once the rails are in. left/right rather
   than a margin or a transform: the transform slot is the scroll-away's. */
@media (min-width: 1180px) {
    .landing-page nav { left: var(--rail-l); right: var(--rail-r); }
}

/* Rail links land the same way the top nav's do: every section on the
   page carries ~120px of top padding, so the jump is pulled back past
   it to leave the heading just under the nav rather than 190px down. */
#hero, #scene-research, #figures,
#scene-revisions, #anywhere, #why, #faq { scroll-margin-top: -90px; }
@media (max-width: 600px) {
    #hero, #scene-research, #figures,
    #scene-revisions, #anywhere, #why, #faq { scroll-margin-top: -42px; }
}


/* ONE CONTINUOUS SHEET: <main> is papyrus from the nav to the footer, and the rhythm comes from hairlines, numbers and exactly one dark plate. */
.landing-page main {
    position: relative;
    z-index: 2;
    color: var(--td1);
    /* A single light at the head of the sheet, then flat. A radial over
       9000px would read as a stain rather than as paper under a lamp. */
    background:
        radial-gradient(ellipse 90% 520px at 50% 0, var(--doc-bg-light) 0%, transparent 100%),
        var(--doc-bg);
}
/* The grain moves to the sheet, so it is one texture rather than one per
   band. */
.landing-page main::before {
    content: '';
    position: absolute; inset: 0;
    pointer-events: none;
    z-index: 0;
    opacity: 0.5;
    /* Never the scroll anchor: spanning the sheet, it is main's first box and
       always partly in view, so nothing reflowing above the reader was compensated. */
    overflow-anchor: none;
    background:
        radial-gradient(1px 1px at 12% 22%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 47% 68%, rgba(90,74,44,0.09), transparent 60%),
        radial-gradient(1px 1px at 78% 34%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 31% 84%, rgba(90,74,44,0.08), transparent 60%),
        radial-gradient(1px 1px at 88% 76%, rgba(90,74,44,0.09), transparent 60%);
    background-size: 180px 180px, 220px 220px, 260px 260px, 200px 200px, 240px 240px;
}
.landing-page main > * { position: relative; z-index: 1; }

/* The per-band grounds retire: there is one sheet now. */
.landing-page .paper-hero,
.landing-page .paper-band,
.landing-page .paper-band--cta { background: none; }
.landing-page .paper-hero::before { content: none; }

/* ---- Type on paper ---- */
.landing-page main .chapter-heading,
.landing-page main .stage-heading,
.landing-page main .faq-heading,
.landing-page main .cta h2 { color: var(--td1); }
.landing-page main .chapter-desc,
.landing-page main .stage-desc,
.landing-page main .cta p { color: var(--td2); }
/* Gold is a chrome signal and washes out on papyrus; brick is the accent
   this ground owns. Flat, no gradient clip. */
.landing-page main .accent {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--doc-accent);
}


/* ---- FAQ, as a document's own question list ---- */
.landing-page .faq-item { border-bottom-color: rgba(16,16,10,0.12); }
.landing-page .faq-item:first-child { border-top-color: rgba(16,16,10,0.12); }
.landing-page .faq-item:hover { border-bottom-color: rgba(139,58,42,0.30); }
.landing-page .faq-q { color: var(--td1); }
.landing-page .faq-q:hover { color: var(--doc-accent); }
.landing-page .faq-chev { color: var(--doc-accent); }
.landing-page .faq-a { color: var(--td2); }
.landing-page .faq-a a { color: var(--doc-accent); }

/* ---- The closer sits on the sheet already, so the wash behind the copy
   only has to lift it off the ghosted manuscript. ---- */
.cta-copy::before {
    background: radial-gradient(ellipse at 50% 50%, var(--doc-bg-light) 0%, rgba(220,208,176,0.92) 42%, transparent 72%);
}

/* The wandering pen is drawn in cream on the dark ground and is invisible
   on paper, so it keeps to the ends of the page rather than showing as a
   smear behind the sheet. */
.landing-page #agent-bg { opacity: 0.5; }


/* Type scale retuned for the COLUMN: the heading clamps are vw-based, and once
   the rails take 550px they were sizing to a screen the text no longer occupies. */
@media (min-width: 1180px) {
    .landing-page main { --font-section: 500 clamp(32px, 3.5vw, 54px)/1.2 var(--serif); }
}


/* ONE DOCUMENT: the column is a manuscript in the editor's own grammar, and this block overrides the band-era hero layout above rather than editing it. */

/* ---- The glass nav retires on this page. The letterhead below owns
   the brand and the off-page links; the rails own navigation. ---- */
.landing-page nav { display: none; }

/* ---- Letterhead: brand in the paper's ink, quiet running-head links,
   one hairline under it. ---- */
.doc-masthead {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-10);
    flex-wrap: wrap;
    padding-bottom: var(--space-7);
    border-bottom: 1px solid rgba(16,16,10,0.16);
    margin-bottom: var(--space-18);
}
.doc-brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-4);
    text-decoration: none;
}
.doc-brand-mark { height: 30px; width: auto; display: block; }
.doc-brand-name { font: 600 21px/1 var(--serif); letter-spacing: -0.01em; color: var(--td1); }
.doc-brand-owl { color: var(--doc-accent); }
.doc-masthead-links { display: flex; align-items: baseline; gap: var(--space-11); flex-wrap: wrap; }
.doc-masthead-links a {
    font: 500 13.5px var(--sans);
    color: var(--td3);
    text-decoration: none;
    transition: color 150ms;
}
.doc-masthead-links a:hover { color: var(--doc-accent); }
.doc-masthead-links .doc-masthead-signin { color: var(--doc-accent); font-weight: 600; }
.doc-masthead-links .doc-masthead-signin:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---- The title block is the top of the paper now, not a centred hero:
   no viewport-height stage, no bottom fade, §1 just continues. ---- */
.landing-page .paper-hero {
    min-height: 0;
    display: block;
    overflow: visible;
    padding: var(--space-13) var(--space-17) 0;
}

/* ---- The section grammar. Same column as the title block, the app's
   own components inside. ---- */
.doc-sec {
    position: relative;
    z-index: 2;
    max-width: calc(760px + 2 * var(--space-17));
    margin: 0 auto;
    padding: var(--space-20) var(--space-17);
}
/* EVERY section head starts on the same line. A section needing extra width
   for a figure does NOT widen: the FIGURE breaks out of the column instead,
   symmetrically, by --fig-bleed. Zero until the column can give it away. */
/* The bleed is the SMALLER of what the design wants and what the page has: a px
   ladder alone is a second guess at a width the rails already determine, and the
   two disagreed. --fig-room is the real gutter between the fixed rails. */
.landing-page {
    --fig-room: calc((100vw - var(--rail-l) - var(--rail-r) - 760px) / 2 - 14px);
    --fig-bleed: 0px;
}
@media (min-width: 1360px) { .landing-page { --fig-bleed: max(0px, min(60px,  var(--fig-room))); }
}
@media (min-width: 1560px) { .landing-page { --fig-bleed: max(0px, min(116px, var(--fig-room))); }
}
.doc-fig-wide {
    width: calc(100% + 2 * var(--fig-bleed));
    margin-left: calc(-1 * var(--fig-bleed));
}

/* The section head is the app's own (brick numeral, serif title) at display
   scale, because a landing page has to be read across a room. */
.doc-sec-head { margin-bottom: var(--space-14); }
.doc-sec-title {
    font: var(--font-section);
    color: var(--td1);
    letter-spacing: var(--track-heading);
    margin: 0 0 var(--space-8);
    /* 24ch holds every head on ONE line (the longest is 23 characters); past that
       a head wraps, and it shows. */
    max-width: 24ch;
}
.doc-sec-num {
    color: var(--doc-accent);
    font-variant-numeric: tabular-nums;
    margin-right: 0.42em;
}

/* ---- The checkpoint list is the app's own #revision-list (see §3 above),
   which carries its own type, spacing, hover and active state. ---- */

/* ---- Anchors: no fixed bar to clear anymore, just breathing room. ---- */
#hero, #scene-research,
#scene-revisions, #anywhere, #why, #faq { scroll-margin-top: 18px !important; }

/* ---- Small screens ---- */
@media (max-width: 900px) {
    .landing-page .paper-hero { padding: var(--space-10) var(--space-12) 0; }
    .doc-sec { padding: var(--space-16) var(--space-12); }
    .doc-masthead { margin-bottom: var(--space-13); }
    /* The letterhead is ONE row on a phone as on the desk. nowrap is safe: brand
       plus four links measure ~305px against a 320px floor. */
    .doc-masthead { flex-wrap: nowrap; gap: var(--space-6); }
    .doc-masthead-links { flex-wrap: nowrap; gap: var(--space-7); }
    .doc-masthead-links a { font-size: 12.5px; }
    .doc-sec-title { max-width: 100%; }
    .doc-sec-head { margin-bottom: var(--space-12); }
}

/* A post carries all five links, which want 275px and get 224 on a phone, so
   the longest goes. Five fit on one line down to 450px, hence 600 and not 900. */
@media (max-width: 600px) {
    .doc-masthead-home { display: none; }
}


/* THE COLOPHON: the footer is the foot of the same sheet, printed to the trim. Every rule is scoped to .landing-page; the markup is sync_chrome.py's. */
.landing-page footer {
    /* Longhand, never the shorthand: the inline padding is the RAILS (the
       min-width:1180 block above), and a shorthand zeroes it and re-centres. */
    padding-top: var(--space-19);
    padding-bottom: var(--space-20);
    background: var(--doc-bg);
    /* Glass over a dark body. There is nothing behind the sheet to blur. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}
/* The gold horizon retires with the ground it was lighting. */
.landing-page footer::before { content: none; }
/* The sheet's grain continues past </main>, same recipe as main::before. One
   shared layer would need a wrapper the synced chrome cannot supply. */
.landing-page footer::after {
    content: '';
    position: absolute; inset: 0;
    pointer-events: none;
    z-index: 0;
    opacity: 0.5;
    background:
        radial-gradient(1px 1px at 12% 22%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 47% 68%, rgba(90,74,44,0.09), transparent 60%),
        radial-gradient(1px 1px at 78% 34%, rgba(90,74,44,0.10), transparent 60%),
        radial-gradient(1px 1px at 31% 84%, rgba(90,74,44,0.08), transparent 60%),
        radial-gradient(1px 1px at 88% 76%, rgba(90,74,44,0.09), transparent 60%);
    background-size: 180px 180px, 220px 220px, 260px 260px, 200px 200px, 240px 240px;
}
/* The imprint prints to the TRIM, not to the text measure: it takes --fig-bleed,
   the ladder the compare figure and the device pair bleed on. Derived from
   --fig-room, so it can never slide under a rail, and it falls back to the measure. */
.landing-page .footer-wrap {
    position: relative;
    z-index: 1;
    max-width: calc(760px + 2 * var(--space-17) + 2 * var(--fig-bleed));
    padding: 0 var(--space-17);
}

/* The closing rule, drawn on the content rather than across the page.
   It is the widest rule on the sheet, which is what the block being back
   matter rather than a section buys it. */
.landing-page .footer-inner {
    /* Five blocks on one pitch across the trim. The link track carries the same
       max-content floor its own columns do, or the block overflows the rule silently. */
    grid-template-columns: minmax(0, 1.5fr) minmax(max-content, 4fr);
    gap: var(--space-14);
    border-top: 1px solid rgba(16,16,10,0.16);
    padding-top: var(--space-15);
    margin-bottom: var(--space-15);
}
.landing-page .footer-brand { gap: var(--space-8); }

/* The plaque was built to survive a dark footer, and on paper it is a plate,
   which this page has exactly one of (the running app). The sign-off is the
   masthead's wordmark instead, so the sheet opens and closes in one hand. */
.landing-page .footer-plaque {
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    gap: var(--space-4);
}
.landing-page .footer-plaque:hover { transform: none; }
.landing-page .footer-plaque-mark { height: 30px; }
.landing-page .footer-plaque-name {
    font: 600 21px/1 var(--serif);
    color: var(--td1);
}
.landing-page .footer-plaque .brand-owl-grad {
    -webkit-text-fill-color: var(--doc-accent);
    color: var(--doc-accent);
}
/* The tagline is the page's own <h1> read back at the foot, so it speaks
   in the manuscript's serif rather than in interface sans. */
.landing-page .footer-tagline {
    font: 400 15px/1.6 var(--serif);
    color: var(--td2);
    max-width: 32ch;
}

/* Even fractions so the width reaches the CONTENT. Floored at max-content,
   never bare 1fr: below 1360 the bleed is 0 and a quarter column is ~102px. */
.landing-page .footer-cols {
    grid-template-columns: repeat(4, minmax(max-content, 1fr));
    gap: var(--space-14);
}
.landing-page .footer-col { gap: var(--space-6); }
/* The group label LEADS its list, head brighter than list. It keeps its own
   channels and takes the document's own ink on top. */
.landing-page .footer-col-title {
    font: var(--font-microcap);
    color: var(--td1);
    letter-spacing: var(--track-eyebrow);
    margin-bottom: var(--space-4);
}
/* Running-foot links, set exactly like the running-head links in the
   masthead: same size, weight and ink, brick on hover. The two blocks are the
   same object at opposite ends of the paper. */
.landing-page .footer-col a {
    font: 500 13.5px var(--sans);
    color: var(--td3);
    /* No column can be narrower than its longest link now, so nothing
       needs to break inside a word to fit. Swept 520 to 1920: no wrap. */
    overflow-wrap: normal;
}
.landing-page .footer-col a:hover { color: var(--doc-accent); }

/* The imprint line. Quiet ink at full opacity rather than dark ink at
   0.6: a translucent grey over papyrus grain picks up the texture. */
.landing-page .footer-bottom {
    border-top: 1px solid rgba(16,16,10,0.10);
    padding-top: var(--space-9);
    font: 400 12.5px var(--sans);
    color: var(--td3);
    opacity: 1;
}
.landing-page .footer-bottom-sep { color: var(--td3); opacity: 0.6; }

@media (max-width: 900px) {
    /* Matches .doc-sec's own narrow padding, so the column holds. */
    .landing-page .footer-wrap { padding: 0 var(--space-12); }
}
@media (max-width: 800px) {
    .landing-page .footer-inner { grid-template-columns: 1fr; gap: var(--space-15); }
}
@media (max-width: 600px) {
    /* The stack keeps its natural order: the sign-off is ink on paper now, and
       a document is signed before its index, not after it. */
    .landing-page .footer-cols { order: 0; }
    .landing-page .footer-brand { order: 0; }
}
@media (max-width: 560px) {
    .landing-page .footer-cols {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-13);
    }
    .landing-page .footer-col a { overflow-wrap: anywhere; }
}

/* The doodle canvas is invisible under a column that covers the viewport, which
   below 1180px it does here. agent-bg.js early-returns on a hidden canvas. */
@media (max-width: 1179px) {
    .landing-page #agent-bg { display: none; }
}