/* ── Self-hosted brand faces ───────────────────────────────────────────────
   Playfair Display and Inter, served from this origin instead of Google's CDN.

   Three reasons, in order of importance:

   1. Privacy and the law. fonts.gstatic.com receives the IP address of every
      visitor who loads the page. Our own privacy policy names every recipient
      of personal data and Google is not among them, and a German court
      (LG Munchen I, 3 O 17493/20) held that embedding Google Fonts without
      consent is an unlawful transfer under the GDPR. Self-hosting removes the
      transfer entirely, so the policy stays true and there is nothing to
      consent to.
   2. Weight. These are the variable fonts: one file covers 400-800 instead of
      four static files, and unicode-range means a reader only downloads the
      subset their text actually needs.
   3. Correctness. The old Google request asked for Playfair 900 and 600-italic
      that nothing uses, while Inter 800 and Playfair 500-italic WERE rendered
      and never requested, so the browser was synthesising them. A variable
      range covers every weight on the page for real.

   Both families are SIL Open Font License 1.1, which permits redistribution. */


/* ── Display: Fraunces 600, roman and italic ───────────────────────────────
   The same two instances the app bundles (Fraunces_600SemiBold and
   _600SemiBold_Italic, src/components/ui/text.tsx), subset to latin here.
   Replaces four Playfair files and a 66 KB Fraunces static that was declared
   `font-weight: 100 900` despite having no fvar table -- so every weight was
   being synthesised from one instance. 39 KB total, down from 142 KB.

   One display face, not two. Playfair carried the headline accent and the pull
   quote while Fraunces carried the wordmark and the app card: two serifs
   splitting one job, which is what made the page read as assembled rather than
   designed. */
/* ── Body: Instrument Sans ────────────────────────────────────────────────
   The site was running two type systems: privacy.html and terms.html have
   always paired Fraunces with Instrument Sans, while every other page used
   Inter. The legal pages had the better one. Inter is the single most common
   face on the web -- the default of every framework template -- and at display
   sizes it read as exactly that. It is gone; the pairing is now one system on
   every page.

   Normal and italic, latin and latin-ext, the same four subsets the legal pages
   already load, so a visitor who has read the privacy policy has them cached. */
