/* =============================================================================
   CIVILNEER DESIGN SYSTEM
   Sections: Fonts -> Tokens -> Reset -> Typography -> Layout -> Nav -> Buttons
   -> Cards -> Badges -> Forms -> Tables -> Tooltips -> Modal -> Progress
   -> Empty states -> Landing page -> App surface -> Upload page
   -> Processing page -> Results page -> Footer -> Responsive
   ============================================================================= */

/* The `hidden` attribute must actually hide, everywhere.

   Browsers implement `hidden` as a plain `display: none` in their own
   user-agent stylesheet, which any author rule setting `display` outranks
   -- so an element that is styled `display: flex` (or grid, or block) and
   also toggled via the hidden attribute silently stays on screen. That is
   not hypothetical here: it shipped three times on the processing page
   alone (the queued spinner, which kept turning after an analysis had
   finished; the stats grid; and the section checklist), because the layout
   rule and the JS that sets `hidden` live far apart and each looks correct
   on its own.

   `!important` is deliberate. Without it this rule only wins by source
   order and still loses to anything more specific than a single class, so
   the bug would keep coming back the moment someone wrote `.card .thing`.
   Hiding is not a style opinion to be overridden -- if something needs to
   stay visible, it should not carry the attribute. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------------------
   Fonts

   Inter is self-hosted rather than linked from Google Fonts on purpose: a
   fonts.googleapis.com request would send every visitor's IP address to a
   third party on every page load, which contradicts what templates/public/
   security.html tells customers about not sharing their data. Self-hosting
   also removes a third-party render-blocking dependency.

   One variable file per subset covers the whole 400-700 range, which is what
   makes the intermediate weights used throughout this stylesheet (550, 650)
   resolve as designed instead of rounding to the nearest static weight.

   Inter is licensed under the SIL Open Font License 1.1 -- see
   static/vendor/fonts/LICENSE.
   --------------------------------------------------------------------------- */

@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/static/vendor/fonts/inter-latin.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: "Inter";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/static/vendor/fonts/inter-latin-ext.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;
}

/* ---------------------------------------------------------------------------
   Tokens (light values on :root; dark values under prefers-color-scheme and
   the manual [data-theme] override -- three states: explicit light, explicit
   dark, system default)
   --------------------------------------------------------------------------- */

:root {
    --brand-50: #eef2ff;
    --brand-100: #dbe4ff;
    --brand-400: #4d72ef;
    --brand-500: #2450e8;
    --brand-600: #1c3fc4;
    --brand-700: #16309c;
    --brand-900: #0c1a4d;

    /* The "Civilneer" wordmark's two colours, sampled from the actual logo
       (static/brand/civilneer-mark.png): navy #12314F, orange #F2994A. Kept
       separate from --brand-* above, which is this site's own indigo accent
       ramp for buttons/links, not the logo's palette.

       --word-orange is the same literal value in every theme -- it is the
       logo's ink, not a UI accent, so it does not adapt. --word-navy only
       has a real value here in light mode; dark mode below sets it to
       var(--text) so "Civil" keeps matching today's near-white heading
       colour instead of turning illegible navy-on-near-black.

       Wordmark text is exempt from WCAG's contrast minimums (logos and
       brand names are explicitly carved out under SC 1.4.3), which is why
       the true logo orange is used here rather than a darkened "safe" one
       -- matching the actual mark takes priority for a brand name. */
    --word-navy: #12314f;
    --word-orange: #f2994a;

    --bg: #f5f7fb;
    --surface: #ffffff;
    --surface-2: #f7f9fc;
    --surface-hover: #eef1f8;
    --border: #e3e7f0;
    --border-strong: #cbd2e3;

    --text: #10142a;
    --text-muted: #5b6478;
    /* Carries the legal disclaimer, upload limits, privacy notes and table
       headers -- all small text, so it has to clear WCAG AA (4.5:1) against
       --bg, --surface and --surface-2 alike. Measured: 4.66 / 5.00 / 4.74. */
    --text-faint: #67707f;
    --text-on-brand: #ffffff;

    --pass-bg: #e7f7ec;
    --pass-text: #127a3c;
    --pass-border: #b7e6c6;
    --review-bg: #fdecea;
    --review-text: #b8321f;
    --review-border: #f5c2ba;

    --focus-ring: #4d72ef;

    /* Admin chrome. Intentionally darker than the customer surface in both
       themes so an internal page can never be mistaken for a customer one --
       but defined as tokens rather than hardcoded in templates/admin/base.html,
       so the header and the tokenised body below it stay coherent when the
       viewer is in light mode. */
    --admin-chrome: #1b2233;
    --admin-chrome-text: #f0f2f8;
    --admin-chrome-muted: #a8b0c4;
    --admin-chrome-border: #2b3348;
    --admin-strip-bg: #4a1210;
    --admin-strip-text: #ffd9d6;

    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 18px;
    --radius-xl: 24px;
    --radius-full: 999px;

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;
    --space-9: 96px;

    --shadow-sm: 0 1px 2px rgba(16, 20, 40, 0.06);
    --shadow-md: 0 8px 24px rgba(16, 20, 40, 0.08);
    --shadow-lg: 0 24px 60px rgba(16, 20, 40, 0.14);

    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --dur-fast: 120ms;
    --dur-base: 180ms;
    --dur-slow: 320ms;

    --font-sans: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
    --font-mono: ui-monospace, "SF Mono", "Cascadia Code", "Roboto Mono", Consolas, monospace;

    --page-max-width: 1180px;
    --nav-height: 68px;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --brand-50: #131b3a;
        --brand-100: #1a2550;
        --brand-400: #6a8dff;
        --brand-500: #7c9bff;
        --brand-600: #97b0ff;
        --brand-700: #b7c7ff;
        --brand-900: #eef2ff;

        --bg: #090c17;
        --surface: #10142a;
        --surface-2: #161b36;
        --surface-hover: #1c2240;
        --border: #232a4a;
        --border-strong: #333c65;

        --text: #eef1fb;
        --text-muted: #9aa3c4;
        --text-faint: #8b93b0;
        --text-on-brand: #0a0e1c;

        --pass-bg: rgba(52, 211, 153, 0.14);
        --pass-text: #4ade80;
        --pass-border: rgba(52, 211, 153, 0.32);
        --review-bg: rgba(248, 113, 113, 0.14);
        --review-text: #f87171;
        --review-border: rgba(248, 113, 113, 0.32);

        --focus-ring: #7c9bff;

    /* "Civil" keeps the page's normal near-white heading colour in dark mode
       rather than turning navy-on-near-black; --word-orange is the fixed
       logo ink and does not change between themes. */
    --word-navy: var(--text);
    --word-orange: #f2994a;

    --admin-chrome: #161b36;
    --admin-chrome-text: #eef1fb;
    --admin-chrome-muted: #9aa3c4;
    --admin-chrome-border: #232a4a;
    --admin-strip-bg: #2e1614;
    --admin-strip-text: #f19189;

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
        --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
        --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.5);
    }
}

