/* ============================================================
   Landing — "Clinical Precision" marketing styles.
   Shared primitives live in ui.css (all routes).
   The mobile glass nav lives in landing-glass-nav.css.
   Reveal classes are applied by static/js/landing/reveal.js.
   ============================================================ */

/* ---------- Typography ---------- */

/* ---------- The typography rule ----------
   One split, applied everywhere so it stops feeling arbitrary:

     HANDWRITTEN (Caveat) — anything that names something.
       headings h1-h5, kickers, buttons, field labels, stat values
       and labels, margin notes, the brand wordmark.

     TYPESET (Figtree) — anything you actually read.
       paragraphs, list items, table cells, small print, form help.

     MONO (JetBrains) — measured values: doses, units, counts.

   The test: if it is a label, it is handwritten. If it is a sentence,
   it is typed. */

.landing-page :is(h1, h2, h3, h4, h5),
.marketing-page-shell :is(h1, h2, h3, h4, h5) {
    font-family: 'Caveat', 'Bricolage Grotesque', ui-sans-serif, cursive;
    font-weight: 700;
    letter-spacing: 0;
    line-height: 1.08;
}

/* Headings arrived from many templates carrying their own size, casing
   and colour utilities (text-[10px], uppercase, tracking-[0.15em],
   text-muted-foreground/80, text-lg...). Uppercase micro-labels were
   designed for a grotesk and look wrong hand-lettered, so every heading
   is normalised here to one sentence-case ink voice. These selectors
   outrank the single-class utilities, so no !important is needed. */
.landing-page :is(h2, h3, h4, h5),
.marketing-page-shell :is(h2, h3, h4, h5) {
    text-transform: none;
    letter-spacing: 0;
    color: var(--foreground);
}

/* Handwriting sits smaller than a grotesk at the same px, so the smaller
   headings need a bump to keep their place in the hierarchy. */
.landing-page h3,
.marketing-page-shell h3 {
    font-size: 1.75rem;
}

.landing-page h4,
.marketing-page-shell h4 {
    font-size: 1.4rem;
}

.landing-page h5,
.marketing-page-shell h5 {
    font-size: 1.2rem;
}

/* Body copy stays typeset — handwriting is unreadable in long passages.

   The whole selector is wrapped in :where() so it contributes zero
   specificity. It previously scored (0,1,1) via :is() and quietly beat any
   single-class font on a p/li/td/th — a <p class="lg-card-title"> came out
   in the grotesk instead of the hand. Note the scope class needs :where()
   too: `.landing-page :where(p)` still scores (0,1,0), which *ties*
   .lg-card-title, and landing.css loads after ui.css, so the tie went to the
   base style. Same trap that hit .lg-empty__title and .lg-stat-caption in
   ui.css: a base element style must never outrank a component class. */
:where(.landing-page) :where(p, li, td, th, .lg-hero-sub),
:where(.marketing-page-shell) :where(p, li, td, th) {
    font-family: 'Figtree', ui-sans-serif, system-ui, sans-serif;
}

/* Field labels name a thing, so they are handwritten — but the values
   people read off stay mono, and helper text stays typeset. */