@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('../fonts/instrumentsans-3.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Instrument Sans';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('../fonts/instrumentsans-2.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Instrument Sans';
    font-style: italic;
    font-weight: 400 700;
    font-display: swap;
    src: url('../fonts/instrumentsans-1.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Fraunces';
    font-style: normal;
    font-weight: 600;
    font-display: optional;
    src: url('../fonts/fraunces-600.woff2') format('woff2');
}

@font-face {
    font-family: 'Fraunces';
    font-style: italic;
    font-weight: 600;
    font-display: optional;
    src: url('../fonts/fraunces-600-italic.woff2') format('woff2');
}















/* ── Metric-matched fallbacks ──────────────────────────────────────────────
   The webfonts are preloaded, but on a 3G connection 123 KB still cannot
   arrive before first paint, so the page renders in a fallback and reflows
   when the real faces swap in. That reflow was the homepage's entire CLS:
   0.219, one shift at ~1.65s, the hero growing 31px as the headline re-wrapped.
   (/nl scored 0.002 purely because the Dutch copy happened to wrap to the same
   number of lines — luck, not design.)

   These two faces make the fallback occupy the same space as the real one, so
   the swap changes glyph shapes and nothing else. size-adjust is the ratio of
   the two fonts' advance widths over a representative sentence; the ascent and
   descent overrides are the webfont's own metrics divided by that ratio.
   Measured from the live fonts at a 100px em, not copied from a table.

   Keep them LAST in each stack: 'Inter' first so the real face wins once it
   loads. If either webfont is ever re-subset or swapped, re-measure — stale
   numbers here are worse than none, because they shift text in both states. */
/* Metric-matched fallback for Fraunces, same method as the Inter one: the
   size-adjust is solved against rendered geometry, not taken from a table.
   Values are set below after measurement. */
@font-face {
    font-family: 'Instrument Fallback';
    src: local('Helvetica Neue'), local('Arial'), local('Liberation Sans');
    size-adjust: 99.52%;
    ascent-override: 97.47%;
    descent-override: 25.12%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Fraunces Fallback';
    src: local('Georgia'), local('Times New Roman'), local('Liberation Serif');
    font-style: normal;
    font-weight: 600;
    size-adjust: 93.53%;
    ascent-override: 104.78%;
    descent-override: 27.80%;
    line-gap-override: 0%;
}

@font-face {
    font-family: 'Fraunces Fallback';
    src: local('Georgia'), local('Times New Roman'), local('Liberation Serif');
    font-style: italic;
    font-weight: 600;
    size-adjust: 87.91%;
    ascent-override: 111.48%;
    descent-override: 29.58%;
    line-gap-override: 0%;
}



/* Fraunces is `font-display: optional`, not `swap`, and that is deliberate.
   `swap` re-renders when the face arrives, which re-wraps the headline and cost
   this page a CLS of 0.219 once already. `optional` commits to the fallback if
   the face misses first paint and never swaps -- so the metric-matched
   'Fraunces Fallback' above must stay accurate, and both instances must stay
   preloaded, or the display face simply never appears. */
/* Playfair's real faces are declared `font-weight: 600 700` (normal) and
   `500 700` (italic), and Times switches to a genuinely different bold above
   weight 500 — so one averaged size-adjust cannot serve both. Tuned separately
   against the rendered geometry at 360x640 with the webfonts blocked: the
   italic value matches the nowrap "running partner" span to the pixel (238px),
   which is what decides where the headline wraps, and the normal value matches
   the h1's full height (131px). Solved, not estimated. */




:root {
    /* Mirrors .container's horizontal padding; see .app-shots. */
    --container-pad: 16px;
    --zinq-orange: #C85A3C;
    --zinq-surface: #F5F4F0;
    --zinq-dark: #15120F;
    --nav-height: 80px;

    --bg-color: #F7F5F0;
    /* Two accent tokens, not one — the app's system, adopted here because the
       old single #C85A3C sat in a contrast dead zone: 4.43:1 against near-black
       AND 4.21:1 against white, so no label colour could make the primary CTA
       pass AA. Splitting fill from text is what fixes it.

         --amber      fills only. White on it = 4.60:1 (AA).
         --amber-text amber used as TEXT. 5.31:1 on cream, 5.78:1 on white. */
    --amber: #C05436;
    --rule-soft: #DED7C9;
    /* The focus ring. Was the teal --primary, a colour used by nothing else
       on the site. 5.31:1 on cream, well over SC 1.4.11's 3:1 floor. */
    --focus-ring: #A8482E;
    --amber-text: #A8482E;
    --button-orange-text: #FFFFFF;
    --text-main: #1A1A1A;
    /* Warm, biased to the cream. Was #4B5563 — Tailwind's slate-600, a cool
       blue-grey that made every paragraph read slightly dirty against a warm
       background. This is the app's own ink-2, and it is also higher contrast:
       9.04:1 against the page versus 6.94:1. */
    --text-muted: #4A423A;
    --card-bg: #FFFFFF;
    --card-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    --nav-bg: rgba(247, 245, 240, 0.95);
    --border-subtle: rgba(0, 0, 0, 0.05);
    --footer-bg: #15120F;

    --bg-problem: #FCFAF6;
    --bg-hiw: var(--bg-color);
    --bg-trust: var(--card-bg);
    --bg-city: var(--bg-color);
    --bg-pricing: var(--bg-color);

    --featured-card-bg: rgba(255, 255, 255, 0.6);
    --featured-card-text: var(--text-main);
    --featured-card-subtext: var(--text-muted);

    --card-border: 1px solid transparent;
    --avatar-grad: linear-gradient(135deg, #B8D4D4, #E8E0D4);
    --avatar-grad-marco: linear-gradient(135deg, #FFD194, #70E1F5);
    --tag-text: #FFFFFF;
    --prob-border-strava: 1px solid rgba(192, 57, 43, 0.2);
    --city-stat-num: var(--text-main);

    --waitlist-input-bg: #FFFFFF;
    --waitlist-input-text: #1A1A1A;
    --waitlist-placeholder: rgba(26, 26, 26, 0.5);
    --waitlist-social: inherit;

    --price-card-border: 1px solid transparent;
    --price-lifetime-bg: var(--card-bg);
    --hero-ambient: radial-gradient(circle at 50% 20%, color-mix(in oklab, var(--zinq-orange) 22%, transparent) 0%, transparent 60%);
    --discount-bg: transparent;
    --discount-border: 1px solid var(--border-subtle);

    --f-logo: #FFFFFF;
    --f-sub: rgba(255, 255, 255, 0.5);
    --f-center: rgba(255, 255, 255, 0.7);
    --f-social-default: rgba(255, 255, 255, 0.5);
    --f-social-hover: var(--amber);
    --f-bottom-border: 1px solid rgba(255, 255, 255, 0.1);
    --f-copyright: rgba(255, 255, 255, 0.66);

    --theme-toggle-border: rgba(26, 26, 26, 0.2);
    --theme-toggle-hover: rgba(0, 0, 0, 0.06);

    --radius-input: 12px;
    --radius-section: 16px;
    /* These three were referenced throughout the stylesheet but never defined —
       at HEAD too, not a regression. `.btn { border-radius: var(--radius-pill) }`
       therefore resolved to nothing, so every button that did not hardcode its
       own radius rendered square. That is why the header, the hero and the
       community CTA looked like three unrelated components. */
    --radius-pill: 100px;
    --radius-card: 14px;
    --footer-text: rgba(255, 255, 255, 0.72);
    /* Inter is the house voice, including every headline. Playfair used to set
       all of h1-h4 and the effect was that nothing stood out: when the display
       face says everything, it says nothing. It is now reserved -- the wordmark,
       the etymology line, the stat figures, and the italic phrase inside the
       hero headline -- so the serif reads as a deliberate accent against Inter
       rather than as the default. */

    /* ── Type roles ────────────────────────────────────────────────────────
       Eight roles, not seventeen sizes. The page had 88/50/40/30/27/26/22/20/
       18/17/16/15/14/13/12/11/10 in play, with four values inside 3px of each
       other doing jobs a reader could not tell apart -- an accumulation, not a
       scale. Each role below names a job; nothing sets a raw font-size.

       Display roles are Fraunces, the product's own face. UI roles are Inter.
       That split is the app's (DESIGN.md: "display / numerals : Fraunces"), and
       keeping it means the two surfaces finally speak once. */
    /* The middle term is 6vw + 1rem and must stay that way: the mobile ramp
       below 781px uses 8.05vw precisely so the two meet at 62.8px on the
       boundary. Changing this to a plain vw multiplier broke that and the
       headline shrank from 62.8px at 780px to 53.6px at 800px -- bigger screen,
       smaller type. The ceiling is the role's, the slope is the boundary's. */
    --t-display:   clamp(2.4rem, 6vw + 1rem, 5.25rem);
    --t-statement: clamp(1.75rem, 3.5vw, 2.875rem);
    --t-title:     clamp(1.75rem, 2.5vw, 2.375rem);
    --t-subtitle:  1.3125rem;
    --t-lead:      clamp(1.0625rem, 0.6vw + 0.9rem, 1.25rem);
    --t-body:      1.0625rem;
    --t-meta:      0.9375rem;
    --t-label:     0.75rem;

    /* The wordmark is a mark, not a text role, so it sits outside the ramp on
       purpose -- but it is still named rather than hardcoded in two places. */
    --t-wordmark:      1.6875rem;
    --t-wordmark-sm:   1.375rem;

    --lh-display:  1.02;
    --lh-title:    1.1;
    --lh-body:     1.6;
    --tr-display:  -0.03em;
    --tr-title:    -0.02em;
    --tr-label:    0.14em;

    --font-head: 'Fraunces', 'Fraunces Fallback', Georgia, serif;
    --font-body: 'Instrument Sans', 'Instrument Fallback', system-ui, sans-serif;
    --font-accent: 'Fraunces', 'Fraunces Fallback', Georgia, serif;
    /* The wordmark is not the accent face. The app renders it as `zinq.` in
       Fraunces 600 with a clay full stop (src/components/ui/text.tsx), and the
       site was rendering `Zinq` in Playfair with no stop -- the same product
       wearing two different marks. This matches the product. */
    --font-wordmark: 'Fraunces', 'Fraunces Fallback', Georgia, serif;

    --h2-size: clamp(2.25rem, 4vw, 3.5rem);
    --color-surface-match: rgba(46, 125, 114, 0.1);
    --color-text-match: #2E7D72;
    --card-width: 320px;
    --card-gap: 20px;
}

[data-theme="dark"] {
    --zinq-surface: #15120F;
    --zinq-dark: #F7F5F0;
    --zinq-orange: #FF9854;
    --amber-text: #FF9854;        /* 8.77:1 on the dark ground */
    --focus-ring: #FF9854;
    --rule-soft: rgba(255, 255, 255, 0.14);
    /* White, as in light mode: the fill is the same clay in both themes, so the
       label must be too. Near-black on it was 4.05:1. */
    --button-orange-text: #FFFFFF;


    --color-accent-primary: #FDBA74;
    --color-accent-surface: rgba(251, 146, 60, 0.12);
    --color-error-primary: #FF8A80;
    --color-error-surface: rgba(255, 138, 128, 0.12);

    --bg-color: #15120F;
    --text-main: #F8FAFC;
    /* The warm counterpart of the light value. 6.92:1 on the dark ground. */
    --text-muted: #A79C8D;
    --card-bg: #1A1510;
    --card-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.05);
    --nav-bg: rgba(21, 18, 15, 0.95);
    --border-subtle: rgba(255, 255, 255, 0.06);
    --footer-bg: #100C09;

    --bg-problem: #1A1510;
    --bg-hiw: #15120F;
    --bg-trust: #1A1510;
    --bg-city: #15120F;
    --bg-pricing: #15120F;

    --featured-card-bg: var(--footer-bg);
    --featured-card-text: #FFFFFF;
    --featured-card-subtext: rgba(255, 255, 255, 0.8);

    --card-border: 1px solid var(--border-subtle);
    --avatar-grad: linear-gradient(135deg, #1A4A4A, #2A3A4A);
    --avatar-grad-marco: linear-gradient(135deg, #1A4A4A, #2A3A4A);
    --tag-text: #E2E8F0;
    --prob-border-strava: 1px solid rgba(231, 76, 60, 0.4);
    --city-stat-num: #F8FAFC;

    --waitlist-input-bg: #0F1115;
    --waitlist-input-text: #F8FAFC;
    --waitlist-placeholder: #94A3B8;
    --waitlist-social: rgba(255, 255, 255, 0.9);

    --price-card-border: 1px solid var(--border-subtle);
    --price-lifetime-bg: var(--card-bg);
    --color-surface-match: rgba(255, 255, 255, 0.06);
    --color-text-match: #FFFFFF;
    --discount-bg: rgba(255, 255, 255, 0.04);
    --discount-border: 1px solid rgba(255, 255, 255, 0.08);

    --f-logo: #F0EEE9;
    --f-sub: rgba(240, 238, 233, 0.55);
    --f-center: rgba(240, 238, 233, 0.7);
    --f-social-default: rgba(240, 238, 233, 0.5);
    --f-bottom-border: 1px solid rgba(255, 255, 255, 0.06);
    --f-copyright: rgba(240, 238, 233, 0.66);

    --theme-toggle-border: rgba(240, 238, 233, 0.2);
    --theme-toggle-hover: rgba(255, 255, 255, 0.06);
    --hero-ambient: radial-gradient(circle at 50% 20%, color-mix(in oklab, var(--zinq-orange) 7%, transparent) 0%, transparent 60%);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

img,
picture,
svg,
video {
    max-width: 100%;
    display: block;
}

section[id] {
    scroll-margin-top: 100px;
}

html {
    width: 100%;
}

body {
    font-family: var(--font-body);
    background-color: var(--bg-color);
    color: var(--text-main);
    font-size: var(--t-body);
    line-height: 1.6;
    letter-spacing: -0.01em;

    width: 100%;
    position: relative;
    transition: background-color 0.3s ease, color 0.3s ease;
    -webkit-font-smoothing: antialiased;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}


/* Theme-switching: kill ALL transitions so every element changes in one paint frame */
html.theme-switching,
html.theme-switching *,
html.theme-switching *::before,
html.theme-switching *::after {
    transition: none !important;
}

main {
    flex-grow: 1;
}

/* h1 and h2 are display roles and take Fraunces. h3 and h4 are UI -- card
   titles, step titles, FAQ questions -- and take the body face. That split is
   what keeps the serif meaningful rather than ambient: if every heading is a
   serif, none of them reads as one. */
h1,
h2 {
    font-family: var(--font-head);
    color: var(--text-main);
    font-weight: 600;
}

h3,
h4 {
    font-family: var(--font-body);
    color: var(--text-main);
    font-weight: 600;
    letter-spacing: -0.015em;
}

h2 {
    font-size: clamp(26px, 4.5vw, 40px) !important;
    line-height: 1.15 !important;
    margin-bottom: clamp(16px, 2.5vw, 32px);
}

a {
    text-decoration: none;
    color: inherit;
}

.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

/* Base Transitions for Dark Mode */
section,
#navbar,
footer,
.f-icon,
.f-bottom {
    transition-property: background-color, color, border-color, box-shadow;
    transition-duration: 0.3s;
    transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    border-radius: var(--radius-pill);
    font-family: var(--font-body);
    font-weight: 600;
    cursor: pointer;
    border: none;
    letter-spacing: -0.01em;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
}

.btn:active {
    transform: scale(0.97) !important;
}

.btn-amber {
    background-color: var(--amber);
    color: var(--button-orange-text);
}

/* Hover lifts; it does not repaint. The fill used to shift to #C86422 on hover,
   which is 3.96:1 against white text -- below AA, and invisible to axe because
   axe does not evaluate hover states. The resting #C05436 is 4.60:1 and now
   stays put through every state. */
@media (hover: hover) and (pointer: fine) {
    .btn-amber:hover {
        transform: translateY(-2px) !important;
    }
}

/* Subdue mockup UI buttons globally to enforce Single CTA rule */


/* Nav */
/* Scoped to the header. A bare `nav` selector also claimed the footer nav,
   which pinned it under the header where nobody could see it. */
#navbar {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
    padding: 24px 0;
    transition: transform 0.2s ease, opacity 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
}

#navbar.scrolled {
    /* Token, not a literal. This was hardcoded to the light value with a
       [data-theme="dark"] nav.scrolled override to correct it -- but once the
       header rules were scoped to #navbar, that override could no longer win:
       an id beats an attribute plus a type selector, so dark mode showed the
       light header. --nav-bg was already defined correctly in both themes and
       used nowhere. Near-solid because there is no backdrop-filter behind it. */
    background-color: var(--nav-bg);
    border-bottom: 1px solid var(--border-subtle);
    padding: 16px 0;
}



/* Graceful degradation for image tag pills */


.nav-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    font-family: var(--font-wordmark);
    font-weight: 600;
    font-size: var(--t-wordmark);
    letter-spacing: -0.022em;   /* the app's tracking-disp */
    color: var(--text-main);
    text-transform: lowercase;
}

/* The clay full stop is part of the mark, not punctuation. */
.logo-dot,
.f-logo-dot {
    color: var(--amber);
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

.lang-dropdown-container {
    position: relative;
    display: inline-block;
}

.lang-dropdown-trigger {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: rgba(0, 0, 0, 0.04);
    border: 1px solid rgba(0, 0, 0, 0.1);
    color: var(--text-main);
    padding: 5px 10px;
    border-radius: 100px;
    font-size: var(--t-label);
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

[data-theme="dark"] .lang-dropdown-trigger {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 255, 255, 0.15);
}

.lang-dropdown-trigger:hover {
    background: rgba(0, 0, 0, 0.08);
}

[data-theme="dark"] .lang-dropdown-trigger:hover {
    background: rgba(255, 255, 255, 0.12);
}

.lang-dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 130px;
    background: var(--bg-color, #ffffff);
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 12px;
    padding: 6px;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
    display: none;
    flex-direction: column;
    gap: 2px;
    z-index: 1000;
}

[data-theme="dark"] .lang-dropdown-menu {
    background: #1a1512;
    border-color: rgba(255, 255, 255, 0.15);
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
}

.lang-dropdown-container.open .lang-dropdown-menu {
    display: flex;
}

.lang-dropdown-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    font-size: var(--t-meta);
    font-weight: 600;
    color: var(--text-main);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.lang-dropdown-item:hover {
    background: rgba(192, 84, 54, 0.12);
    color: var(--amber-text);
}

.lang-dropdown-item.active {
    font-weight: 600;
    color: var(--amber-text);
}

.lang-dropdown-item .lang-check {
    opacity: 0;
    font-size: var(--t-label);
}

.lang-dropdown-item.active .lang-check {
    opacity: 1;
}

.theme-toggle {
    width: 44px;
    height: 44px;
    background: transparent;
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--t-subtitle);
    opacity: 0.8;
    transition: transform 0.2s ease, opacity 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
    color: var(--text-main);
}

@media (hover: hover) {
    .theme-toggle:hover {
        background-color: transparent;
        opacity: 1;
        transform: scale(1.1);
    }
}

[data-theme="dark"] .theme-toggle {
    opacity: 0.85;
}

@media (hover: hover) {
    [data-theme="dark"] .theme-toggle:hover {
        background-color: transparent;
        opacity: 1;
        transform: scale(1.1);
    }
}

.nav-btn {
    padding: 10px 24px;
    font-size: var(--t-meta);
}

.btn-nav-outline {
    background: rgba(192, 84, 54, 0.1) !important;
    border: 1px solid rgba(192, 84, 54, 0.35);
    /* Was #D97736 on its own wash: 2.62:1, the worst contrast on the page. */
    color: var(--amber-text) !important;
    font-weight: 600;
    transition: background-color .2s ease, border-color .2s ease, color .2s ease;
    box-shadow: none !important;
}

@media (hover: hover) {
    .btn-nav-outline:hover {
        background: rgba(217, 119, 54, 0.2) !important;
        border-color: rgba(217, 119, 54, 0.6);
        color: var(--amber-text) !important;
    }
}

/* Hero */
.hero {
    /* One screen, nothing else. The page below is a reward for scrolling, not
       a thing half-visible at the fold competing with the headline.
       svh, not vh: on mobile browsers vh is the tallest the viewport ever gets,
       so 100vh guarantees the CTA is pushed under the address bar. */
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Clears the fixed nav so the copy is optically centred, not mathematically. */
    padding-top: clamp(96px, 15vh, 132px);
    padding-bottom: clamp(28px, 5vh, 44px);
    position: relative;
    z-index: 10;
    background: var(--hero-ambient);
}

@supports not (min-height: 100svh) {
    .hero {
        min-height: 100vh;
    }
}

.hero > .container {
    width: 100%;
}

.hero-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 100%;
    min-width: 0;
}

.hero h1 {
    /* Stops a single word stranding on the last line at awkward widths. */
    text-wrap: balance;
    /* Width sets the ceiling, height sets the cap: the hero is one screen tall,
       so on a short laptop the headline has to give way or the CTA does. */
    font-size: min(var(--t-display), 13vh);
    /* One weight, one face. The accent no longer has to be balanced against a
       different family at a different weight -- headline and accent are both
       Fraunces 600, so they share a colour by construction and the italic does
       the contrasting on its own. */
    font-weight: 600;
    line-height: var(--lh-display);
    letter-spacing: var(--tr-display);
    margin-bottom: clamp(12px, 2.6vh, 24px);
}

.hero p.subheadline {
    text-wrap: pretty;
    font-size: clamp(17px, 2.2vh, 20px);
    color: var(--text-main);
    opacity: 0.85;
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: clamp(22px, 4.4vh, 40px);
    line-height: 1.5;
}

.hero-cta {
    margin-bottom: 16px;
}

/* The hero CTA is the brand button at hero scale — it inherits its fill from
   .btn-amber rather than overriding it. It used to paint itself near-black with
   an orange outline, which matched nothing else on the page. */
.hero-btn {
    height: 60px;
    min-width: 220px;
    font-size: var(--t-body);
    padding: 0 44px;
    border-radius: 100px;
    font-weight: 600;
    transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease, filter 0.2s ease;
}

@media (hover: hover) {
    .hero-btn:hover {
        transform: translateY(-2px);
        filter: brightness(1.06);
        box-shadow: 0 8px 20px rgba(200, 90, 60, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
    }
}

.hero-btn:active {
    transform: translateY(0);
}

/* Problem Section */
.problem-section {
    background: var(--bg-problem);
    border-radius: var(--radius-section) var(--radius-section) 0 0;
    padding: 96px 0;
}

/* The statement is the quote and the link under it, centred. It was a two-column
   grid with the quote left and a grey explanatory line to its right, which left
   more than half the right column empty and put a small muted paragraph beside a
   50px display quote -- two things at opposite ends of the scale competing in one
   row. The explanation is gone: the quote does not need glossing, and the link
   below it is the only thing there was ever anything to do about. */
.prob-statement {
    margin: clamp(64px, 9vh, 112px) auto 8px;
    max-width: 940px;
    text-align: center;
}

.story-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: clamp(24px, 3.5vh, 40px);
    color: var(--amber-text);
    font-weight: 600;
    font-size: var(--t-body);
    text-decoration: none;
    transition: opacity 0.2s ease;
}

.story-link:hover {
    opacity: 0.8;
}

.story-link-arrow {
    font-size: 1.15em;
    line-height: 1;
    transition: transform 0.2s cubic-bezier(0.23, 1, 0.32, 1);
}

.story-link:hover .story-link-arrow {
    transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
    .story-link-arrow {
        transition: none;
    }
}

/* ── Real app screenshots ──────────────────────────────────────────────────
   Three phones, shipped at 600x1298 and displayed around 300px wide, so they
   stay crisp on a 2x screen. Both dimensions are on the <img> so the row
   reserves its height before the files arrive -- these sit below the fold and
   lazy-load, which is exactly the situation that produces a layout shift if
   the box is not reserved. */
.app-shots-section {
    padding: 96px 0;
}

.app-shots-sub {
    max-width: 56ch;
    margin: -28px auto 56px;
    text-align: center;
    font-size: var(--t-body);
    line-height: 1.6;
    color: var(--text-muted);
    text-wrap: pretty;
}

.app-shots {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(20px, 3.4vw, 52px);
    justify-items: center;
    max-width: 1000px;
    margin-inline: auto;
}

.app-shot {
    margin: 0;
    max-width: 300px;
}

.app-shot img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 22px;
    border: 1px solid var(--rule-soft);
    /* The screens are a warm off-white almost identical to the page, so without
       a little lift they dissolve into the background. */
    box-shadow: 0 18px 44px rgba(21, 18, 15, 0.10), 0 2px 6px rgba(21, 18, 15, 0.04);
    background: #F7F5F0;
}

.app-shot-cap {
    margin: 18px 0 0;
    text-align: center;
    font-size: var(--t-meta);
    line-height: 1.45;
    color: var(--text-muted);
}

/* Below 780px three phones would be 110px wide and unreadable, so the row
   becomes a swipeable rail instead of shrinking. tabindex on the list keeps it
   reachable by keyboard, since a scroll container is not focusable by default. */
@media (max-width: 780px) {
    .app-shots-section {
        padding: 64px 0;
    }

    .app-shots-sub {
        margin: -18px auto 36px;
        font-size: var(--t-body);
    }

    .app-shots {
        display: flex;
        gap: 18px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        /* Bleed to the viewport edge by cancelling exactly the container's own
           padding, which is 16px below 1024px. Guessing 20px here put the rail
           4px past the edge and gave the whole page a horizontal scrollbar --
           a var, not a number, so the two cannot drift apart again. */
        padding: 4px var(--container-pad) 8px;
        margin-inline: calc(var(--container-pad) * -1);
        scrollbar-width: none;
    }

    .app-shots::-webkit-scrollbar {
        display: none;
    }

    .app-shot {
        flex: 0 0 auto;
        width: 216px;
        scroll-snap-align: center;
    }

    .app-shot img {
        border-radius: 18px;
    }
}

.app-shots:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 6px;
    border-radius: 8px;
}