:root[data-theme="dark"] {
    --brand-50: #131b3a;
    --brand-100: #1a2550;
    --brand-400: #6a8dff;
    --brand-500: #7c9bff;
    --brand-600: #97b0ff;
    --brand-700: #b7c7ff;
    --brand-900: #eef2ff;

    --bg: #090c17;
    --surface: #10142a;
    --surface-2: #161b36;
    --surface-hover: #1c2240;
    --border: #232a4a;
    --border-strong: #333c65;

    --text: #eef1fb;
    --text-muted: #9aa3c4;
    --text-faint: #8b93b0;
    --text-on-brand: #0a0e1c;

    --pass-bg: rgba(52, 211, 153, 0.14);
    --pass-text: #4ade80;
    --pass-border: rgba(52, 211, 153, 0.32);
    --review-bg: rgba(248, 113, 113, 0.14);
    --review-text: #f87171;
    --review-border: rgba(248, 113, 113, 0.32);

    --focus-ring: #7c9bff;

    /* "Civil" keeps the page's normal near-white heading colour in dark mode
       rather than turning navy-on-near-black; --word-orange is the fixed
       logo ink and does not change between themes. */
    --word-navy: var(--text);
    --word-orange: #f2994a;

    --admin-chrome: #161b36;
    --admin-chrome-text: #eef1fb;
    --admin-chrome-muted: #9aa3c4;
    --admin-chrome-border: #232a4a;
    --admin-strip-bg: #2e1614;
    --admin-strip-text: #f19189;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.5);
}

/* ---------------------------------------------------------------------------
   Reset & base
   --------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    transition: background-color var(--dur-base) var(--ease), color var(--dur-base) var(--ease);
}

img { max-width: 100%; display: block; }

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

button { font-family: inherit; border: none; background: none; padding: 0; margin: 0; color: inherit; cursor: pointer; }

::selection { background: var(--brand-100); color: var(--brand-900); }

:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

@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;
    }
}

.container {
    max-width: var(--page-max-width);
    margin: 0 auto;
    padding: 0 24px;
}

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

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 650;
    letter-spacing: -0.02em;
    color: var(--text);
}

h1 { font-size: 44px; line-height: 1.12; letter-spacing: -0.03em; }
h2 { font-size: 28px; line-height: 1.2; }
h3 { font-size: 18px; line-height: 1.3; }

p { margin: 0; color: var(--text-muted); }

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--brand-500);
}

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.text-muted { color: var(--text-muted); }
.section-cta-line { text-align: center; margin-top: var(--space-5); font-weight: 600; }
.section-cta-line a { color: var(--brand-500); }
.section-cta-line a:hover { color: var(--brand-600); }

/* ---------------------------------------------------------------------------
   Navigation
   --------------------------------------------------------------------------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    height: var(--nav-height);
    display: flex;
    align-items: center;
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border);
}

.header-inner {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
}

.brand-lockup {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* The mark is now the real logo PNG, which carries its own navy tile and
   rounded corners -- no gradient background or padding box behind it. */
.brand-mark {
    width: 30px;
    height: 30px;
    flex: none;
    display: block;
}


.brand-name {
    font-weight: 700;
    font-size: 17px;
    letter-spacing: -0.02em;
}

.brand-name .word-civil { color: var(--word-navy); }
.brand-name .word-neer { color: var(--word-orange); }

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

.nav-link {
    padding: 8px 14px;
    border-radius: var(--radius-full);
    font-size: 14px;
    font-weight: 550;
    color: var(--text-muted);
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.nav-link:hover { background: var(--surface-hover); color: var(--text); }
.nav-link.is-active { background: var(--brand-50); color: var(--brand-600); }

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

/* Account menu (signed-in header).

   Built on a native <details>/<summary> so keyboard access, Enter/Space
   toggling and the expanded state come from the browser rather than from
   hand-rolled ARIA. app/base.html adds only outside-click and Escape
   closing on top. */

.account-menu { position: relative; }

.account-menu > summary {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border-radius: var(--radius-full);
    border: 1px solid var(--border);
    background: var(--surface);
    font-size: 13.5px;
    font-weight: 550;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.account-menu > summary::-webkit-details-marker { display: none; }
.account-menu > summary:hover { background: var(--surface-hover); color: var(--text); border-color: var(--border-strong); }

.account-avatar {
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    flex: none;
    border-radius: var(--radius-full);
    background: var(--brand-500);
    color: var(--text-on-brand);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
}

.account-email {
    max-width: 15ch;
    overflow: hidden;
    text-overflow: ellipsis;
}

.account-caret { width: 12px; height: 12px; flex: none; transition: transform var(--dur-fast) var(--ease); }
.account-menu[open] .account-caret { transform: rotate(180deg); }

.account-menu-panel {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 200;
    min-width: 220px;
    padding: 6px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-md);
}

.account-menu-header {
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 6px;
}

.account-menu-header strong { display: block; font-size: 13px; font-weight: 600; word-break: break-all; }
.account-menu-header span { font-size: 12px; color: var(--text-muted); }

.account-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 9px 10px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    font-weight: 550;
    color: var(--text-muted);
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.account-menu-item:hover { background: var(--surface-hover); color: var(--text); }
.account-menu-item.is-signout { color: var(--review-text); }
.account-menu-item.is-signout:hover { background: var(--review-bg); }

.theme-toggle {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.theme-toggle:hover { background: var(--surface-hover); color: var(--text); }
.theme-toggle svg { width: 17px; height: 17px; }

/* Touch-target expansion.

   WCAG 2.5.5 asks for a 44x44 CSS-pixel target. Several icon controls here
   are deliberately smaller than that visually -- making them physically
   bigger would unbalance the header and the zoom cluster. Instead each one
   keeps its drawn size and gets an invisible centred ::before that reaches
   44x44, so the tappable area is compliant while the design is unchanged.
   The pseudo-element is inert to pointer semantics beyond hit-testing. */

.theme-toggle, .nav-menu-toggle, .modal-close-button { position: relative; }

.theme-toggle::before,
.nav-menu-toggle::before,
.modal-close-button::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
}

/* The zoom cluster is the exception: its buttons sit 2px apart, so a 44px
   wide overlay on each would overlap its neighbour and the later button in
   DOM order would capture taps meant for the earlier one -- worse than a
   small target. They get vertical expansion only, plus a wider drawn size. */

.zoom-btn { position: relative; }

.zoom-btn::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: 44px;
    transform: translateY(-50%);
}

.nav-menu-toggle {
    display: none;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
}
.nav-menu-toggle:hover { background: var(--surface-hover); color: var(--text); }
.nav-menu-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]):not([data-theme="dark"]) .theme-toggle .icon-sun { display: none; }
    :root:not([data-theme="light"]):not([data-theme="dark"]) .theme-toggle .icon-moon { display: block; }
}

/* ---------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 11px 20px;
    border-radius: var(--radius-full);
    border: 1px solid transparent;
    font-size: 14.5px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
        color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.btn:active { transform: translateY(1px); }

.btn-primary {
    background: var(--brand-500);
    color: var(--text-on-brand);
    box-shadow: var(--shadow-sm);
}

.btn-primary:hover { background: var(--brand-600); box-shadow: var(--shadow-md); }

.btn-secondary {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border-strong);
}

.btn-secondary:hover { background: var(--surface-hover); border-color: var(--text-faint); }

.btn-ghost {
    background: transparent;
    color: var(--text-muted);
}

.btn-ghost:hover { background: var(--surface-hover); color: var(--text); }

/* For irreversible destructive actions (account deletion) -- distinct from
   .badge-review's softer "needs attention" tone, this is a real warning
   color on a filled button, not just a status pill. */
