/* ==========================================================================
   Goals. Delivered — design system
   Soft aurora background, floating white cards, pill controls.
   ========================================================================== */

:root {
    --ink: #17181c;
    --ink-soft: #3f4450;
    --ink-muted: #6b7280;
    --line: #e7e7ec;
    --line-soft: #f0f0f4;
    --surface: #ffffff;
    --accent: #2c757c;
    --accent-soft: rgba(44, 117, 124, 0.12);
    --danger: #d92d5a;
    --danger-soft: rgba(217, 45, 90, 0.08);
    --success: #1a7f4f;
    --potent-purple: #5b3fb0;

    /* Width of the app shell. Header, page and footer all line up on this. */
    --page-max: 1320px;

    /* The Freethinking Group secondary palette, straight from the 2023 brand
       guidelines. The app already used three of these without naming them --
       teal as the accent, red and orange in the score colours -- so they are
       declared once here rather than repeated as literals. */
    --tfg-black: #1d1d1b;
    --tfg-red: #e5291c;
    --tfg-orange: #f28e1b;
    --tfg-yellow: #f0bb32;
    --tfg-blue: #78bdc4;
    --tfg-teal: #2c757c;
    --tfg-purple: #712b70;

    /* The brand ramp, purple through to yellow. It travels via red and orange
       rather than interpolating purple straight to yellow, which would pass
       through mud -- and those two stops are brand colours in their own right,
       so the whole sweep stays inside the TFG palette.

       Shared by the striated panel on the login screen and the band behind the
       app, so the two can never drift apart. Used as
       linear-gradient(<angle>, var(--ramp-stops)).

       The band is laid out wider than the viewport so it has room to drift,
       which means the first and last stops sit off-screen. The sweep is
       therefore compressed into the middle: purple lands at the left edge of
       the viewport and yellow at the right, with both ends held flat so the
       overhang stays in colour as it moves. */
    --ramp-stops:
        #712b70 0%,
        #712b70 13%,
        #8e2f5f 26%,
        #b83a3c 40%,
        #e5291c 52%,
        #ee6a1c 62%,
        #f28e1b 71%,
        #f0bb32 81%,
        #f0bb32 100%;

    /* The light working surface, with its dot grid. */
    --surface-page: #f7f8fa;
    --dot-grid: radial-gradient(rgba(23, 24, 28, 0.08) 1px, transparent 1px);

    --radius-card: 24px;
    --radius-input: 12px;
    --radius-pill: 999px;
    --shadow-card: 0 1px 2px rgba(16, 24, 40, 0.05), 0 12px 32px -8px rgba(16, 24, 40, 0.12);
    --shadow-pill: 0 1px 2px rgba(16, 24, 40, 0.06), 0 4px 12px -2px rgba(16, 24, 40, 0.08);
    /* Montserrat is the group's typeface -- the 2023 rebrand moved the logo and
       body copy off Avenir onto Montserrat ExtraBold and Regular. It is wider
       and rounder than Inter, so the tracking through this file is set for it
       rather than inherited from the previous face. */
    --font: 'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    font-family: var(--font);
    color: var(--ink);
    margin: 0;
    padding: 0;
    min-height: 100vh;
    background-color: var(--surface-page);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* --- App backdrop -------------------------------------------------------
   The same treatment as the login screen: the dotted working surface, with a
   band of the brand ramp and its striations across the top that fades out
   before it reaches the content. The striations reuse .landing-streaks, so
   there is one implementation of that texture, not two.
   ------------------------------------------------------------------------ */

.app-backdrop {
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background-color: var(--surface-page);
    background-image: var(--dot-grid);
    background-size: 22px 22px;
    background-position: -1px -1px;
}

/* The colour band drifts. It is laid out wider than the viewport and moved
   with a transform rather than by animating background-position: a transform
   runs on the compositor, so this costs nothing on a page someone keeps open
   all day, where repainting a full-width gradient every frame would not. */
.app-backdrop::before {
    content: "";
    position: absolute;
    top: 0;
    left: -18%;
    right: -18%;
    height: 420px;
    background: linear-gradient(104deg, var(--ramp-stops));
    /* Kept light: headings and body text sit on this, and it has to stay a
       wash rather than a statement. */
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.34) 42%, transparent 88%);
    mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.34) 42%, transparent 88%);
    animation: ramp-drift 96s ease-in-out infinite alternate;
    will-change: transform;
}

@keyframes ramp-drift {
    from { transform: translate3d(-4%, 0, 0) scale(1.02); }
    to   { transform: translate3d(4%, 0, 0) scale(1.06); }
}

.app-backdrop .landing-streaks {
    inset: 0 0 auto;
    height: 420px;
    opacity: 0.5;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.3) 45%, transparent 88%);
    mask-image: linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.3) 45%, transparent 88%);
}

/* The striations drift too, but at roughly a third of the landing page's pace.
   The landing is a screen you look at once, so it can afford to be lively;
   this sits behind a tool someone keeps open all day, where the aim is
   something you notice only if you stop and look for it. Each cycle runs over
   a minute, far below the rate that reads as motion in peripheral vision.

   Only transforms are animated, so the whole backdrop stays on the compositor
   and never repaints. */
.app-backdrop .streak-a { animation-duration: 68s; }
.app-backdrop .streak-b { animation-duration: 92s; }
.app-backdrop .streak-c { animation-duration: 54s; }

/* Whatever else is true, a background that moves on its own is the first thing
   to stop when someone has asked for less motion. The global reduced-motion
   reset already freezes these; this states it where the animation is declared
   so it cannot be lost if that reset is ever narrowed. */
@media (prefers-reduced-motion: reduce) {
    .app-backdrop::before,
    .app-backdrop .streak-layer { animation: none; transform: none; }
}

/* --- Typography ---------------------------------------------------------
   Tracking and leading are size-specific, not one value for the whole scale.
   Letters read further apart as type grows, so large text is tightened and
   small text is left alone or opened up slightly; leading runs the other way,
   tight on headings and loose on body copy. A single letter-spacing across a
   30px-to-17px range -- which is what this used to be -- is wrong at one end
   or the other by definition.

   Sizes are in rem so that a reader who raises their browser text size scales
   the type rather than being ignored.
   ------------------------------------------------------------------------ */

h1, h2, h3, h4 {
    margin: 0;
    font-weight: 700;
    color: var(--ink);
    font-optical-sizing: auto;
    text-wrap: balance;
}

h1 { font-size: 1.875rem; letter-spacing: -0.034em; line-height: 1.16; }
h2 { font-size: 1.375rem; letter-spacing: -0.025em; line-height: 1.26; }
h3 { font-size: 1.0625rem; letter-spacing: -0.016em; line-height: 1.36; }
h4 { font-size: 0.9375rem; letter-spacing: -0.009em; line-height: 1.42; }

p { margin: 0; color: var(--ink-soft); font-size: 0.9375rem; line-height: 1.6; letter-spacing: 0; }

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

.muted { color: var(--ink-muted); }
/* Small copy takes a touch of positive tracking; at this size letters set
   solid are harder to tell apart, which is the opposite problem to a heading. */
.small { font-size: 0.8125rem; letter-spacing: 0.002em; line-height: 1.5; }

/* Accent word treatment, teal into potent purple. Used on the login headline
   and on the app's hero figures. Wrap the words you want lifted. */