.landing-page label,
.marketing-page-shell label {
    font-family: 'Caveat', ui-sans-serif, cursive;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.landing-page label :is(p, span.text-xs, .text-muted-foreground),
.marketing-page-shell label :is(p, span.text-xs) {
    font-family: 'Figtree', ui-sans-serif, system-ui, sans-serif;
    font-weight: 400;
    letter-spacing: 0;
}

/* Handwriting has less optical weight than a grotesk, so it needs size. */
.landing-page h2 {
    font-size: clamp(2.1rem, 4.2vw, 3rem);
    margin-bottom: 0.5rem;
}

.lg-kicker {
    font-family: 'Caveat', ui-sans-serif, cursive;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: none;
}

/* ---------- Layout ---------- */

.landing-page {
    position: relative;
    isolation: isolate;
    overflow: clip;
}

/* A narrower measure than the app default: it reads better for long
   copy and leaves genuine margin for the doodles to live in. */
.landing-page .marketing-wrap,
.marketing-page-shell .marketing-wrap {
    max-width: 58rem;
}

/* ---------- Section rhythm ----------
   One rhythm for every marketing page. Templates each carried their own
   py-* utilities (py-8 / py-10 / py-14 / py-20), so the gap between two
   sections was 64px on /about, 80px on /faq, 112px on a feature page and
   152px at the foot of /compare — the same page furniture spaced four
   different ways. Declared here rather than edited into 30 templates, and
   unlayered CSS outranks Tailwind's utility layer.

   Scoped to page-level sections only: <section> inside an article (the
   privacy and terms bodies use 19 of them for clauses) must keep its own
   much tighter spacing. */
.landing-page > section,
.landing-page > main > section,
.landing-page > div > section {
    padding-block: 2.5rem;
}

@media (min-width: 640px) {
    .landing-page > section,
    .landing-page > main > section,
    .landing-page > div > section {
        padding-block: 3.5rem;
    }
}

/* The hero sets its own vertical space and the band under it is pulled up
   against it, so neither takes the rhythm. */
.landing-page > section.landing-hero,
.landing-page > main > section.landing-hero {
    padding-block: 0;
}

/* The grid lives on <body> (ui.css) so it spans every page; the hero
   just needs a red margin rule like a real pad. */
.landing-page::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: max(1.5rem, calc(50% - 34rem));
    width: 2px;
    z-index: -1;
    pointer-events: none;
    background: color-mix(in srgb, #d4614f 55%, transparent);
    opacity: 0.5;
}

@media (max-width: 1099px) {
    .landing-page::before {
        display: none;
    }
}

.landing-aurora {
    display: none;
}

/* ---------- Header: solid, sticky, bold ---------- */

.lg-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--background);
    border-bottom: 1px solid var(--border);
}

.lg-header__pill {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    max-width: 64rem;
    margin: 0 auto;
    padding: 0.85rem 1rem;
}

.lg-header__links a {
    padding: 0.45rem 0.75rem;
    border-radius: 0.375rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--muted-foreground);
    transition: color 140ms ease;
}

.lg-header__links a:hover {
    color: var(--foreground);
}

.lg-header__links a[data-active="true"] {
    color: var(--accent);
}

/* ---------- Hero ---------- */

.lg-hero-title {
    font-size: clamp(3rem, 9vw, 5.6rem);
    line-height: 0.92;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
}

/* ---------- Scratch-out / rewrite ----------
   The hero phrase is written, scribbled out by hand, erased, and the
   next one written in — the way you'd revise a line in a notebook.
   landing.js drives the state classes. */

.lg-rewrite {
    position: relative;
    display: inline-block;
}

.lg-rewrite__text {
    display: inline-block;
    color: var(--accent);
    /* Written left-to-right, like ink being laid down. */
    clip-path: inset(0 0 0 0);
    opacity: 1;
    transition: opacity 240ms ease;
}

.lg-rewrite.is-writing .lg-rewrite__text {
    animation: lgWriteIn 760ms cubic-bezier(0.42, 0, 0.3, 1) both;
}

.lg-rewrite.is-erasing .lg-rewrite__text {
    animation: lgEraseOut 420ms cubic-bezier(0.55, 0, 0.9, 0.5) both;
}

@keyframes lgWriteIn {
    from { clip-path: inset(0 100% 0 0); }
    to   { clip-path: inset(0 0 0 0); }
}

/* Erased from the right back to the left, like a rubber going over it. */
@keyframes lgEraseOut {
    from { clip-path: inset(0 0 0 0); opacity: 1; }
    to   { clip-path: inset(0 0 0 100%); opacity: 0.15; }
}

/* The scribble drawn through the phrase before it is erased. */
.lg-rewrite__scratch {
    position: absolute;
    inset: -8% -4%;
    width: 108%;
    height: 116%;
    pointer-events: none;
    overflow: visible;
    opacity: 0;
    color: var(--accent);
}

.lg-rewrite__scratch path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
}

.lg-rewrite.is-scratching .lg-rewrite__scratch {
    opacity: 0.85;
}

.lg-rewrite.is-scratching .lg-rewrite__scratch path {
    animation: lgScratch 520ms cubic-bezier(0.5, 0, 0.4, 1) both;
}

.lg-rewrite.is-scratching .lg-rewrite__scratch path:nth-child(2) {
    animation-delay: 160ms;
}

.lg-rewrite.is-erasing .lg-rewrite__scratch {
    opacity: 0;
    transition: opacity 320ms ease;
}

@keyframes lgScratch {
    from { stroke-dashoffset: 1; }
    to   { stroke-dashoffset: 0; }
}