.btn-danger {
    background: var(--review-text);
    color: #fff;
    box-shadow: var(--shadow-sm);
}

.btn-danger:hover { filter: brightness(0.9); box-shadow: var(--shadow-md); }

.btn-block { width: 100%; }
.btn-sm { padding: 8px 16px; font-size: 13.5px; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

.btn-arrow { transition: transform var(--dur-fast) var(--ease); }
.btn:hover .btn-arrow { transform: translateX(2px); }

/* ---------------------------------------------------------------------------
   Cards
   --------------------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 28px;
    box-shadow: var(--shadow-sm);
    transition: border-color var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease), background-color var(--dur-base) var(--ease);
}

.card-hover:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-md);
}

/* ---------------------------------------------------------------------------
   Badges / status pills
   --------------------------------------------------------------------------- */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 11px;
    border-radius: var(--radius-full);
    font-size: 12px;
    font-weight: 650;
    letter-spacing: 0.02em;
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-muted);
    white-space: nowrap;
}

.badge-pass { background: var(--pass-bg); color: var(--pass-text); border-color: var(--pass-border); }
.badge-review { background: var(--review-bg); color: var(--review-text); border-color: var(--review-border); }
.badge-brand { background: var(--brand-50); color: var(--brand-600); border-color: var(--brand-100); }

/* ---------------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------------- */

label { font-size: 13.5px; font-weight: 600; color: var(--text); }

input[type="text"], input[type="email"], input[type="password"], input[type="file"], textarea, select {
    font-family: inherit;
    font-size: 14.5px;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

textarea, select { width: 100%; }
textarea { resize: vertical; min-height: 96px; }

input:focus, textarea:focus, select:focus {
    border-color: var(--brand-500);
    box-shadow: 0 0 0 3px var(--brand-50);
    outline: none;
}

/* ---------------------------------------------------------------------------
   Tables
   --------------------------------------------------------------------------- */

table { width: 100%; border-collapse: collapse; font-size: 13.5px; }

th {
    text-align: left;
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-faint);
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    vertical-align: top;
}

tbody tr {
    cursor: default;
    transition: background-color var(--dur-fast) var(--ease);
}

tbody tr:hover { background: var(--surface-2); }
tbody tr:last-child td { border-bottom: none; }

.table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-md); }
.table-scroll table { min-width: 640px; }

/* ---------------------------------------------------------------------------
   Empty states
   --------------------------------------------------------------------------- */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: var(--space-7) var(--space-4);
    text-align: center;
    color: var(--text-faint);
    font-size: 14px;
}

/* ---------------------------------------------------------------------------
   Site footer
   --------------------------------------------------------------------------- */

.site-footer {
    border-top: 1px solid var(--border);
    padding: 22px 0;
    margin-top: var(--space-8);
}

.site-footer p {
    font-size: 13px;
    color: var(--text-faint);
    text-align: center;
}

/* Public-site footer: link columns above the disclaimer. Visitors scroll here
   deliberately to check a company is real, so it carries navigation, the
   legal pages and an identity line rather than a single sentence. The app and
   admin surfaces keep the plain single-paragraph variant above. */

.site-footer-rich { padding: var(--space-7) 0 var(--space-5); text-align: left; }

.footer-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
    gap: var(--space-6);
    padding-bottom: var(--space-5);
    border-bottom: 1px solid var(--border);
}

.footer-brand .brand-lockup { margin-bottom: 12px; }
.footer-brand p { font-size: 13.5px; color: var(--text-muted); text-align: left; max-width: 34ch; }

.footer-col h3 {
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-faint);
    margin-bottom: 12px;
}

.footer-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.footer-col a { font-size: 13.5px; color: var(--text-muted); }
.footer-col a:hover { color: var(--brand-500); }

.footer-base {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
    padding-top: var(--space-4);
}

.footer-base p { font-size: 12.5px; text-align: left; margin: 0; }

@media (max-width: 720px) {
    .footer-grid { grid-template-columns: 1fr 1fr; gap: var(--space-5); }
    .footer-brand { grid-column: 1 / -1; }
    .footer-base { flex-direction: column; align-items: flex-start; }
}

/* ---------------------------------------------------------------------------
   Reveal-on-load micro animation (landing page)
   --------------------------------------------------------------------------- */

.reveal-up {
    animation: reveal-up var(--dur-slow) var(--ease) both;
}

.reveal-up.delay-1 { animation-delay: 60ms; }
.reveal-up.delay-2 { animation-delay: 120ms; }

@keyframes reveal-up {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}

/* =============================================================================
   LANDING PAGE
   ============================================================================= */

.landing-hero {
    padding: 76px 0 88px;
    border-bottom: 1px solid var(--border);
    background:
        radial-gradient(720px 360px at 15% -10%, var(--brand-50), transparent 60%),
        var(--bg);
}

.hero-layout {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--space-8);
    align-items: center;
}

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    border-radius: var(--radius-full);
    background: var(--surface);
    border: 1px solid var(--border);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-muted);
    box-shadow: var(--shadow-sm);
    margin-bottom: 22px;
}

.badge-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--brand-500);
}

.hero-copy h1 { margin-bottom: 18px; }

/* Sits between the headline and the lead, pointing at the finding in the
   hero panel. Mono for the two figures, so they read as measurements
   rather than prose. */
.hero-proof {
    display: flex;
    align-items: baseline;
    gap: 9px;
    max-width: 46ch;
    margin: 18px 0 0;
    font-size: 14.5px;
    color: var(--text-muted);
}

.hero-proof span[aria-hidden] { color: var(--brand-500); font-weight: 700; }

.hero-proof strong {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text);
}

.hero-lead {
    font-size: 17.5px;
    line-height: 1.6;
    max-width: 46ch;
    margin-bottom: 30px;
}

/* The lead is two paragraphs now -- mechanism, then payoff. Only the second
   carries the gap down to the buttons. */
.hero-lead:not(.hero-lead-second) { margin-bottom: 14px; }

.hero-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 30px;
}

/* A single stacked list rather than a wrapping row. Six items never fit
   across a hero column that caps near 560px, and the earlier two-column
   version left the reader scanning in two directions at once. One per line
   reads top to bottom and stays identical at every width. */
.hero-trust-row {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 9px;
    font-size: 13.5px;
    color: var(--text-faint);
}

.hero-trust-row li {
    display: flex;
    align-items: center;
    gap: 9px;
}

.hero-trust-row li::before {
    content: "";
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--pass-text);
}

/* Illustrative product preview window */

.preview-window {
    border-radius: var(--radius-xl);
    border: 1px solid var(--border);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.preview-topbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}

.window-dots { display: flex; gap: 6px; }
.window-dots span { width: 9px; height: 9px; border-radius: 50%; background: var(--border-strong); }

.preview-title { font-size: 12.5px; font-weight: 600; color: var(--text-faint); }

.preview-content { padding: 20px; display: flex; flex-direction: column; gap: 16px; }

/* The results screen's four summary cards, condensed to one line here. At
   hero size the 2x2 grid of boxes took roughly half the panel and pushed
   the marked drawing -- the thing worth looking at -- into a strip at the
   bottom. Counts describe the single section drawn below, so the panel
   doesn't quote totals for sections it isn't showing. */