.text-gradient {
    background: linear-gradient(96deg, var(--accent) 0%, var(--potent-purple) 78%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* also fill-color, so this still wins where the element's own rule sets a
       colour more specifically (e.g. .result-hero .result-value) */
    -webkit-text-fill-color: transparent;
}

/* Set on #contentToPrint while html2canvas captures the PDF, which renders
   clipped-to-text gradients as nothing. See public/js/download_to_pdf.js. */
.is-exporting .text-gradient {
    background: none;
    color: var(--ink);
    -webkit-text-fill-color: var(--ink);
}

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

.page {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 28px 20px 72px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.page-intro { padding: 12px 6px 0; }
.page-intro h1 { margin-bottom: 6px; }

.card {
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 32px 36px;
}

.card-flush { padding: 0; overflow: hidden; }

.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.stack { display: flex; flex-direction: column; gap: 20px; }
.cluster { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.spread { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }

.divider { border: none; border-top: 1px solid var(--line-soft); margin: 20px 0; }

/* --- Header / nav ------------------------------------------------------ */

.site-header {
    position: sticky;
    top: 16px;
    z-index: 50;
    max-width: var(--page-max);
    margin: 16px auto 0;
    padding: 0 20px;
}

/* A floating translucent layer with the page running underneath it. The
   saturation boost is what stops a plain blur going grey and lifeless over
   colour -- it is the difference between frosted glass and tracing paper.

   The material also gets thicker once there is content behind it: at the top
   of the page there is nothing to separate from, so it sits light; as soon as
   the page scrolls under, the blur and shadow deepen. Real chrome earns its
   weight from what it is covering. */
.site-header .bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    background: rgba(255, 255, 255, 0.78);
    backdrop-filter: blur(14px) saturate(180%);
    -webkit-backdrop-filter: blur(14px) saturate(180%);
    border: 1px solid rgba(231, 231, 236, 0.9);
    /* The bright top edge reads as light catching the leading face. */
    border-top-color: rgba(255, 255, 255, 0.85);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-pill);
    padding: 10px 12px 10px 22px;
    transition: box-shadow 0.28s ease, background-color 0.28s ease, backdrop-filter 0.28s ease;
}

.site-header.is-scrolled .bar {
    background: rgba(255, 255, 255, 0.86);
    backdrop-filter: blur(22px) saturate(190%);
    -webkit-backdrop-filter: blur(22px) saturate(190%);
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 10px 28px -6px rgba(16, 24, 40, 0.16);
}

/* --- Brand mark: header (logo + product name) ------------------------------- */

.site-header .brand-mark { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.site-header .brand-mark:hover { text-decoration: none; }

.brand-logo-img {
    display: block;
    height: 26px;
    width: auto;
    flex-shrink: 0;
}

.brand-name {
    font-family: var(--font);
    font-weight: 700;
    font-size: 15.5px;
    letter-spacing: -0.01em;
    color: var(--ink);
    white-space: nowrap;
}

/* --- Auth headline (product name + powered-by credit) ----------------------- */

.auth-heading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center;
}

.auth-heading .app-name {
    font-family: var(--font);
    font-weight: 800;
    font-size: 28px;
    letter-spacing: -0.02em;
    color: var(--ink);
}

/* --- "Powered by potent.ai" credit, reused in auth header + app footer ------ */

/* Product attribution: "Built by <TFG> | Powered by potent.ai". Two parts of
   one credit, so they sit on a single baseline with a hairline between them
   rather than reading as two separate notices. */
.attribution {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.attribution-part {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    white-space: nowrap;
}

.attribution-label {
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--ink-muted);
}

.attribution-tfg {
    height: 22px;
    width: auto;
    display: block;
}

.attribution-mark {
    height: 15px;
    width: auto;
    display: block;
}

.attribution-potent {
    font-family: 'Montserrat', var(--font);
    font-weight: 800;
    font-size: 0.8125rem;
    letter-spacing: -0.005em;
    text-transform: lowercase;
    color: var(--potent-purple);
}

.attribution-sep {
    width: 1px;
    height: 14px;
    background: var(--line);
    flex: 0 0 auto;
}

.site-footer .attribution { margin-left: auto; }

@media (max-width: 640px) {
    .site-header { top: 10px; margin-top: 10px; padding: 0 12px; }
    .site-header .bar { padding: 8px 10px 8px 14px; }
    .brand-logo-img { height: 22px; }
    .brand-name { font-size: 14px; }
    .auth-heading .app-name { font-size: 23px; }
    .brand-select { max-width: 130px; font-size: 12.5px; padding: 8px 32px 8px 12px; }
    .header-controls { gap: 6px; }
    .icon-button { width: 36px; height: 36px; }
    .card { padding: 24px 20px; }
    .auth-card { padding: 30px 24px; }
}

.header-controls { display: flex; align-items: center; gap: 10px; }

.brand-select {
    appearance: none;
    -webkit-appearance: none;
    font-family: var(--font);
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink);
    background-color: var(--surface);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.6' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-pill);
    padding: 9px 38px 9px 16px;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    max-width: 190px;
    text-overflow: ellipsis;
}

.brand-select:hover { border-color: #d5d5dd; }
.brand-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }

.icon-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--line);
    background: var(--surface);
    box-shadow: var(--shadow-pill);
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease;
}

.icon-button:hover { transform: translateY(-1px); border-color: #d5d5dd; text-decoration: none; }

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

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    font-family: var(--font);
    font-size: 14.5px;
    font-weight: 600;
    letter-spacing: 0.005em;
    border-radius: var(--radius-pill);
    padding: 11px 22px;
    border: 1px solid transparent;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
    text-decoration: none;
    white-space: nowrap;
}

.btn:hover { text-decoration: none; }

.btn-primary {
    background: var(--ink);
    color: #fff;
    box-shadow: 0 2px 6px rgba(16, 24, 40, 0.18), 0 8px 20px -6px rgba(16, 24, 40, 0.25);
}