/* ── Page header (about, and any page that is not the homepage) ────────────
   The homepage hero is min-height: 100svh because its job is to fill a screen
   with one statement and one button. About reused it and got 1000px of viewport
   holding two short paragraphs, with roughly 300px of nothing between the lead
   and the first real content. A header, not a hero. */
.page-head {
    padding: clamp(128px, 17vh, 168px) 0 clamp(40px, 6vh, 72px);
    text-align: center;
    background: var(--hero-ambient);
}

.page-eyebrow {
    font-size: var(--t-label);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--tr-label);
    color: var(--text-muted);
    margin: 0 0 18px;
}

.page-head h1 {
    font-size: var(--t-title);
    line-height: var(--lh-title);
    letter-spacing: var(--tr-title);
    margin: 0;
}

.page-head-dot {
    color: var(--amber);
}

.page-lead {
    max-width: 52ch;
    margin: 20px auto 0;
    font-size: var(--t-lead);
    line-height: 1.6;
    color: var(--text-muted);
    text-wrap: pretty;
}

/* ── The story ────────────────────────────────────────────────────────────
   The quote was inside a white card with a shadow, which is the pattern the
   homepage dropped when eight boxed FAQ items turned the page into a ladder.
   It is the strongest line on this page, so it is set like the homepage's pull
   quote: display size, centred, no box. */
.story-section {
    padding: clamp(48px, 8vh, 88px) 0 clamp(56px, 9vh, 96px);
}

.story-section .editorial-blockquote {
    margin: 0 auto;
}

.story-byline {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-top: clamp(28px, 4vh, 40px);
}

.story-avatar {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--rule-soft);
    display: block;
}

.story-name {
    display: block;
    font-size: var(--t-meta);
    font-weight: 600;
    color: var(--text-main);
    text-align: left;
}

.story-role {
    display: block;
    font-size: var(--t-meta);
    color: var(--text-muted);
    text-align: left;
}

.story-body {
    max-width: 62ch;
    margin: clamp(40px, 6vh, 64px) auto 0;
}

.story-body p {
    font-size: var(--t-body);
    line-height: var(--lh-body);
    color: var(--text-main);
    margin: 0 0 1.15em;
    text-wrap: pretty;
}

.story-body p:last-child {
    margin-bottom: 0;
}

.about-match {
    padding: 0 0 clamp(72px, 11vh, 120px);
}

/* The section titles are centred, so a lead under one has to be too. This class
   had no rule at all, which meant it inherited the body's left alignment and sat
   off-axis under a centred heading. */
.section-subtitle {
    max-width: 56ch;
    margin: -28px auto clamp(40px, 6vh, 64px);
    text-align: center;
    font-size: var(--t-body);
    line-height: var(--lh-body);
    color: var(--text-muted);
    text-wrap: pretty;
}

@media (max-width: 780px) {
    .section-subtitle {
        margin: -16px auto 32px;
    }
}

.about-cta {
    margin-top: clamp(48px, 7vh, 80px);
    text-align: center;
}

.about-cta .hero-micro {
    margin-top: 14px;
}

@media (max-width: 780px) {
    .page-head {
        padding: clamp(112px, 15vh, 136px) 0 32px;
    }

    .story-section {
        padding: 40px 0 48px;
    }
}

/* A small label over a hairline before each section title. The sections used to
   open cold on a large centred h2, which gave the page no rhythm between them
   and nothing to scan by. Borrowed from the Enblox reference, adapted: their
   labels sit left over a rule, ours centre because these titles are centred. */
.section-label {
    display: block;
    text-align: center;
    font-family: var(--font-body);
    font-size: var(--t-label);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: var(--tr-label);
    color: var(--text-muted);
    border-top: 1px solid var(--rule-soft);
    padding-top: 26px;
    margin: 0 0 18px;
}

.trust-section .section-label {
    text-align: left;
}

@media (max-width: 780px) {
    .section-label {
        font-size: var(--t-label);
        padding-top: 20px;
        margin-bottom: 14px;
    }
}

h2.section-title,
.section-title {
    font-size: var(--t-title);
    font-weight: 600;
    line-height: var(--lh-title);
    letter-spacing: var(--tr-title);
    text-align: center;
    margin-bottom: 48px;
}

.problem-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 56px;
    max-width: 1060px;
    margin: 0 auto;
}

/* Fix Heavy Warning Tags (Light Mode) */

.prob-title {
    font-family: var(--font-body);
    font-size: var(--t-subtitle);
    font-weight: 600;
    margin-bottom: 12px;
}

.prob-text {
    font-size: var(--t-body);
    color: var(--text-muted);
}

/* How it works */
.hiw-section {
    padding: 76px 0;
    background: var(--bg-hiw);
}

.timeline-grid {
    display: grid;
    width: 100%;
    gap: 56px;
    max-width: 1060px;
    margin: 0 auto;
}

@media (min-width: 768px) {
    .timeline-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* The boxed treatment lived here. The step is now a rule and its content, to
   match the problem columns; the declarations that painted a card are gone
   rather than overridden, so nothing has to win a specificity fight. */
.timeline-step {
    text-align: left;
}

.hiw-title {
    font-family: var(--font-body);
    font-size: var(--t-subtitle);
    font-weight: 600;
    margin-bottom: 12px;
    color: var(--text-main);
}

.hiw-text {
    font-size: var(--t-body);
    color: var(--text-muted);
}

/* Trust Section */
.trust-section {
    background: var(--bg-trust);
    border-radius: var(--radius-section);
    /* Was 96px, sized around two paragraphs of prose that are now three short
       rows. The same padding around less content just reads as a gap. */
    padding: 76px 0;
    max-width: 1200px;
    margin: 0 auto;
    width: calc(100% - 48px);
}

.trust-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 80px;
    max-width: 1140px;
    margin: 0 auto;
    align-items: center;
}

.trust-title {
    text-wrap: balance;
    font-size: var(--h2-size);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.1;
    margin-bottom: 24px;
}


/* Footer */
footer {
    background: var(--footer-bg);
    color: var(--footer-text);
    padding: 60px 0 24px 0;
    border-top: 1px solid var(--border-subtle);
}

.footer-grid {
    display: grid;
    /* The brand block caps at 42ch and the links sat in one `auto` column hard
       right, which left roughly 700px of dead ground down the middle at 1440.
       Three named columns spread the links across that space instead. */
    grid-template-columns: minmax(0, 1.15fr) repeat(3, minmax(max-content, 0.6fr));
    gap: 48px;
    margin-bottom: 48px;
    align-items: start;
}

.f-logo {
    font-family: var(--font-wordmark);
    font-size: var(--t-wordmark-sm);
    margin-bottom: 8px;
    font-weight: 600;
    letter-spacing: -0.022em;
    color: var(--f-logo);
    text-transform: lowercase;
}

.f-sub {
    font-size: var(--t-meta);
    color: var(--f-sub);
}

.f-center {
    font-size: var(--t-meta);
    /* Playfair's italic, not Inter's. The display face is on the page anyway
       for the wordmark, so this line costs nothing extra -- and now that
       headlines are Inter it is one of the few places the serif appears. */
    font-family: var(--font-accent);
    font-style: italic;
    color: var(--f-center);
    text-align: center;
    line-height: 1.45;
    max-width: 800px;
    margin: 0 auto;
}

.f-social {
    display: flex;
    justify-content: flex-end;
    gap: 16px;
}

.f-icon {
    width: 24px;
    height: 24px;
    color: var(--f-social-default);
}

.f-icon:hover {
    color: var(--f-social-hover);
}