.preview-summary-line {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 0 2px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--text-muted);
    white-space: nowrap;
}

.preview-summary-line strong {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 13.5px;
    color: var(--text);
}

/* Pushed right and allowed to shrink: on the narrowest panel the breakdown
   truncates rather than wrapping the row to a second line, which is what
   made this strip twice as tall as it needed to be. */
.preview-summary-line span {
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-faint);
}

/* The results screen's verdict card, scaled for the hero panel: same
   component and colours, smaller figure so it doesn't dominate a column
   roughly half the width it was designed for. */
/* Written as .verdict-card.preview-verdict on purpose. A bare
   .preview-verdict ties with .verdict-card on specificity and loses on source
   order, since the component is defined further down the file -- so this
   override silently did nothing and the hero panel has been rendering at the
   full results-screen padding all along. Doubling the class wins regardless
   of order.

   The values here are the ones the hero actually shipped with, not the
   tighter ones this rule originally asked for: now that it applies, pinning
   them keeps the homepage looking exactly as it does today rather than
   changing it as a side effect of giving the results screen more room. */
.verdict-card.preview-verdict { padding: 24px 28px; gap: 14px; margin-bottom: 14px; }
.preview-verdict .verdict-figure { min-width: 54px; }
.preview-verdict .verdict-figure strong { font-size: 30px; }
.preview-verdict .verdict-figure span { font-size: 9.5px; margin-top: 2px; line-height: 1.25; }
.preview-verdict .verdict-copy h2 { font-size: 14px; margin-bottom: 0; line-height: 1.3; }

/* Marked-drawing preview. Stands in for the results screen's embedded PDF
   viewer -- same reading order (label highlights coloured by verdict, one
   showing the tooltip text the marked PDF actually carries). */
.preview-marked {
    position: relative;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
    overflow: hidden;
}

.preview-marked-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 11.5px;
    font-weight: 650;
    color: var(--text-faint);
}

.preview-marked-hint { font-weight: 500; font-size: 11px; opacity: 0.75; }
.preview-marked-sta { margin-left: auto; font-family: var(--font-mono); font-weight: 500; }
.preview-marked-svg { display: block; width: 100%; height: auto; }

/* Each highlighted label reveals its measurement on hover, the same way a
   finding does in the results page's viewer. */
.pm-label[data-marked-label] { cursor: pointer; }
.pm-label[data-marked-label] rect { transition: filter 0.15s ease; }
.pm-label[data-marked-label]:hover rect { filter: brightness(1.08); }

.preview-marked-tip {
    position: absolute;
    z-index: 3;
    pointer-events: none;
    white-space: pre;
    padding: 9px 12px;
    border-radius: var(--radius-sm, 8px);
    background: var(--text);
    color: var(--bg);
    font-family: var(--font-mono);
    font-size: 11.5px;
    line-height: 1.65;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
    opacity: 0;
    transform: translateY(3px);
    transition: opacity 0.13s ease, transform 0.13s ease;
}

.preview-marked-tip.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    .pm-label[data-marked-label] rect,
    .preview-marked-tip { transition: none; }
}

.pm-grid { stroke: var(--border); stroke-width: 1; fill: none; }
.pm-surface { stroke: var(--text); stroke-width: 1.7; fill: none; stroke-linejoin: round; }
.pm-leader { stroke: var(--text-faint); stroke-width: 0.9; fill: none; stroke-dasharray: 3 3; opacity: 0.75; }

.pm-label text { font-family: var(--font-mono); font-size: 10.5px; font-weight: 600; }
.pm-label rect { stroke-width: 1.3; }
.pm-label-pass rect { fill: var(--pass-bg); stroke: var(--pass-text); }
.pm-label-pass text { fill: var(--pass-text); }
.pm-label-review rect { fill: var(--review-bg); stroke: var(--review-text); }
.pm-label-review text { fill: var(--review-text); }

/* ---------------------------------------------------------------------------
   Demo page

   The card spacing these components use now lives on the components
   themselves (see .verdict-card / .summary-strip / .preview-card) rather than
   being overridden here -- the results screen wanted the same room the demo
   did, so there is one set of values instead of two. What stays below is only
   what is genuinely specific to this being a scrolling marketing page.
   --------------------------------------------------------------------------- */

.demo-hero { padding-bottom: 40px; }
.demo-results { padding-top: 8px; }

/* The viewer's own 75vh is sized for a full-height app screen, where the
   drawing is the task. On a marketing page that swallows the whole viewport
   and buries the CTA below it, so bound it here only. */
.demo-results .pdf-viewer { height: min(72vh, 620px); }

@media (max-width: 720px) {
    .demo-results .pdf-viewer { height: 60vh; }
}

/* The demo's replayed analysis panel borrows the processing page's own
   card, so it needs that page's centring without inheriting the full-height
   layout the live screen uses. */
.demo-processing .processing-card { max-height: none; margin: 0 auto; }
.demo-processing .processing-container { align-items: center; }

/* Swatches for the "Standard QC Colors" section.

   Deliberately not the .badge-pass / .badge-review chips. Those are UI status
   colours -- green for pass -- and they are right for a status chip, but that
   section is explaining the colours the *marked PDF* strokes, and a green chip
   beside the words "Yellow Highlight" contradicts itself. These carry the real
   values from STATUS_COLORS in app/single_section_marker_pdf.py, so the sample
   is the thing being described. #FFBF00 is (1.0, 0.749, 0.0); #D90000 is
   (0.85, 0, 0). Both are fixed, not themed, for the same reason the logo's
   orange is: they are the drawing's ink, not this site's palette. */
.qc-swatch {
    display: inline-block;
    width: 46px;
    height: 20px;
    border-radius: 4px;
    border: 1px solid rgba(0, 0, 0, 0.28);
    margin-bottom: 14px;
}

.qc-swatch-pass { background: #FFBF00; }
.qc-swatch-review { background: #D90000; }

/* Provenance note under the demo's marked drawing. Small, but it is the
   page's honesty statement -- it says what was changed about the sheet and
   what wasn't. */
.demo-provenance {
    margin-top: 26px;
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-faint);
    max-width: 78ch;
}

/* Benefit / workflow grids */

.landing-section { padding: 80px 0; }
.landing-section + .landing-section { border-top: 1px solid var(--border); }

.section-heading { max-width: 640px; margin-bottom: 44px; }
.section-heading h2 { margin: 10px 0 12px; }
.section-heading p { font-size: 15.5px; }

.benefit-grid, .workflow-grid, .pillar-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}

.benefit-card, .pillar-card {
    padding: 28px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    background: var(--surface);
    transition: border-color var(--dur-base) var(--ease), transform var(--dur-base) var(--ease), box-shadow var(--dur-base) var(--ease);
}

.benefit-card:hover, .pillar-card:hover {
    border-color: var(--border-strong);
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}

.benefit-icon {
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-md);
    background: var(--brand-50);
    color: var(--brand-600);
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 13px;
    margin-bottom: 18px;
}

.benefit-card h3, .pillar-card h3 { font-size: 17.5px; margin-bottom: 8px; }
.benefit-card p, .pillar-card p { font-size: 14.5px; }

.workflow-step { position: relative; padding: 28px 24px 24px; border-radius: var(--radius-lg); border: 1px solid var(--border); background: var(--surface); }