.btn-primary:hover { transform: translateY(-1px); background: #26282f; }

.btn-secondary {
    background: var(--surface);
    color: var(--ink);
    border-color: var(--line);
    box-shadow: var(--shadow-pill);
}

.btn-secondary:hover { transform: translateY(-1px); border-color: #d5d5dd; }

.btn-accent {
    background: var(--accent);
    color: #fff;
    box-shadow: 0 2px 6px rgba(44, 117, 124, 0.25), 0 8px 20px -6px rgba(44, 117, 124, 0.35);
}

.btn-accent:hover { transform: translateY(-1px); background: #25646a; }

.btn-danger {
    background: var(--danger);
    color: #fff;
    box-shadow: 0 2px 6px rgba(217, 45, 90, 0.25), 0 8px 20px -6px rgba(217, 45, 90, 0.35);
}

.btn-danger:hover { transform: translateY(-1px); background: #c02450; }

.btn-block { width: 100%; }

.btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

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

.field { display: flex; flex-direction: column; gap: 7px; }

.field-label {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-soft);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.field-hint { font-size: 12px; font-weight: 500; color: var(--ink-muted); }

.control {
    font-family: var(--font);
    font-size: 15px;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid #dcdce3;
    border-radius: var(--radius-input);
    padding: 11px 14px;
    width: 100%;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.control::placeholder { color: #a6aab4; }

.control:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

.control[readonly] {
    background: #f7f7fa;
    color: var(--ink-muted);
    cursor: default;
}

.control[readonly]:focus { border-color: #dcdce3; box-shadow: none; }

select.control {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.6' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
    padding-right: 40px;
    cursor: pointer;
}

.field.has-error .control { border-color: var(--danger); }
.field.has-error .control:focus { box-shadow: 0 0 0 4px var(--danger-soft); }

.field-error {
    font-size: 13px;
    font-weight: 500;
    color: var(--danger);
    display: none;
}

.field.has-error .field-error { display: block; }

.choice-group-wrap.has-error .field-error { display: block; }

.field-error-list {
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--danger);
}
.choice-group-wrap.has-error .choice { border-color: var(--danger); }

/* form grid for the scenario detail pages */
.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px 28px;
}

@media (max-width: 720px) {
    .form-grid { grid-template-columns: 1fr; }
}

/* --- Section headings inside form cards -------------------------------- */

.form-section { padding-top: 6px; }

.section-title {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 4px;
}

.section-title .icon-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 11px;
    background: #f4f4f8;
    border: 1px solid var(--line-soft);
    flex-shrink: 0;
}

.section-title h3 { font-size: 16px; }

.section-title .rule {
    flex: 1;
    border-top: 1px solid var(--line-soft);
}

.section-note { margin: 6px 0 14px; font-size: 14px; color: var(--ink-muted); }

/* --- Choice pills (radio / checkbox cards) ------------------------------ */

.choice-group { display: flex; flex-direction: column; gap: 12px; }
.choice-row { display: flex; gap: 12px; flex-wrap: wrap; }

.choice {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: var(--surface);
    padding: 16px 18px;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}

.choice:hover { border-color: #d0d0d9; }

.choice input { position: absolute; opacity: 0; pointer-events: none; }

.choice .dot {
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1.8px solid #c9c9d2;
    flex-shrink: 0;
    margin-top: 2px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.choice input:checked ~ .dot {
    border-color: var(--accent);
    border-width: 5.5px;
}

.choice input:focus-visible ~ .dot { box-shadow: 0 0 0 4px var(--accent-soft); }

.choice.checked, .choice:has(input:checked) {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.choice .choice-body { display: flex; flex-direction: column; gap: 2px; }
.choice .choice-title { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.choice .choice-desc { font-size: 13px; color: var(--ink-muted); line-height: 1.5; }

.choice-pill {
    align-items: center;
    border-radius: var(--radius-pill);
    padding: 10px 18px;
}

.choice-pill .dot { margin-top: 0; }

/* --- Alerts ------------------------------------------------------------- */

.alert {
    border-radius: 14px;
    padding: 14px 18px;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.55;
}

.alert-danger {
    background: var(--danger-soft);
    border: 1px solid rgba(217, 45, 90, 0.25);
    color: #ab1e44;
}

.alert-success {
    background: rgba(26, 127, 79, 0.08);
    border: 1px solid rgba(26, 127, 79, 0.25);
    color: var(--success);
}

/* Buyable but not sensible -- sits between success and danger, matching the
   amber used for the caution state on the result page. */
.alert-warning {
    background: rgba(242, 142, 27, 0.10);
    border: 1px solid rgba(242, 142, 27, 0.30);
    color: #9a5a06;
}

.alert ul { margin: 4px 0 0; padding-left: 18px; }

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

.table-wrap { overflow-x: auto; }

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14.5px;
    font-variant-numeric: tabular-nums;
}

.data-table th.num, .data-table td.num { text-align: right; }
.data-table td.num { font-weight: 600; color: var(--ink); }
.data-table th .unit { text-transform: none; letter-spacing: 0; font-weight: 500; color: #a2a7b2; }

.data-table th {
    text-align: left;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
    background: #fafafc;
    padding: 14px 24px;
    border-bottom: 1px solid var(--line-soft);
    white-space: nowrap;
}

.data-table td {
    padding: 15px 24px;
    border-bottom: 1px solid var(--line-soft);
    color: var(--ink-soft);
}

.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr { transition: background-color 0.12s ease; }
.data-table tbody tr:hover { background: #fafbfd; }

.data-table .empty-cell {
    text-align: center;
    color: var(--ink-muted);
    padding: 36px 24px;
}

/* --- Stat / result display ---------------------------------------------- */

.result-hero {
    text-align: center;
    padding: 18px 0 6px;
}

.result-hero .result-label {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-muted);
    margin-bottom: 10px;
}

/* The biggest figure on the page, so the tightest tracking and the tightest
   leading in the system. It also fluidly scales rather than stepping at one
   breakpoint, which keeps the relationship to its label steady in between. */
.result-hero .result-value {
    font-size: clamp(2.25rem, 6.5vw, 3.5rem);
    font-weight: 700;
    letter-spacing: -0.038em;
    color: var(--ink);
    line-height: 1.04;
    font-optical-sizing: auto;
}

/* The breakpoint step this used to need is now handled by the clamp above,
   which scales continuously instead of jumping at 640px. */

.score-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
}

.score-tile {
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 16px 18px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--surface);
}

.score-tile .score-name { font-size: 13.5px; font-weight: 600; color: var(--ink-soft); }

.score-dot { width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0; }

/* --- Result dashboard ----------------------------------------------------- */

/* status / category tag */
.tag {
    display: inline-flex;
    align-items: center;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    border-radius: var(--radius-pill);
    padding: 4px 11px;
}

.tag-accent { color: var(--accent); background: var(--accent-soft); }
.tag-plum { color: var(--potent-purple); background: rgba(91, 63, 176, 0.10); }

.meta-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

.meta-chip {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-muted);
    background: #f6f6f9;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-pill);
    padding: 4px 12px;
    white-space: nowrap;
}

.delta-pill {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    margin-top: 14px;
    font-size: 13px;
    font-weight: 700;
    border-radius: var(--radius-pill);
    padding: 6px 15px;
    border: 1px solid transparent;
    font-variant-numeric: tabular-nums;
}

.delta-pill .delta-note { font-weight: 500; opacity: 0.8; }
.delta-pill.up { color: var(--success); background: rgba(26, 127, 79, 0.08); border-color: rgba(26, 127, 79, 0.22); }
.delta-pill.down { color: var(--danger); background: var(--danger-soft); border-color: rgba(217, 45, 90, 0.22); }
.delta-pill.flat { color: var(--ink-soft); background: #f5f5f8; border-color: var(--line); }

/* KPI tiles */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
}

@media (max-width: 860px) { .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 460px) { .kpi-grid { grid-template-columns: minmax(0, 1fr); } }

.kpi-tile {
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: 18px;
    box-shadow: var(--shadow-card);
    padding: 18px 20px 20px;
}

.kpi-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 12px;
}

.kpi-label { font-size: 12.5px; font-weight: 600; color: var(--ink-muted); line-height: 1.4; }

.kpi-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    flex-shrink: 0;
}

.i-blue { color: #2563a8; background: rgba(37, 99, 168, 0.10); }
.i-purple { color: var(--potent-purple); background: rgba(91, 63, 176, 0.10); }
.i-green { color: var(--success); background: rgba(26, 127, 79, 0.10); }
.i-amber { color: #b26a06; background: rgba(242, 142, 27, 0.14); }
.i-ink { color: #fff; background: var(--ink); }

/* A third the size of the hero figure, so it does not want the hero's
   tracking -- at 23px that reads as cramped rather than confident. */
.kpi-value {
    font-size: 1.4375rem;
    font-weight: 700;
    letter-spacing: -0.021em;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.kpi-sub { margin-top: 6px; font-size: 12px; color: var(--ink-muted); line-height: 1.45; }

/* two-panel row */
.panel-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}

@media (max-width: 860px) { .panel-grid { grid-template-columns: minmax(0, 1fr); } }

.panel-grid .card { padding: 26px 28px 28px; }

.score-pill {
    font-size: 15px;
    font-weight: 700;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: var(--radius-pill);
    padding: 6px 14px;
    font-variant-numeric: tabular-nums;
}

/* meters */
.meter-list { display: flex; flex-direction: column; gap: 18px; margin-top: 18px; }

.meter-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}

.meter-name {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-size: 14px;
    font-weight: 700;
    color: var(--ink);
}

.meter-name .score-dot { width: 9px; height: 9px; }

.meter-weight {
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-muted);
    background: #f4f4f8;
    border-radius: var(--radius-pill);
    padding: 2px 8px;
}

.meter-val { font-size: 13.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.meter-val .muted { font-weight: 500; }

.meter-track {
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--line-soft);
    overflow: hidden;
}

.meter-fill {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    transition: width 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.meter-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 7px;
    font-size: 12px;
    color: var(--ink-muted);
}

.meter-rating { font-weight: 700; white-space: nowrap; }

/* build-up list */
.flow-list { list-style: none; margin: 18px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }

.flow-row {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    align-items: center;
    gap: 13px;
    padding: 13px 0;
    border-bottom: 1px solid var(--line-soft);
}

.flow-row:last-child { border-bottom: none; }

.flow-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    font-size: 12.5px;
    font-weight: 700;
}

.flow-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.flow-label { font-size: 14px; font-weight: 700; color: var(--ink); }
.flow-note { font-size: 12px; color: var(--ink-muted); line-height: 1.45; }

.flow-value {
    font-size: 15px;
    font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.flow-value.pos { color: var(--success); }
.flow-value.neg { color: #b26a06; }

.flow-total { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 16px; }
.flow-total .flow-value { font-size: 18px; }

/* inputs summary */
.fact-block + .fact-block { margin-top: 22px; }

.fact-heading {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--ink-muted);
    margin-bottom: 12px;
}

.fact-heading .muted { text-transform: none; letter-spacing: 0; font-weight: 500; }

.fact-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 12px;
}

.fact {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: #fafafc;
    border: 1px solid var(--line-soft);
    border-radius: 13px;
    padding: 12px 14px;
}

.fact-label { font-size: 12px; font-weight: 600; color: var(--ink-muted); }
.fact-value { font-size: 15px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* --- Auth pages ---------------------------------------------------------- */

.auth-wrap {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 48px 20px;
    gap: 28px;
}

.auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: 40px 40px 36px;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.auth-card .auth-title { font-size: 1.5rem; letter-spacing: -0.021em; line-height: 1.22; }
.auth-card .auth-sub { font-size: 0.875rem; line-height: 1.5; color: var(--ink-muted); margin-top: -14px; }

.auth-footer { font-size: 13px; color: var(--ink-muted); text-align: center; }

/* --- Landing / login split screen ---------------------------------------- */

.landing-body { background-color: #ffffff; }

.landing {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
    min-height: 100vh;
}

/* Left: the pitch ---------------------------------------------------------- */

.landing-copy {
    display: flex;
    flex-direction: column;
    gap: 40px;
    padding: 40px 56px 36px;
    background-color: var(--surface-page);
    background-image: var(--dot-grid);
    background-size: 22px 22px;
    background-position: -1px -1px;
}

.landing-brand { display: flex; align-items: center; gap: 9px; }
.landing-logo { height: 26px; width: auto; display: block; }

.landing-wordmark {
    font-weight: 700;
    font-size: 16px;
    letter-spacing: -0.02em;
    color: var(--ink);
}

.landing-main {
    display: flex;
    flex-direction: column;
    gap: 22px;
    margin-top: auto;
    margin-bottom: auto;
    max-width: 560px;
}

.landing-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.landing-eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}

.landing-title {
    font-size: clamp(2rem, 3.4vw, 3rem);
    line-height: 1.08;
    letter-spacing: -0.035em;
    font-weight: 700;
}

/* colour comes from .text-gradient, which the app's hero figures share */
.landing-title-accent { display: block; }

.landing-lede {
    font-size: 1rem;
    line-height: 1.65;
    letter-spacing: 0;
    color: var(--ink-soft);
    max-width: 48ch;
}

.landing-points {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 8px;
}

.landing-point { display: flex; align-items: flex-start; gap: 14px; }

.landing-point-num {
    flex: none;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 12px;
    font-weight: 700;
    color: var(--accent);
    background: var(--accent-soft);
    margin-top: 1px;
}

.landing-point h3 { font-size: 0.9375rem; letter-spacing: -0.005em; line-height: 1.4; font-weight: 700; margin-bottom: 3px; }
.landing-point p { font-size: 0.875rem; line-height: 1.55; color: var(--ink-muted); }

.landing-credit {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding-top: 20px;
    border-top: 1px solid var(--line);
    font-size: 13px;
    color: var(--ink-muted);
}

.landing-credit strong { font-weight: 700; color: var(--ink-soft); }

.landing-credit-sep {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: #c9cbd3;
}

/* Right: the gradient panel + login card ----------------------------------- */

.landing-visual {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px 40px;
    background:
        radial-gradient(460px 760px at 62% 44%, rgba(255, 255, 255, 0.62), transparent 60%),
        radial-gradient(560px 640px at 98% 4%, rgba(255, 219, 180, 0.9), transparent 62%),
        linear-gradient(156deg, var(--ramp-stops));
}

.landing-streaks {
    position: absolute;
    inset: -6%;
    -webkit-mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.7), #000 18%, #000 76%, rgba(0, 0, 0, 0.7));
    mask-image: linear-gradient(180deg, rgba(0, 0, 0, 0.7), #000 18%, #000 76%, rgba(0, 0, 0, 0.7));
}

.streak-layer { position: absolute; inset: 0; display: block; }

/* wide soft bands — the underlying rhythm */
.streak-a {
    background: repeating-linear-gradient(90deg,
        rgba(255, 255, 255, 0) 0 18px,
        rgba(255, 255, 255, 0.55) 18px 34px,
        rgba(255, 255, 255, 0) 34px 58px);
    filter: blur(9px);
    animation: streak-drift-a 26s ease-in-out infinite alternate;
}

/* violet/blue verticals, denser toward the left edge */
.streak-b {
    background: repeating-linear-gradient(90deg,
        rgba(78, 63, 150, 0) 0 6px,
        rgba(78, 63, 150, 0.26) 6px 11px,
        rgba(78, 63, 150, 0) 11px 27px);
    filter: blur(3px);
    -webkit-mask-image: linear-gradient(90deg, #000 0%, rgba(0, 0, 0, 0.75) 45%, rgba(0, 0, 0, 0.25) 100%);
    mask-image: linear-gradient(90deg, #000 0%, rgba(0, 0, 0, 0.75) 45%, rgba(0, 0, 0, 0.25) 100%);
    animation: streak-drift-b 34s ease-in-out infinite alternate;
}

/* fine bright filaments, the striated "combed" texture */
.streak-c {
    background: repeating-linear-gradient(90deg,
        rgba(255, 255, 255, 0) 0 3px,
        rgba(255, 255, 255, 0.7) 3px 5px,
        rgba(255, 255, 255, 0) 5px 7px,
        rgba(38, 48, 84, 0.14) 7px 8px,
        rgba(255, 255, 255, 0) 8px 12px);
    filter: blur(1.1px);
    opacity: 0.9;
    animation: streak-drift-c 20s ease-in-out infinite alternate;
}

@keyframes streak-drift-a {
    from { transform: translateX(-8px) scaleY(1); }
    to   { transform: translateX(8px) scaleY(1.04); }
}

@keyframes streak-drift-b {
    from { transform: translateX(10px); }
    to   { transform: translateX(-10px); }
}

@keyframes streak-drift-c {
    from { transform: translateX(4px) scaleX(1.01); }
    to   { transform: translateX(-6px) scaleX(1); }
}

.landing-login {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 424px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 38px 38px 34px;
    border-radius: 26px;
    border: 1px solid rgba(255, 255, 255, 0.75);
    background: rgba(255, 255, 255, 0.88);
    -webkit-backdrop-filter: blur(20px) saturate(1.3);
    backdrop-filter: blur(20px) saturate(1.3);
    box-shadow: 0 2px 6px rgba(20, 28, 60, 0.06), 0 34px 64px -22px rgba(20, 28, 60, 0.42);
}

.landing-login .auth-title { font-size: 24px; }
.landing-login .auth-sub { font-size: 14px; color: var(--ink-muted); margin-top: -14px; }

.login-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: -4px;
}

.login-remember {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    color: var(--ink-soft);
    cursor: pointer;
}

.login-remember input {
    width: 16px;
    height: 16px;
    accent-color: var(--accent);
    cursor: pointer;
}

.login-forgot { font-size: 13.5px; font-weight: 500; }

/* forms inside the card space themselves; the card only spaces its own blocks */
.landing-login .auth-form {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.login-alt {
    font-size: 13.5px;
    color: var(--ink-muted);
    text-align: center;
    margin: 0;
}

/* a submit button that has to read as a link (log out, resend, etc.) */
.link-button {
    font: inherit;
    font-size: 13.5px;
    color: var(--accent);
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    text-decoration: none;
}

.link-button:hover { text-decoration: underline; }
.link-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

@media (max-width: 1080px) {
    .landing-copy { padding: 36px 40px 32px; gap: 32px; }
    .landing-visual { padding: 44px 32px; }
}

@media (max-width: 900px) {
    .landing { grid-template-columns: minmax(0, 1fr); min-height: 0; }
    /* returning users come here to sign in, so the card leads on small screens */
    .landing-visual { order: -1; min-height: 74vh; padding: 40px 20px; }
    .landing-copy { padding: 44px 24px 32px; gap: 30px; }
    .landing-main { margin: 0; }
    .landing-title { font-size: clamp(30px, 8vw, 40px); }
}

@media (max-width: 480px) {
    .landing-login { padding: 30px 24px 26px; border-radius: 22px; }
    .landing-visual { padding: 28px 16px; }
}

/* --- Admin area ---------------------------------------------------------- */

/* "Admin" link in the app header */
.header-link {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-soft);
    padding: 9px 16px;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    white-space: nowrap;
}

.header-link:hover { text-decoration: none; background: #f2f2f6; color: var(--ink); }
.header-link.is-current { background: var(--accent-soft); color: var(--accent); }

.admin-tabs {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding: 4px;
    background: rgba(255, 255, 255, 0.7);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: var(--radius-pill);
    box-shadow: var(--shadow-pill);
    align-self: flex-start;
    max-width: 100%;
}

.admin-tab {
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-muted);
    padding: 8px 18px;
    border-radius: var(--radius-pill);
    white-space: nowrap;
}

.admin-tab:hover { text-decoration: none; color: var(--ink); background: #f4f4f8; }
.admin-tab.is-current { background: var(--ink); color: #fff; }
.admin-tab.is-current:hover { background: var(--ink); color: #fff; }

/* headline figures on the admin overview */
.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
}

.stat-cell {
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: 18px;
    box-shadow: var(--shadow-card);
    padding: 20px 22px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.stat-figure {
    font-size: 30px;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.stat-caption { font-size: 13px; color: var(--ink-muted); }

/* header strip inside a flush card, above a table */
.card-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 22px 24px;
    border-bottom: 1px solid var(--line-soft);
}

.card-bar h2 { font-size: 17px; }

.data-table .row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    white-space: nowrap;
}

.data-table .row-actions form { display: inline-flex; margin: 0; }

.data-table .meta-chips { margin-top: 0; display: inline-flex; }

/* two fields side by side on wide screens, stacked when there isn't room */
.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 20px;
}

.check-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 10px;
}

.check {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    color: var(--ink-soft);
    background: #fbfbfd;
    border: 1px solid var(--line);
    border-radius: var(--radius-input);
    padding: 11px 14px;
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.check:hover { border-color: #d5d5dd; background: #fff; }
.check input { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; flex: none; }
.check:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--ink); }

.form-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    flex-wrap: wrap;
}

@media (max-width: 640px) {
    .header-link { padding: 8px 12px; font-size: 12.5px; }
    .card-bar { padding: 18px 20px; }
    .form-actions { justify-content: stretch; }
    .form-actions .btn { flex: 1; }
}

/* --- Footer -------------------------------------------------------------- */

/* A real footer rather than a line of small print: a rule across the page
   closes the content, and the product sits opposite who made it. */
.site-footer {
    margin-top: 48px;
    border-top: 1px solid var(--line);
    background: rgba(255, 255, 255, 0.55);
}

.site-footer-inner {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 22px 20px 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    color: var(--ink-muted);
}

.footer-product {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.004em;
    color: var(--ink-soft);
}

.footer-copyright { font-weight: 500; color: var(--ink-muted); }

/* Stacked and left-aligned on a narrow screen -- pushing the credit to the
   right edge of a phone leaves it stranded away from everything else. */
@media (max-width: 560px) {
    .site-footer-inner { flex-direction: column; align-items: flex-start; gap: 14px; }
    .site-footer .attribution { margin-left: 0; }
}

@media (prefers-reduced-transparency: reduce) {
    .site-footer { background: var(--surface); }
}

/* --- Utilities ----------------------------------------------------------- */

.hidden { display: none !important; }
.text-center { text-align: center; }
.mt-4 { margin-top: 4px; }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.w-narrow { max-width: 260px; }

.reveal { animation: reveal 0.3s ease; }

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

/* --- Breadcrumbs ----------------------------------------------------------- */

.crumbs {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    font-size: 13px;
    font-weight: 500;
    color: var(--ink-muted);
    margin: 2px 0 6px;
}

.crumbs a {
    color: var(--ink-muted);
    text-decoration: none;
    padding: 5px 12px;
    border-radius: var(--radius-pill);
    border: 1px solid transparent;
    transition: color 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
}

.crumbs a:hover {
    color: var(--ink);
    background: rgba(255, 255, 255, 0.75);
    border-color: var(--line);
    text-decoration: none;
}

.crumbs .sep {
    display: inline-flex;
    width: 14px;
    height: 14px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%23c3c6cf' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.7' d='m8 6 4 4-4 4'/%3E%3C/svg%3E");
}

.crumbs .current { color: var(--ink-soft); font-weight: 600; padding: 5px 4px; }

/* --- Wizard / stepper ----------------------------------------------------- */

.stepper {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 14px;
}

.step-pill {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--line);
    background: var(--surface);
    padding: 7px 16px 7px 8px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink-muted);
    transition: border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}

.step-pill .step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: #f0f0f4;
    font-size: 12px;
    font-weight: 700;
    color: var(--ink-muted);
    transition: background-color 0.2s ease, color 0.2s ease;
}

.step-pill.active {
    border-color: var(--ink);
    color: var(--ink);
    box-shadow: var(--shadow-pill);
}

.step-pill.active .step-num { background: var(--ink); color: #fff; }

.step-pill.done { color: var(--accent); border-color: rgba(44, 117, 124, 0.35); }
.step-pill.done .step-num { background: var(--accent); color: #fff; }

.step-connector { flex: 0 0 18px; border-top: 1.5px solid var(--line); }

.progress-meta {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.progress-meta .step-label { font-size: 13.5px; font-weight: 700; color: var(--ink-soft); }

.progress-meta .pct {
    font-size: 13px;
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.progress-track {
    height: 6px;
    border-radius: var(--radius-pill);
    background: var(--line-soft);
    overflow: hidden;
    margin-bottom: 26px;
}

.progress-fill {
    position: relative;
    height: 100%;
    width: 0;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--accent), #6db5bd);
    transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
    overflow: hidden;
}

.progress-fill::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(100deg, transparent 30%, rgba(255, 255, 255, 0.45) 50%, transparent 70%);
    animation: shimmer 2.2s ease-in-out infinite;
}

@keyframes shimmer {
    0% { transform: translateX(-100%); }
    60%, 100% { transform: translateX(100%); }
}

/* A step arrives from the side it is travelling from: forward comes in from
   the right, back comes in from the left. Both directions used to run the same
   upward fade, which told the user nothing about which way they had moved.
   Each direction is the mirror of the other, so going back undoes the path
   going forward drew. */
.wizard-step { display: none; }
.wizard-step.active { display: block; }

.wizard-step.active[data-enter="forward"] { animation: step-in-right 0.34s cubic-bezier(0.22, 0.61, 0.36, 1); }
.wizard-step.active[data-enter="back"] { animation: step-in-left 0.34s cubic-bezier(0.22, 0.61, 0.36, 1); }
/* First paint has no direction because nothing came before it. */
.wizard-step.active[data-enter="initial"] { animation: reveal 0.35s ease; }

@keyframes step-in-right {
    from { opacity: 0; transform: translate3d(30px, 0, 0); }
    to { opacity: 1; transform: none; }
}

@keyframes step-in-left {
    from { opacity: 0; transform: translate3d(-30px, 0, 0); }
    to { opacity: 1; transform: none; }
}

/* Reduced motion keeps the change of step legible without the travel. */
@media (prefers-reduced-motion: reduce) {
    .wizard-step.active[data-enter] { animation: none; }
}

.wizard-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 26px;
}

.summary-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 1px solid var(--line);
    background: rgba(255, 255, 255, 0.75);
    border-radius: var(--radius-pill);
    padding: 6px 14px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-soft);
    box-shadow: var(--shadow-pill);
}