.f-bottom {
    border-top: var(--f-bottom-border);
    padding-top: 20px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px 32px;
    font-size: var(--t-label);
    color: var(--f-copyright);
}

.f-bottom>span {
    justify-self: start;
}

.f-bottom a {
    color: inherit;
}

.f-bottom a:hover {
    color: #FFFFFF;
    text-decoration: underline;
}

.f-disclaimer {
    font-size: var(--t-label);
    /* var(--f-sub) at 0.7 opacity landed on 3.22:1. Legal text has to be
       readable — that is the entire point of printing it. */
    color: rgba(255, 255, 255, 0.68);
    text-align: center;
    opacity: 1;
    line-height: 1.4;
    max-width: 480px;
    margin: 0 24px;
}



/* WCAG 2.4.1 Bypass Blocks. Off-screen until focused, then it lands as a normal
   pill at the top left. A keyboard user should not have to tab the wordmark,
   language menu, theme toggle and nav CTA on every page before reaching the
   content. */
.skip-link {
    position: absolute;
    left: 12px;
    top: 12px;
    z-index: 2000;
    padding: 12px 20px;
    border-radius: var(--radius-pill, 100px);
    background: var(--amber, #C05436);
    color: #fff;
    font-family: var(--font-body, sans-serif);
    font-size: var(--t-meta);
    font-weight: 600;
    text-decoration: none;
    transform: translateY(-160%);
    transition: transform 0.18s cubic-bezier(0.23, 1, 0.32, 1);
}

.skip-link:focus {
    transform: translateY(0);
}

/* Animations */
/* Scoped to .js deliberately. `.reveal` starts at opacity 0 and an
   IntersectionObserver adds `.active` on scroll -- so with scripting off the
   observer never runs and 21 of the 22 revealed blocks stayed invisible: the
   entire page below the hero rendered blank. The text was in the HTML, but any
   renderer that paints CSS without running JS saw an empty page, which is the
   exact "content hidden behind JavaScript" pattern that costs visibility with
   crawlers that do not execute scripts.

   The `js` class is added by the inline head script before first paint, so
   there is no flash of unhidden content for the 99% who do have JS. */
.js .reveal {
    opacity: 0;
    transform: translateY(20px);
    transition-property: opacity, transform, background-color, color, border-color, box-shadow;
    transition-duration: 0.5s, 0.5s, 0.3s, 0.3s, 0.3s, 0.3s;
    transition-timing-function: ease;
}

.js .reveal.active {
    opacity: 1;
    transform: translateY(0);
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Responsive */
@media (max-width: 780px) {
    h1 {
        font-size: 2.2rem !important;
    }

    .trust-section {
        padding: 60px 0;
    }

    .trust-grid {
        grid-template-columns: 1fr;
    }

    .hero {
        padding-top: 100px;
        text-align: center;
    }

    .hero-label,
    .subheadline {
        margin-left: auto;
        margin-right: auto;
    }

    :root {
        --card-width: min(300px, calc(100% - 64px));
        --card-gap: 12px;
    }

    /* Very small phones (≤ 380px) — tighten further */
    @media (max-width: 380px) {
        :root {
            --card-width: min(280px, calc(100% - 56px));
            --card-gap: 8px;
        }
    }

    /* Hide navbar CTA on mobile to avoid header clutter; utilities align to the right */
    .nav-btn {
        display: none !important;
    }

    @keyframes bounceHint {

        0%,
        100% {
            transform: translateX(0);
        }

        50% {
            transform: translateX(4px);
        }
    }

    @keyframes bounceHintLeft {

        0%,
        100% {
            transform: translateX(0);
        }

        50% {
            transform: translateX(-4px);
        }
    }

    .problem-grid,
    .pricing-grid,
    .city-grid {
        grid-template-columns: 1fr;
    }

    .hiw-grid {
        grid-template-columns: 1fr;
        gap: 40px;
        border-left: none;
        padding-left: 0;
        margin-left: 0;
    }

    .hiw-arrow {
        display: none;
    }

    .hiw-col {
        padding-top: 0;
    }

    .hiw-text {
        margin-bottom: 0 !important;
    }

    .pc-free,
    .pc-supporter,
    .pc-founders {
        padding: 16px 16px 12px 16px !important;
        margin: 0 auto 16px auto !important;
    }

    /* These centred the old footer. Left alone they reproduced the exact
       problem the rebuild fixed: the wordmark, the tagline and the copyright
       centred while the etymology line, the links and the disclaimer stayed
       left. One alignment, not two. */
    .footer-grid {
        grid-template-columns: 1fr;
    }

    .f-bottom {
        display: flex !important;
        flex-direction: column !important;
        align-items: flex-start !important;
        gap: 12px !important;
    }

    .f-disclaimer {
        margin: 0 !important;
        max-width: 100% !important;
    }

    .section-title,
    .trust-title,
    .waitlist-section h2,
    .pricing-section .section-title {
        font-size: clamp(24px, 6vw, 28px) !important;
        line-height: 1.15 !important;
        margin-top: 0 !important;
        padding-top: 4px !important;
    }

    .container {
        padding-left: 16px !important;
        padding-right: 16px !important;
    }

    .hero h1 {
        font-size: clamp(36px, 10vw, 48px) !important;
        line-height: 1.1 !important;
        letter-spacing: -0.02em;
        padding: 0 12px !important;
    }

    /* Mobile Compactness Overrides */
    .problem-section,
    .hiw-section,
    .city-section,
    .pricing-section,
    .waitlist-section {
        padding: 64px 0 !important;
    }

    /* Reduce bottom margins on mobile grids to prevent compounding vertical gaps */
    .timeline-grid,
    .city-grid,
    .pricing-grid {
        margin-bottom: 0 !important;
    }

    .trust-section {
        padding: 40px 16px 48px 16px !important;
        width: calc(100% - 32px) !important;
        border-radius: var(--radius-section) !important;
        margin: 0 auto !important;
    }

    .trust-title {
        margin-bottom: 32px !important;
    }

    /* Mobile Typography Strict Overrides */
    /* Consolidated above */

    .prob-title,
    .hiw-title,
    .price-title,
    .city-stat {
        font-size: var(--t-body) !important;
    }

    .prob-text,
    .hiw-text,
    .trust-text,
    .city-para,
    .bn-text,
    .waitlist-sub {
        font-size: var(--t-meta) !important;
        line-height: 1.5 !important;
    }

    .hero {
        padding-top: 90px !important;
        padding-bottom: 40px !important;
    }

    .hero h1 {
        margin-bottom: 8px !important;
    }

    .subheadline {
        font-size: var(--t-body) !important;
        line-height: 1.5 !important;
        margin-bottom: 16px !important;
        padding: 0 12px;
    }

    .hero-cta {
        margin-bottom: 12px !important;
    }

    .problem-grid,
    .city-grid {
        gap: 12px !important;
        margin-bottom: 16px !important;
    }

    .hiw-grid {
        gap: 16px !important;
    }

    .hiw-title {
        margin-bottom: 4px !important;
    }

    .city-para {
        margin-top: 16px !important;
        margin-bottom: 16px !important;
    }

    .city-section p.reveal:last-child {
        margin-top: 8px !important;
        margin-bottom: -16px !important;
    }

    .pricing-section .section-title {
        margin-bottom: 16px !important;
    }

    .pricing-grid {
        gap: 16px !important;
    }

    footer {
        padding-top: 32px !important;
    }

    .city-card {
        padding: 24px 20px !important;
    }

    .city-icon {
        margin-bottom: 12px !important;
    }

    .city-stat {
        font-size: var(--t-lead) !important;
        margin-bottom: 8px !important;
    }

    .city-card.featured .city-stat {
        font-size: var(--t-subtitle) !important;
    }

    .section-title {
        margin-bottom: 24px !important;
    }

    .prob-title,
    .pricing-name,
    .hiw-title {
        font-size: var(--t-subtitle) !important;
    }

    .social-proof-pill,

    /* =========================================
               ZINQ MOBILE UI/UX ENFORCEMENT PATCH
            ========================================= */

    /* 1. Strict Typographic Clamp for Mobile H2s */
    h2,
    .section-title,
    .trust-title {
        font-size: clamp(1.5rem, 6vw, 1.75rem) !important;
        line-height: 1.15 !important;
        margin-bottom: 1.5rem !important;
        letter-spacing: -0.01em !important;
    }

    /* 2. Absolute Margins & Unbreakable Stacked Cards */
    .timeline-grid,
    .problem-grid,
    .city-grid,
    .trust-grid {
        display: flex !important;
        flex-direction: column !important;
        width: 100% !important;
        gap: 24px !important;
        box-sizing: border-box !important;
    }

    .pricing-grid {
        display: flex !important;
        flex-direction: column !important;
        width: 100% !important;
        gap: 16px !important;
        box-sizing: border-box !important;
    }

    /* 3. The Tag Wrap Fix (Profile Cards) */

    /* 4. Touch Target & Padding Optimization */
    .price-card,
    .city-card {
        width: 100% !important;
        padding: 20px 24px !important;
        border-radius: 16px !important;
        box-sizing: border-box !important;
    }

    .price-card {
        padding: 24px 20px 20px !important;
    }

    /* 5. Mobile Pricing Badge Positioning Fix */
    .price-card.pc-free,
    .price-card.pc-supporter,
    .price-card.pc-founders {
        position: relative !important;
        margin-top: 24px !important;
    }

    .pop-badge {
        position: absolute !important;
        top: 0 !important;
        left: 24px !important;
        transform: translateY(-50%) !important;
        z-index: 2 !important;
    }
}

/* ZINQ CRO CSS UPDATES */
body,
main,
section,

section[id],
div[id] {
    scroll-margin-top: calc(var(--nav-height) + 24px);
}

/* CRO: Dimmed button with a black/white shine to indicate "Coming Soon" */


/* Dark Mode Contrast Overrides */

/* Luminous Dark Mode: Overlay pills on user photos use Glassmorphism */

/* Dark mode non-overlay pills: 12% tint bg + luminous text */

/* Dark mode match badges: solid backgrounds{
    box-shadow: 0 0 0 6px var(--bg-pricing) !important;
}

/* App UI Mockup Buttons - De-escalated */

[data-theme="dark"] .prob-text {
    color: #A5B0BB;
}


#netlify-badge,
netlify-badge,
a[href*="netlify.com"] {
    display: none !important;
    opacity: 0 !important;
    pointer-events: none !important;
    visibility: hidden !important;
}

/* Floating Match Badge Animation */
@keyframes gentleFloat {
    0% {
        transform: translateY(0px);
    }

    50% {
        transform: translateY(-4px);
    }

    100% {
        transform: translateY(0px);
    }
}

/* Waving Character Animation */
@keyframes waveEmoji {
    0% {
        transform: rotate(0deg);
    }

    10% {
        transform: rotate(14deg);
    }

    20% {
        transform: rotate(-8deg);
    }

    30% {
        transform: rotate(14deg);
    }

    40% {
        transform: rotate(-4deg);
    }

    50% {
        transform: rotate(10deg);
    }

    60% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(0deg);
    }
}

/* Micro-interactions: heartbeat pulse on match badge hover */


.editorial-blockquote {
    /* The comment below has been here a while and was right; the type was not.
       This line is the strongest thing on the page and it was set at 24px in a
       620px column while the headline ran at 88px -- a quarter the size of the
       hero, boxed in the middle of the weakest section, reading exactly like the
       footnote it was trying not to be.

       It is now the page's second scale moment: large enough to stop a reader,
       deliberately below the h1 so the hero still leads, and left-aligned --
       which also breaks the run of five identically centred 40px section titles
       that made the whole page one rhythmic note. */
    /* Measure, not a hard cap: at this size 15ch wrapped it into seven cramped
       lines with a dead right half. ~30ch lands it on three or four. */
    /* Measure, not a hard cap: 15ch wrapped it into seven cramped lines, 30ch
       into five. ~44ch lands it on four, and centring it in a 940px block is
       what the two-column version was never going to give it. */
    max-width: min(44ch, 100%);
    margin: 0 auto;
    padding: 0;
    border-left: none;
    background: none;
    border-radius: 0;
    font-size: var(--t-statement);
    font-weight: 600;
    line-height: 1.18;
    letter-spacing: var(--tr-title);
    color: var(--text-main);
    opacity: 1;
    text-wrap: balance;
    font-family: 'Fraunces', 'Fraunces Fallback', Georgia, serif;
    font-style: italic;
    box-shadow: none;
    text-align: center;
    position: relative;
    z-index: 1;
}


[data-theme="dark"] .editorial-blockquote {
    background: none;
}

/* Mobile Flawless Adjustments */
@media (max-width: 600px) {
    .editorial-blockquote {
        padding: 0 !important;
        margin: 56px 0 24px !important;
        max-width: 100% !important;
        line-height: 1.2 !important;
    }

    
    .city-card.featured {
        padding: 40px 24px !important;
    }

    .form-container {
        padding: 32px 20px !important;
    }

    .price-btn {
        height: 54px !important;
        font-size: var(--t-body) !important;
    }

    .social-proof-pill {
        padding: 8px 16px;
        font-size: var(--t-label);
    }

    .price-card.pc-supporter .price-title {
        flex-direction: column;
        align-items: flex-start !important;
        gap: 8px;
    }

    /* --- Exact Mobile Overrides --- */
    .hero {
        padding-top: 80px !important;
        padding-bottom: 44px !important;
    }

    .hero h1 {
        /* The floor has to stay below the vw value or clamp() pins the
           headline to it and the viewport-relative sizing never engages —
           that was pushing the headline to 7 lines on a 393px screen and
           burying the signup form and profile cards below the fold. */
        font-size: clamp(2.3rem, 10vw, 4.4rem) !important;
        line-height: 0.96 !important;
        margin-bottom: 24px !important;
    }

    .hero p.subheadline {
        font-size: var(--t-body) !important;
        max-width: 24ch !important;
        margin: 0 auto 24px auto !important;
        line-height: 1.45 !important;
    }

    .timeline-step {
        padding: 16px 0 0 !important;
    }

    .timeline-step .hiw-title {
        margin-bottom: 8px !important;
    }

    .timeline-step .hiw-text {
        font-size: var(--t-meta) !important;
        line-height: 1.5 !important;
    }

    .step-number {
        margin-bottom: 12px !important;
    }

    .community-section {
        padding-top: 40px !important;
    }

    .trust-section {
        padding: 40px 0 !important;
    }

    .problem-section {
        padding: 40px 0 !important;
    }

    footer {
        padding: 32px 0 80px 0 !important;
    }

    .f-bottom {
        margin-top: 24px !important;
        gap: 16px !important;
    }
}

/* --- Extra Narrow Mobile (380px) --- */
@media (max-width: 380px) {
    .hero {
        padding-top: 64px !important;
        padding-bottom: 36px !important;
    }

    .hero h1 {
        /* Must stay below what the 600px rule resolves to at 380px,
           otherwise the smallest screens get the largest headline. */
        font-size: clamp(2.05rem, 9.5vw, 2.9rem) !important;
    }

    .hero p.subheadline {
        max-width: 22ch !important;
        font-size: var(--t-body) !important;
    }

    .feature-card,
    .city-card {
        padding: 12px !important;
    }

    .prob-title {
        font-size: var(--t-body) !important;
    }
}

/* Extracted Inline Styles */

@keyframes pulse-orange {
    0% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(249, 115, 22, 0.7);
        /* Orange */
    }

    70% {
        transform: scale(1);
        box-shadow: 0 0 0 6px rgba(249, 115, 22, 0);
    }

    100% {
        transform: scale(0.95);
        box-shadow: 0 0 0 0 rgba(249, 115, 22, 0);
    }
}