.workflow-step > span {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--brand-500);
    color: var(--text-on-brand);
    font-weight: 700;
    font-size: 13.5px;
    margin-bottom: 16px;
}

.workflow-step h3 { margin-bottom: 6px; font-size: 16.5px; }
.workflow-step p { font-size: 14px; }

/* PASS / REVIEW explainer strip */

.status-explainer {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.status-explainer-card {
    padding: 26px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    background: var(--surface);
}

.status-explainer-card .badge { margin-bottom: 14px; }
.status-explainer-card p { font-size: 14.5px; }

/* Privacy / security section */

.privacy-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
}

.privacy-item {
    display: flex;
    gap: 14px;
    padding: 20px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
}

.privacy-item-icon {
    flex: none;
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-sm);
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--brand-500);
}

.privacy-item h3 { font-size: 14.5px; margin-bottom: 4px; }
.privacy-item p { font-size: 13.5px; }

/* Closing CTA */

.cta-panel {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 44px 48px;
    border-radius: var(--radius-xl);
    background: linear-gradient(155deg, var(--brand-700), var(--brand-900));
    color: #fff;
}

.cta-panel h2 { color: #fff; margin-bottom: 8px; }
.cta-panel p { color: rgba(255, 255, 255, 0.72); max-width: 46ch; }
.cta-panel .btn-primary { background: #fff; color: var(--brand-700); }
.cta-panel .btn-primary:hover { background: var(--brand-50); }

/* =============================================================================
   REQUEST ACCESS (private beta intake)

   Form on the left, expectations on the right. The aside is not decoration:
   it answers the three things a firm weighs before handing over project
   drawings -- what it costs, what happens to the files, and how finished the
   product actually is.
   ============================================================================= */

.request-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: var(--space-6);
    align-items: start;
}

.request-aside { padding-top: var(--space-2); }
.request-aside h2 { font-size: 19px; margin-bottom: var(--space-4); }

/* Honeypot. Kept out of the layout without display:none, since some bots
   skip fields that are explicitly hidden that way. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.price-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }

.price-list li {
    display: flex;
    align-items: flex-start;
    gap: 11px;
    font-size: 14.5px;
    color: var(--text-muted);
}

.price-list svg { width: 17px; height: 17px; flex: none; margin-top: 3px; color: var(--pass-text); }
.price-list strong { color: var(--text); font-weight: 600; }
.price-list a { color: var(--brand-500); font-weight: 550; }

@media (max-width: 900px) {
    .request-layout { grid-template-columns: 1fr; }
}

/* =============================================================================
   APP SURFACE (signed-in pages: dashboard, account, team)

   Deliberately separate from the landing-page components above. Marketing
   pages are read once, top to bottom, and are sized to persuade -- 80px
   section rhythm, 44px headings, a hero band. The signed-in app is scanned
   repeatedly and sized to operate: roughly a 32px rhythm, 28px page titles,
   no hero. Same tokens, same cards, same colours; different density.

   Before this section existed the dashboard/account/team pages were built
   from .landing-hero and .benefit-grid, which is why they read as a brochure
   with a file input attached.
   ============================================================================= */

.app-page { padding: var(--space-6) 0 var(--space-8); }

.app-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    padding-bottom: var(--space-4);
    margin-bottom: var(--space-6);
    border-bottom: 1px solid var(--border);
}

.app-header h1 { font-size: 28px; line-height: 1.2; letter-spacing: -0.022em; }
.app-header .app-header-text > p { font-size: 14.5px; margin-top: 4px; max-width: 60ch; }
.app-header-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }

.app-section + .app-section { margin-top: var(--space-6); }
.app-section > h2 { font-size: 18px; margin-bottom: var(--space-3); }

.card-compact { padding: 20px; }

.app-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-3);
}

.app-tile { display: block; }
.app-tile h2, .app-tile h3 { font-size: 15.5px; margin-bottom: 4px; }
.app-tile p { font-size: 13.5px; }

/* Definition-style rows for account/settings detail */

.app-rows { display: flex; flex-direction: column; }

.app-row {
    display: grid;
    grid-template-columns: minmax(0, 200px) minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: center;
    padding: 14px 0;
    border-bottom: 1px solid var(--border);
}

.app-row:last-child { border-bottom: none; }
.app-row dt, .app-row .app-row-label { font-size: 13.5px; font-weight: 600; color: var(--text); }
.app-row dd, .app-row .app-row-value { margin: 0; font-size: 14px; color: var(--text-muted); }
.app-row .app-row-action { justify-self: end; }

@media (max-width: 720px) {
    .app-row { grid-template-columns: 1fr; gap: var(--space-2); }
    .app-row .app-row-action { justify-self: start; }
}

/* =============================================================================
   UPLOAD PAGE
   ============================================================================= */

.upload-hero { padding: 64px 0 40px; }

.upload-hero-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
    gap: var(--space-7);
    align-items: start;
}

.upload-copy h1 { margin: 14px 0 16px; font-size: 36px; }
.upload-copy .hero-text { font-size: 16px; max-width: 48ch; }

.beta-checks {
    margin-top: 28px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.beta-checks > div {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--border);
    font-size: 13.5px;
}

.beta-checks strong { color: var(--text); font-weight: 650; }
.beta-checks span { color: var(--text-muted); text-align: right; }

.upload-card h2 { margin: 4px 0 8px; font-size: 20px; }
.upload-card > p { font-size: 13.5px; margin-bottom: 20px; }

.upload-form { display: flex; flex-direction: column; gap: 16px; }

.file-drop {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    padding: 40px 24px;
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    background: var(--surface-2);
    cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}

.file-drop:hover { border-color: var(--brand-400); background: var(--brand-50); }
.file-drop.is-dragover { border-color: var(--brand-500); background: var(--brand-50); }
.file-drop.has-file { border-style: solid; border-color: var(--pass-border); background: var(--pass-bg); }

.file-drop input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.file-drop-icon {
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border-radius: var(--radius-md);
    background: var(--surface);
    border: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 700;
    color: var(--brand-500);
}

.file-drop-title { font-weight: 600; font-size: 14.5px; color: var(--text); }
.file-drop small { font-size: 12.5px; color: var(--text-faint); }
.file-drop small.has-file { color: var(--pass-text); font-weight: 600; }

.beta-info-grid {
    padding: 20px 24px 88px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 18px;
}

.beta-info-card h3 { font-size: 15px; margin-bottom: 8px; }
.beta-info-card p { font-size: 13.5px; }

/* =============================================================================
   PROCESSING PAGE
   ============================================================================= */

.processing-section { padding: 40px 0; min-height: calc(100vh - var(--nav-height)); display: flex; align-items: center; }
/* align-items: center overrides flex's default stretch -- without it, this
   row flex container stretches .processing-card to fill its own height,
   which forces the card to always be its full max-height (collapsing the
   checklist to 0) even when there's only a couple of rows to show. */
.processing-container { width: 100%; display: flex; justify-content: center; align-items: center; }
/* max-height caps the card to the viewport instead of letting it grow past
   it and get clipped; the card is a column flexbox so the checklist below
   (the only item with flex-grow) is the sole scrollable region -- header,
   stats, note, and the "View results" button all stay in fixed, always-
   visible positions instead of possibly ending up below the fold. */