.chip .chip-label { color: var(--ink-muted); font-weight: 500; }

/* --- Accordions ----------------------------------------------------------- */

details.accordion {
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    overflow: hidden;
}

details.accordion > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 24px 30px;
    user-select: none;
}

details.accordion > summary::-webkit-details-marker { display: none; }

details.accordion > summary h2 { font-size: 19px; }

details.accordion > summary .summary-side {
    display: flex;
    align-items: center;
    gap: 12px;
}

.count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 26px;
    height: 26px;
    padding: 0 9px;
    border-radius: var(--radius-pill);
    background: #f0f0f4;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--ink-soft);
}

.chev {
    display: inline-flex;
    width: 20px;
    height: 20px;
    transition: transform 0.25s ease;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.7' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");
}

details[open] > summary .chev { transform: rotate(180deg); }

.accordion-body { animation: reveal 0.3s ease; }

/* result rows inside the results accordion — fixed column widths so every
   row (each an independent grid) lines up pixel-for-pixel with its neighbors
   and with the header row below, regardless of content length. */

.result-grid-cols { grid-template-columns: minmax(0, 1fr) 190px 100px 120px 28px 28px 20px; }

.row-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    border: none;
    background: transparent;
    color: var(--ink-muted);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.row-action:hover { background: var(--danger-soft); color: var(--danger); }