/* --- GLOBAL UI HARMONIZATION OVERRIDES --- */

/* Buttons */
.btn {
    transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.2s ease, background-color 0.2s ease !important;
}

.btn-amber {
    box-shadow: 0 4px 12px rgba(217, 119, 54, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.2) !important;
}

@media (hover: hover) and (pointer: fine) {
    .btn-amber:hover {
        transform: translateY(-2px) scale(1.02) !important;
        box-shadow: 0 8px 24px rgba(217, 119, 54, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.3) !important;
    }
}

/* ── The hero CTA's one moment ──────────────────────────────────────────────
   The pace rail spends about three seconds explaining the product: your range,
   their range, the stretch you share, the number. It finishes at ~4.15s having
   made the argument -- and then nothing points at the thing you do about it.

   So the button answers, once. A single soft ring leaves its edge at 4.3s and
   fades. It fires exactly one time, never loops, and is scoped to .hero-btn --
   the nav and community buttons stay quiet, because two things asking for
   attention is the same as none.

   Deliberately not a gradient sweep or a shimmer: this button is a flat
   terracotta pill and a moving highlight would read as a different, glossier
   product. It borrows the button's own colour and its own radius, and the only
   things it animates are transform and opacity, so it cannot shift layout.

   Fill mode is `forwards`, not `both`: `both` would apply the from-state during
   the 4.3s delay and park a visible ring on the button from first paint. */
.hero-btn {
    position: relative;
}

.hero-btn::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    border: 1.5px solid var(--amber);
    opacity: 0;
    pointer-events: none;
    animation: ctaArrive 1.1s cubic-bezier(0.23, 1, 0.32, 1) 4.3s forwards;
}

@keyframes ctaArrive {
    from { opacity: 0.5; transform: scale(1); }
    to   { opacity: 0;   transform: scale(1.17); }
}

/* Reduced motion keeps the button entirely still -- the ring is decoration and
   decoration is the first thing to go. */
@media (prefers-reduced-motion: reduce) {
    .hero-btn::after { animation: none; opacity: 0; }
}

/* --- MOBILE FIXES FOR HARMONIZED UI --- */
@media (max-width: 768px) {

    .city-card {
        padding: 28px 20px !important;
        border-radius: 20px !important;
    }

    .price-card {
        padding: 28px 24px;
    }

    .pricing-grid {
        gap: 16px;
    }

    .btn {
        height: 48px;
    }
}

/* --- FIX HERO FORM DESKTOP LAYOUT --- */

/* --- FIX HERO MARGIN & PLACEHOLDER FOCUS --- */
.hero h1 {
    margin-bottom: 36px !important;
}

/* --- CRITICAL BUG FIXES --- */
/* Z-Index fix for Custom Dropdown */
.hero {
    position: relative;
    z-index: 900;
}

.hero-text {
    position: relative;
    z-index: 10;
    max-width: 100%;
    min-width: 0;
}

.hero-cta {
    position: relative;
    z-index: 999;
}


/* --- HERO CTA --- */
/* Two links, not a form: the primary opens the app, the secondary scrolls down.
   One button: the nav carries the same link, and anyone who wants the detail
   scrolls. A second button beside it only competed with the first. */
.hero-actions {
    display: flex;
    justify-content: center;
    margin-top: 4px;
}

.hero-micro {
    margin: 16px 0 0;
    font-size: var(--t-meta);
    font-weight: 400;
    color: var(--text-muted);
    letter-spacing: 0.01em;
}

@media (max-width: 768px) {
    /* Sized to its content, not to the column. At 100% it came out 358px wide
       on a 390px screen -- 92% of the viewport and exactly the width of the pace
       rail beneath it, which made the two read as one stacked slab rather than a
       button above a graphic. */
    .hero-actions .hero-btn {
        min-width: 200px;
        width: auto;
    }

    .hero-micro {
        text-align: center;
    }
}

/* --- SVG PROBLEM ICONS --- */

/* --- CONTENT BLOCK LAYERING SAFEGUARD --- */
/* Ensures content blocks appear above background elements */
.timeline-step,
.editorial-blockquote,
.story-bridge {
    position: relative;
    z-index: 10;
}

/* --- ABOUT PAGE SPECIFIC STYLES --- */
@keyframes pulseBlob {
    0% {
        transform: translateX(-50%) scale(1);
        opacity: 0.6;
    }

    100% {
        transform: translateX(-50%) scale(1.1);
        opacity: 1;
    }
}