.processing-card {
    width: min(560px, 100%);
    max-height: calc(100vh - var(--nav-height) - 80px);
    display: flex;
    flex-direction: column;
    text-align: center;
    overflow: hidden;
}
.processing-card h1 { font-size: 26px; margin: 12px 0 10px; flex: none; }
.processing-card #processing-message { font-size: 14.5px; margin-bottom: 28px; flex: none; }

.progress-track {
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
    margin-bottom: 24px;
    flex: none;
}

.progress-bar {
    height: 100%;
    border-radius: var(--radius-full);
    background: linear-gradient(90deg, var(--brand-400), var(--brand-500));
    transition: width var(--dur-slow) var(--ease);
    animation: progress-bar-pulse 1.4s ease-in-out infinite;
}

@keyframes progress-bar-pulse {
    0%, 100% { filter: brightness(1); }
    50% { filter: brightness(1.3); }
}

.processing-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-bottom: 24px;
    flex: none;
}

.processing-stats > div { padding: 14px; border-radius: var(--radius-md); background: var(--surface-2); border: 1px solid var(--border); }
.processing-stats strong { display: block; font-size: 22px; font-family: var(--font-mono); }
.processing-stats span { font-size: 11.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.04em; }

.section-checklist {
    /* The one item in .processing-card's column flex allowed to shrink --
       flex-grow stays 0 so a short list just sizes to its own content
       instead of stretching to fill leftover space, but flex-shrink lets
       it give way once the card as a whole would otherwise exceed its own
       max-height, scrolling internally rather than pushing the header,
       stats, note, or button out of view. min-height:0 overrides flexbox's
       default min-height:auto, which would otherwise refuse to let this
       shrink below its content size and defeat the whole point. */
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 20px;
    text-align: left;
}

.section-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    font-size: 13.5px;
}

.section-row-icon { width: 16px; text-align: center; color: var(--text-faint); }
.section-row-label { flex: 1; color: var(--text); }
.section-row-page { color: var(--text-faint); font-size: 12px; }

.section-row--analyzing .section-row-icon { color: var(--brand-500); animation: section-row-spin 0.9s linear infinite; }
.section-row--pass { background: var(--pass-bg); }
.section-row--pass .section-row-icon { color: var(--pass-text); }
.section-row--review { background: var(--review-bg); }
.section-row--review .section-row-icon { color: var(--review-text); }
.section-row--review .section-row-label { color: var(--review-text); }

.section-row-flags {
    background: var(--review-border);
    color: var(--review-text);
    font-size: 11.5px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius-full);
}

@keyframes section-row-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

.queued-spinner-wrap { display: flex; justify-content: center; padding: 8px 0 28px; flex: none; }

.queued-spinner {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 2.5px solid var(--border-strong);
    border-top-color: var(--brand-500);
    animation: section-row-spin 0.9s linear infinite;
}

.section-page-group {
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.section-page-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: var(--surface-2);
    font-size: 13.5px;
}

.section-page-header .section-row-icon { color: var(--brand-500); animation: section-row-spin 0.9s linear infinite; }
.section-page-status { color: var(--brand-500); font-size: 12px; }

.section-subrow {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 12px 6px 34px;
    font-size: 13px;
}

.section-subrow .section-row-icon { width: 14px; color: var(--brand-500); animation: section-row-spin 0.9s linear infinite; }
.section-subrow .section-row-label { color: var(--text-faint); }

.processing-done { margin-bottom: 20px; flex: none; }

.active-job-actions {
    display: flex;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
}
.active-job-actions form { display: contents; }

.cancel-box { margin-bottom: 20px; flex: none; }
.cancel-box form { display: contents; }

.processing-note { font-size: 13px; color: var(--text-faint); margin-bottom: 20px; flex: none; }

.processing-error {
    margin-top: 22px;
    padding: 16px;
    flex: none;
    border-radius: var(--radius-md);
    background: var(--review-bg);
    border: 1px solid var(--review-border);
    text-align: left;
}

.processing-error strong { color: var(--review-text); display: block; margin-bottom: 4px; }
.processing-error p { font-size: 13.5px; margin-bottom: 12px; }

/* =============================================================================
   RESULTS PAGE
   ============================================================================= */

.results-section { padding: 44px 0 96px; }

.results-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    margin-bottom: 28px;
}

.results-header h1 { font-size: 30px; margin: 8px 0 4px; }
.results-header p { font-size: 14px; }
.results-header-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* Verdict card.

   Replaces a five-across grid of equal cards plus a separate status banner
   that restated the same conclusion. Only one number on this screen drives
   what the engineer does next, so it gets the weight and the semantic
   surface; the supporting counts move to the quieter strip below. */

.verdict-card {
    display: flex;
    align-items: center;
    gap: var(--space-6);
    padding: 28px 32px;
    border-radius: var(--radius-lg);
    border: 1px solid;
    margin-bottom: 28px;
}

.verdict-card.verdict-pass { background: var(--pass-bg); border-color: var(--pass-border); }
.verdict-card.verdict-review { background: var(--review-bg); border-color: var(--review-border); }

.verdict-figure {
    flex: none;
    text-align: center;
    min-width: 96px;
}

.verdict-figure strong {
    display: block;
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 52px;
    line-height: 1;
    letter-spacing: -0.03em;
}

.verdict-figure span {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.verdict-pass .verdict-figure strong, .verdict-pass .verdict-figure span { color: var(--pass-text); }
.verdict-review .verdict-figure strong, .verdict-review .verdict-figure span { color: var(--review-text); }

.verdict-copy h2 { font-size: 19px; margin-bottom: 6px; }
.verdict-copy p { font-size: 14px; max-width: 62ch; }

/* Supporting counts -- deliberately lighter than the verdict above. */

.summary-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-bottom: 32px;
}

.summary-card {
    padding: 20px 22px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface);
}

.summary-card span { display: block; font-size: 12px; color: var(--text-faint); margin-bottom: 6px; }
.summary-card strong { display: block; font-size: 22px; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.summary-card p { font-size: 12.5px; margin-top: 4px; }

.preview-section { margin-bottom: 28px; }
.preview-card { padding: 24px; }

.preview-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 20px;
}

.preview-card-header h3 { font-size: 16px; }
.preview-card-header p { font-size: 13px; margin-top: 2px; }
.preview-card-header a { font-size: 13px; font-weight: 600; color: var(--brand-500); }
.preview-card-header a:hover { text-decoration: underline; }

.preview-card-actions { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }

.zoom-controls {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface);
}

.zoom-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 30px;
    border-radius: var(--radius-full);
    font-size: 15px;
    font-weight: 650;
    line-height: 1;
    color: var(--text-muted);
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.zoom-btn:hover { background: var(--surface-2); color: var(--text); }
.zoom-btn:disabled { opacity: 0.4; cursor: default; }
.zoom-btn:disabled:hover { background: none; color: var(--text-muted); }

.zoom-btn-reset { width: auto; padding: 0 10px; font-size: 12px; }

.zoom-level {
    min-width: 40px;
    text-align: center;
    font-size: 12px;
    font-weight: 650;
    font-family: var(--font-mono);
    color: var(--text-muted);
}