.row-action:focus-visible { outline: 2px solid var(--danger); outline-offset: 1px; }

a.row-open { text-decoration: none; }
a.row-open:hover { background: var(--accent-soft); color: var(--accent); text-decoration: none; }
a.row-open:focus-visible { outline-color: var(--accent); }

.btn-sm { font-size: 13px; padding: 8px 16px; gap: 7px; }

.detail-side { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.result-list-head {
    display: grid;
    align-items: center;
    gap: 16px;
    padding: 0 30px 10px;
    font-size: 11.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
}

.result-list-head .col-value { text-align: right; }

details.result-item { border-top: 1px solid var(--line-soft); }

details.result-item > summary {
    list-style: none;
    cursor: pointer;
    display: grid;
    align-items: center;
    gap: 16px;
    padding: 16px 30px;
    transition: background-color 0.15s ease;
}

details.result-item > summary::-webkit-details-marker { display: none; }
details.result-item > summary:hover { background: #fafbfd; }

details.result-item .r-name { font-size: 14.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
details.result-item .r-meta { font-size: 13px; color: var(--ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
details.result-item .r-headline { font-size: 14.5px; font-weight: 700; color: var(--accent); white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; }

details.result-item .result-detail {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
    padding: 4px 30px 20px;
    animation: reveal 0.25s ease;
}

.mini-scores { display: flex; gap: 10px; flex-wrap: wrap; }

.mini-score {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface);
    padding: 6px 13px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--ink-soft);
}

.mini-score .score-dot { width: 10px; height: 10px; }

/* keep the name column readable once the window narrows */
@media (max-width: 900px) {
    .result-grid-cols { grid-template-columns: minmax(0, 1fr) 130px 88px 110px 28px 28px 18px; gap: 10px; }
    .result-list-head, details.result-item > summary { padding-left: 22px; padding-right: 22px; }
}

@media (max-width: 720px) {
    .result-grid-cols { grid-template-columns: minmax(0, 1fr) 110px 28px 28px 18px; }
    .result-list-head { display: none; }
    details.result-item .r-meta { display: none; }
}

/* --- Flow entry tiles ------------------------------------------------------ */

.tile-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 18px;
}

@media (max-width: 720px) {
    .tile-grid { grid-template-columns: 1fr; }
}

a.action-tile {
    display: flex;
    flex-direction: column;
    gap: 14px;
    background: var(--surface);
    border: 1px solid rgba(231, 231, 236, 0.9);
    border-radius: 20px;
    box-shadow: var(--shadow-card);
    padding: 26px 28px;
    text-decoration: none;
    color: var(--ink);
    transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}

a.action-tile:hover {
    transform: translateY(-2px);
    border-color: rgba(44, 117, 124, 0.45);
    box-shadow: 0 2px 4px rgba(16, 24, 40, 0.06), 0 18px 40px -10px rgba(16, 24, 40, 0.18);
    text-decoration: none;
}

.action-tile .tile-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.action-tile .tile-title { font-size: 16.5px; font-weight: 700; letter-spacing: -0.01em; }
.action-tile .tile-desc { font-size: 13.5px; color: var(--ink-muted); line-height: 1.55; }

.action-tile .tile-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #f4f4f8;
    border: 1px solid var(--line-soft);
    transition: background-color 0.18s ease, transform 0.18s ease;
    flex-shrink: 0;
    background-repeat: no-repeat;
    background-size: 16px;
    background-position: center;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='%2317181c' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.7' d='M4 10h12m-5-5 5 5-5 5'/%3E%3C/svg%3E");
}

a.action-tile:hover .tile-arrow { transform: translateX(3px); }

.tile-tag {
    align-self: flex-start;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--accent);
    background: var(--accent-soft);
    border-radius: var(--radius-pill);
    padding: 4px 11px;
}

/* --- Icons (inline data-uri sprites) ------------------------------------- */

.mynaui--logout {
    display: inline-block;
    width: 20px;
    height: 20px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%2317181c' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M13.496 21H6.5c-1.105 0-2-1.151-2-2.571V5.57c0-1.419.895-2.57 2-2.57h7M16 15.5l3.5-3.5L16 8.5m-6.5 3.496h10'/%3E%3C/svg%3E");
}

.fluent--form-new-20-regular {
    display: inline-block;
    width: 20px;
    height: 20px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='white' d='M6 3a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h3.6a5.5 5.5 0 0 1-.393-1H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3.207q.524.149 1 .393V6a3 3 0 0 0-3-3zm3.5 7h1.837c.895-.63 1.986-1 3.163-1h-5a.5.5 0 0 0 0 1m-4-5a.5.5 0 0 0 0 1h9a.5.5 0 0 0 0-1zm1 6a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m0-1a.5.5 0 1 1 0-1a.5.5 0 0 1 0 1m0 5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m0-2a.5.5 0 1 1 0 1a.5.5 0 0 1 0-1M19 14.5a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0m-4-2a.5.5 0 0 0-1 0V14h-1.5a.5.5 0 0 0 0 1H14v1.5a.5.5 0 0 0 1 0V15h1.5a.5.5 0 0 0 0-1H15z'/%3E%3C/svg%3E");
}