.founder-card {
    background: var(--card-bg);
    border: 1px solid var(--border-subtle);
    border-radius: 24px;
    box-shadow: 0 24px 48px -12px rgba(0, 0, 0, 0.06);
    padding: clamp(32px, 6vw, 56px) clamp(24px, 6vw, 88px);
    position: relative;
    overflow: hidden;
    text-align: left;
    max-width: 800px;
    margin: 0 auto;
    transition: background-color 0.3s cubic-bezier(0.16, 1, 0.3, 1), color 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.feature-card {
    background: var(--card-bg);
    border: 1px solid var(--border-subtle);
    padding: 32px 28px;
    border-radius: 24px;
    text-align: left;
    box-shadow: var(--card-shadow);
    transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.3s cubic-bezier(0.16, 1, 0.3, 1), color 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

@media (hover: hover) {
    .feature-card:hover {
        transform: translateY(-4px);
        box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
    }
}

[data-theme="dark"] .feature-card {
    border: 1px solid rgba(255, 255, 255, 0.08);
}

[data-theme="dark"] .feature-card:hover {
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
}

@keyframes pulseBlobOpacity {
    0% {
        opacity: 0.35;
    }

    100% {
        opacity: 0.8;
    }
}

.founder-card {
    background: var(--card-bg);
    border: var(--card-border);
    border-radius: var(--radius-card);
    box-shadow: var(--card-shadow);
    padding: clamp(32px, 6vw, 56px) clamp(24px, 6vw, 88px);
    position: relative;
    overflow: hidden;
    text-align: left;
    max-width: 800px;
    margin: 0 auto;
    transition: background-color 0.3s cubic-bezier(0.16, 1, 0.3, 1), color 0.3s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

[data-theme="dark"] .founder-card {
    border: 1px solid rgba(255, 255, 255, 0.08);
}

@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Accessibility Focus States */
:focus-visible {
    outline: 2px solid var(--focus-ring) !important;
    outline-offset: 4px !important;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
.theme-toggle:focus-visible {
    outline: 2px solid var(--focus-ring) !important;
    outline-offset: 4px !important;
}

/* ═══════════════════════════════════════════
   FAQ Accordion Styles
   ═══════════════════════════════════════════ */

.faq-accordion {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* A list, not eight boxes. Each item carried a full 1px border, so eight
   stacked cards drew sixteen horizontal lines -- by far the largest single
   source of the rules on this page, and the reason the lower half read as a
   ladder. One divider between items draws seven, and the open/closed state is
   already carried by the chevron and the answer itself. */
.faq-item {
    background: none;
    border: 0;
    border-radius: 0;
    overflow: hidden;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.faq-item + .faq-item {
    border-top: 1px solid var(--rule-soft);
}

.faq-item:hover > .faq-question {
    color: var(--amber-text);
}


.faq-question {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 22px 28px;
    font-size: var(--t-body);
    font-weight: 600;
    color: var(--text-main);
    cursor: pointer;
    list-style: none;
    user-select: none;
    line-height: 1.4;
    transition: color 0.2s ease;
}

/* Remove default marker in all browsers */
.faq-question::-webkit-details-marker {
    display: none;
}
.faq-question::marker {
    display: none;
    content: '';
}

/* Chevron icon via pseudo-element */
.faq-question::after {
    content: '';
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    margin-left: 16px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    transition: transform 0.25s ease;
}

[data-theme="dark"] .faq-question::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
}

/* Rotate chevron when open */
.faq-item[open] > .faq-question::after {
    transform: rotate(180deg);
}

.faq-item[open] > .faq-question {
    /* Was the teal --primary token, a colour that belonged to no other element
       and failed contrast in dark mode at 4.40:1. */
    color: var(--amber-text);
}

.faq-answer {
    padding: 0 28px 22px 28px;
    font-size: var(--t-meta);
    color: var(--text-muted);
    line-height: 1.7;
    margin: 0;
    animation: faqFadeIn 0.25s ease;
}

@keyframes faqFadeIn {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Mobile adjustments */
@media (max-width: 600px) {
    .faq-question {
        padding: 18px 20px;
        font-size: var(--t-meta);
    }
    .faq-answer {
        padding: 0 20px 18px 20px;
        font-size: var(--t-meta);
    }
}

/* --- Press feedback (craft pass) -------------------------------------
   Only .btn responded to being pressed. On touch,
an element that does not
   react reads as broken before it reads as slow. Subtle scale,
short and
   ease-out so the response is felt on the first frame. */
.faq-question,
.theme-toggle,
.lang-dropdown-trigger,
.lang-dropdown-item {
    transition: transform 140ms cubic-bezier(.23, 1, .32, 1),
                background-color 140ms cubic-bezier(.23, 1, .32, 1);
}

.faq-question:active,
.lang-dropdown-item:active {
    transform: scale(0.99);
}

.theme-toggle:active,
.lang-dropdown-trigger:active {
    transform: scale(0.94);
}

@media (prefers-reduced-motion: reduce) {
    .faq-question,
.theme-toggle,
.lang-dropdown-trigger,
.lang-dropdown-item {
        transition: none;
    }
    .faq-question:active,
.theme-toggle:active,
.lang-dropdown-trigger:active,
.lang-dropdown-item:active {
        transform: none;
    }
}

/* ── App preview card ──────────────────────────────────────────────────────
   A faithful copy of the real Discover row plus a received run proposal, so
   the section shows the product rather than an idealised mock of it.

   Colours, radii, spacing and type are the app's own tokens, transcribed from
   zinq-app/design-tokens.js. They are literal values here on purpose: this
   repo has no build step and no shared token file, so keeping them named and
   in one block is the closest thing to a single source. If the app palette
   moves, move these with it.

   ground #F7F5F0 · paper #FFFFFF · ink #15120F · ink-2 #4A423A · quiet #736A60
   rule #E3DDD1 · rule-2 #EFEAE0 · clay #C05436 · band-me #D6CCB8
   radius card 14px · pill 100px · spacing 4/8/12/16/20/28/40 */

.app-card {
    --app-ground: #F7F5F0;
    --app-paper: #FFFFFF;
    --app-ink: #15120F;
    --app-ink-2: #4A423A;
    --app-quiet: #736A60;
    --app-rule: #E3DDD1;
    --app-rule-2: #EFEAE0;
    --app-clay: #C05436;
    --app-band-me: #D6CCB8;
    --app-edge: #948770;

    width: 100%;
    /* Was 380px, which left it floating with ~150px of slack in a ~530px grid
       column. A wider card also gives the day strip and the proposal rows room
       to breathe, which is how they actually look in the app. */
    max-width: 520px;
    background: var(--app-paper);
    border: 1px solid var(--app-rule);
    border-radius: 14px;
    padding: 20px;
    /* Warm near-black shadow. Pure black reads blue-grey against this cream. */
    box-shadow: 0 12px 32px rgba(21, 18, 15, 0.07);
    text-align: left;
    /* The whole card is an illustration: no text selection, no I-beam, no
       hover affordance anywhere inside it. */
    user-select: none;
    cursor: default;
}

/* The card is a fixed artefact: it must not follow the site's dark theme,
   because the app has no dark mode yet and showing one would be another
   screenshot of something that does not exist. */
[data-theme="dark"] .app-card {
    background: var(--app-paper);
    border-color: var(--app-rule);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.app-card-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.app-card-id {
    min-width: 0;
}

/* Fraunces is the app's display face. Latin subset only, below the fold, and
   `swap` — it never blocks the hero. */
.app-name {
    font-family: 'Fraunces', 'Fraunces Fallback', Georgia, serif;
    font-weight: 600;
    font-size: 30px;
    line-height: 1.02;
    letter-spacing: -0.022em;
    color: var(--app-ink);
}

.app-meta {
    margin-top: 4px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--app-quiet);
}

.app-card-pace {
    text-align: right;
    flex-shrink: 0;
}

.app-pace-num {
    font-family: 'Fraunces', 'Fraunces Fallback', Georgia, serif;
    font-weight: 600;
    font-size: 30px;
    line-height: 1.02;
    /* Tabular figures so the pace column never jitters between rows. */
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.03em;
    color: var(--app-ink);
}

.app-pace-unit {
    margin-top: 4px;
    font-size: 10px;
    line-height: 1.4;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--app-quiet);
}

/* The day strip. Shared days are marked by BOTH the rule colour and the text
   colour — never colour alone, so it survives a colour-blind reader. */
.app-week {
    display: flex;
    gap: 6px;
    margin-top: 16px;
}

.app-day {
    flex: 1;
    border-top: 2px solid var(--app-band-me);
    padding: 6px 0 4px;
    text-align: center;
}

.app-day span {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    color: var(--app-quiet);
}

.app-day.is-both {
    border-top-color: var(--app-clay);
}

.app-day.is-both span {
    color: var(--app-clay);
}

/* Everything under the shared-day strip is centred. The app itself left-aligns
   this block, so the card is knowingly not a pixel-exact transcription here --
   on a page where the card sits in a right-hand column, a left-aligned run
   proposal put a third stack of text against the left edge and the card read as
   bottom-heavy. Centred, the proposal reads as the card's conclusion. */
.app-run {
    margin-top: 20px;
    padding-top: 20px;
    border-top: 1px solid var(--app-rule-2);
    text-align: center;
}

.app-run-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--app-ink);
}

.app-run-text {
    margin-top: 4px;
    font-size: 15px;
    line-height: 1.55;
    color: var(--app-ink-2);
}

.app-run-actions {
    display: flex;
    gap: 8px;
    margin-top: 16px;
    justify-content: center;
}

/* Rendered as spans, not buttons: this is a picture of the app, and a control
   that looks pressable but does nothing is worse than one that does not. */
.app-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Depicted at 36px, not the app's real 44px minimum. These are a picture of
       a control, and at full scale the fake Accept measured 227x51 — larger
       than the real CTA further down the page (135x48) and in the identical
       fill. The biggest, most saturated pill on the section was the one thing
       that did nothing when clicked. Shrinking it restores the hierarchy:
       live controls read larger than depicted ones.

       The fill colour stays exactly the app's, so the depiction is still
       truthful and the label keeps its 4.60:1 contrast. */
    min-height: 36px;
    /* Content-sized, not stretched. In the app these fill the row; at depiction
       scale a pair of full-width bars was the heaviest thing on the section.
       The fill itself cannot be softened — clay on white is already 4.60:1 and
       any lightening drops the label below AA — so the weight comes out of the
       geometry instead. */
    flex: 0 0 auto;
    padding: 9px 22px;
    border-radius: 100px;
    font-size: 13.5px;
    line-height: 1.2;
    font-weight: 600;
    /* Nothing here is clickable, so nothing here should invite a click. */
    pointer-events: none;
    cursor: default;
}

/* One `go` per screen: clay fill, paper label. */
.app-btn-go {
    background: var(--app-clay);
    color: var(--app-paper);
}

.app-btn-line {
    /* --app-edge is the app's token for a boundary that IS the affordance
       (3.52:1 here, over SC 1.4.11's 3:1). The near-black 1px it had before
       measured 18.66:1 and shouted louder than the filled button beside it. */
    border: 1px solid var(--app-edge);
    color: var(--app-ink);
}

@media (max-width: 600px) {
    .app-card {
        padding: 16px;
    }

    .app-name,
    .app-pace-num {
        font-size: 26px;
    }
}


/* ── Pace overlap rail ─────────────────────────────────────────────────────
   The hero's signature. Two runners' pace ranges drawn on one min/km scale,
   with the stretch they can both hold lit in the accent. It is the product's
   entire premise in one graphic, and it earns the fold: the eye finishes on it
   and is pulled past it, which is the job a scroll chevron would otherwise do
   badly.

   Geometry: the scale runs 4:00–7:00, so a pace maps to
   (seconds - 240) / 180. Those percentages are inline on the elements because
   they are data, not styling — change the ranges and the numbers move with
   them. */

.pace-rail {
    --pr-track-bg: rgba(21, 18, 15, 0.055);
    --pr-own: #D8CDBC;
    --pr-both: var(--amber);

    max-width: 600px;
    /* Pushed well down so it lands near the fold and pulls the eye past it. */
    margin: clamp(28px, 11vh, 132px) auto 0;
    text-align: left;
}

[data-theme="dark"] .pace-rail {
    --pr-track-bg: rgba(255, 255, 255, 0.09);
    --pr-own: #5A5044;
}

.pr-track {
    display: flex;
    align-items: center;
    gap: 12px;
}

.pr-track + .pr-track {
    margin-top: 12px;
}

/* The two runners' names, set like the app's Micro label. */
.pr-who {
    width: 56px;
    flex-shrink: 0;
    font-size: var(--t-label);
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Tabular so the four pace figures sit in true columns. */
/* The range belongs to the runner, so it is printed beside their name rather
   than pinned to the ends of the track — where it pointed at the scale's edge
   instead of at where that runner's range actually starts. */
.pr-range {
    flex-shrink: 0;
    width: 84px;
    font-size: var(--t-meta);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--text-main);
    opacity: 0.75;
}

.pr-rail {
    position: relative;
    flex: 1;
    height: 14px;
    border-radius: 2px;
    background: var(--pr-track-bg);
    overflow: hidden;
}

/* Choreography, not decoration. This graphic IS the product thesis -- your
   range, their range, and the stretch you can both hold -- so it has to play as
   a sentence in that order. It used to fire all four bars at once, 0.62s, with
   no delay: the whole thing was finished roughly half a second after paint,
   while the reader was still on the headline. They never saw it move, only
   noticed afterwards that it had. The caption made it worse by landing at 1.05s
   -- announcing the answer before the bars it describes had been watched.

   The delays below are keyed to reading the headline first (~1.2s), then:
   you (1.15s) -> them (1.70s) -> the overlap ignites (2.85s) -> the number
   confirms it (3.55s). Each step starts before the previous finishes, so it
   reads as one connected movement rather than four separate events. */
.pr-seg {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left center;
    animation: prDraw 0.95s cubic-bezier(0.22, 1, 0.36, 1) both;
}


.pr-own {
    background: var(--pr-own);
}

/* The overlap is the point, so it arrives last and on its own. */
/* The payoff: the stretch both runners can hold, lit last and on its own beat
   so the eye has somewhere to land after the two ranges are down. */
.pr-both {
    background: var(--pr-both);
    animation-name: prIgnite;
    animation-duration: 0.85s;
}

/* All four delays live here and nowhere else. There were briefly two competing
   stagger blocks -- one keyed on :nth-of-type, this one on :nth-child -- at
   equal specificity, so the later block silently won and the timings above it
   did nothing. One source of truth.

   Your range, then theirs, then the stretch you share. Each starts before the
   previous ends so it reads as one movement, not four events. */
.pr-track:nth-child(1) .pr-own  { animation-delay: 1.15s; }
.pr-track:nth-child(2) .pr-own  { animation-delay: 1.70s; }
.pr-track:nth-child(1) .pr-both { animation-delay: 2.85s; }
.pr-track:nth-child(2) .pr-both { animation-delay: 2.93s; }

@keyframes prDraw {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

@keyframes prIgnite {
    from { transform: scaleX(0); opacity: 0.4; }
    to   { transform: scaleX(1); opacity: 1; }
}

.pr-caption {
    margin: 18px 0 0;
    text-align: center;
    font-size: var(--t-meta);
    color: var(--text-muted);
    letter-spacing: 0.01em;
    opacity: 0;
    /* Confirms the number only once the overlap has actually lit. */
    animation: prCaption 0.6s ease forwards 3.55s;
}

.pr-caption strong {
    color: var(--amber-text);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

@keyframes prCaption {
    from { opacity: 0; transform: translateY(4px); }
    to   { opacity: 1; transform: none; }
}

/* Someone who has asked for less motion gets the finished state, immediately. */
@media (prefers-reduced-motion: reduce) {
    .pr-seg,
    .pr-caption {
        animation: none;
        transform: none;
        opacity: 1;
    }
}

@media (max-width: 600px) {
    .pace-rail {
        max-width: 100%;
    }

    .pr-who {
        width: 42px;
        font-size: 9px;
        letter-spacing: 0.12em;
    }

    .pr-range {
        width: 74px;
        font-size: 12px;
    }

    .pr-caption {
        font-size: 12.5px;
    }
}


/* ── Safety controls list ──────────────────────────────────────────────────
   Set as a definition list because that is what it is: a term and what it
   does. Visually it borrows the app's settings rows — a micro label above a
   plain statement, hairline between — so the page shows the same grammar the
   product uses for the same job. */

.controls {
    margin: 0;
    max-width: 520px;
}

.control {
    padding: 18px 0;
    border-bottom: 1px solid var(--border-subtle, rgba(0, 0, 0, 0.08));
}

.control:first-child {
    padding-top: 0;
}

.control:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.control-key {
    font-size: var(--t-label);
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--amber-text);
}

.control-val {
    margin: 7px 0 0;
    font-size: 17px;
    line-height: 1.5;
    color: var(--text-main);
    opacity: 0.88;
}

@media (max-width: 600px) {
    .control {
        padding: 15px 0;
    }

    .control-val {
        font-size: 16px;
    }
}


/* ── Short-viewport ladder ─────────────────────────────────────────────────
   A hero pinned to one screen only works if its contents shrink with the
   screen. These come last, and carry !important, because the width-based
   mobile rules above already use it.

   The two axes are scoped apart on purpose. A height-only headline cap was
   overriding the narrow-width sizes and making the headline BIGGER on a small
   phone — 48px where the width rules had correctly chosen 39px — which is what
   pushed the CTA under the fold on a 667px screen. Width owns the headline
   below 600px; height owns it above. */

@media (max-height: 780px) {
    .hero {
        padding-top: clamp(84px, 13vh, 118px) !important;
        padding-bottom: 26px !important;
    }

    .hero p.subheadline {
        margin-bottom: clamp(16px, 3vh, 26px) !important;
    }

    .pace-rail {
        margin-top: clamp(22px, 6vh, 60px) !important;
    }

    .pr-caption {
        margin-top: 12px !important;
    }
}

/* Short AND wide: the headline is the thing with room to give. */
@media (max-height: 780px) and (min-width: 601px) {
    .hero h1 {
        font-size: min(var(--t-display), 11vh) !important;
        margin-bottom: 10px !important;
    }

    .hero p.subheadline {
        font-size: clamp(15px, 2vh, 18px) !important;
    }
}

@media (max-height: 690px) and (min-width: 601px) {
    .hero h1 {
        font-size: min(var(--t-display), 9.6vh) !important;
    }

    .hero {
        padding-top: 80px !important;
    }

    .hero-btn {
        height: 52px !important;
        font-size: 16px !important;
    }
}

/* Short AND narrow: the width rules already sized the headline correctly, so
   only the rhythm around it tightens. */
@media (max-height: 780px) and (max-width: 600px) {
    .hero {
        /* 78, not 72: at 640-667px tall the headline's leading was crossing the
           nav's baseline. There is room below for it — the rail still clears
           the fold by ~35px. */
        padding-top: 84px !important;
        padding-bottom: 20px !important;
    }

    .hero h1 {
        margin-bottom: 10px !important;
    }

    .pace-rail {
        margin-top: 24px !important;
    }
}

/* Below this the headline, the CTA and the rail simply need more room than the
   window has. A cramped one-screen hero is worse than an honest scroll. */
@media (max-height: 600px) {
    .hero {
        min-height: auto;
        padding-top: 96px !important;
        padding-bottom: 44px !important;
    }

    .pace-rail {
        margin-top: 34px !important;
    }
}


/* ── Problem columns ───────────────────────────────────────────────────────
   Three editorial columns. Each opens with a 2px rule — the same device the
   app's day strip uses to head a column — then the flaw as a micro label, then
   the tool, then why it falls short.

   Everything here is deliberately achromatic. Terracotta is Zinq's accent and
   it appears nowhere in this section, so the eye meets colour for the first
   time at the answer rather than at the problem. */

/* No rule above the column. There were 53 horizontal lines on this page and
   six of them were these -- one over each problem column and each step -- which
   is enough repetition that none of them read as structure any more, only as
   texture. The terracotta numeral and the label already mark where a column
   starts; the rule was drawing a boundary the eye did not need. */
.prob-col {
    padding-top: 4px;
}


.prob-flaw {
    margin: 0 0 14px;
    font-size: var(--t-label);
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.prob-title {
    font-family: var(--font-body);
    font-size: var(--t-subtitle);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin: 0 0 10px;
    color: var(--text-main);
}

.prob-text {
    margin: 0;
    font-size: 17px;
    line-height: 1.55;
    color: var(--text-muted);
    max-width: 34ch;
}

@media (max-width: 600px) {
    .prob-col {
        padding-top: 16px;
    }

    .prob-flaw {
        margin-bottom: 10px;
    }

    .prob-title {
        font-size: 22px;
    }

    .prob-text {
        font-size: 16px;
        max-width: none;
    }
}

/* The bridge line was orphaning its last word ("feels.") on a line of its own.
   Balanced wrapping evens the two lines instead. */
.story-bridge p {
    text-wrap: balance;
}


/* ── Touch targets ─────────────────────────────────────────────────────────
   Measured on a 390px viewport, these were all under the 44px guideline and
   the footer links were under WCAG 2.2 SC 2.5.8's 24px floor at 19px tall.
   The fix is padding, not size: the text stays exactly as designed and the
   tappable box grows around it. */

/* 24px is WCAG 2.2 SC 2.5.8's floor and applies to every input type; 44px is
   the touch guideline. Splitting them keeps a mouse-driven footer compact —
   at a flat 44px the links stacked into two rows with a gap that read as a
   layout bug — while a thumb still gets a full-size target. */
.f-nav a,
.f-bottom a,
.story-bridge a,
.lang-dropdown-trigger,
.lang-dropdown-item {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
}

.f-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
}

@media (pointer: coarse) {

        .f-nav a,
    .f-bottom a,
    .story-bridge a,
    .lang-dropdown-trigger,
    .lang-dropdown-item {
        min-height: 44px;
    }

    .f-social a {
        min-width: 44px;
        min-height: 44px;
    }
}

/* On a phone the footer link rows would otherwise stack to 44px each and push
   the legal links a long way down; tighten the gap now that each row is taller. */


/* ── Hero type ramp below 781px ────────────────────────────────────────────
   One authoritative ramp, replacing three that disagreed.

   Before this, `.hero h1` was governed by `clamp(2.3rem, 10vw, 4.4rem)` under
   600px, a hard `clamp(36px, 10vw, 48px)` cap under 780px, and `6vw + 1rem`
   above that. The middle cap won between 601-780px, so the headline measured
   60px at a 600px viewport, dropped to 48px at 650px, and only recovered at
   800px — it got SMALLER as the screen got BIGGER.

   8.05vw is chosen so the ramp meets the base `6vw + 1rem` exactly at 781px
   (62.8px both sides), which is what makes it continuous across the boundary.

   The subheadline had the same shape of bug for a different reason: a fixed
   `24ch` cap held it at 265px from 390px all the way to 600px, so on a 600px
   screen the measure filled 44% of the width and ran to six lines. A `ch` cap
   does not scale with the viewport; `min(46ch, 100%)` does — the container
   governs on a phone, the reading measure governs on a tablet. */

@media (max-width: 780px) {
    .hero h1 {
        /* Width sets the ramp, height sets a floor. On a tall narrow canvas
           (a resized desktop window, a big phone) 8vw alone left the headline
           small against 900+ pixels of height, and the leftover space pooled
           at the top and bottom of the hero. Taking the larger of the two
           makes the type answer the canvas it is actually on.
           The 4.1rem ceiling is what stops it overflowing a short screen. */
        font-size: clamp(2.05rem, 8.05vw, 3.95rem) !important;
        line-height: 1.0 !important;
        letter-spacing: -0.02em !important;
        padding: 0 !important;
    }

    .hero p.subheadline {
        max-width: min(46ch, 100%) !important;
        font-size: clamp(16px, 3vw, 19px) !important;
        line-height: 1.5 !important;
        margin-left: auto !important;
        margin-right: auto !important;
    }

    /* A pill that spans the full width of a tablet reads as a slab, not a
       button. Full-bleed is right on a phone and wrong by about 400px. */
    .hero-actions .hero-btn {
        width: auto;
        max-width: 100%;
    }

    .hero-actions {
        justify-content: center;
    }

    /* The hero centred its contents, so the taller the screen the further the
       headline drifted from the nav: 23px of gap at 640px tall, 36px at 844,
       77px at 932, 154px on a 768px tablet. The eye starts at the top of the
       screen, not its middle.

       Anchored to the top instead, with the pace rail taking `margin-top: auto`
       so it still lands at the fold. The slack now pools between the CTA and
       the rail, where it costs nothing, rather than above the headline. */
    .hero {
        justify-content: flex-start;
        /* With the content top-anchored, this padding alone sets the distance
           from the fixed nav -- it is no longer absorbed by centring. The nav
           is ~92px tall, so this leaves roughly 28px of air under it. */
        padding-top: clamp(118px, 15vh, 140px) !important;
    }

    /* The rail is inside .container, not a direct child of .hero, so
       `margin-top: auto` on it did nothing until the container became the flex
       column that owns the leftover height. */
    .hero > .container {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
    }

    .pace-rail {
        margin-top: auto !important;
        margin-bottom: clamp(4px, 1.5vh, 18px) !important;
        /* Explicit width because the container is now a column flex parent: the
           rail's `margin: ... auto` centres it but lets it shrink to content,
           which took it from 343px to 173px. In a column flex container the
           cross axis is the width, and that is the second time this has bitten
           on this page. */
        width: 100%;
        align-self: stretch;
    }

    /* Stacked, the card no longer shares a row with the copy, so the 380px cap
       just left it floating in whitespace narrower than the list above it. */
    .app-card {
        max-width: min(460px, 100%);
    }
}


/* The rail is the fold anchor, so on a tall narrow screen it should sit near
   the fold rather than leaving a pool of empty page under it. Growing its top
   margin pushes it down and lifts the copy, because the hero centres its
   contents.

   min-height matters here: without it this rule outranked the short-viewport
   ladder and put 109px of margin back on a 640px-tall screen, which pushed the
   headline under the nav. */
@media (max-width: 780px) and (min-height: 781px) {

    /* Height floor for the headline. Width sets the ramp; on a tall narrow
       canvas that ramp alone left the type small against 900+ pixels of height
       and the slack pooled above and below the hero. Gated to tall screens
       because on a 640px one there is no slack to spend — 6vh there pushed the
       headline into the nav. Same 781px boundary as the short-viewport ladder,
       so the file has one height threshold rather than two.

       The height term is itself bounded by 12vw, and that bound is load
       bearing. "running partner" is one nowrap span — it must never break
       across lines — and it measures about 7.26em, so it outgrows the viewport
       once the headline passes roughly (width - 32px) / 7.26. At 393x873 a
       plain 6vh produced 52px and the span overflowed by 0.7px. Bounding by
       width makes the expression self-limiting at every size, which is why
       there is no width breakpoint here. */
    .hero h1 {
        font-size: clamp(2.05rem, max(8.05vw, min(6vh, 12vw)), 4.1rem) !important;
    }

    .pace-rail {
        /* Was 17vh, which was a mistake: the hero centres its contents, so
           adding N to this margin shrinks the top and bottom gaps by N/2 each
           while opening the middle by the full N. That put a hole between the
           CTA and the rail — the two things most worth reading together — to
           save half as much space at the bottom. Space under the last element
           reads as breathing room; space in the middle reads as broken. */
        margin-top: clamp(36px, 7vh, 88px) !important;
    }
}


/* ── How it works: three steps ─────────────────────────────────────────────
   The last section still built as boxes. It now shares the grammar of the
   problem columns — a rule on top, then the content — with one deliberate
   difference: these rules and numbers carry the accent, because this is Zinq's
   own answer. The problems above are drawn without it. Reading down the page,
   colour arrives exactly where the product does.

   The numbering stays. Numbered markers are decoration when the content is a
   list, but this is a real sequence: you cannot propose a run before there is
   anyone to propose it to. Order carries information here, so it is shown. */

.timeline-step {
    text-align: left;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 20px 0 0;
}

/* The numbered steps used a solid accent rule. Against three soft rules in the
   section above it read as a warning stripe rather than a signal — the accent
   was doing the work of a highlighter. The rule now matches its siblings and
   the NUMBER alone carries the colour, which is enough to say "this is the
   product's answer" without shouting it. */

.step-number {
    display: block;
    background: none;
    border: 0;
    padding: 0;
    margin: 0 0 14px;
    font-family: var(--font-body);
    font-size: var(--t-label);
    font-weight: 600;
    letter-spacing: 0.15em;
    font-variant-numeric: tabular-nums;
    color: var(--amber-text);
}

.hiw-title {
    font-family: var(--font-body);
    font-size: var(--t-subtitle);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin: 0 0 10px;
    color: var(--text-main);
}

.hiw-text {
    margin: 0;
    font-size: 17px;
    line-height: 1.55;
    color: var(--text-muted);
    max-width: 34ch;
}

@media (max-width: 600px) {
    .timeline-step {
        padding: 16px 0 0;
    }

    .step-number {
        margin-bottom: 10px;
    }

    .hiw-title {
        font-size: 22px;
    }

    .hiw-text {
        font-size: 16px;
        max-width: none;
    }
}


/* ── Footer ────────────────────────────────────────────────────────────────
   A brand block and a link column, each left-aligned within itself. The
   previous version spread six elements across three alignments in two
   different grids, so no two things shared an edge. */

.f-brand {
    max-width: 42ch;
}

.f-sub {
    margin: 0 0 18px;
}

.f-center {
    margin: 0 0 24px;
    text-align: left;
    max-width: 38ch;
}

.f-social {
    display: flex;
    justify-content: flex-start;
    gap: 8px;
}

/* Three columns, each with a heading. A single undifferentiated list mixed
   the product, the guides and the legal pages at one weight, so nothing told
   the eye where to look. */
.f-nav {
    /* Not `display: contents`, which would have made the three columns direct
       children of the footer grid but drops the <nav> landmark from the
       accessibility tree in more than one engine. Spanning three tracks and
       re-gridding inside keeps both the layout and the landmark. */
    grid-column: span 3;
    display: grid;
    grid-template-columns: repeat(3, minmax(max-content, 1fr));
    gap: 32px;
}

.f-col {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
}

.f-col-title {
    font-family: var(--font-body);
    /* The bare `h2` rule sets font-size and line-height with !important, and a
       second one does it again under 780px, so these labels rendered at 40px.
       Matching the !important is the contained fix: dropping it from the global
       rule would resize every section title on the site. */
    font-size: var(--t-label) !important;
    line-height: 1.2 !important;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.45);
    margin: 0 0 2px;
}

.f-nav a {
    /* var(--f-sub) is white at 50%, which is 4.02:1 on the footer ground —
       fine for the tagline it was written for, under AA for a link. */
    color: rgba(255, 255, 255, 0.72);
    text-decoration: none;
    font-size: 14px;
    line-height: 1.3;
    transition: color 0.2s ease;
}

.f-nav a:hover {
    color: var(--f-logo);
}

/* The footer is the last chance to act, so the CTA is a link with weight
   rather than another button competing with the hero. */
.f-nav .f-open {
    /* The footer is dark in BOTH themes, so it needs the light-on-dark accent
       regardless. var(--amber-text) is tuned for light grounds and measured
       3.23:1 here. This is 9.4:1. */
    color: #FF9854;
    font-weight: 600;
}

.f-nav .f-open:hover {
    color: var(--f-logo);
}

/* The arrow is the only thing in the footer that moves, so it reads as the one
   link that leaves the site rather than navigating within it. */
.f-nav .f-open::after {
    content: "\00a0\2192";
    display: inline-block;
    transition: transform 0.2s ease;
}

.f-nav .f-open:hover::after {
    transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
    .f-nav .f-open::after {
        transition: none;
    }
}

.f-disclaimer {
    text-align: right;
    /* At 80ch the trademark line filled the row and dropped a lone "Inc." onto
       a second line. Two balanced lines read as a deliberate block. */
    max-width: 62ch;
    margin: 0;
    text-wrap: balance;
}

@media (max-width: 1024px) {
    .footer-grid {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    .f-nav {
        grid-column: span 1;
    }
}

@media (max-width: 560px) {
    /* Three equal columns do not fit, and letting them wrap naturally dropped
       Legal alone onto a second row with half the width empty beside it. Place
       them instead: the two short lists share the left column, the long one
       takes the right. */
    .f-nav {
        grid-template-columns: 1fr 1fr;
        gap: 24px;
    }

    .f-col:nth-child(1) {
        grid-area: 1 / 1;
    }

    .f-col:nth-child(2) {
        grid-area: 1 / 2 / span 2;
    }

    .f-col:nth-child(3) {
        grid-area: 2 / 1;
    }

    /* Touch targets are already 44px tall under `pointer: coarse`, so the flex
       gap on top of that spaced the links twice. 6px is enough to keep two
       links that both wrap to two lines from reading as one paragraph. */
    .f-col {
        gap: 6px;
    }

    .f-col-title {
        margin-bottom: 6px;
    }
}

@media (max-width: 780px) {
    .footer-grid {
        grid-template-columns: 1fr;
        gap: 36px;
    }

    .f-brand,
    .f-center {
        max-width: none;
    }

    .f-bottom {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }

    .f-disclaimer {
        text-align: left;
        max-width: none;
    }
}


/* ── Buttons ───────────────────────────────────────────────────────────────
   One shape for the whole site: a pill. What varies is weight, not geometry.

     .btn-amber        primary   clay fill, white label
     .btn-nav-outline  quiet     header only, a tinted wash
     .hero-btn         primary at hero scale

   The card buttons inside .app-card are deliberately NOT part of this family:
   that card is a picture of the product, so its controls follow the app's own
   button spec instead. Everything else here matches. */

.btn {
    height: 48px;
    padding: 0 28px;
    font-size: var(--t-meta);
    border-radius: var(--radius-pill);
}

/* The hero keeps its larger size but inherits the same shape and fill. */
.hero-btn {
    height: 60px;
    font-size: 18px;
    padding: 0 44px;
}

/* On a phone the hero button was 358x60 on a 390px screen -- 92% of the viewport
   and exactly the width of the pace rail below it, so the two read as one
   stacked slab. Width is handled above (sized to content); this trims the height
   so it is no longer taller than the headline's own type size. 54px stays well
   clear of the 24px WCAG 2.2 target minimum and of the 44px comfortable-thumb
   figure. */
@media (max-width: 780px) {
    .hero-btn {
        height: 54px;
        font-size: 17px;
        padding: 0 34px;
    }
}

.btn-nav-outline {
    /* 44, not 42: on a touch tablet the header button is a real tap target and
       42px sat just under the threshold. The two pixels cost nothing here. */
    height: 44px;
    padding: 0 20px;
    font-size: 15px;
}


/* ── App card column ───────────────────────────────────────────────────────
   The card was pinned at 292px from a 360px viewport all the way to 600px —
   about half the available width — and no max-width could fix it, because it
   was never being asked to fill anything.

   Two things centred it into a shrink-to-fit box: `.trust-grid` centres its
   items, and the wrapper carried an inline `align-items: center`. In a column
   flex container that is the CROSS axis, so both made the card size to its
   content. The inline style is gone; below the two-column breakpoint the
   column and the card stretch instead, and the card's own max-width does the
   capping with `margin-inline: auto` keeping it centred when it is capped. */

.trust-card-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
}

.app-card {
    margin-inline: auto;
}

@media (max-width: 780px) {

    .trust-grid {
        align-items: stretch !important;
    }

    .trust-card-col {
        align-items: stretch;
        height: auto;
    }

    /* Fill the column. 460px was the cap; it never got near it. */
    .app-card {
        max-width: 100%;
    }
}


/* ── City page prose ───────────────────────────────────────────────────────
   Long-form body copy on /rotterdam. The section it sits in was built for
   three short columns, so its paragraphs had no spacing of their own and ran
   together into one block. */

.city-prose {
    font-size: 17px;
    line-height: 1.65;
    color: var(--text-muted);
}

.city-prose p {
    margin: 0 0 20px;
}

.city-prose p:last-child {
    margin-bottom: 0;
}

.city-prose em {
    font-style: italic;
    color: var(--text-main);
}

@media (max-width: 600px) {
    .city-prose {
        font-size: 16px;
    }

    .city-prose p {
        margin-bottom: 16px;
    }
}


/* ── Long-form guides ──────────────────────────────────────────────────────
   /how-to-find-a-running-partner and /hardloopmaatje-vinden. A single reading
   column, because that is the whole job of the page — no grid, no cards. The
   measure is capped in ch rather than px so it stays a reading measure as the
   type scales. */

.guide {
    padding-top: 132px;
    padding-bottom: 80px;
    background: var(--bg-color);
}

.guide > .container {
    max-width: 720px;
}

.guide-head {
    margin-bottom: 48px;
}

.guide h1 {
    font-family: var(--font-head);
    font-size: var(--t-title);
    font-weight: 600;
    line-height: 1.06;
    letter-spacing: -0.028em;
    text-wrap: balance;
    margin: 0 0 20px;
    color: var(--text-main);
}

.guide-byline {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: baseline;
    margin: 18px 0 0;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-muted);
}

.guide-byline a {
    color: var(--amber-text);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.guide-byline a:hover { text-decoration-thickness: 2px; }

.guide-standfirst {
    font-size: 19px;
    line-height: 1.6;
    color: var(--text-main);
    opacity: 0.9;
    margin: 0;
    max-width: 62ch;
    text-wrap: pretty;
}

.guide-h2 {
    font-family: var(--font-head);
    font-size: var(--t-subtitle);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.2;
    text-wrap: balance;
    margin: 52px 0 18px;
    color: var(--text-main);
}

.guide p {
    font-size: 17.5px;
    line-height: 1.68;
    color: var(--text-muted);
    margin: 0 0 20px;
    max-width: 66ch;
}

.guide p strong {
    color: var(--text-main);
    font-weight: 600;
}

/* The one CTA in the body of the page. Set apart by a rule rather than a
   filled box, so it reads as part of the article rather than an ad in it. */
.guide-cta {
    margin: 56px 0;
    padding: 32px 0;
    border-top: 2px solid var(--amber);
    border-bottom: 1px solid var(--rule-soft);
}

.guide-cta h2 {
    font-family: var(--font-head);
    font-size: var(--t-subtitle);
    font-weight: 600;
    line-height: 1.2;
    margin: 0 0 10px;
    color: var(--text-main);
}

.guide-cta p {
    margin-bottom: 22px;
}

.guide-faq {
    margin-top: 56px;
}

.guide-faq .faq-accordion {
    max-width: 100%;
}

.guide-related {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 28px;
    margin-top: 56px;
    padding-top: 24px;
    border-top: 1px solid var(--rule-soft);
}

.guide-related a {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    font-size: 15px;
    font-weight: 600;
    color: var(--amber-text);
    text-decoration: none;
}

.guide-related a:hover {
    text-decoration: underline;
}

@media (pointer: coarse) {
    .guide-related a {
        min-height: 44px;
    }
}

@media (max-width: 780px) {
    .guide {
        padding-top: 104px;
        padding-bottom: 56px;
    }

    .guide-standfirst {
        font-size: 17.5px;
    }

    .guide p {
        font-size: 16.5px;
    }

    .guide-h2 {
        margin-top: 40px;
    }
}