.pdf-viewer {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    width: 100%;
    height: 75vh;
    min-height: 420px;
    max-height: 900px;
    overflow: auto;
    padding: 14px;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.pdf-page { position: relative; width: 100%; line-height: 0; flex-shrink: 0; }

.pdf-page-image {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 6px;
    background: #fff;
    box-shadow: var(--shadow-sm);
}

.pdf-finding-hotspot {
    position: absolute;
    cursor: help;
    outline: none;
    border-radius: 3px;
    transition: box-shadow var(--dur-fast) var(--ease);
    /* Matches STATUS_COLORS["PASS"] / light_review's label_fill_opacity
       in single_section_marker_pdf.py, so the viewer and the downloaded
       PDF read the same way. */
    background: rgba(255, 191, 0, 0.4);
}

.pdf-finding-hotspot[data-status="REVIEW"] {
    /* Matches STATUS_COLORS["REVIEW"] in single_section_marker_pdf.py. */
    background: rgba(217, 0, 0, 0.4);
}

.pdf-finding-hotspot:hover, .pdf-finding-hotspot:focus-visible {
    box-shadow: 0 0 0 2px var(--brand-500);
}

.pdf-finding-tooltip {
    position: absolute;
    z-index: 1200;
    max-width: 240px;
    padding: 10px 12px;
    border-radius: var(--radius-md);
    background: var(--text);
    color: var(--bg);
    font-size: 12.5px;
    font-family: var(--font-mono);
    line-height: 1.6;
    white-space: pre-line;
    box-shadow: var(--shadow-lg);
    pointer-events: none;
    opacity: 0;
    transform: translateY(2px);
    transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}

.pdf-finding-tooltip.is-visible { opacity: 1; transform: translateY(0); }
.pdf-finding-tooltip[hidden] { display: none; }

.summary-download-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(300px, 0.8fr);
    gap: 20px;
    align-items: start;
}

.page-summary-card h2 { font-size: 16px; margin-bottom: 6px; }
.page-summary-card h3 { font-size: 13px; color: var(--text-faint); text-transform: uppercase; letter-spacing: 0.04em; margin: 18px 0 8px; }
.page-summary-card h3:first-of-type { margin-top: 18px; }
.summary-group { display: flex; flex-wrap: wrap; gap: 8px; }

.downloads-card { display: flex; flex-direction: column; gap: 18px; }
.package-badge { display: inline-flex; margin-bottom: 10px; }
.downloads-card h2 { font-size: 17px; margin-bottom: 6px; }
.downloads-card > .package-card-top > p { font-size: 13.5px; }

.package-files { display: flex; flex-direction: column; gap: 10px; }

.package-file {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
}

.package-file-icon {
    width: 34px;
    height: 34px;
    flex: none;
    display: grid;
    place-items: center;
    border-radius: var(--radius-sm);
    background: var(--surface);
    border: 1px solid var(--border);
    font-family: var(--font-mono);
    font-size: 10.5px;
    font-weight: 700;
    color: var(--brand-500);
}

.package-file strong { font-size: 13.5px; display: block; }
.package-file small { font-size: 12px; color: var(--text-faint); }

.package-privacy-note { font-size: 12px; color: var(--text-faint); }

/* Package delivery status. Replaces the old manual Download button: the
   package now fetches automatically and this reports where it has got to. */
.package-status {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
    background: var(--surface-2);
    font-size: 13.5px;
    color: var(--text-muted);
}

.package-status[data-state="done"] {
    background: var(--pass-bg);
    border-color: var(--pass-border);
    color: var(--pass-text);
    font-weight: 550;
}

.package-status[data-state="failed"] {
    background: var(--review-bg);
    border-color: var(--review-border);
    color: var(--review-text);
    font-weight: 550;
}

.package-spinner {
    width: 15px;
    height: 15px;
    flex: none;
    border-radius: 50%;
    border: 2px solid var(--border-strong);
    border-top-color: var(--brand-500);
    animation: package-spin 700ms linear infinite;
}

.package-status[data-state="done"] .package-spinner,
.package-status[data-state="failed"] .package-spinner { display: none; }

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

@media (prefers-reduced-motion: reduce) {
    .package-spinner { animation: none; border-top-color: var(--border-strong); }
}

/* =============================================================================
   ERROR / FEEDBACK-THANKS PAGES
   ============================================================================= */

/* Legal pages (privacy, terms). Long-form prose, so the measure is capped
   near 70 characters and headings get more space above than below to bind
   each one to the text it introduces. */

.legal-body { max-width: 70ch; }
.legal-body h2 { font-size: 21px; margin: var(--space-7) 0 var(--space-3); }
.legal-body h2:first-child { margin-top: 0; }
.legal-body p { margin-bottom: var(--space-3); font-size: 15.5px; }
.legal-body ul { margin: 0 0 var(--space-4); padding-left: 22px; color: var(--text-muted); }
.legal-body li { margin-bottom: 10px; font-size: 15.5px; }
.legal-body a { color: var(--brand-500); font-weight: 550; }
.legal-body a:hover { text-decoration: underline; }
.legal-body strong { color: var(--text); }

.error-card, .thanks-card { max-width: 560px; margin: 60px auto; text-align: center; }
.error-card h1, .thanks-card h1 { font-size: 26px; margin: 10px 0 12px; }
.error-card p, .thanks-card p { font-size: 14.5px; }
.error-actions, .thanks-actions { display: flex; justify-content: center; gap: 12px; margin: 22px 0 14px; flex-wrap: wrap; }
.error-note { font-size: 12.5px; color: var(--text-faint); }

/* =============================================================================
   FEEDBACK MODAL
   ============================================================================= */

body.modal-open { overflow: hidden; }

.feedback-modal-backdrop[hidden] { display: none; }

.feedback-modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: grid;
    place-items: center;
    padding: 24px;
    background: rgba(9, 12, 24, 0.5);
    backdrop-filter: blur(6px);
    animation: fade-in var(--dur-base) var(--ease) both;
}

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

.feedback-modal {
    width: min(560px, 100%);
    padding: 28px;
    border-radius: var(--radius-xl);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    animation: modal-in var(--dur-base) var(--ease) both;
}

@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: none; } }

.feedback-modal-header { display: flex; justify-content: space-between; gap: 18px; align-items: flex-start; }
.feedback-modal-header h2 { margin: 8px 0 0; font-size: 22px; }

.modal-close-button {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface-2);
    color: var(--text-muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease);
}

.modal-close-button:hover { background: var(--surface-hover); color: var(--text); }

.feedback-modal-copy { margin: 12px 0 20px; font-size: 13.5px; }
.feedback-form { display: flex; flex-direction: column; gap: 16px; }
.feedback-form label { display: flex; flex-direction: column; gap: 6px; }

/* ---------------------------------------------------------------------------
   Auth pages (login/signup/mfa/forgot-password)
   --------------------------------------------------------------------------- */