.solar--download-minimalistic-bold {
    display: inline-block;
    width: 20px;
    height: 20px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%2317181c' d='M12.554 16.506a.75.75 0 0 1-1.107 0l-4-4.375a.75.75 0 0 1 1.107-1.012l2.696 2.95V3a.75.75 0 0 1 1.5 0v11.068l2.697-2.95a.75.75 0 1 1 1.107 1.013z'/%3E%3Cpath fill='%2317181c' d='M3.75 15a.75.75 0 0 0-1.5 0v.055c0 1.367 0 2.47.117 3.337c.12.9.38 1.658.981 2.26c.602.602 1.36.86 2.26.982c.867.116 1.97.116 3.337.116h6.11c1.367 0 2.47 0 3.337-.116c.9-.122 1.658-.38 2.26-.982c.602-.602.86-1.36.982-2.26c.116-.867.116-1.97.116-3.337V15a.75.75 0 0 0-1.5 0c0 1.435-.002 2.436-.103 3.192c-.099.734-.28 1.122-.556 1.399c-.277.277-.665.457-1.4.556c-.755.101-1.756.103-3.191.103H9c-1.435 0-2.437-.002-3.192-.103c-.734-.099-1.122-.28-1.399-.556c-.277-.277-.457-.665-.556-1.4c-.101-.755-.103-1.756-.103-3.191'/%3E%3C/svg%3E");
}

.ic--baseline-border-color {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%233f4450' d='M13.06 5.19l3.75 3.75L7.75 18H4v-3.75zm4.82 2.68l-3.75-3.75l1.83-1.83a.996.996 0 0 1 1.41 0l2.34 2.34c.39.39.39 1.02 0 1.41z'/%3E%3C/svg%3E");
}

.hugeicons--apple-stocks {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%233f4450' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5'%3E%3Cpath d='M2.5 12c0-4.478 0-6.718 1.391-8.109S7.521 2.5 12 2.5c4.478 0 6.718 0 8.109 1.391S21.5 7.521 21.5 12c0 4.478 0 6.718-1.391 8.109S16.479 21.5 12 21.5c-4.478 0-6.718 0-8.109-1.391S2.5 16.479 2.5 12'/%3E%3Cpath d='M2.5 14.5h.539c.472 0 .708 0 .914-.099c.205-.098.352-.283.647-.652L6 12l1.5 2.5L9 11l2.5 5L15 9l2 3.5l1.5-1.5l1.445 2.168c.252.378.378.567.562.681q.055.034.114.061c.198.09.425.09.879.09M15 2.5v3m0 16v-7'/%3E%3Ccircle cx='15' cy='9' r='1'/%3E%3C/g%3E%3C/svg%3E");
}

.mdi--talking {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%233f4450' d='M9 5a4 4 0 0 1 4 4a4 4 0 0 1-4 4a4 4 0 0 1-4-4a4 4 0 0 1 4-4m0 10c2.67 0 8 1.34 8 4v2H1v-2c0-2.66 5.33-4 8-4m7.76-9.64c2.02 2.2 2.02 5.25 0 7.27l-1.68-1.69c.84-1.18.84-2.71 0-3.89zM20.07 2c3.93 4.05 3.9 10.11 0 14l-1.63-1.63c2.77-3.18 2.77-7.72 0-10.74z'/%3E%3C/svg%3E");
}

.fluent--data-funnel-20-regular {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath fill='%233f4450' d='M2 4a2 2 0 0 1 2-2h12a2 2 0 1 1 0 4H4a2 2 0 0 1-2-2m2-1a1 1 0 0 0 0 2h12a1 1 0 1 0 0-2zm0 7a2 2 0 0 1 2-2h8a2 2 0 1 1 0 4H6a2 2 0 0 1-2-2m2-1a1 1 0 0 0 0 2h8a1 1 0 1 0 0-2zm2 5a2 2 0 1 0 0 4h4a2 2 0 1 0 0-4zm-1 2a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2H8a1 1 0 0 1-1-1'/%3E%3C/svg%3E");
}

.icon-park-outline--creative {
    display: inline-block;
    width: 18px;
    height: 18px;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3E%3Cg fill='none' stroke='%233f4450' stroke-linejoin='round' stroke-width='4'%3E%3Cpath d='M42 39V9a3 3 0 0 0-3-3H9a3 3 0 0 0-3 3v30a3 3 0 0 0 3 3h30a3 3 0 0 0 3-3Z'/%3E%3Cpath d='m24 18.316l-2.896 5.91l-6.578.954l4.765 4.658l-1.139 6.478L24 33.199l5.849 3.117l-1.13-6.478l4.756-4.658l-6.541-.954z'/%3E%3Cpath stroke-linecap='round' d='M18.316 12.632h11.368'/%3E%3C/g%3E%3C/svg%3E");
}

/* --- Accessibility -------------------------------------------------------- */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.btn:focus-visible,
a:focus-visible,
summary:focus-visible,
.icon-button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

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

/* --- Print (PDF export) --------------------------------------------------- */

@media print {
    .app-backdrop, .site-header, .site-footer { display: none; }
    /* clipped-to-text gradients print as nothing, so fall back to solid ink */
    .text-gradient { background: none; color: var(--ink); -webkit-text-fill-color: var(--ink); }
}

/* --- Impact of underfunding --------------------------------------------
   The section that says what a short budget costs in share. Tinted rather
   than plain white so it reads as a warning without shouting, in two tones:
   decline (share going backwards) and caution (growth, but short of goal).
   ------------------------------------------------------------------------ */

.decline-card { border-left: 4px solid var(--danger); }
.decline-card.is-caution { border-left-color: #f28e1b; }

.tag-danger { color: var(--danger); background: var(--danger-soft); }
.tag-warn { color: #b3660c; background: rgba(242, 142, 27, 0.12); }

.decline-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
    margin-top: 20px;
}

.decline-tile {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 16px 18px;
    border: 1px solid var(--line);
    border-radius: var(--radius-input);
    background: #fcfcfd;
}

.decline-tile-label { font-size: 12.5px; font-weight: 600; color: var(--ink-muted); }
.decline-tile-value { font-size: 24px; font-weight: 800; color: var(--ink); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.decline-tile-sub { font-size: 12px; color: var(--ink-muted); line-height: 1.45; }

/* Funding bar ---------------------------------------------------------- */

.fund-bar-block, .decline-chart-block { margin-top: 26px; }

.fund-bar-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.fund-bar-title { font-size: 14px; font-weight: 700; color: var(--ink); }
.fund-bar-pct { font-size: 13.5px; font-weight: 700; color: var(--danger); font-variant-numeric: tabular-nums; }
.is-caution .fund-bar-pct { color: #b3660c; }

/* The track is the full ask; the fill is what the client actually has, so
   the empty remainder is the shortfall and needs no second element. */
.fund-bar {
    position: relative;
    height: 22px;
    border-radius: var(--radius-pill);
    overflow: hidden;
    background: repeating-linear-gradient(
        -45deg,
        var(--danger-soft) 0 6px,
        rgba(217, 45, 90, 0.16) 6px 12px
    );
}

.is-caution .fund-bar {
    background: repeating-linear-gradient(
        -45deg,
        rgba(242, 142, 27, 0.10) 0 6px,
        rgba(242, 142, 27, 0.20) 6px 12px
    );
}

.fund-bar-have {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--accent), #3f8f96);
}

/* Small inline bar for the route 1 trajectory table. Deliberately not .fund-bar:
   there the empty space is a funding shortfall and is hatched red, here it is
   simply headroom the brand has not reached yet. */
.progress-mini {
    display: block;
    height: 10px;
    max-width: 220px;
    border-radius: var(--radius-pill);
    background: rgba(17, 17, 26, 0.07);
    overflow: hidden;
}

.progress-mini > span {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--accent), #3f8f96);
}

.fund-bar-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    margin-top: 10px;
    font-size: 12.5px;
    color: var(--ink-soft);
}

.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }
.swatch-have { background: var(--accent); }
.swatch-gap { background: rgba(217, 45, 90, 0.35); }
.is-caution .swatch-gap { background: rgba(242, 142, 27, 0.45); }

/* Erosion curve -------------------------------------------------------- */

/* Narrow screens scroll the chart rather than squashing its labels. */
.chart-scroll { overflow-x: auto; }
.decline-chart { display: block; width: 100%; min-width: 520px; height: auto; }

.decline-note {
    margin: 18px 0 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--ink-muted);
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}

/* Hint text under an optional field. */
.field-hint-block { font-size: 12px; line-height: 1.5; color: var(--ink-muted); margin-top: 6px; }

/* Signed figures in the year-by-year decline table. */
.data-table td.pos { color: var(--success); font-weight: 700; }
.data-table td.neg { color: var(--danger); font-weight: 700; }

/* ==========================================================================
   Underfunding section — Apple-design pass
   Hierarchy, type and material only. The page has no gestures, so none of the
   spring/velocity work applies; the single piece of motion here is a one-shot
   reveal that makes the curve read as a trajectory over time.
   ========================================================================== */

/* --- Material ------------------------------------------------------------
   A warning surface should read as its own layer, not a white card with a
   stripe. Larger surfaces read as thicker material: a deeper shadow than the
   cards around it, a tinted wash instead of a hard 4px rule, and a bright top
   edge where the light catches. No backdrop-filter — this sits over a plain
   surface where it would buy nothing, and html2canvas rasterises it badly.
   ------------------------------------------------------------------------ */

.decline-card {
    border-left: none;
    border: 1px solid rgba(217, 45, 90, 0.16);
    background:
        linear-gradient(180deg, rgba(217, 45, 90, 0.055) 0%, rgba(217, 45, 90, 0.012) 340px, transparent 640px),
        var(--surface);
    box-shadow:
        0 1px 2px rgba(16, 24, 40, 0.05),
        0 18px 44px -12px rgba(217, 45, 90, 0.18);
}