/* The old blinking caret has no place in a handwritten line. */
.typing-cursor {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .lg-rewrite.is-writing .lg-rewrite__text,
    .lg-rewrite.is-erasing .lg-rewrite__text,
    .lg-rewrite.is-scratching .lg-rewrite__scratch path {
        animation: none;
    }

    .lg-rewrite__scratch {
        display: none;
    }
}

.lg-hero-sub {
    font-size: clamp(1.05rem, 2vw, 1.2rem);
    line-height: 1.6;
    color: var(--muted-foreground);
}

/* ---------- Syringe: vertical, injects into the page ----------
   fluid.js sets --lg-inject (0-1) from hero scroll progress and
   --lg-progress (0-1) from whole-page scroll progress. */

.lg-syringe {
    display: block;
    width: auto;
    height: clamp(11rem, 26vh, 15rem);
    margin: 0 auto;
    overflow: visible;
}

/* Plunger depresses as you scroll out of the hero. */
.lg-syringe__plunger {
    transform: translateY(calc(var(--lg-inject, 0) * 140px));
}

/* Fluid empties from the top as the plunger comes down. */
.lg-syringe__fluid {
    transform-origin: bottom center;
    transform: scaleY(calc(1 - (var(--lg-inject, 0) * 0.92)));
}

/* Retired float — no-op so existing markup degrades cleanly. */
.lg-float,
.lg-float--delay {
    animation: none;
}

/* ---------- Scroll reveal (progressive enhancement) ---------- */

.reveal-section .marketing-wrap > * {
    opacity: 0;
    transform: translateY(18px);
}

.reveal-section.reveal-visible .marketing-wrap > * {
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.5s cubic-bezier(0.23, 1, 0.32, 1),
        transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal-section.reveal-visible .marketing-wrap > *:nth-child(2) { transition-delay: 0.07s; }
.reveal-section.reveal-visible .marketing-wrap > *:nth-child(3) { transition-delay: 0.14s; }
.reveal-section.reveal-visible .marketing-wrap > *:nth-child(n+4) { transition-delay: 0.21s; }

/* ---------- Reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
    .reveal-section .marketing-wrap > * {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ---------- Mobile tap targets ----------
   Audited every public page at 390px. No page overflowed horizontally, but
   the touchable rows were built for a cursor: the ~19 footer links were 17px
   tall (under even the 24px AA floor), the FAQ and home accordions 26-28px,
   the small buttons 36-38px, and the "See how it works" links 24px. Heights
   are raised only below the sm breakpoint, so the desktop layout is
   untouched. Where a link already fills a row, the height comes from
   min-height rather than padding so nothing reflows. */

@media (max-width: 639px) {
    /* Footer link columns. space-y-2.5 supplied the separation before; the
       row height does it now, so the extra margin is dropped to keep the
       footer from doubling in height. */
    .landing-page footer ul a,
    .marketing-page-shell footer ul a {
        display: flex;
        align-items: center;
        min-height: 40px;
    }

    .landing-page footer ul > li + li,
    .marketing-page-shell footer ul > li + li {
        margin-top: 0;
    }

    /* Accordion rows: the whole row is the toggle, so it should be easy to
       hit without aiming at the text. */
    .landing-page summary,
    .marketing-page-shell summary {
        min-height: 44px;
        padding-block: 0.35rem;
    }

    /* Standalone "See how X works" links — these are the section's action,
       not a link inside a sentence. */
    .landing-page a.font-medium:has(svg),
    .marketing-page-shell a.font-medium:has(svg) {
        min-height: 40px;
    }

    /* Small buttons are a desktop density; on a phone they are the primary
       control (header sign-in, the stats range switch, calculator modes). */
    .landing-page .lg-btn--sm,
    .marketing-page-shell .lg-btn--sm,
    .calculator-page .lg-btn--sm,
    .calculator-page .calc-mode-btn {
        min-height: 2.75rem;
    }

    /* The brand lockup in the header is a link too. */
    .lg-header__pill > a:first-child {
        min-height: 44px;
    }

    /* Table-of-contents rows (the numbered step list on /guide). Whole-row
       links, same as the footer's. */
    .landing-page li > a.flex,
    .marketing-page-shell li > a.flex {
        min-height: 40px;
    }

    /* Text-only utility buttons ("Clear" on the calculator history) — a
       28x16 target. Widened by padding since there is no row to fill. */
    .calculator-page button.text-xs,
    .landing-page button.text-xs:not(.lg-btn) {
        min-height: 40px;
        padding-inline: 0.5rem;
    }
}