.auth-section { padding: 64px 0; display: flex; justify-content: center; }
.auth-card { width: 100%; max-width: 480px; padding: 34px 36px; }
.auth-card h1 { font-size: 25px; margin-bottom: 6px; }
.auth-card .hero-lead { margin-bottom: var(--space-5); }
.auth-form { display: flex; flex-direction: column; gap: 16px; }
.auth-form label { display: flex; flex-direction: column; gap: 6px; }
.field-hint { font-size: 12.5px; color: var(--text-muted); font-weight: 400; }
.auth-legal { margin-top: var(--space-4); font-size: 12.5px; color: var(--text-muted); line-height: 1.55; }
.auth-legal a { color: var(--brand-500); font-weight: 550; }
.auth-form-footer { margin-top: var(--space-5); font-size: 13.5px; color: var(--text-muted); text-align: center; }
.auth-form-footer a { color: var(--brand-500); font-weight: 600; }
.auth-error { background: var(--review-bg); color: var(--review-text); border: 1px solid var(--review-border); border-radius: var(--radius-md); padding: 10px 14px; font-size: 13.5px; margin-bottom: var(--space-4); }
.auth-notice { background: var(--brand-50); color: var(--brand-600); border: 1px solid var(--brand-100); border-radius: var(--radius-md); padding: 10px 14px; font-size: 13.5px; margin-bottom: var(--space-4); }

/* =============================================================================
   ADMIN SURFACE (admin.civilneer.com)

   Was an inline <style> block in templates/admin/base.html with hardcoded hex
   values that ignored the token system and did not respond to theme, which
   produced a permanently dark header sitting on a light body. Same visual
   intent -- distinctly not-a-customer-page -- now expressed through the
   --admin-* tokens so it holds in both themes.
   ============================================================================= */

.admin-strip {
    background: var(--admin-strip-bg);
    color: var(--admin-strip-text);
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-align: center;
    padding: 6px 12px;
}

.admin-header { background: var(--admin-chrome); border-bottom: 1px solid var(--admin-chrome-border); }

.admin-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
    padding-top: 14px;
    padding-bottom: 14px;
}

.admin-brand { color: var(--admin-chrome-text); font-weight: 700; letter-spacing: -0.01em; font-size: 16px; }
.admin-header nav { display: flex; gap: 4px; }

.admin-header nav a {
    color: var(--admin-chrome-muted);
    font-size: 14px;
    padding: 7px 12px;
    border-radius: var(--radius-full);
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.admin-header nav a:hover { background: rgba(255, 255, 255, 0.08); color: var(--admin-chrome-text); }
.admin-header nav a.is-active { background: rgba(255, 255, 255, 0.12); color: var(--admin-chrome-text); }

/* Logout is a POST form (not a plain link) so a clicked cross-site link
   can't force a logout -- styled to match the sibling nav <a> tags exactly. */
.admin-header nav form { display: contents; }
.admin-header nav button.admin-logout-btn {
    font: inherit;
    color: var(--admin-chrome-muted);
    font-size: 14px;
    padding: 7px 12px;
    border: none;
    border-radius: var(--radius-full);
    background: transparent;
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.admin-header nav button.admin-logout-btn:hover { background: rgba(255, 255, 255, 0.08); color: var(--admin-chrome-text); }

.admin-main { padding: var(--space-6) 0 var(--space-8); }
.admin-main h1 { font-size: 26px; margin-bottom: 6px; }
.admin-main > .container > p:first-of-type { margin-bottom: var(--space-5); }

.admin-back { display: inline-block; font-size: 13.5px; color: var(--brand-500); margin-bottom: var(--space-4); }
.admin-back:hover { text-decoration: underline; }

.admin-json {
    white-space: pre-wrap;
    word-break: break-word;
    font-family: var(--font-mono);
    font-size: 12.5px;
    line-height: 1.6;
    max-height: 480px;
    overflow: auto;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 14px;
    margin: 0;
}

.admin-artifact-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }

.admin-artifact-list a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-mono);
    font-size: 13px;
    color: var(--brand-500);
}

.admin-artifact-list a:hover { text-decoration: underline; }

.access-request-list { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-4); }

.access-request-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.access-request-head h2 { font-size: 17px; margin-bottom: 2px; }
.access-request-head p { font-size: 13.5px; }
.access-request-message { margin-top: var(--space-3); font-size: 14.5px; white-space: pre-line; }
.access-request-meta { font-size: 11.5px; color: var(--text-faint); }

.access-request-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-3);
}
.access-request-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.access-request-approve { margin-top: var(--space-3); }

.invite-link-box {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
    margin-top: var(--space-3);
    padding: 12px 14px;
    border: 1px solid var(--pass-border);
    background: var(--pass-bg);
    border-radius: var(--radius-md);
}

.invite-link-label {
    flex-basis: 100%;
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--pass-text);
}

.invite-link {
    flex: 1 1 320px;
    font-family: var(--font-mono);
    font-size: 12.5px;
    word-break: break-all;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 8px 10px;
}

/* ---------------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------------- */

@media (max-width: 1080px) {
    .summary-download-grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
    h1 { font-size: 34px; }
    .hero-layout, .upload-hero-grid { grid-template-columns: 1fr; gap: var(--space-6); }
    .benefit-grid, .workflow-grid, .pillar-grid, .privacy-grid { grid-template-columns: repeat(2, 1fr); }
    .status-explainer { grid-template-columns: 1fr; }
    .beta-info-grid { grid-template-columns: 1fr; }
    .cta-panel { flex-direction: column; text-align: center; padding: 36px; }
    .summary-strip { grid-template-columns: repeat(2, 1fr); }
}

/* The nav collapses to a drawer well before the other mobile rules kick in.
   With six marketing links plus the sign-in/start-free actions, the header
   needs roughly 890px to lay out in a row -- below that it overflowed the
   viewport and pushed the whole page into horizontal scroll. */

@media (max-width: 940px) {
    .header-inner { position: relative; }
    .nav-menu-toggle { display: grid; }
    .nav[data-nav-menu] {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        padding: 8px 18px 16px;
        background: var(--surface);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--shadow-md);
    }
    .nav[data-nav-menu].nav-open { display: flex; }
    .nav[data-nav-menu] .nav-link { display: block; padding: 10px 14px; }
}

@media (max-width: 720px) {
    .container { padding: 0 18px; }
    h1 { font-size: 28px; }
    h2 { font-size: 22px; }
    .landing-section { padding: 56px 0; }
    .landing-hero { padding: 48px 0 56px; }
    .benefit-grid, .workflow-grid, .pillar-grid, .privacy-grid, .processing-stats { grid-template-columns: 1fr; }
    .summary-strip { grid-template-columns: repeat(2, 1fr); }
    .results-header { flex-direction: column; }
    .card { padding: 20px; }
    .card-compact { padding: 18px; }
    .app-header { align-items: flex-start; }
    .verdict-card { flex-direction: column; align-items: flex-start; gap: var(--space-3); padding: 20px; }
    .verdict-figure { min-width: 0; text-align: left; display: flex; align-items: baseline; gap: 10px; }
    .verdict-figure strong { font-size: 40px; }
    .verdict-figure span { margin-top: 0; }

    /* The roomier desktop gaps are most of the width on a phone. */
    .verdict-card { margin-bottom: 20px; }
    .summary-strip { gap: 12px; margin-bottom: 24px; }
    .summary-card { padding: 16px 18px; }
    .preview-card { padding: 18px; }
    .preview-section { margin-bottom: 22px; }
}

@media (max-width: 480px) {
    .summary-strip { grid-template-columns: 1fr; }
    .hero-actions { flex-direction: column; align-items: stretch; }
    .hero-trust-row { flex-direction: column; gap: 8px; }
    .account-email { display: none; }
}