.decline-card.is-caution {
    border-color: rgba(242, 142, 27, 0.20);
    background:
        linear-gradient(180deg, rgba(242, 142, 27, 0.06) 0%, rgba(242, 142, 27, 0.014) 340px, transparent 640px),
        var(--surface);
    box-shadow:
        0 1px 2px rgba(16, 24, 40, 0.05),
        0 18px 44px -12px rgba(242, 142, 27, 0.20);
}

/* --- Hierarchy: the pair the section exists to make ---------------------- */

.decline-hero {
    margin-top: 1.5rem;
    padding: 1.5rem 1.5rem 1.375rem;
    border-radius: 18px;
    border: 1px solid rgba(217, 45, 90, 0.14);
    background: rgba(255, 255, 255, 0.72);
}

.is-caution .decline-hero { border-color: rgba(242, 142, 27, 0.18); }

.decline-hero-pair {
    display: flex;
    align-items: flex-end;
    gap: clamp(1rem, 4vw, 2.5rem);
    flex-wrap: wrap;
}

.decline-hero-figure { display: flex; flex-direction: column; gap: 0.375rem; }

/* Small text takes slightly positive tracking to stay legible; the display
   figures below take negative tracking as they grow. One value for both
   would be wrong at one end or the other. */
.decline-hero-label {
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--ink-muted);
    line-height: 1.3;
}

.decline-hero-value {
    font-size: clamp(2.25rem, 6vw, 3.25rem);
    font-weight: 800;
    line-height: 0.95;
    letter-spacing: -0.042em;
    font-variant-numeric: tabular-nums;
    color: var(--ink-soft);
    font-optical-sizing: auto;
}

.decline-hero-unit { font-size: 0.5em; font-weight: 700; letter-spacing: -0.01em; margin-left: 0.08em; }

/* The outcome is the number that matters, so it carries the colour and the ink. */
.decline-hero-figure.is-outcome .decline-hero-value { color: var(--danger); }
.is-caution .decline-hero-figure.is-outcome .decline-hero-value { color: #b3660c; }

/* A drawn connector rather than a typographic arrow: it aligns to the figures
   instead of sitting on the text baseline, and survives font fallback. */
.decline-hero-link {
    flex: 0 0 auto;
    align-self: center;
    width: 2.25rem;
    height: 2px;
    margin-bottom: 0.75rem;
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(217, 45, 90, 0.25), var(--danger));
    position: relative;
}

.decline-hero-link::after {
    content: '';
    position: absolute;
    right: -1px;
    top: 50%;
    width: 7px;
    height: 7px;
    border-top: 2px solid var(--danger);
    border-right: 2px solid var(--danger);
    transform: translateY(-50%) rotate(45deg);
}

.is-caution .decline-hero-link { background: linear-gradient(90deg, rgba(242, 142, 27, 0.3), #f28e1b); }
.is-caution .decline-hero-link::after { border-color: #f28e1b; }

.decline-hero-note {
    margin: 1.125rem 0 0;
    font-size: 0.875rem;
    line-height: 1.55;
    color: var(--ink-soft);
    max-width: 62ch;
}

.decline-hero-note strong { color: var(--ink); font-weight: 700; }

/* --- Supporting figures, demoted ----------------------------------------
   Scoped to this card on purpose. The tile classes are shared with the Route 1
   trajectory section, where the same tiles are the headline and there is no
   hero above them to rank against -- quietening them there would demote a
   section's main figures for a hierarchy it does not have. Only the tiles
   sitting underneath the paired hero get stepped down.
   ------------------------------------------------------------------------ */

.decline-card .decline-tiles { margin-top: 1rem; gap: 0.75rem; }

.decline-card .decline-tile { background: rgba(255, 255, 255, 0.66); padding: 0.875rem 1rem; }

.decline-card .decline-tile-label { letter-spacing: 0.015em; }

.decline-card .decline-tile-value {
    font-size: 1.3rem;
    letter-spacing: -0.018em;
    color: var(--ink-soft);
}

/* The year table repeats what the chart already labels, so it reads as
   reference rather than headline. */
.decline-card .data-table { font-size: 0.82rem; }
.decline-card .data-table th { color: var(--ink-muted); }

/* --- Motion --------------------------------------------------------------
   One reveal, triggered when the section is actually looked at. Critically
   damped in feel — no overshoot, because no gesture carried momentum into it;
   bounce here would be decoration. Transform and opacity only.
   ------------------------------------------------------------------------ */

[data-reveal] {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity 520ms cubic-bezier(0.22, 0.61, 0.36, 1),
                transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
    will-change: opacity, transform;
}

[data-reveal].is-revealed { opacity: 1; transform: none; }

.decline-chart .chart-line {
    transition: stroke-dashoffset 1100ms cubic-bezier(0.33, 0.9, 0.4, 1);
}

.decline-chart.is-revealed .chart-line { stroke-dashoffset: 0; }

.decline-chart .chart-area { opacity: 0; transition: opacity 620ms ease-out 420ms; }
.decline-chart.is-revealed .chart-area { opacity: 1; }

.decline-chart .chart-dot { opacity: 0; transition: opacity 320ms ease-out var(--dot-delay, 0ms); }
.decline-chart.is-revealed .chart-dot { opacity: 1; }

/* The bar fills from empty, so the funded portion reads as a measure being
   taken rather than a shape that was always there. */
.fund-bar-have { transform-origin: left center; }
[data-reveal] .fund-bar-have,
.fund-bar-block[data-reveal] .fund-bar-have { transform: scaleX(0); }
.fund-bar-block[data-reveal].is-revealed .fund-bar-have {
    transform: scaleX(1);
    transition: transform 760ms cubic-bezier(0.22, 0.61, 0.36, 1) 120ms;
}

/* --- Accessibility and export -------------------------------------------
   Reduced motion still gets the content, just without the travel. The export
   class forces every reveal to its settled state so a PDF captured mid-reveal
   cannot come out half-drawn.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    [data-reveal] {
        opacity: 1;
        transform: none;
        transition: opacity 200ms ease;
    }
    .decline-chart .chart-line { stroke-dashoffset: 0; transition: none; }
    .decline-chart .chart-area,
    .decline-chart .chart-dot { opacity: 1; transition: none; }
    .fund-bar-block[data-reveal] .fund-bar-have,
    .fund-bar-block[data-reveal].is-revealed .fund-bar-have { transform: scaleX(1); transition: none; }
}

.is-exporting [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
.is-exporting .decline-chart .chart-line { stroke-dashoffset: 0 !important; transition: none !important; }
.is-exporting .decline-chart .chart-area,
.is-exporting .decline-chart .chart-dot { opacity: 1 !important; transition: none !important; }
.is-exporting .fund-bar-have { transform: scaleX(1) !important; transition: none !important; }

@media (prefers-reduced-transparency: reduce) {
    .decline-card,
    .decline-card.is-caution { background: var(--surface); }
    .decline-hero, .decline-tile { background: var(--surface); }
}

@media (prefers-contrast: more) {
    .decline-card { border-color: var(--danger); background: var(--surface); }
    .decline-card.is-caution { border-color: #b3660c; background: var(--surface); }
    .decline-hero { border-color: var(--danger); background: var(--surface); }
    .decline-hero-value { color: var(--ink); }
}

/* ==========================================================================
   Press feedback
   Feedback belongs on the press, not the release. Before this the whole app
   had exactly one :active rule, so every button, tile and row felt dead under
   the finger until it had already done something. Each control now gives way
   the instant it is pressed, and the press transition is deliberately faster
   than the hover one -- going down should feel immediate, coming back up can
   settle.
   ========================================================================== */

.btn:active,
.icon-button:active,
.action-tile:active,
.row-action:active,
.header-link:active,
.choice:active,
.accordion > summary:active,
.brand-mark:active {
    transition-duration: 90ms;
}

/* Scale rather than translate: it reads as the surface taking the pressure
   wherever the control sits, and does not fight the -1px hover lift. */
.btn:active { transform: scale(0.972); }
.icon-button:active { transform: scale(0.94); }
.action-tile:active { transform: scale(0.992); }
.choice:active { transform: scale(0.99); }
.header-link:active,
.brand-mark:active { transform: scale(0.96); }
.row-action:active { transform: scale(0.9); }
.accordion > summary:active { transform: scale(0.995); }

/* Controls that had no transition at all cannot animate a press, so give them
   one. Kept to transform and background, both compositor-friendly. */
.action-tile,
.choice,
.header-link,
.brand-mark,
.row-action,
.accordion > summary {
    transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Removes the tap-highlight flash and the ~300ms synthetic click delay, both
   of which sit directly on the input path. */
.btn,
.icon-button,
.action-tile,
.choice,
.header-link,
.brand-mark,
.row-action,
.accordion > summary,
.brand-select {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

/* A press is a pointer state, not a preference about motion -- removing it
   entirely would leave the control feeling broken rather than calm. Reduced
   motion keeps the confirmation and drops the travel. */
@media (prefers-reduced-motion: reduce) {
    .btn:active,
    .icon-button:active,
    .action-tile:active,
    .row-action:active,
    .header-link:active,
    .choice:active,
    .accordion > summary:active,
    .brand-mark:active {
        transform: none;
        filter: brightness(0.96);
    }
}

/* ==========================================================================
   Display preferences
   Reduced motion already had a global reset. Transparency and contrast were
   handled nowhere in the app, so a reader who had asked for either got the
   same frosted, low-contrast surfaces as everyone else.
   ========================================================================== */

/* Someone who turns transparency down is usually telling you the blur makes
   text harder to read. Solidify the surfaces and drop the blur entirely --
   a lighter blur is still a blur. */
@media (prefers-reduced-transparency: reduce) {
    .site-header .bar,
    .site-header.is-scrolled .bar {
        background: var(--surface);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    .landing-login {
        background: var(--surface);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border-color: var(--line);
    }

    /* The dotted working surface and the drifting colour band behind the app
       are decoration; at this setting they are just noise behind text. */
    .app-backdrop { background-image: none; }
    .app-backdrop .landing-streaks { display: none; }
}

/* More contrast means defined edges and darker ink, not just bolder text.
   Shadows stop doing the separating and borders take over, because a shadow
   is a low-contrast cue by definition. */
@media (prefers-contrast: more) {
    :root {
        --ink-muted: #4b5160;
        --ink-soft: #23262e;
        --line: #9aa0ad;
    }

    .card,
    .kpi-tile,
    .decline-tile,
    .action-tile,
    .auth-card,
    .landing-login {
        border: 1px solid var(--line);
        box-shadow: none;
    }

    .site-header .bar,
    .site-header.is-scrolled .bar {
        background: var(--surface);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border-color: var(--ink-soft);
        box-shadow: none;
    }

    .control,
    .brand-select {
        border-color: var(--ink-soft);
    }

    .btn-secondary { border-color: var(--ink-soft); }

    /* A hairline focus ring is the first thing to disappear at this setting,
       and it is the one people navigating by keyboard depend on. */
    :focus-visible {
        outline: 3px solid var(--ink);
        outline-offset: 2px;
    }

    .muted, .kpi-sub, .field-hint, .field-hint-block, .section-note { color: var(--ink-soft); }

    /* Clipped-to-text gradients lose contrast against the page; the same
       fallback the PDF export already uses works here. */
    .text-gradient {
        background: none;
        color: var(--ink);
        -webkit-text-fill-color: var(--ink);
    }
}

/* --- Confirmation dialog -------------------------------------------------
   A modal task, so it pairs the surface with a dimming scrim and pushes the
   page back -- the opposite of the header, which stays translucent precisely
   because it must not block the flow.
   ------------------------------------------------------------------------ */

.confirm-dialog {
    width: min(30rem, calc(100vw - 2rem));
    padding: 26px 28px 24px;
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    box-shadow: 0 2px 8px rgba(16, 24, 40, 0.08), 0 32px 64px -20px rgba(16, 24, 40, 0.40);
    color: var(--ink);
}

.confirm-dialog::backdrop {
    background: rgba(16, 18, 24, 0.45);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
}

/* The panel arrives as a material -- scale and blur together -- rather than
   fading in flat. Entry only: dismissal is immediate, because a confirmation
   the user has rejected should get out of the way at once. */
.confirm-dialog[open] { animation: dialog-in 0.24s cubic-bezier(0.22, 0.61, 0.36, 1); }
.confirm-dialog[open]::backdrop { animation: backdrop-in 0.24s ease-out; }

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

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

@media (prefers-reduced-motion: reduce) {
    .confirm-dialog[open], .confirm-dialog[open]::backdrop { animation: none; }
}

@media (prefers-reduced-transparency: reduce) {
    .confirm-dialog::backdrop { background: rgba(16, 18, 24, 0.72); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* A button that reads as a link, for actions sitting inside a sentence. */
.link-button {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* --- Vibrancy on the translucent sign-in card ----------------------------
   Flat grey text sitting on a blurred surface loses contrast as whatever is
   behind it shifts -- and behind this card is a moving colour ramp, so it
   shifts constantly. Text over the material gets darker ink, a touch more
   weight and a small tracking bump; the colour that carries meaning stays on
   the solid controls rather than the translucent foreground.
   ------------------------------------------------------------------------ */

.landing-login .auth-sub {
    color: var(--ink-soft);
    letter-spacing: 0.004em;
}

.landing-login .field-label {
    color: var(--ink);
    font-weight: 600;
    letter-spacing: 0.008em;
}

.landing-login .auth-footer,
.landing-login .remember-label {
    color: var(--ink-soft);
    letter-spacing: 0.004em;
}

/* The inputs are a solid layer on top of the material rather than more glass:
   stacking one translucent surface on another is where legibility collapses. */
.landing-login .control {
    background: var(--surface);
}

/* ==========================================================================
   Home — the two routes
   These two cards are the whole point of the page, so they carry more weight
   than the archive and the explainer below them. Each one leads with an icon
   and closes with what you need to bring, because that is the actual decision
   being made here: do you have a budget, or do you have a target.
   ========================================================================== */

.intro-brand { font-weight: 700; color: var(--ink-soft); }

.tile-grid { gap: 20px; }

a.action-tile {
    position: relative;
    gap: 12px;
    padding: 24px 26px 22px;
    overflow: hidden;
}

/* A wash in the route's own colour, so the two are told apart before a word
   is read. It stays faint -- this is identity, not decoration. */
a.action-tile::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(150deg, var(--tile-tint) 0%, transparent 62%);
    opacity: 0.85;
    pointer-events: none;
    transition: opacity 0.18s ease;
}

a.action-tile > * { position: relative; }

a.action-tile.is-route-1 { --tile-ink: var(--accent); --tile-tint: rgba(44, 117, 124, 0.07); }
a.action-tile.is-route-2 { --tile-ink: var(--potent-purple); --tile-tint: rgba(91, 63, 176, 0.07); }

a.action-tile:hover { border-color: color-mix(in srgb, var(--tile-ink) 45%, transparent); }
a.action-tile:hover::before { opacity: 1; }

.tile-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.tile-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 12px;
    color: var(--tile-ink);
    background: color-mix(in srgb, var(--tile-ink) 11%, transparent);
    flex: 0 0 auto;
}

/* The route number is still the product's language, so it stays -- but as a
   marker beside the icon rather than the first thing read. */
.action-tile .tile-tag {
    align-self: center;
    color: var(--tile-ink);
    background: color-mix(in srgb, var(--tile-ink) 10%, transparent);
    font-size: 0.6875rem;
}

.action-tile .tile-title {
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -0.012em;
    line-height: 1.32;
}

.action-tile .tile-desc { font-size: 0.84375rem; letter-spacing: 0.002em; }

.tile-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 4px;
    padding-top: 14px;
    border-top: 1px solid var(--line-soft);
}

.tile-start { font-size: 0.8125rem; color: var(--ink-muted); letter-spacing: 0.004em; }
.tile-start strong { font-weight: 700; color: var(--tile-ink); }

.action-tile .tile-arrow {
    background-color: color-mix(in srgb, var(--tile-ink) 10%, transparent);
    border-color: transparent;
}

/* --- Empty state --------------------------------------------------------- */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 4px 30px 28px;
}

.empty-state-title { font-size: 0.9375rem; font-weight: 700; color: var(--ink); }
.empty-state .btn { margin-top: 8px; }

/* color-mix is well supported, but a browser without it would render the
   tints as nothing at all, so fall back to the flat surface. */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
    .tile-icon, .action-tile .tile-tag, .action-tile .tile-arrow { background: #f4f4f8; }
}

/* --- Header on small screens ---------------------------------------------
   The bar's contents ran to 455px inside a 351px pill on a phone, so the
   brand selector was being cut off the right-hand edge. The wordmark is the
   least useful thing there -- the logo already identifies the product, and
   the brand you are planning for is the control people actually need.
   ------------------------------------------------------------------------ */

@media (max-width: 480px) {
    .site-header .bar { padding: 8px 8px 8px 12px; gap: 8px; }
    .brand-name { display: none; }
    .header-controls { gap: 6px; }
    .header-link { padding: 6px 10px; }
    .brand-select { max-width: 118px; }
}

/* --- Results list on a phone ---------------------------------------------
   Below this width the row stops pretending to be a table. Five columns left
   the name column about 59px wide, so every calculation showed as "PR..." --
   the one piece of information that tells them apart. Name takes a line of
   its own, and the figure sits with the row's actions underneath it.
   ------------------------------------------------------------------------ */

@media (max-width: 560px) {
    .result-grid-cols {
        grid-template-columns: minmax(0, 1fr) 28px 28px 18px;
        grid-template-areas:
            "name  name name name"
            "value open del  chev";
        row-gap: 4px;
    }

    details.result-item .r-name {
        grid-area: name;
        white-space: normal;
        overflow: visible;
        line-height: 1.35;
    }

    details.result-item .r-headline { grid-area: value; text-align: left; }
    details.result-item > summary .row-open { grid-area: open; }
    details.result-item > summary button.row-action { grid-area: del; }
    details.result-item > summary .chev { grid-area: chev; }
}

/* --- Text over the colour band -------------------------------------------
   The page intro sits on the ramp, not on the working surface. Muted grey
   measured 3.5:1 against that wash -- under the 4.5:1 needed for body text --
   so intro copy steps up a tone. Same principle as the sign-in card: text on
   a coloured material needs more contrast, not the same as text on white.
   ------------------------------------------------------------------------ */

.page-intro p,
.page-intro .muted { color: var(--ink-soft); }

.page-intro .crumbs a { color: var(--ink-soft); }
.page-intro .crumbs .current { color: var(--ink); }
