/* SciBloom prototype — design system lifted from web/style.css so the
   prototype reads as the same product: DM Sans body, Source Serif 4 display,
   orange gradient CTAs, warm background, the shared form + button classes. */

@font-face {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/dmsans-latin.woff2') format('woff2');
}

@font-face {
    font-family: 'Source Serif 4';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/static/fonts/sourceserif4-700-latin.woff2') format('woff2');
}

@font-face {
    font-family: 'Source Serif 4';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/sourceserif4-400italic-latin.woff2') format('woff2');
}

:root {
    --orange-50: #fff7ed;
    --orange-100: #ffedd5;
    --orange-200: #fed7aa;
    --orange-300: #fdba74;
    --orange-400: #fb923c;
    --orange-500: #f97316;
    --orange-600: #ea580c;
    --orange-700: #c2410c;
    --warm-50: #fffbf5;
    --warm-100: #fef7ec;
    --warm-200: #fdf0dc;
    --warm-300: #f1e6d6;
    --slate-200: #e2e8f0;
    --slate-500: #64748b;
    --slate-600: #475569;
    --slate-700: #334155;
    --slate-800: #1e293b;
    --slate-900: #0f172a;
    --lime-300: #bef264;
    --lime-400: #a3e635;

    --font-display: 'Source Serif 4', Georgia, serif;
    --font-body: 'DM Sans', system-ui, sans-serif;

    --section-pad-x: clamp(1.25rem, 4vw, 2.5rem);
    --shadow-soft: 0 10px 40px rgba(15, 23, 42, 0.06);
    --shadow-card: 0 20px 60px rgba(15, 23, 42, 0.08);
}

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

body {
    font-family: var(--font-body);
    background: var(--warm-50);
    color: var(--slate-900);
    line-height: 1.6;
    min-height: 100vh;
    overflow-x: hidden;
}

a {
    color: var(--orange-600);
}

/* Drifting blob backdrop — same as the marketing site, dialled softer */
.blobs {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
}

.blob {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.45;
}

.blob-1 {
    width: 560px;
    height: 560px;
    background: linear-gradient(135deg, var(--orange-200), var(--orange-100));
    top: -240px;
    right: -160px;
}

.blob-2 {
    width: 380px;
    height: 380px;
    background: linear-gradient(135deg, var(--lime-300), var(--lime-400));
    bottom: -140px;
    left: -120px;
    opacity: 0.25;
}

/* Brand bar */
/* WRAPS RATHER THAN OVERFLOWS, and the reason is Log out (SCI-108 PR2).
   base.html.j2 states the invariant this protects: logout must be reachable on
   EVERY logged-in screen, because researchers on shared lab machines sign out
   mid-assessment.

   This was a `space-between` row with no wrap and no responsive rule at any
   breakpoint, so it simply ran off the edge. Measured at 375px: four nav items
   overflowed by 22px, and adding "Compare" as the fifth took that to 108px —
   putting Log out entirely off-screen at x458 in a 375px viewport, and
   `body { overflow-x: hidden }` means it could not even be scrolled to.

   Deliberately NOT inside a media query. `flex-wrap` engages only when the
   content does not fit, so wide viewports are byte-identical to before and
   there is no breakpoint to pick — and, unlike a tuned font size or gap, it
   cannot be broken again by the SIXTH nav item.

   STAYS ON SCREEN WHILE SCROLLING (SCI-181). Patricia's "but then you are
   out" (28 August) and Nour's "I would have stopped here" (10 September) are
   both symptoms of the same dead end: SCI-150's done-when ("No screen in the
   signed-in app is terminal") passes on paper, because every page has the nav
   at the top, but it fails in use, because nobody reads to the bottom of a
   long page and then scrolls back up. `position: sticky` keeps the bar, and
   Log out with it, reachable from wherever the reader stops.

   `z-index: 2` is unchanged: already above `<main>` (1) and below the
   coach/learn pop-up scrim (50), so an open pop-up still covers the bar
   rather than a pinned bar covering the pop-up. The background stops page
   text showing through sharply as it scrolls under a pinned, translucent bar;
   the hairline border is the same line the footer draws on its own top edge. */
.brand-bar {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    /* Row gap so a wrapped nav does not sit flush against the wordmark. */
    gap: 0.75rem 1rem;
    padding-block: 1.5rem;
    /* Full-width bar, same 1100px content column as before (SCI-181 Decision
       1): a pinned 1100px box centred on a wide screen would leave page text
       visibly scrolling past on both sides of it. Grows the side padding
       instead of centring a fixed-width box, so the logo and nav sit exactly
       where they did at every width already in use. */
    padding-inline: max(var(--section-pad-x), calc((100% - 1100px) / 2 + var(--section-pad-x)));
    background: rgba(255, 251, 245, 0.88);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--warm-300);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--slate-900);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    letter-spacing: -0.01em;
}

.brand-mark {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
}

.brand-word .highlight {
    color: var(--orange-500);
    font-style: italic;
}

/* Centred column for the auth + flow screens */
main {
    position: relative;
    z-index: 1;
    max-width: 480px;
    margin: 0 auto;
    padding: clamp(1.5rem, 5vw, 3rem) var(--section-pad-x) 4rem;
}

main.wide {
    /* Wider flow column (SCI-64): more horizontal room means the long quiz
       options wrap to fewer lines, buying vertical headroom so the tallest
       questions fit a 13" laptop (1280x800) without scrolling. max-width only,
       so narrow/mobile viewports are unaffected. */
    max-width: 720px;
    /* Trim the top/bottom chrome on flow screens so the Continue button clears
       the fold on the tallest questions (auth screens keep the base padding). */
    padding-top: 1.25rem;
    padding-bottom: 2rem;
}

.card {
    background: white;
    border-radius: 24px;
    padding: clamp(1.75rem, 4vw, 2.5rem);
    border: 1px solid var(--slate-200);
    border-left: 4px solid var(--orange-500);
    box-shadow: var(--shadow-card);
}

/* Tighter vertical padding on the flow screens only (SCI-64 13" fit); the
   auth screens (default `main`) keep the roomier base padding. */
main.wide .card {
    padding: clamp(1.4rem, 3vw, 2rem);
}

.page-title {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--slate-900);
    line-height: 1.25;
    letter-spacing: -0.01em;
    font-size: clamp(1.5rem, 3.2vw, 2rem);
}

/* Smaller question headline on flow screens (SCI-64): the quiz prompts are
   full sentences, not short titles, so a calmer size keeps the long ones from
   reading as a wall of display type while short ones still lead clearly. */
main.wide .page-title {
    font-size: clamp(1.2rem, 2.2vw, 1.5rem);
    line-height: 1.3;
}

.page-title .highlight {
    color: var(--orange-500);
    font-style: italic;
    font-weight: 400;
}

.page-intro {
    color: var(--slate-700);
    font-size: 1rem;
    line-height: 1.65;
    margin-top: 0.85rem;
}

.prose {
    color: var(--slate-700);
    line-height: 1.7;
}

.prose p { margin-top: 1rem; }
.prose h2 {
    font-family: var(--font-display);
    color: var(--slate-900);
    font-size: 1.15rem;
    margin-top: 1.5rem;
}

/* Primary button — pill, orange gradient (web/style.css .btn-primary) */
.btn-primary {
    display: inline-block;
    padding: 0.95rem 2.1rem;
    background: linear-gradient(135deg, var(--orange-500), var(--orange-600));
    border: none;
    border-radius: 999px;
    color: white;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    box-shadow: 0 6px 20px rgba(249, 115, 22, 0.32);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.btn-primary:hover,
.btn-primary:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 10px 28px rgba(249, 115, 22, 0.42);
}

.btn-primary:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* Quiet secondary action (logout) */
.btn-text {
    display: inline-block;
    background: none;
    border: none;
    padding: 0;
    color: var(--slate-600);
    font-family: var(--font-body);
    font-size: 0.95rem;
    text-decoration: underline;
    cursor: pointer;
}

.btn-text:hover { color: var(--orange-600); }

/* Signed-in nav slot in the brand bar (SCI-73 PR 2 added the Careers link
   beside the logout form). */
/* Wraps for the same reason as `.brand-bar` above, and it is the second half of
   the same guarantee: the bar wrapping puts the nav on its own line, and this
   is what saves the nav when that line is itself too narrow — a 320px phone, or
   a future sixth item. Without both, Log out can still be pushed off the edge. */
.brand-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1.25rem;
}

/* Jump targets (for example /compare's #learning-paths, and the career page's
   section anchors) land clear of the pinned bar rather than under it
   (SCI-181 Decision 2). Set once, on the scrolling element, rather than per
   anchor with `scroll-margin-top`: this covers every `#anchor` in the app,
   present and future, from one place. Sized from the bar's measured wide-
   screen height (81px) plus ~15px of breathing room; the media query below
   overrides it under the 56rem breakpoint — it must come AFTER this rule in
   source order, since both selectors are a bare `html` and the cascade
   breaks the tie by position, not by which one is inside a media query.
   Without JavaScript the bar's exact height can't be read at runtime, so
   these are measured, not computed — a future nav item that wraps the bar
   onto another row needs both numbers revisited.

   The base font lives here too (SCI-215): 112.5% of the browser's 16px is
   18px, and nearly every size in this file is rem, so text and spacing scale
   together. Percent, not px, so a reader's own browser setting still counts.
   Column widths are px and do not grow. 112.5% rather than 125%, because
   125% inside the fixed 720px column would make /compare and the career page
   cramped and much longer; the landing page (web/style.css) is not
   affected. Kept in this rule, not a second `html {}`: the scroll-padding
   test reads the first one. Both scroll-padding offsets are rem, so they grow
   with the bar they clear. */
html {
    font-size: 112.5%;
    scroll-padding-top: 6rem;
}

/* Slimmer bar on phones and tablets (SCI-181): less padding so the now-sticky
   bar takes less of a small screen. Longhands, not a `padding` shorthand — a
   shorthand here would reset the side padding Decision 1 sets above. The nav
   itself (links, gaps between them) is untouched, so a thumb has as much room
   around Log out as it does today. Measured at review: 120px from 320 to
   375px wide, where the nav wraps to its own row. At the 18px base
   (SCI-215) it is 133px from 364px up, and up to 363px the nav wraps a
   third row (171px) — the narrow query after this one covers that. */
@media (max-width: 56rem) {
    .brand-bar {
        padding-top: 0.7rem;
        padding-bottom: 0.7rem;
        gap: 0.35rem 1rem;
    }

    html {
        /* A taller offset for the taller two-row bar at this width (Decision
           2): 120px measured + ~15px breathing room. Must come after the
           base `html` rule above — equal specificity means source order
           decides, and this needs to win under the breakpoint. */
        scroll-padding-top: 8.5rem;
    }
}

/* The narrowest phones (SCI-215 review). At the 18px base the nav wraps onto
   a third row up to 363px wide (iPhone SE 1st gen, Galaxy Fold, and 360px
   Androids): the bar measured 171px at 320–363px, past the 153px the query
   above leaves, so jump targets landed partly under it. 10.5rem is 189px:
   171px + ~15px of air. The query reaches 368px, a few pixels past the
   measured wrap, so font rendering that differs slightly cannot reopen the
   gap; 364–368px pays ~56px of extra air, and 375px keeps 153px. After the
   56rem query on purpose — both are a bare `html` nested in a media query,
   so source order decides and this one must win here. Media query rem is
   the browser's 16px, not the root font, so 23rem is 368px. */
@media (max-width: 23rem) {
    html {
        scroll-padding-top: 10.5rem;
    }
}

/* Form controls — from web/style.css */
.form {
    margin-top: 1.75rem;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

.form-label {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--slate-600);
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.form-field input {
    width: 100%;
    padding: 0.95rem 1.1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--slate-900);
    transition: border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
}

.form-field input::placeholder { color: var(--slate-500); }

/* Background page 4 (SCI-226) has the app's first dropdowns, drawn like the
   text inputs above. The native arrow is kept: no `appearance: none`, so
   nothing has to redraw it. */
.form-field select {
    width: 100%;
    padding: 0.85rem 1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--slate-900);
}

.form-field select:focus {
    outline: none;
    border-color: var(--orange-400);
    background: white;
    box-shadow: 0 0 0 4px rgba(249, 115, 22, 0.12);
}

/* "(optional)" after a label: the label's case and weight, undone. Same as
   the public site's web/style.css. */
.form-optional {
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--slate-500);
}

.form-field input:focus {
    outline: none;
    border-color: var(--orange-400);
    background: white;
    box-shadow: 0 0 0 4px rgba(249, 115, 22, 0.12);
}

.form-check {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.55rem 0;
    margin-bottom: 1.5rem;
    color: var(--slate-700);
    font-size: 0.97rem;
    line-height: 1.5;
    cursor: pointer;
}

.form-check input[type="checkbox"] {
    flex-shrink: 0;
    margin-top: 0.2rem;
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--orange-500);
    cursor: pointer;
}

.form-submit {
    width: 100%;
    margin-top: 0.25rem;
}

/* Inline error banner */
.form-error {
    margin-bottom: 1.25rem;
    padding: 0.85rem 1.1rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 12px;
    color: #b91c1c;
    font-size: 0.92rem;
    line-height: 1.5;
}

/* What to expect, on /signup between the intro and the form (SCI-215). Warm
   and quiet: it explains, it is not a call to action. */
.expect-box {
    margin-top: 1.1rem;
    padding: 0.9rem 1.1rem;
    background: var(--orange-100);
    border-radius: 14px;
}

.expect-heading {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--orange-700);
}

.expect-body {
    margin-top: 0.3rem;
    font-size: 0.92rem;
    line-height: 1.55;
    color: var(--slate-700);
}

.form-alt {
    margin-top: 1.5rem;
    font-size: 0.95rem;
    color: var(--slate-600);
    text-align: center;
}

.form-alt a {
    color: var(--orange-600);
    font-weight: 600;
    text-decoration: none;
}

.form-alt a:hover { text-decoration: underline; }

.muted {
    color: var(--slate-500);
    font-size: 0.85rem;
    line-height: 1.6;
    margin-top: 1.25rem;
}

/* Assessment flow (Part 2) — one question per screen */
.progress {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--orange-600);
    margin-bottom: 0.5rem;
}

/* Section intro (SCI-64) — one-line lead on the first question of a section. */
.section-intro {
    color: var(--slate-500);
    font-style: italic;
    font-size: 0.95rem;
    line-height: 1.5;
    margin-bottom: 0.75rem;
}

.options {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 1rem;
}

.option {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
    padding: 0.7rem 1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    color: var(--slate-700);
    line-height: 1.5;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.option:hover { border-color: var(--orange-300); }

.option input[type="radio"] {
    flex-shrink: 0;
    margin-top: 0.25rem;
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--orange-500);
    cursor: pointer;
}

.option:has(input:checked) {
    border-color: var(--orange-500);
    background: white;
    box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.1);
}

.form-field textarea {
    width: 100%;
    padding: 0.95rem 1.1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--slate-900);
    resize: vertical;
    transition: border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
}

.form-field textarea:focus {
    outline: none;
    border-color: var(--orange-400);
    background: white;
    box-shadow: 0 0 0 4px rgba(249, 115, 22, 0.12);
}

/* Follow-up block revealed by a radio choice. Hidden by default; each phase1
   page emits per-choice :has() rules that display the matching block when its
   radio is checked — CSS only, works without JavaScript. */
.reveal {
    display: none;
    margin-top: 1.25rem;
    padding: 1rem 1.1rem;
    background: var(--warm-100);
    border-left: 3px solid var(--orange-300);
    border-radius: 0 12px 12px 0;
}

.reveal .options { margin-top: 0.75rem; }
.reveal .form-label { margin-top: 0.5rem; }

.q-hint {
    color: var(--slate-500);
    font-style: italic;
    font-size: 0.9rem;
    margin-top: 0.6rem;
}

.flow-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-top: 1.15rem;
}

/* Keep the Continue action visible on the longest questions (SCI-64): on the
   flow screens the nav sticks to the bottom of the viewport while a tall
   question scrolls, then settles at its natural place at the end of the card.
   The white background + upward glow cover the option text scrolling beneath. */
main.wide .flow-nav {
    position: sticky;
    bottom: 0;
    background: white;
    padding-top: 0.85rem;
    padding-bottom: 0.4rem;
    box-shadow: 0 -16px 16px -8px white;
}

/* Phase indicator (SCI-64) — persistent three-step, effort-weighted bar above
   the card on every flow screen. Segment widths are the weights (flex); no
   numeric percentage is shown. */
.phase-indicator {
    display: flex;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.phase-step {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.phase-step-bar {
    height: 6px;
    border-radius: 999px;
    background: var(--slate-200);
}

.phase-step-label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--slate-500);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.phase-step.is-done .phase-step-bar {
    background: var(--orange-500);
}

.phase-step.is-current .phase-step-bar {
    background: linear-gradient(90deg, var(--orange-500), var(--orange-300));
}

.phase-step.is-done .phase-step-label,
.phase-step.is-current .phase-step-label {
    color: var(--slate-700);
}

/* Checkpoint snapshot (post-quiz results overview) */
.snapshot {
    list-style: none;
    margin-top: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.snapshot-row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 0.75rem;
    padding: 0.75rem 1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 12px;
}

.snapshot-cat {
    font-weight: 600;
    color: var(--slate-800);
    flex: 1 1 14rem;
}

.snapshot-levels {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.chip {
    font-size: 0.8rem;
    color: var(--slate-600);
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 999px;
    padding: 0.15rem 0.7rem;
    white-space: nowrap;
}

/* Results ending recap (SCI-64) — what was collected, one honest line each. */
.recap {
    list-style: none;
    margin: 1rem 0 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.recap-row {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    padding: 0.6rem 1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 12px;
    color: var(--slate-700);
}

.recap-row::before {
    content: "\2713";
    color: var(--orange-500);
    font-weight: 700;
}

/* Welcome / orientation (SCI-64) — the journey in three numbered steps */
.journey-steps {
    list-style: none;
    margin: 1.5rem 0;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.journey-step {
    display: flex;
    align-items: flex-start;
    gap: 0.85rem;
}

.journey-step-num {
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 999px;
    background: var(--orange-100);
    color: var(--orange-700);
    font-weight: 700;
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.journey-step-body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
}

.journey-step-label {
    font-weight: 700;
    color: var(--slate-800);
}

.journey-step-desc {
    color: var(--slate-600);
    font-size: 0.95rem;
    line-height: 1.5;
}

/* Phase 3b — CV upload + project descriptions */
.phase3b-section {
    margin-top: 2rem;
    padding-top: 1.75rem;
    border-top: 1px solid var(--slate-200);
}

.phase3b-heading {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--slate-900);
    font-size: 1.25rem;
    margin-bottom: 0.5rem;
}

.input-status {
    margin: 0.85rem 0;
    padding: 0.7rem 1rem;
    background: #ecfdf5;
    border: 1px solid #a7f3d0;
    border-radius: 12px;
    color: #047857;
    font-size: 0.92rem;
    line-height: 1.5;
}

.form-field input[type="file"] {
    width: 100%;
    padding: 0.7rem;
    background: var(--warm-50);
    border: 1px dashed var(--slate-200);
    border-radius: 14px;
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--slate-700);
}

.phase3b-finish {
    margin-top: 2.25rem;
}

/* CV status indicator — distinct icon + colour + text per state. */
.cv-indicator {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 1rem 0;
    padding: 0.75rem 1rem;
    border: 1px solid;
    border-radius: 12px;
    font-size: 0.92rem;
    line-height: 1.5;
}

.cv-indicator-icon {
    flex-shrink: 0;
    font-weight: 700;
    font-size: 1.05rem;
    line-height: 1;
}

#cv-section[data-state="empty"] .cv-indicator {
    background: #eff6ff;
    border-color: #bfdbfe;
    color: #1d4ed8;
}
#cv-section[data-state="empty"] .cv-indicator-icon::before { content: "\2191"; }  /* ↑ */

#cv-section[data-state="loaded"] .cv-indicator {
    background: #ecfdf5;
    border-color: #a7f3d0;
    color: #047857;
}
#cv-section[data-state="loaded"] .cv-indicator-icon::before { content: "\2713"; }  /* ✓ */

#cv-section[data-state="error"] .cv-indicator {
    background: #fef2f2;
    border-color: #fecaca;
    color: #b91c1c;
}
#cv-section[data-state="error"] .cv-indicator-icon::before { content: "\2717"; }  /* ✗ */

/* CV upload pop-up (SCI-98) — the page offers a centred button; the dialog holds
   the drop area and the extract action. */

/* The `hidden` attribute must win inside this section: the buttons and rows below
   carry classes that set `display` themselves (.btn-primary, .btn-text,
   .cv-replace-field), and an author display value beats the browser's rule for
   [hidden] — leaving JS-only controls on screen. */
#cv-section [hidden] {
    display: none;
}

.cv-upload-trigger {
    display: flex;
    justify-content: center;
    margin: 0.5rem 0 1.25rem;
}

/* Two positioning cases. The browser's own stylesheet gives `dialog`
   position: absolute, so the server-rendered `open` dialog (the no-JS path) must
   be pinned back into the page flow; only the JS-opened :modal case floats. */
/* No `display` here on purpose: any author display value would override the
   browser's `dialog:not([open]) { display: none }` and leave the closed pop-up on
   screen. An open dialog is display: block by default anyway. */
.cv-modal {
    position: static;
    width: auto;
    max-width: none;
    margin: 0 0 1.25rem;
    padding: 1.25rem;
    border: 1px solid var(--slate-200);
    border-radius: 18px;
    background: white;
    color: inherit;
}
.cv-modal:modal {
    position: fixed;
    width: min(34rem, calc(100vw - 2rem));
    max-width: 34rem;
    margin: auto;
    padding: clamp(1.25rem, 3vw, 1.75rem);
    border-radius: 24px;
    box-shadow: var(--shadow-card);
}
.cv-modal::backdrop {
    background: rgba(15, 23, 42, 0.45);
}

.cv-modal-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}
.cv-modal-heading {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--slate-900);
    margin: 0;
}
.cv-modal-close {
    flex-shrink: 0;
    background: none;
    border: none;
    padding: 0 0.25rem;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--slate-500);
    cursor: pointer;
}
.cv-modal-replace-note {
    margin: 0.5rem 0 0;
    font-size: 0.9rem;
    color: var(--slate-600);
}

/* Dotted drop target, with a highlight while a file is dragged over it
   (toggled by phase3b.js). */
.cv-dropzone {
    margin: 1rem 0;
    padding: 1.75rem 1.1rem;
    border: 2px dashed var(--slate-200);
    border-radius: 14px;
    background: var(--warm-50);
    text-align: center;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.cv-dropzone.dragover {
    border-color: var(--orange-600);
    background: #fff7ed;
}
.cv-drop-heading {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--slate-900);
}
.cv-drop-hint {
    margin: 0.35rem 0 0.9rem;
    font-size: 0.88rem;
    color: var(--slate-500);
}
.cv-browse-label {
    display: inline-block;
    margin-bottom: 0.75rem;
    color: var(--orange-600);
    font-weight: 600;
    font-size: 0.95rem;
    text-decoration: underline;
    cursor: pointer;
}
.cv-dropzone input[type="file"] {
    display: block;
    width: 100%;
    color: var(--slate-700);
    font-size: 0.9rem;
}
/* JS on: "or browse…" is the affordance, so the native control is hidden — but
   visually, not with display:none, which would drop it out of the tab order and
   can stop its label from opening the picker. Without JS it stays visible. */
.cv-dropzone input[type="file"].cv-file-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.cv-modal-file {
    margin: 0.75rem 0 0;
    font-size: 0.92rem;
    color: var(--slate-700);
}
.cv-modal-error {
    margin: 0.75rem 0 0;
    padding: 0.7rem 0.9rem;
    background: #fef2f2;
    border: 1px solid #fecaca;
    border-radius: 12px;
    color: #b91c1c;
    font-size: 0.9rem;
    line-height: 1.5;
}
.cv-modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1.25rem;
    margin-top: 1.25rem;
}
/* "Extract text" is disabled until a file is chosen, so it has to look it —
   scoped to this section, since nothing else in the app styles :disabled. */
#cv-section .btn-primary:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
.cv-replace-field {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.85rem 0;
    font-size: 0.9rem;
    color: var(--slate-700);
}

/* Roomy, auto-growing text fields — no fixed height, no overflow clipping. */
textarea.grow {
    min-height: 9.5rem;
    overflow: hidden;
    line-height: 1.6;
}

.save-hint {
    min-height: 1.2em;
    margin: -0.75rem 0 0.75rem;
    font-size: 0.85rem;
    color: var(--slate-500);
}
.save-hint.saved { color: #047857; }
.save-hint.saved::before { content: "\2713 "; }
.save-hint.error { color: #b91c1c; }

.char-count {
    margin: -0.6rem 0 0.75rem;
    font-size: 0.82rem;
    color: var(--slate-500);
    text-align: right;
}
.char-count.char-count-warning { color: #b45309; }

.cv-skipped-note,
.projects-skipped-note {
    margin-top: 0.5rem;
    color: var(--slate-600);
    font-size: 0.95rem;
}
.cv-skipped-note a,
.projects-skipped-note a { color: var(--orange-600); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
    .btn-primary { transition: none; }
}

/* Skills profile (SCI-42) ------------------------------------------------------ */

.skill-group {
    margin-top: 1.75rem;
}

.cat-header {
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--slate-600);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.cat-count {
    color: var(--slate-500);
    font-weight: 500;
}

.skill-card {
    border: 1px solid var(--slate-200);
    border-radius: 12px;
    padding: 0.9rem 1.1rem;
    margin-top: 0.75rem;
    background: white;
}

/* Low-confidence skills carry a highlighted edge + the "we inferred this"
   prompt — visually marked, per the Engineer Brief. */
.skill-card.low-confidence {
    border-left: 3px solid var(--orange-400);
}

.skill-name {
    font-weight: 500;
}

.level-row {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin-top: 0.45rem;
}

.level-bar {
    display: inline-flex;
    gap: 0.25rem;
}

.level-seg {
    width: 26px;
    height: 7px;
    border-radius: 999px;
    background: var(--slate-200);
}

.level-seg.filled {
    background: var(--orange-500);
}

.level-label {
    font-size: 0.9rem;
    color: var(--slate-600);
}

.source-tags {
    margin-top: 0.55rem;
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.inferred-note {
    margin-top: 0.55rem;
    font-size: 0.9rem;
    font-style: italic;
    color: var(--slate-600);
}

/* Radar overview on the profile (browser-checkpoint request) ------------------- */

.skill-radar {
    margin: 1.25rem auto 0.25rem;
}

.skill-radar svg {
    display: block;
    width: 100%;
    max-width: 620px;
    height: auto;
    margin: 0 auto;
}

.radar-ring {
    fill: none;
    stroke: var(--slate-200);
}

.radar-spoke {
    stroke: var(--slate-200);
}

.radar-value {
    fill: rgba(249, 115, 22, 0.16);   /* orange-500 at low opacity */
    stroke: var(--orange-500);
    stroke-width: 2;
    stroke-linejoin: round;
}

.radar-label {
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
    fill: var(--slate-600);
}

.radar-scale {
    font-family: var(--font-body);
    font-size: 10px;
    fill: var(--slate-500);
}

.radar-caption {
    text-align: center;
    font-size: 0.85rem;
    color: var(--slate-500);
    margin-top: 0.4rem;
}

/* Per-skill feedback control (SCI-42 PR 3) -------------------------------------- */

.feedback-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--slate-200);
}

.feedback-q {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--slate-700);
}

.btn-feedback {
    font: inherit;
    font-size: 0.9rem;
    padding: 0.35rem 0.9rem;
    border: 1px solid var(--slate-200);
    border-radius: 999px;
    background: white;
    color: var(--slate-700);
    cursor: pointer;
}

.btn-feedback:hover {
    border-color: var(--orange-300);
}

.btn-feedback.selected {
    background: var(--orange-100);
    border-color: var(--orange-400);
    color: var(--orange-700);
}

.feedback-state {
    margin-top: 0.5rem;
    font-size: 0.9rem;
    color: var(--slate-600);
}

/* Career library (SCI-73 PR 2) ------------------------------------------------- */

/* The library is a grid, not a single reading column, so it gets more room
   than the flow screens. max-width only — narrow viewports are untouched. */
main.library {
    max-width: 980px;
}

/* Nudge for a signed-in user browsing outside the flow. */
.nudge {
    margin-top: 1.25rem;
    padding: 0.9rem 1.15rem;
    background: var(--orange-50);
    border: 1px solid var(--orange-200);
    border-radius: 14px;
    color: var(--slate-700);
    font-size: 0.95rem;
}

.nudge a {
    font-weight: 600;
    white-space: nowrap;
}

/* Preference controls */
.filters {
    margin-top: 1.75rem;
    padding: 1.25rem clamp(1rem, 3vw, 1.5rem);
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 20px;
    box-shadow: var(--shadow-soft);
}

/* Two controls per row on desktop, stacked below ~520px. auto-fit + minmax
   rather than a breakpoint, matching the fluid approach used elsewhere. */
.filter-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: 1rem 1.5rem;
    margin-top: 1rem;
}

.filter {
    border: none;
}

.filter-label {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--slate-700);
    padding: 0;
}

/* One hint for the whole panel — every control behaves the same way. */
.filter-hint {
    margin-top: 0.35rem;
    color: var(--slate-500);
    font-size: 0.85rem;
}

/* Segmented control: radio/checkbox inputs styled as adjacent stops. The
   inputs stay in the DOM (visually hidden, not display:none) so the control
   remains keyboard-reachable and screen-reader-announced. */
.segmented {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.segment {
    font-size: 0.85rem;
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--slate-200);
    border-radius: 999px;
    background: white;
    color: var(--slate-700);
    cursor: pointer;
}

.segment input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.segment:hover {
    border-color: var(--orange-300);
}

.segment:has(input:checked) {
    background: var(--orange-100);
    border-color: var(--orange-400);
    color: var(--orange-700);
    font-weight: 500;
}

.segment:has(input:focus-visible) {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

.filter-actions {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    margin-top: 1.5rem;
    flex-wrap: wrap;
}

/* Apply is a filter control, not a page CTA — scoped to the library's filter
   panel so the global .btn-primary keeps its full size everywhere else,
   including the preferences page's Continue button (which is deliberately not
   inside a .filters panel). */
.filters .btn-primary {
    padding: 0.55rem 1.25rem;
    font-size: 0.9rem;
    box-shadow: 0 3px 10px rgba(249, 115, 22, 0.22);
}

.filters .btn-primary:hover,
.filters .btn-primary:focus-visible {
    box-shadow: 0 6px 16px rgba(249, 115, 22, 0.3);
}

/* The preferences page stacks the same six controls one per row (SCI-118).
   The library's breathing room comes from .filter-row's grid gap, which a
   plain vertical stack has none of — without this each legend runs into the
   stops above it and six controls read as one dense block. */
.preferences .filter {
    margin-top: 1.35rem;
}

/* Sections you can tell apart (SCI-215; Nour, 2026-09-14): on this page each
   title is a heading, clearly bigger and darker than the 0.85rem stops under
   it, and a thin line separates every section from the next. Scoped to
   `.preferences` so the library's filter panel, which shares these classes,
   keeps its compact labels. `.filter + .filter` is what leaves the first
   section without a line above it.

   The float is what keeps the line ABOVE the title: a fieldset draws its
   <legend> straddling its own top border, so without it the divider would run
   through the middle of every title. A floated legend is laid out in the
   content box like any block; the clear puts the stops back underneath it.
   The clear also swallows the stops' own margin-top (a cleared block starts
   at the float's bottom edge), so the gap lives on the legend instead. */
.preferences .filter-label {
    float: left;
    width: 100%;
    margin-bottom: 0.5rem;
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--slate-900);
}

.preferences .filter-label + * {
    clear: both;
}

.preferences .filter + .filter {
    margin-top: 1.5rem;
    padding-top: 1.35rem;
    border-top: 1px solid var(--slate-200);
}

/* Per-control "What do these mean?" disclosure. <details>, not a JS toggle,
   matching .skill-group on the career detail page.

   In flow and BELOW the stops. The alternative — absolutely positioning the
   open panel so nothing reflows — puts it straight over the stops it is
   explaining, which is worse than the reflow it avoids. Opening here leaves
   every stop of this control exactly where it was and fully visible; the next
   control moves down, which is ordinary disclosure behaviour. */
.filter-help {
    margin-top: 0.5rem;
}

.filter-help-summary {
    display: inline-block;
    font-size: 0.8rem;
    color: var(--slate-500);
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.filter-help-summary::-webkit-details-marker {
    display: none;
}

.filter-help-summary::marker {
    content: "";
}

.filter-help-summary::after {
    content: " ▾";
    text-decoration: none;
}

.filter-help[open] > .filter-help-summary::after {
    content: " ▴";
}

.filter-help-summary:hover {
    color: var(--orange-600);
}

.filter-help-summary:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* white, not --warm-50: that is the token body already paints, so the panel
   would have no fill contrast and only its border to sit on. Every other card
   on this surface (.filters, the .career-* blocks) is white on the warm
   ground. */
.filter-help-body {
    max-width: 34rem;
    margin-top: 0.45rem;
    padding: 0.85rem 1rem;
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 14px;
}

.filter-help-question {
    font-style: italic;
    font-size: 0.85rem;
    color: var(--slate-700);
}

.filter-help-defs {
    margin-top: 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: var(--slate-600);
}

/* Label above its definition, no generated separator. An inline pair needs a
   punctuation mark between the two, and a CSS-drawn one is emitted whether or
   not the definition is there — a stop whose copy is missing then renders as a
   label followed by a dangling mark, which reads as truncated rather than as
   absent. Stacking needs no separator at all. */
.filter-help-def dt {
    font-weight: 600;
    color: var(--slate-700);
}

.filter-help-def dd {
    margin: 0;
}

/* The "tick nothing and you see all N" line, directly above Continue. */
.preferences-note {
    margin-top: 1.5rem;
}

/* Tiles */
.career-group {
    margin-top: 2.25rem;
}

/* Collapsible bucket section. The whole header row is the control, with a
   chevron on the right that turns as the section opens. The browser's own
   triangle is suppressed (two rules — WebKit still needs its pseudo-element
   hidden separately) so the chevron is the only affordance. */
.career-group-summary {
    cursor: pointer;
    list-style: none;
    justify-content: flex-start;
    padding: 0.35rem 0;
    border-bottom: 1px solid var(--slate-200);
}

.career-group-summary::-webkit-details-marker {
    display: none;
}

.career-group-summary:hover .cat-name,
.career-group[open] .career-group-summary:hover .cat-name {
    color: var(--orange-600);
}

.career-group-summary:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* The chevron: a rotated CSS box, so there is no icon file to ship. */
.career-group-summary::after {
    content: "";
    margin-left: auto;
    width: 0.5rem;
    height: 0.5rem;
    border-right: 2px solid var(--slate-500);
    border-bottom: 2px solid var(--slate-500);
    /* Closed: points down (expand). Nudged up so it sits on the text baseline. */
    transform: translateY(-2px) rotate(45deg);
    transition: transform 0.2s ease;
}

.career-group[open] > .career-group-summary::after {
    /* Open: points up (collapse). */
    transform: translateY(2px) rotate(-135deg);
}

@media (prefers-reduced-motion: reduce) {
    .career-group-summary::after { transition: none; }
}

/* Two per line on desktop (the 980px column fits exactly two 24rem tracks),
   one per line as soon as a tile would go under 24rem — which is what gives
   the 320px case a single column with no media query. */
.career-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
    gap: 1rem;
    margin-top: 0.85rem;
}

.career-tile {
    background: white;
    border: 1px solid var(--slate-200);
    border-left: 4px solid var(--orange-500);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    box-shadow: var(--shadow-soft);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.career-title {
    font-family: var(--font-display);
    font-size: 1.05rem;
    line-height: 1.3;
    color: var(--slate-900);
}

.career-title a {
    text-decoration: none;
    color: inherit;
}

.career-title a:hover {
    color: var(--orange-600);
    text-decoration: underline;
}

.career-one-liner {
    font-size: 0.92rem;
    color: var(--slate-600);
    line-height: 1.5;
}

.career-tags {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: auto;
    padding-top: 0.35rem;
}

.tag {
    font-size: 0.78rem;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--warm-100);
    border: 1px solid var(--slate-200);
    color: var(--slate-600);
}

/* "Your choice" badge on the chosen career's tile (SCI-73 PR 3). The existing
   .status-* badges live in the admin-only _admin_style.html.j2 block, which
   user-facing pages never load — this is the same look, in the shared sheet. */
.badge {
    display: inline-block;
    vertical-align: middle;
    margin-left: 0.5rem;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    background: var(--orange-100);
    border: 1px solid var(--orange-400);
    color: var(--orange-700);
    font-family: var(--font-body);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

/* Career detail page (SCI-73 PR 3) --------------------------------------------- */
/* The page uses main.wide: one measured reading column. The library's grid
   width would make these paragraphs too wide to scan, and the auth screens'
   480px too narrow. */

.detail-back {
    font-size: 0.9rem;
    margin-bottom: 0.75rem;
}

.detail-back a {
    text-decoration: none;
}

.detail-back a:hover {
    text-decoration: underline;
}

.detail-header {
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--slate-200);
}

.detail-label {
    display: block;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--slate-500);
}

.detail-aka {
    margin-top: 1.25rem;
    color: var(--slate-700);
}

.detail-signature {
    margin-top: 1.25rem;
}

.detail-signature .career-tags {
    margin-top: 0.45rem;
}

/* Label/value pairs: two columns on desktop, stacked once there isn't room. */
.detail-facts {
    display: grid;
    grid-template-columns: minmax(8rem, auto) 1fr;
    gap: 0.5rem 1.25rem;
    margin-top: 1.5rem;
}

.detail-facts dt {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--slate-500);
}

.detail-facts dd {
    color: var(--slate-800);
}

/* "At a glance" card (SCI-207): the .career-tile card without its orange left
   border, so it doesn't read as a clickable tile. Grid rows (Alicia, plan
   review 2026-10-01): three across in the reading column, one per line on
   phones, with no media query. 9rem: the root size is 18px and the list area
   583px on desktop, so 12rem (692px with gaps) and even 10rem (585px) fall
   back to two across (SCI-207 verify). */
.glance {
    margin-top: 1.5rem;
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    box-shadow: var(--shadow-soft);
}

.glance-heading {
    font-family: var(--font-display);
    font-size: 1.05rem;
    line-height: 1.3;
    color: var(--slate-900);
    margin-bottom: 0.75rem;
}

.glance-list {
    display: grid;
    /* min() keeps one column from overflowing a container narrower than 9rem. */
    grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
    gap: 0.85rem 1.25rem;
}

.glance-label {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--slate-500);
}

/* The tile rule's margin-top: auto is for card bottoms; here the chips sit
   just under their label. */
.glance-row dd .career-tags {
    margin-top: 0.3rem;
    padding-top: 0;
}

/* Decorative and aria-hidden, so the text-contrast rule that pushed the tip
   label to orange-700 doesn't apply. Named for any inline icon, not just
   the card's, since SCI-210 reuses the macro. */
.inline-icon {
    width: 1.1em;
    height: 1.1em;
    flex: none;
    color: var(--orange-600);
}

/* Stacked on phones (SCI-215 review). Side by side, the label column sized to
   the longest label, then "How close to the science core" (now in the card,
   SCI-207), which left the values about 120px at 375px wide: "Way in" ran one
   or two words a line. Stacked, each value gets the full width, and the row
   gap under it separates it from the next label. */
@media (max-width: 40rem) {
    .detail-facts {
        grid-template-columns: 1fr;
        gap: 0.15rem;
    }

    .detail-facts dd {
        margin-bottom: 0.75rem;
    }
}

.detail-section {
    margin-top: 2rem;
}

.detail-section-heading {
    font-family: var(--font-display);
    font-size: 1.2rem;
    color: var(--slate-900);
    margin-bottom: 0.5rem;
}

/* The four sections as bullets (SCI-209). Explicit padding: the global reset
   zeroes it, which would push the markers outside the text column. */
.detail-bullets {
    list-style: disc;
    padding-left: 1.25rem;
    color: var(--slate-700);
    line-height: 1.7;
}

.detail-bullets li + li {
    margin-top: 0.4rem;
}

/* A bullet's job search tip, on its own line with a thin accent bar (the
   `.reveal` bar). Label in orange-700: orange-500/600 fail AA at this size. */
.detail-tip {
    display: block;
    margin-top: 0.25rem;
    padding-left: 0.75rem;
    border-left: 3px solid var(--orange-300);
    font-size: 0.92rem;
}

.detail-tip strong {
    color: var(--orange-700);
}

/* Where the career's skills come from, under "Skills for this role" (SCI-215). */
.skills-source {
    color: var(--slate-600);
    font-size: 0.92rem;
}

/* "On this page" jump row (SCI-181, Option B — Alicia, plan review 2026-09-22).
   White pill links with a thin border and an orange arrow, under the existing
   `.detail-label` style (no new heading style needed). The arrow is drawn by
   CSS so a screen reader reads only the heading. */
.detail-jump {
    margin-top: 1.25rem;
}

.detail-jump-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-top: 0.5rem;
}

.detail-jump-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    gap: 0.35rem;
    padding: 0.4rem 0.9rem;
    border-radius: 999px;
    background: white;
    border: 1px solid var(--slate-200);
    color: var(--slate-700);
    font-size: 0.9rem;
    text-decoration: none;
    white-space: nowrap;
}

.detail-jump-link::after {
    content: "\2193";
    color: var(--orange-600);
    font-size: 0.85em;
}

.detail-jump-link:hover {
    border-color: var(--orange-400);
    color: var(--orange-700);
}

.detail-jump-link:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* Skills on the detail page are compact pills flowing in rows (wireframe),
   not the assessment page's stacked cards. */
.skill-group-label {
    font-family: var(--font-body);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--slate-600);
}

/* The collapsed "useful skills" disclosure (SCI-119) — a <summary> styled
   like the label it replaces, plus the affordances a <summary> needs that a
   plain heading doesn't. */
.skill-group-summary {
    cursor: pointer;
}

.skill-group-summary:hover {
    color: var(--orange-600);
}

.skill-group-summary:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

.skill-pills {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.6rem;
    padding: 0;
}

.skill-pill {
    font-size: 0.85rem;
    padding: 0.25rem 0.7rem;
    border-radius: 999px;
    background: white;
    border: 1px solid var(--slate-200);
    color: var(--slate-800);
}

/* Essential skills, one closed box per ESCO group (SCI-217 PR2). The summary
   reuses .skill-group-summary's pointer, hover and focus ring, but not the
   uppercase label style: "Communication and collaboration · 6 skills" is a
   title to read, not a tag. 44px tall so it is a fair tap target. */
.essential-group {
    margin-top: 0.4rem;
}

.essential-group > .skill-group-summary {
    display: list-item;
    min-height: 44px;
    padding: 0.6rem 0;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--slate-800);
    border-bottom: 1px solid var(--slate-200);
}

/* Restated here: the rule above sets a colour at the same specificity as
   .skill-group-summary:hover and comes later, so it would win. */
.essential-group > .skill-group-summary:hover {
    color: var(--orange-600);
}

.essential-group > .skill-pills {
    margin-bottom: 0.8rem;
}

.detail-sourcing {
    margin-top: 2rem;
    font-size: 0.85rem;
    color: var(--slate-500);
}

.detail-reflection {
    margin-top: 1.5rem;
    padding: 1rem 1.15rem;
    background: var(--warm-100);
    border-radius: 14px;
    color: var(--slate-700);
    font-size: 0.95rem;
}

.detail-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1.5rem;
}

/* Quiet companion to .btn-primary. Rendered disabled once the coach interest is
   recorded (SCI-88) — it must look secondary, not broken. */
.btn-secondary {
    display: inline-block;
    padding: 0.95rem 2.1rem;
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 999px;
    color: var(--slate-700);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.btn-secondary:disabled {
    color: var(--slate-500);
    cursor: not-allowed;
    opacity: 0.7;
}

/* The chosen state replaces the button: same pill, no shadow lift, not
   clickable — it reports a fact rather than offering an action. */
.btn-primary.is-chosen {
    background: var(--orange-100);
    color: var(--orange-700);
    border: 1px solid var(--orange-400);
    box-shadow: none;
    cursor: default;
}

/* Coach interest (SCI-88) — the quiet, persistent copy under the noted button
   and the lead-in above the no-results trigger. */
.coach-noted,
.no-results-coach {
    margin: 0.75rem 0 0;
    font-size: 0.95rem;
    color: var(--slate-600);
    max-width: 46rem;
}

/* Coach confirmation pop-up (SCI-88) — shown once, on the view straight after
   the click, so the confirmation cannot be scrolled past or missed.
   Server-rendered with no JavaScript (the page's CSP allows no inline script),
   so the scrim is a real element rather than a ::backdrop, which only paints
   for a dialog opened via showModal(). */
.coach-pop-scrim {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(15, 23, 42, 0.45);
}

.coach-pop {
    width: min(30rem, 100%);
    padding: clamp(1.5rem, 4vw, 2rem);
    border-radius: 24px;
    background: white;
    box-shadow: var(--shadow-card);
    text-align: center;
}

.coach-pop-heading {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.35rem;
    color: var(--slate-900);
    margin: 0;
}

.coach-pop-body {
    margin: 0.75rem 0 1.5rem;
    color: var(--slate-600);
}

/* An <a>, not a <button>: dismissing navigates back to the same page without
   the one-shot param. .btn-primary is written for form buttons, so the link
   needs the pill's own box back. */
.coach-pop-dismiss {
    display: inline-block;
    text-decoration: none;
}

/* No-results state */
.no-results {
    margin-top: 1.75rem;
}

.active-filters {
    list-style: none;
    margin-top: 0.85rem;
    color: var(--slate-700);
    font-size: 0.95rem;
}

.active-filter-label {
    font-weight: 600;
}

/* "x of 29 careers match your preferences." above the results (SCI-215). */
.library-count {
    margin-top: 1.5rem;
    color: var(--slate-700);
    font-weight: 600;
}

.no-results-actions {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
    margin-top: 1.25rem;
    font-size: 0.95rem;
}

/* "Where to next" closing block (SCI-181) — shared by the career page and the
   full /compare comparison, the two long pages that used to end in the
   footer with no way on. Generic names, because two screens use them. */
.page-next {
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--slate-200);
}

.page-next-list {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 1.25rem;
    margin-top: 0.5rem;
}

.page-next-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--orange-600);
    font-weight: 600;
    text-decoration: none;
}

.page-next-link:hover {
    text-decoration: underline;
    color: var(--orange-700);
}

.page-next-link:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* --- Founder admin view (SCI-86) --- */

.admin-section {
    margin-top: 2.5rem;
}

.admin-table {
    width: 100%;
    margin-top: 1rem;
    border-collapse: collapse;
    font-size: 0.95rem;
}

.admin-table th {
    text-align: left;
    padding: 0.5rem 0.75rem;
    color: var(--slate-500);
    font-weight: 500;
    border-bottom: 1px solid var(--slate-200);
}

.admin-table td {
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid var(--slate-200);
    color: var(--slate-700);
}

.admin-table a {
    color: var(--orange-600);
    text-decoration: none;
}

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

.export-actions {
    margin-top: 1rem;
    display: flex;
    gap: 1rem;
    align-items: center;
}

.admin-textblock,
.import-summary {
    margin-top: 1rem;
    padding: 1rem 1.25rem;
    background: var(--warm-100);
    border: 1px solid var(--slate-200);
    border-radius: 12px;
    font-size: 0.9rem;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--slate-800);
    max-height: 22rem;
    overflow-y: auto;
    /* Drag-resizable like the prototype's project-description fields (A1.4). */
    resize: vertical;
}

.admin-subhead {
    margin-top: 1.75rem;
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 600;
    color: var(--slate-700);
}

.admin-block-label {
    margin-top: 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--slate-500);
}

.admin-lines {
    margin-top: 0.75rem;
    padding-left: 1.25rem;
    color: var(--slate-700);
    font-size: 0.95rem;
    line-height: 1.6;
}

.admin-nowrap {
    white-space: nowrap;
}

.json-preview {
    margin-bottom: 1rem;
}

.tabs {
    display: flex;
    gap: 0.5rem;
    margin: 0.5rem 0 0.75rem;
}

.tab {
    font-size: 0.85rem;
    padding: 0.3rem 0.85rem;
    border: 1px solid var(--slate-200);
    border-radius: 999px;
    background: white;
    color: var(--slate-700);
    cursor: pointer;
}

.tab:hover {
    border-color: var(--orange-300);
}

.tab.selected {
    background: var(--orange-100);
    border-color: var(--orange-400);
    color: var(--orange-700);
}

.admin-back {
    margin-bottom: 0.75rem;
}

.admin-back a {
    color: var(--orange-600);
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
}

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

.admin-collapsible {
    margin-top: 1.75rem;
}

.admin-summary {
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 600;
    color: var(--slate-700);
}

/* jsonviewer-style collapsible tree (SCI-86 A1.5) */
.json-tree {
    padding: 1rem 1.25rem;
    background: var(--warm-100);
    border: 1px solid var(--slate-200);
    border-radius: 12px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.85rem;
    line-height: 1.6;
    max-height: 26rem;
    overflow-y: auto;
    resize: vertical;
}

.json-node > summary {
    cursor: pointer;
    list-style-position: outside;
}

.json-children {
    padding-left: 1.25rem;
    border-left: 1px solid var(--slate-200);
    margin-left: 0.3rem;
}

.json-key {
    color: var(--slate-800);
    font-weight: 600;
}

.json-punct {
    color: var(--slate-500);
}

.json-string {
    color: var(--orange-700);
}

.json-number {
    color: var(--slate-600);
}

.json-null {
    color: var(--slate-500);
    font-style: italic;
}

/* ---------------------------------------------------------------------------
   Skills profile (SCI-143) — the chip ledger

   Rebuilt against `design_handoff_skills_snapshot/` on 2026-08-20. Every value
   here is the handoff's, including the ones that look wrong: the 15rem spine, the
   0.96rem area label and the 1.02rem body are deliberate and must not be snapped
   to a 4/8px grid.

   THE BARS ARE GONE (Alicia, 2026-08-20). An area's size is stated by its count,
   not drawn. Nothing in this block draws a length, and nothing should: a length is
   a comparison, and this screen makes none.
   --------------------------------------------------------------------------- */

/* The handoff's content column. main.wide caps at 720px for the quiz flow, which
   is the wrong measure for a ledger — a 39-chip row wraps to six lines in it. */
main.skills {
    max-width: 60rem;
}

/* In the accessibility tree, absent from the page. Used for the chip's state in
   words: dot fill, border style and the trailing "?" are visual-only signals, and
   a provenance claim is exactly what a screen-reader user cannot check against a
   pill. Nothing that is ONLY here may be the sole carrier of an action. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

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

.snapshot-kicker {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--orange-700);
}

/* The count IS the heading. Line-height 1.08 is tight on purpose — at 2.9rem the
   default would open a gap the sub-line then has to fight across. */
.snapshot-title {
    margin-top: 0.55rem;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 3.4vw, 2.9rem);
    line-height: 1.08;
    letter-spacing: -0.02em;
    color: var(--slate-900);
}

/* Italic 400, not bold: the number is the one warm thing in the heading and it
   leans into the sentence rather than shouting over it. Source Serif ships only
   700 roman and 400 italic here, so this pairing is also the only one available —
   the constraint and the intent agree. */
.snapshot-count {
    font-style: italic;
    font-weight: 400;
    color: var(--orange-500);
}

.snapshot-sub {
    margin-top: 0.45rem;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 1.02rem;
    color: var(--slate-500);
}

/* The line that owns the limitation. Held to 38rem — the prose measure, not the
   ledger's — because it is the paragraph most likely to be skipped, and a
   960px-wide paragraph guarantees it. */
.snapshot-limits {
    margin-top: 0.85rem;
    max-width: 38rem;
    font-size: 1.02rem;
    line-height: 1.7;
    color: var(--slate-700);
}

.snapshot-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 2.5rem;
    margin-top: 1.7rem;
    padding-bottom: 1.4rem;
    border-bottom: 1px solid var(--warm-300);
}

/* tabular-nums so the four figures sit on a shared grid rather than drifting with
   the width of a 1 against a 4. */
.snapshot-figure {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 2rem;
    line-height: 1;
    color: var(--slate-900);
    font-variant-numeric: tabular-nums;
}

.snapshot-stat-label {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.8rem;
    color: var(--slate-500);
}

.snapshot-reveal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-top: 1rem;
}

/* A hairline under it rather than a full underline: it is a control, and it sits
   beside a sentence it must not be mistaken for. */
.snapshot-show-all {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--orange-600);
    text-decoration: none;
    border-bottom: 1px solid var(--orange-200);
}

.snapshot-show-all:hover {
    border-bottom-color: var(--orange-500);
}

/* `flex-start`, not `center`: the sentence wraps to two lines on a narrow screen,
   and a centred ring then hangs between them pointing at nothing. */
.snapshot-hint {
    display: inline-flex;
    align-items: flex-start;
    gap: 0.5rem;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--slate-600);
}

/* The same hollow ring an unsettled chip wears, so the sentence points at the mark
   it is describing instead of naming it in the abstract. The margin drops it onto
   the first line's optical centre — an empty box has no baseline to align to. */
.snapshot-hint-ring {
    width: 8px;
    height: 8px;
    margin-top: 0.42rem;
    border-radius: 50%;
    background: transparent;
    border: 1.5px solid var(--orange-300);
    flex-shrink: 0;
}

/* --- Section heading ------------------------------------------------------- */

.skills-section {
    margin-top: 2.4rem;
}

.ledger-head {
    display: flex;
    align-items: baseline;
    gap: 0.8rem;
    padding-bottom: 0.6rem;
}

.ledger-head-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
    color: var(--slate-900);
}

.ledger-head-count {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 0.95rem;
    color: var(--slate-500);
    white-space: nowrap;
}

/* Fills the line out to the content edge, so the heading reads as a ruled entry in
   a ledger rather than as a floating title. */
.ledger-rule {
    flex: 1;
    height: 1px;
    background: var(--warm-300);
}

/* --- The ledger row -------------------------------------------------------- */

/* 15rem, not 14 or 16: the widest ESCO area heading in the set wraps to two lines
   under 15rem and leaves a ragged spine. Do not round it. */
.ledger-row {
    display: grid;
    grid-template-columns: 15rem 1fr;
    column-gap: 1.75rem;
    padding: 1.05rem 0;
    border-top: 1px solid var(--warm-200);
}

/* Dashed, and otherwise identical. That is the whole argument: an area we found
   nothing in is laid out exactly like one we did, because a missing area is a fact
   about the CV rather than about the person. */
.ledger-row.is-empty {
    border-top: 1px dashed var(--warm-300);
}

/* `align-content: flex-start` is load-bearing, not tidying. The cell is a grid item
   and therefore as tall as the whole row; without it a wrapped flex line — the
   "edited by you" note — is spread to the bottom of a 39-chip row, half a screen
   from the name it belongs to. */
.ledger-label {
    display: flex;
    align-items: baseline;
    align-content: flex-start;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* Takes the remaining width and wraps INSIDE it. Without `flex: 1 1 0` a long area
   name ("Communication and collaboration") fills the 15rem spine on its own and
   shoves the count onto a line of its own — which is what the handoff's
   space-between row is drawn to avoid. `min-width: 0` lets it actually shrink. */
.ledger-area-name {
    flex: 1 1 0;
    min-width: 0;
    font-weight: 500;
    font-size: 0.96rem;
    line-height: 1.35;
    color: var(--slate-800);
}

.ledger-area-count {
    flex: 0 0 auto;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 0.86rem;
    color: var(--slate-500);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.ledger-row.is-empty .ledger-area-name {
    font-weight: 400;
    color: var(--slate-500);
}

.ledger-row.is-empty .ledger-area-count {
    color: var(--warm-300);
}

/* Takes the whole spine on its own line, under the name and count. Small and warm
   rather than loud: it explains a number that moved, it is not a warning. */
.ledger-area-edited {
    flex-basis: 100%;
    margin-top: 0.2rem;
    font-size: 0.78rem;
    color: var(--orange-700);
}

.ledger-empty {
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--slate-500);
}

/* --- Chips ----------------------------------------------------------------- */

.skill-chips {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.skill-chip-slot {
    display: flex;
}

/* The pill. Sized md — the handoff's desktop size — with the touch bump handled at
   the breakpoint below rather than by growing the pill itself. */
.skill-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.9rem;
    border-radius: 999px;
    font-size: 0.875rem;
    line-height: 1.2;
    text-align: left;
    text-decoration: none;
    background: white;
    border: 1px solid var(--slate-200);
    color: var(--slate-700);
    transition: border-color 0.2s ease, background 0.2s ease;
}

.skill-chip-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--orange-400);
}

/* Uncertain — thin evidence, and the user has not said either way. Dashed border
   AND a hollow dot AND the "?", three signals for one state, because it is the one
   state the screen is asking the reader to act on. */
.skill-chip.is-unsettled,
.skill-chip.is-unsure {
    background: var(--warm-50);
    border: 1px dashed var(--orange-200);
    color: var(--slate-600);
}

.skill-chip.is-unsettled .skill-chip-dot,
.skill-chip.is-unsure .skill-chip-dot {
    background: transparent;
    border: 1.5px solid var(--orange-300);
}

/* The trailing "?" — text, not an icon, so the uncertain state survives greyscale,
   a colour-blind reader and a stylesheet that failed to load. */
.skill-chip-mark {
    margin-left: -0.15rem;
    font-weight: 600;
    color: var(--orange-600);
}

.skill-chip.is-confirmed {
    background: var(--orange-50);
    border: 1px solid var(--orange-200);
    color: var(--orange-700);
}

.skill-chip.is-confirmed .skill-chip-dot {
    background: var(--orange-500);
}

/* Struck through and faded, but still here and still a link — a rejected skill
   leaves the counts, never the page, so the user can always undo. */
.skill-chip.is-declined {
    background: transparent;
    border: 1px dashed var(--slate-200);
    color: var(--slate-500);
    text-decoration: line-through;
    opacity: 0.6;
}

.skill-chip.is-declined .skill-chip-dot {
    background: var(--orange-400);
}

/* The chip whose prompt is open. Solid orange border on white — the dashes drop
   away, so "this is the one you're answering" reads even at a glance down the
   page. */
.skill-chip.is-picked {
    background: white;
    border: 1px solid var(--orange-400);
}

.skill-chip:hover {
    border-color: var(--orange-400);
}

.skill-chip:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* --- The per-area reveal --------------------------------------------------- */

/* No underline, unlike the header's control: these sit inside a row of pills and a
   rule under them would read as a seventh chip shape. */
.ledger-more,
.ledger-less {
    display: inline-block;
    padding: 0.35rem 0.2rem;
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
}

.ledger-more {
    color: var(--orange-600);
}

/* Quieter than "+n more". Expanding is the thing the reader wants; collapsing is
   housekeeping, and it should not compete with the chips it sits beside. */
.ledger-less {
    color: var(--slate-500);
}

.ledger-more:focus-visible,
.ledger-less:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* /compare's "Show n more" (SCI-217 PR2): a <details> after a row's first 8
   chips, styled as My skills' .ledger-more text button. Both labels are in the
   markup and the open state picks one, as .ledger-less is quieter than
   .ledger-more there. Padded to 44px tall for touch. */
.gap-more-toggle {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-top: 0.2rem;
    padding: 0 0.2rem;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--orange-600);
    cursor: pointer;
    list-style: none;
}

.gap-more-toggle::-webkit-details-marker {
    display: none;
}

.gap-more-toggle:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

.gap-more-open,
.gap-more[open] .gap-more-closed {
    display: none;
}

.gap-more[open] .gap-more-open {
    display: inline;
}

.gap-more[open] .gap-more-toggle {
    color: var(--slate-500);
}

/* --- The claim prompt ------------------------------------------------------ */

/* The prompt's slot in the chip list (SCI-215): it takes the full row, so the
   wrap breaks right after the chip that was clicked and the chips after it
   continue below the prompt. The flex gap already spaces it from the chips
   above and below; the prompt's own top margin is dropped here so the space
   above it is not double that below. */
.claim-slot {
    flex-basis: 100%;
}

.claim-slot > .claim-prompt {
    margin: 0.35rem 0 0.6rem;
    /* An answer lands on this prompt (#claim-…, Marina, 2026-08-20), and the
       chip it belongs to is the row just above it. html's scroll-padding
       alone stops the prompt right at the bar's edge, so the chip whose state
       just changed sat under the bar (SCI-215 review). This extra margin keeps
       one chip row — pill, list gap, the touch slot's padding and this top
       margin, about 3.2rem — plus a little air in view above the prompt. */
    scroll-margin-top: 3.5rem;
}

/* Inline, under the chip it was opened from — not an overlay. Warm ground and a
   generous radius so it reads as a note that opened in place rather than as a
   dialog that interrupted. 30rem keeps the ESCO description at a readable measure
   inside a 1fr cell that can be much wider. */
.claim-prompt {
    margin-top: 0.75rem;
    max-width: 30rem;
    padding: 1.1rem 1.25rem;
    background: var(--warm-100);
    border: 1px solid var(--warm-200);
    border-radius: 18px;
}

.claim-skill {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.2rem;
    line-height: 1.3;
    color: var(--slate-900);
}

.claim-label {
    display: block;
    margin: 0.9rem 0 0.3rem;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--slate-500);
}

.claim-description {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--slate-700);
}

/* Italic serif, matching the header's sub-line: both are the screen quoting
   something rather than speaking. */
.claim-evidence {
    margin-top: 0.4rem;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--slate-600);
}

/* The user's own answer, in the same slot a model sentence occupies. The quote
   rule does the work — it reads as "this came from you" without needing a second
   colour the page would then have to explain. */
.claim-evidence.is-yours {
    padding-left: 0.7rem;
    border-left: 3px solid var(--orange-500);
    color: var(--slate-800);
}

.claim-where {
    width: 100%;
    padding: 0.55rem 0.8rem;
    min-height: 2.75rem;
    border: 1px solid var(--warm-300);
    border-radius: 12px;
    background: white;
    font: inherit;
    font-size: 0.9rem;
    color: var(--slate-800);
}

.claim-where:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 1px;
}

.claim-hint {
    margin-top: 0.35rem;
    font-size: 0.8rem;
    color: var(--slate-500);
}

/* A <fieldset> for the legend, not for the frame: the three buttons are one
   question and a screen reader should hear it before them. */
/* A <legend> sits on the fieldset's BORDER edge and is not a flex item, so neither
   its own margin-top nor the fieldset's padding-top moves it — the padding opens a
   gap between the legend and the buttons instead, which is the opposite of what is
   wanted. `margin-top` on the fieldset is what actually carries the question clear
   of the optional hint above it; without it "Is this right?" sits flush under
   "Optional — skip it if you'd rather not say" and reads as part of that sentence.
   The small padding is the deliberate half of the pair: legend to buttons. */
.claim-verdicts {
    border: 0;
    margin: 0.9rem 0 0;
    padding: 0.15rem 0 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.claim-verdicts > .claim-label {
    margin: 0;
}

/* Size sm, from the handoff. Real submit buttons — the click IS the answer, with
   no radio-then-submit two-step. */
.claim-btn {
    display: inline-block;
    padding: 0.65rem 1.4rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition: box-shadow 0.25s ease, border-color 0.25s ease;
}

.claim-btn.is-secondary {
    background: white;
    color: var(--orange-700);
    border-color: var(--orange-200);
}

.claim-btn.is-ghost {
    background: transparent;
    color: var(--orange-600);
}

.claim-btn.is-secondary:hover {
    border-color: var(--orange-400);
}

.claim-btn:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* THE ANSWER ALREADY GIVEN, AND THE ONLY FILLED BUTTON ON THE PANEL (Marina,
   2026-08-20). It used to be a pale tint beside a permanently orange "I have
   this", so the strongest signal on the prompt pointed at an answer the user had
   not given — the screen contradicting its own sentence. The fill is the state
   nobody has to interpret, and it is the visible half of one `aria-current` also
   announces, never the only carrier of it.

   The three buttons are otherwise identical: none of them is a recommended
   action, and a screen that visually prefers "I have this" would bias the profile
   everything downstream is built on.

   FLAT --orange-700, NOT THE APP'S PRIMARY-BUTTON GRADIENT (Marina, 2026-08-20).
   White on that gradient measures 2.80:1 at its light end and 3.56:1 at its dark
   one, and this text is 14.4px at weight 600 — under 18.66px bold, so WCAG AA
   wants 4.5:1 and neither end reaches it. --orange-700 is 5.18:1 and is already
   this button's own text colour, so the fix stays inside the palette. It matters
   more here than on an ordinary primary button because this fill is not
   decoration: it is the only visual carrier of WHICH ANSWER YOU GAVE, and a state
   nobody can read is a state the screen does not have. */
.claim-btn.is-secondary.is-current {
    background: var(--orange-700);
    color: white;
    border-color: transparent;
    box-shadow: 0 6px 20px rgba(194, 65, 12, 0.32);
}

.claim-btn.is-secondary.is-current:hover {
    border-color: transparent;
    box-shadow: 0 10px 28px rgba(194, 65, 12, 0.42);
}

/* --- Exit ------------------------------------------------------------------ */

.snapshot-exit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-top: 2.2rem;
}

.snapshot-exit-note {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 0.9rem;
    color: var(--slate-500);
}

/* --- The nothing-yet / running / failed screens ---------------------------- */

.skills-state {
    max-width: 42rem;
}

.skills-state-heading {
    font-family: var(--font-display);
    font-size: 1.35rem;
    color: var(--slate-900);
}

.skills-state-body {
    margin: 0.6rem 0 1.1rem;
    color: var(--slate-600);
    line-height: 1.55;
}

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

/* Below the handoff's ~900px break the spine cannot hold: 15rem of a 390px screen
   is most of it. The row stacks — label above chips — and everything else keeps
   its type scale, since a chip that shrinks stops being a comfortable target. */
@media (max-width: 56rem) {
    .ledger-row {
        display: block;
        padding: 0.95rem 0;
    }

    .ledger-label {
        margin-bottom: 0.6rem;
    }

    .snapshot-title {
        font-size: 1.7rem;
    }

    .snapshot-sub,
    .snapshot-limits {
        font-size: 0.95rem;
    }

    .snapshot-stats {
        gap: 1.1rem;
    }

    .snapshot-figure {
        font-size: 1.55rem;
    }

    .ledger-head-name {
        font-size: 1.15rem;
    }

    .ledger-area-name {
        font-size: 0.92rem;
    }

    .claim-prompt {
        padding: 0.95rem 1rem;
    }

    .claim-skill {
        font-size: 1.1rem;
    }
}

/* The md chip is ~33px tall, under the 44px minimum. Pad the SLOT rather than the
   pill so the hit area reaches 44px without the visual chip growing — the row
   would otherwise read as a stack of buttons instead of a line of labels. */
@media (pointer: coarse) {
    .skill-chips {
        gap: 0;
    }

    .skill-chip-slot {
        padding: 0.35rem 0.2rem;
    }
}

/* Honour the reader's setting: drop the chip's colour fade and the answer
   button's shadow swell. Neither moves anything any more — the primary button's
   lift went with the primary button (Marina, 2026-08-20) — but a colour that
   arrives over a quarter of a second is still animation. */
@media (prefers-reduced-motion: reduce) {
    .skill-chip,
    .claim-btn {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Career comparison (SCI-108 PR2) — /compare

   Rides the skills ledger's vocabulary deliberately: `.ledger-*`, `.skill-chip*`,
   `.snapshot-*` and `.visually-hidden` are all reused unchanged, so the two
   screens read as one product and a visual change to the pill is one edit
   affecting both. Only what is genuinely new lives here — the bar, this screen's
   three chip states, the legend, and the fallback block.

   THERE ARE BARS HERE, AND THE SKILLS BLOCK ABOVE FORBIDS THEM. That is not an
   oversight and not a regression. The profile deleted its bars because it had no
   denominator but our own library, which made a length a fact about US. This
   screen's denominator is the career's own required count per group, which is a
   fact about the CAREER — so a length is finally a comparison the reader can
   name. Flagged for the next design handoff (Alicia, 2026-08-20) as the first
   thing to re-examine when this screen gets its own.
   --------------------------------------------------------------------------- */

/* The same 60rem measure as the ledger. main.wide caps at 720px for the quiz
   flow, which is the wrong measure for a chip row. */
main.compare {
    max-width: 60rem;
}

/* The career title IS the H1. `.snapshot-title` supplies the type; this only
   keeps the link from wearing the body underline. Also the "My careers" label
   above it (SCI-184 PR2).

   orange-600, not orange-200 (SCI-184 PR2 review): 200 measured 1.31:1 against
   the page, so the line that marks these as links was all but invisible. 600
   is 3.45:1, over the 3:1 WCAG 1.4.11 floor, the same swap the Log in border
   got in SCI-165. */
.compare-career-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 2px solid var(--orange-600);
}

.compare-career-link:hover {
    border-bottom-color: var(--orange-700);
}

.compare-career-link:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* The count sentence needs more air here than it does on the profile (Alicia,
   2026-08-20). `.snapshot-sub`'s 0.45rem is tuned for the profile's heading — a
   short count, no underline — whereas this heading is a career name that can
   wrap to two lines and carries a 2px link underline, which eats the gap and
   leaves the italic line sitting on it. Scoped to this screen so the profile,
   which is signed off from the handoff, does not move. */
.compare-page .snapshot-sub {
    margin-top: 1rem;
}

/* ESCO, in the limits line — the one outbound link in the signed-in surface.
   Underlined rather than coloured: it sits inside a paragraph of body text, and
   colour alone would make it the loudest thing in a sentence whose whole job is
   to be calm. */
/* ESCO links on /skills and the career page (SCI-215) share /compare's look. */
.compare-esco-link,
.esco-link {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--orange-400);
    text-underline-offset: 0.2em;
}

.compare-esco-link:hover,
.esco-link:hover {
    text-decoration-color: var(--orange-700);
}

.compare-esco-link:focus-visible,
.esco-link:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

/* --- the archive confirmation (SCI-150 PR2b) ------------------------------- */

/* The overlay reuses `.coach-pop*` unchanged — the same call _learn_pop.html.j2
   made, and for the same reason: a second set of identical rules would be a real
   fork. Only the Archive form needs a rule of its own, because the global
   `* { margin: 0 }` reset would otherwise sit it flush against the dismiss link
   below it. The destructive-looking control is the GHOST button and the way out
   is the primary one, which is deliberate: the way out is also autofocused. */
.archive-confirm-form {
    margin-top: 1.1rem;
}

/* --- The legend ------------------------------------------------------------ */

/* Named in VISIBLE words, once, above the ledger. This is what lets the chips
   below carry their state in dot fill and border style without repeating a label
   beside all 63 of them — and it is what makes the three states survive
   greyscale, a colour-blind reader and a stylesheet that half-loaded. */
.gap-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.1rem;
    margin-top: 1.2rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--warm-300);
    border-radius: 0.6rem;
    background: var(--warm-100);
    font-size: 0.84rem;
    color: var(--slate-600);
}

.gap-legend-label {
    font-weight: 600;
    color: var(--slate-800);
}

.gap-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
}

/* --- The three chip states ------------------------------------------------- */
/*
   THIS SCREEN'S THREE STATES ARE CAREER-RELATIVE (has / not sure / nothing
   found); the profile's five are EVIDENCE-relative. They share the pill and
   diverge here, which is why these rules live in this block rather than being
   folded into the skills one.

   NONE OF THE THREE IS CARRIED BY COLOUR ALONE. Each differs in DOT FILL and in
   BORDER STYLE as well as hue, and each carries its state as visually-hidden
   text inside the chip — the same three-signal construction the profile's
   unsettled chip uses. */

/* Solid border, filled dot: your CV or projects show this. */
.skill-chip.is-has {
    background: var(--orange-50);
    border: 1px solid var(--orange-200);
    color: var(--orange-700);
}

.skill-chip.is-has .skill-chip-dot,
.skill-chip-dot.is-has {
    background: var(--orange-500);
}

/* Dashed border, hollow ring: we are not sure, and one answer settles it. */
.skill-chip.is-unclear {
    background: var(--warm-50);
    border: 1px dashed var(--orange-200);
    color: var(--slate-600);
}

.skill-chip.is-unclear .skill-chip-dot,
.skill-chip-dot.is-unclear {
    background: transparent;
    border: 1.5px solid var(--orange-300);
}

/* DOTTED border — a third border style, not a third colour — and a hollow grey
   dot. The quietest of the three on purpose: this is the state that says our
   READING found nothing, never that the person cannot do it, and a loud
   treatment would make the page read as a list of failures. */
.skill-chip.is-gap {
    background: transparent;
    border: 1px dotted var(--slate-200);
    color: var(--slate-500);
}

.skill-chip.is-gap .skill-chip-dot,
.skill-chip-dot.is-gap {
    background: transparent;
    border: 1.5px solid var(--slate-200);
}

/* THESE TWO ARE REQUIRED, NOT DECORATION, and they are scoped to `main.compare`
   for a reason worth writing down. `.skill-chip.is-picked` (above, in the
   profile's block) and the three state rules just above have the SAME
   specificity, these are declared LATER in the file, and each sets the whole
   `border` shorthand — so on THIS screen the state border wins and a picked chip
   would look identical to every other one. (On /skills it works only because the
   profile's state rules sit above `is-picked` rather than below.) Scoping by the
   `main` class outranks both without touching the shared rules.

   Hover matters here for the same reason: these pills became tappable in PR3b,
   and the border change is the affordance that says so. `:focus-visible` uses
   `outline` and is unaffected by any of this.

   THE HOVER RULE IS TYPED AGAINST `a` AND THAT IS THE POINT OF IT. Not every chip
   on this screen is a link: a requirement our extraction library cannot see stays
   a plain <span> (_gap_chip.html.j2), deliberately, because a row created for it
   would show here and nowhere on /skills. A bare `.skill-chip:hover` lights those
   dead pills up too — the affordance promising a click the markup cannot honour.
   The fallback block is empty today and two tests pin that, so this is a rule
   that has to be right before the data makes it visible, not after. */
main.compare .skill-chip.is-picked {
    border: 1px solid var(--orange-400);
}

main.compare a.skill-chip:hover {
    border-color: var(--orange-400);
}

/* --- The bar --------------------------------------------------------------- */

/* Two levels of proportion. The TRACK's width is this group's share of the
   career's biggest group — set inline, because a per-row computed length is the
   one thing a stylesheet cannot express without ~20 hard-coded width classes
   that quantise the bars and hide the arithmetic. The SEGMENTS inside it split
   this group's own count.

   The values are integers derived from row counts and never from user text, and
   `script-src` stays 'self'; `style-src` already allows inline (see
   web/security-headers.conf). */
.gap-bar {
    margin-bottom: 0.55rem;
}

/* A floor so a short track never renders as nothing — and A DELIBERATELY LOW
   ONE, because a floor that reaches a real computed width stops being a safety
   net and starts being a lie.

   THE ARITHMETIC, since the number is not taste. Below the 56rem breakpoint
   `.ledger-row` becomes `display: block`, so the track's cell is the full
   content width: on a 375px phone that is 23.4rem minus 1.25rem of
   `--section-pad-x` each side, ~20.9rem. The smallest track our real content
   produces is 5% — conservation-scientist, whose one-skill groups sit against a
   twenty-skill one (measured across all 33 careers, 2026-08-20). 5% of 20.9rem
   is ~1.05rem, so a 0.5rem floor sits at less than half of it and never binds.

   It was 2.5rem, which is ~12% of that cell — above BOTH the 5% and the 10%
   track conservation-scientist renders, so the two drew the same length and the
   reader could not tell a one-skill group from a two-skill one. That is exactly
   the comparison the bar exists to make (gap/view.py). Pinned by
   test_gap_page.py::test_the_bar_floor_can_never_clamp_a_real_track. */
.gap-bar-track {
    display: flex;
    min-width: 0.5rem;
    height: 6px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--warm-200);
}

.gap-bar-seg {
    display: block;
    height: 100%;
}

.gap-bar-seg.is-has {
    background: var(--orange-500);
}

.gap-bar-seg.is-unclear {
    background: var(--orange-200);
}

/* The lightest of the three, and the same warm ground the empty track uses: an
   unfilled length should read as "not found yet", not as a red mark. */
.gap-bar-seg.is-gap {
    background: var(--warm-300);
}

/* The secondary per-group label, under the `n/m`. An unsure skill counts as
   neither has nor gap, and this is where it goes. */
.ledger-area-unsure {
    flex-basis: 100%;
    margin-top: 0.2rem;
    font-size: 0.78rem;
    color: var(--orange-700);
}

/* --- The fallback block ---------------------------------------------------- */

/* A requirement our extraction library cannot see. Kept, named and counted —
   never dropped — and given no bar, because a bar is a comparison and this is
   precisely the set we cannot make one about. Should be unreachable from real
   content; it ships so that a future content bump degrades visibly. */
.gap-other {
    margin-top: 2.6rem;
}

.gap-other-line {
    margin: 0.5rem 0 0.2rem;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--slate-500);
}

/* No spine: this block has no area name to sit in one, so the row is a single
   full-width cell rather than an empty 15rem column followed by chips. */
.gap-other .ledger-row {
    display: block;
    border-top: 1px dashed var(--warm-300);
}

/* --- The learning-path cards (SCI-108 PR4) --------------------------------- */

/* Up to three cards under the ledger, chosen by how much the documents said
   NOTHING about. Scoped to this screen, the same call the `.compare-page`
   rules above make: nothing here may move the profile, which is signed off. */

.compare-page .learning-line {
    margin: 0.5rem 0 0;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--slate-500);
}

/* Three tracks fit the 60rem column; a card going under 18rem drops to its own
   row, which is what gives the 320px case a single column with no media query.
   Same mechanism as `.career-grid`, one measure smaller. */
.compare-page .learning-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
    gap: 1rem;
    margin-top: 1rem;
    padding: 0;
    list-style: none;
}

.compare-page .learning-card {
    background: white;
    border: 1px solid var(--slate-200);
    border-left: 4px solid var(--orange-500);
    border-radius: 16px;
    padding: 1.1rem 1.25rem;
    box-shadow: var(--shadow-soft);
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.compare-page .learning-card-heading {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    color: var(--slate-900);
    margin: 0;
}

.compare-page .learning-card-line {
    margin: 0;
    font-size: 0.86rem;
    line-height: 1.6;
    color: var(--slate-700);
}

.compare-page .learning-resources {
    list-style: none;
    padding: 0;
    /* Pushes the CTA to the card's foot, so three cards of unequal line length
       still line their buttons up across the row. */
    margin: 0.35rem 0 auto;
}

/* A full-width, borderless button wearing the body font: it is a resource line
   the reader can click, not a pill. The divider is what separates the three. */
.compare-page .learning-resource {
    display: block;
    width: 100%;
    padding: 0.5rem 0;
    border: 0;
    border-top: 1px solid var(--warm-300);
    background: none;
    text-align: left;
    font-family: var(--font-body);
    font-size: 0.84rem;
    line-height: 1.5;
    color: var(--slate-700);
    cursor: pointer;
}

.compare-page .learning-resource:hover {
    color: var(--orange-700);
}

.compare-page .learning-resource:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

.compare-page .learning-resource-kind {
    font-weight: 600;
    color: var(--slate-900);
}

/* The CTA is `.btn-secondary` unchanged; it only needs to stop stretching to
   the card's full width and to sit at the foot. */
.compare-page .learning-card .btn-secondary {
    align-self: flex-start;
    margin-top: 0.6rem;
    padding: 0.6rem 1.2rem;
    font-size: 0.86rem;
}

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

/* Same break as the ledger's. The row stacks there, and a bar that kept the
   spine's width would sit under a label it no longer lines up with. */
@media (max-width: 56rem) {
    .gap-legend {
        font-size: 0.8rem;
    }

    .gap-bar {
        margin-bottom: 0.65rem;
    }
}

/* Honour the reader's setting — the chips here carry no transition of their own,
   but they inherit `.skill-chip`'s, and the skills block already drops it. This
   block adds no animation, deliberately: a bar that grows on load would be a
   length the reader cannot compare while it is moving. */

/* --- The shell's footer (SCI-150) ------------------------------------------ */

/* The public site's mark-plus-meta-links shape (web/style.css `.site-footer`),
   matched rather than shared: the two surfaces have separate stylesheets by
   design, and the app's footer carries only the meta line — the wordmark is
   already in the brand bar at the top of every one of these pages.

   `margin-top: auto` is deliberately absent: these pages have no flex body and
   several of them (the ledger, the library) are far taller than the viewport,
   so a sticky footer would be machinery for the short screens only.

   `z-index: 0`, NOT <main>'s 1 (SCI-193). Positioned at all only to paint above
   the `.blobs` backdrop, which it still does at 0 by coming later in the page.
   At 1, the tie with <main> went to the footer, and on a short page it covered
   the fixed feedback panel inside <main>'s stacking context: the Send button on
   `/careers/chosen` at 1024x768 took no clicks. */
.app-footer {
    position: relative;
    z-index: 0;
    max-width: 1100px;
    margin: 0 auto;
    padding: 2rem var(--section-pad-x) 2.5rem;
    border-top: 1px solid var(--warm-300);
    color: var(--slate-500);
    font-size: 0.9rem;
}

.app-footer-meta a {
    color: var(--slate-600);
    text-decoration: none;
    transition: color 0.2s ease;
}

.app-footer-meta a:hover {
    color: var(--orange-600);
}

.app-footer-sep {
    margin: 0 0.55rem;
}

/* ============================================================================
   The signed-in hub — /home (SCI-150 PR2a)

   Design handoff: design_handoff_home_hub/README.md, with the header block and
   the row grid from README-board-15a-profile-plant.md (Model B, Alicia
   2026-08-25). Values that look odd (2.6rem, 0.62rem, 2.1rem) are deliberate
   and taken from the handoff — do not snap them to a 4/8px grid.

   STATE, NOT PROGRESS. There is no bar, ring, percentage or "3 of 5" in this
   block, and none may be added: a row states what has happened, and the ladder
   is a list of facts rather than a track to the end of.

   ⚠️ --warm-300 is a hairline-on-white token. Row hairlines are --warm-200;
   --warm-300 is for section rules, the nav and the footer. It lands around
   1.1:1 on a warm panel, so it must never carry a mark or text.
   ========================================================================= */

.home-page {
    max-width: 56rem;
}

/* --- header block ------------------------------------------------------- */

.home-header {
    display: flex;
    align-items: flex-end;
    gap: 1.6rem;
    margin-bottom: 1.7rem;
}

.home-title {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 2.1rem;
    line-height: 1.08;
    letter-spacing: -0.02em;
    color: var(--slate-900);
}

/* The one italic-orange phrase per heading — the brand's signature move. */
.home-title-accent {
    font-weight: 400;
    font-style: italic;
    color: var(--orange-500);
}

.home-sub {
    margin: 0.5rem 0 0;
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: 1rem;
    color: var(--slate-500);
}

/* --- the mark's boxes, and the layers in them (PR2b) --------------------- */

/* Both boxes were reserved in PR2a so PR2b could fill them without moving a
   row: `position: relative` is what the stacked, clipped logo layers are
   absolutely positioned against, and `aspect-ratio: 1` is what makes their
   clip-path percentages hold. The layers themselves are _home_mark.html.j2 —
   the whole logo once at 0.2 opacity, then one copy per earned part. */
.home-mark {
    position: relative;
    width: 2.6rem;
    aspect-ratio: 1;
    flex: none;
}

.home-mark-lg {
    width: 104px;
}

/* Every layer fills the box, board 15a's layer spec verbatim. */
.home-mark-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* LAYER 1, drawn in every state: the parts not yet earned. It is what makes
   the seed state a whole faint flower rather than an empty box. */
.home-mark-pale {
    opacity: 0.2;
}

/* Layers 2..n — one earned part each, board 15a's table copied without
   adjustment. Petals fill CLOCKWISE FROM THE TOP, and that order is fixed: it
   is not the career's sector, seniority or match, and only the count means
   anything.

   ⚠️ EVERY PERCENTAGE BELOW IS COUPLED TO THE EXACT BYTES OF logo.png. They are
   measured against the unmodified 1254² asset under `object-fit: contain` in a
   SQUARE box. A re-export with different margins, a padded asset or a non-square
   box invalidates all nine rules at once — and the failure is silent, because a
   clip that lands slightly off still draws something. Board 15a: "If the asset
   is ever re-exported, RE-MEASURE rather than nudge."

   Nothing here transitions or animates: the mark is a static image, and a new
   petal is simply there on the next load. */
.home-mark-part--stem {
    clip-path: polygon(45.5% 47%, 54.5% 47%, 54.5% 100%, 45.5% 100%);
}

.home-mark-part--leaf_r {
    clip-path: polygon(51% 58.5%, 71% 58.5%, 71% 78%, 51% 78%);
}

.home-mark-part--leaf_l {
    clip-path: polygon(28% 58.5%, 49% 58.5%, 49% 78%, 28% 78%);
}

.home-mark-part--centre {
    clip-path: circle(7.9% at 49.4% 39.6%);
}

.home-mark-part--petal_1 {
    clip-path: ellipse(8.0% 9.4% at 49.0% 21.7%);
}

.home-mark-part--petal_2 {
    clip-path: ellipse(9.3% 8.8% at 65.0% 29.2%);
}

.home-mark-part--petal_3 {
    clip-path: ellipse(9.3% 8.8% at 66.2% 45.8%);
}

.home-mark-part--petal_4 {
    clip-path: ellipse(9.1% 8.8% at 32.9% 45.8%);
}

.home-mark-part--petal_5 {
    clip-path: ellipse(8.6% 8.8% at 33.9% 29.2%);
}

/* --- the ladder --------------------------------------------------------- */

.home-rows {
    border-bottom: 1px solid var(--warm-200);
}

.home-row {
    display: grid;
    grid-template-columns: 2.6rem 1fr auto;
    gap: 1rem;
    align-items: center;
    padding: 0.62rem 0;
    border-top: 1px solid var(--warm-200);
}

.home-row-label {
    margin: 0;
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 0.95rem;
    line-height: 1.35;
    color: var(--slate-800);
}

.home-row-meta {
    margin: 0.15rem 0 0;
    font-family: var(--font-body);
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--slate-600);
}

/* An archived row on My careers (SCI-184): label and meta step back to the
   muted tone. The words still say "Archived {date}", so colour never carries
   the state alone. */
.home-row-muted .home-row-label,
.home-row-muted .home-row-meta {
    color: var(--slate-500);
}

/* My careers' Archived heading reuses the detail page's section heading; this
   only spaces it from the list or the empty block above. */
.my-careers-archived {
    margin-top: 2rem;
}

/* A career we removed (SCI-195): room below the heading and above the list.
   The button gives back its own padding so "Got it" lines up with the text. */
.my-careers-retired-note {
    margin: 1rem 0 1.25rem;
}

.my-careers-retired-note .btn-ghost {
    margin-left: -1.4rem;
}

/* Reserved even when empty, so a row with no action leaves its slot rather
   than letting the text cell spread into it and shift the row above.

   TWO CONTROLS FIT HERE SINCE PR2b, on career rows only: Compare and Archive.
   The cell is `auto`-width in the grid above, so it takes what the pair needs
   and the text cell keeps the rest. `flex` rather than leaving them inline, so
   the gap is stated once instead of riding on whitespace between two anchors. */
.home-row-action {
    display: flex;
    align-items: center;
    gap: 0.2rem;
    min-height: 1px;
}

/* --- ghost button ------------------------------------------------------- */

/* The one button variant this screen needs (handoff §Buttons, size sm). The
   44px minimum touch target is met by the padding, not by growing the pill. */
.btn-ghost {
    display: inline-block;
    padding: 0.65rem 1.4rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--orange-600);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.9rem;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: transform 0.25s ease, background 0.25s ease;
}

.btn-ghost:hover {
    background: var(--orange-50);
    transform: translateY(-2px);
}

.btn-ghost:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* --- responsive --------------------------------------------------------- */

/* Below ~900px the row stacks: mark and label on one line, the meta beneath,
   the action full-width under both. The action keeps its own line rather than
   shrinking, so the touch target never drops below 44px. */
@media (max-width: 900px) {
    .home-header {
        gap: 1.1rem;
    }

    .home-mark-lg {
        width: 72px;
    }

    .home-title {
        font-size: 1.8rem;
    }

    .home-row {
        grid-template-columns: 2.6rem 1fr;
        row-gap: 0.5rem;
    }

    /* Under the TEXT column, not spanning from the mark's — and aligned to the
       start of it, so the action reads as part of its row rather than floating
       centred between two of them. `justify-self` rather than a full-width
       pill: a stretched pill is a bigger target than the control deserves and
       loses the row's left spine. The 44px minimum is met by the padding. */
    .home-row-action {
        grid-column: 2;
        justify-self: start;
        /* Two controls wrap to a second line rather than shrinking, so neither
           drops below the 44px touch target the padding provides. */
        flex-wrap: wrap;
    }
}

@media (prefers-reduced-motion: reduce) {
    .btn-ghost {
        transition: none;
    }

    .btn-ghost:hover {
        transform: none;
    }
}

/* In-app feedback strip (SCI-171) ------------------------------------------------

   TWO SHAPES, ONE MARKUP. The first build made this a quiet underlined line at
   the top of the content column. Alicia's verdict on seeing it running was "I
   would miss it for sure", which is the whole ticket failing quietly: a control
   nobody finds collects nothing, and round 1 exists to collect something. So it
   is louder now, in the two different ways the two form factors allow, off ONE
   `<details>` and with no JavaScript — this surface has none and the CSP allows
   no inline script.

   NARROW (the base rules, phones and tablets): still first inside <main>, but
   drawn as a CONTROL rather than as prose — a bordered pill, white on the warm
   ground, in orange rather than the muted body grey. Same position as before,
   different weight.

   WIDE (from 64rem up, `@media` at the end of this block): a tab fixed to the
   right edge and vertically centred, with the panel opening leftward over the
   page. It never scrolls away, which is the point — `/skills` and `/careers` are
   several screens tall, and the in-flow strip is gone by the time a tester has
   formed an opinion worth writing down.

   WHY 64rem AND NOT THE HOUSE 56rem. This breakpoint is not about phone versus
   desktop, it is about whether there is a MARGIN for the tab to stand in. The
   widest content column in the product is `main.library` at 980px; at 1024px
   that leaves 22px each side, so the 44px tab covers half its own width of
   <main>'s own padding and no text at all. Below that the tab would sit on the
   career grid, so it becomes the pill instead. Changing `main.library`'s
   max-width means revisiting this number.

   STILL PASSIVE, STILL NON-MODAL. Nothing here opens itself, nothing dims the
   page, nothing interrupts — the ticket's constraint (the same build runs in
   moderated sessions) is about proactivity, not about visibility, and both
   shapes wait to be clicked. The tab is the louder end of what that allows and
   is worth re-reading if a moderated session ever reports it as a distraction.

   The disclosure itself follows `.filter-help` above, including the swapped
   caret and the suppressed native marker. */
.feedback {
    margin-bottom: 1.5rem;
    text-align: right;
}

/* A pill, not a link: border, fill and orange, because the underlined grey line
   read as a footer link sitting in the wrong place. `inline-flex` with an
   explicit min-height rather than padding alone, so the touch target is 44px by
   measurement instead of by arithmetic that lands a pixel short (WCAG 2.5.5). */
.feedback-summary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0.4rem 1rem;
    border: 1px solid var(--warm-300);
    border-radius: 999px;
    background: white;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--orange-700);
    cursor: pointer;
}

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

.feedback-summary::marker {
    content: "";
}

/* `margin-left`, not a leading space in the content string: the summary is an
   inline-flex box and flex eats leading whitespace in a generated string. */
.feedback-summary::after {
    content: "▾";
    margin-left: 0.4rem;
    text-decoration: none;
}

.feedback[open] > .feedback-summary::after {
    content: "▴";
}

.feedback-summary:hover {
    border-color: var(--orange-600);
    background: var(--orange-50);
}

.feedback-summary:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 3px;
}

/* White on the warm ground, like every other card on this surface — and only
   once opened, so the closed state stays a single line. Left-aligned inside,
   because the strip's right alignment is about where the CONTROL sits, not
   about how a paragraph of the tester's own writing should read. */
.feedback-body {
    max-width: 34rem;
    margin: 0.45rem 0 0 auto;
    padding: 0.85rem 1rem;
    background: white;
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    text-align: left;
}

.feedback-intro {
    font-size: 0.85rem;
    color: var(--slate-600);
}

.feedback-label {
    display: block;
    margin-top: 0.7rem;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--slate-700);
}

.feedback-message {
    width: 100%;
    margin-top: 0.35rem;
    padding: 0.55rem 0.8rem;
    border: 1px solid var(--warm-300);
    border-radius: 12px;
    background: white;
    font: inherit;
    font-size: 0.9rem;
    color: var(--slate-800);
    /* Vertical only: a textarea a reader can widen escapes the card. */
    resize: vertical;
}

.feedback-message:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 1px;
}

.feedback-hint {
    margin-top: 0.35rem;
    font-size: 0.8rem;
    color: var(--slate-500);
}

.feedback-submit {
    margin-top: 0.7rem;
}

.feedback-sent {
    font-size: 0.9rem;
    color: var(--slate-700);
}

/* "Send another" — a LINK, not a second pill. The pill is the control that
   opens the widget; someone reading the thank-you has already found it, and a
   second pill in the panel would read as a second way in rather than a way
   back to the box.

   `inline-flex` with a min-height for the same reason `.feedback-summary` has
   one: a bare text link here is a standalone target, so it gets 24px by
   measurement (WCAG 2.5.8) rather than whatever the line-height happens to
   give it. */
.feedback-again-line {
    margin-top: 0.6rem;
}

.feedback-again {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--orange-700);
    text-decoration: underline;
}

.feedback-again:hover {
    color: var(--orange-600);
}

.feedback-again:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

/* THE WIDE SHAPE: a tab on the right edge, panel opening leftward.

   `position: fixed` is safe here even though <main> is `position: relative;
   z-index: 1`: a positioned ancestor is not a containing block for a fixed
   child, and nothing in this stylesheet puts a transform, filter or `contain`
   on an ancestor of <main> (the one `filter: blur()` is on `.blob`, a sibling
   backdrop). <main>'s stacking context is doing useful work, though — it caps
   this tab below `.coach-pop-scrim` at z-index 50, so an open confirmation
   overlay still covers it, and <main>'s `inert` still reaches it, so a keyboard
   user cannot tab into the tab from behind an overlay.

   THE PANEL IS ABSOLUTELY POSITIONED RATHER THAN A FLEX SIBLING. A closed
   <details> is not `display: none` in Chrome: its content box survives with
   `content-visibility: hidden`, so as a flex item it would still claim its own
   padding and border and shove the tab ~30px in from the edge while painting
   nothing. Out of flow, the panel cannot move the tab whether or not a browser
   collapses it. `right: 100%` means "the tab's left edge", which holds without
   naming the tab's width anywhere. */
@media (min-width: 64rem) {
    .feedback {
        position: fixed;
        top: 50%;
        right: 0;
        transform: translateY(-50%);
        margin-bottom: 0;
        /* Above the rest of <main>, whose positioned descendants come later
           in the page and would otherwise paint over the open panel (the
           button row on `/careers/chosen`, SCI-193). Only within <main>'s
           stacking context, so the pop-up scrim still covers it. */
        z-index: 1;
    }

    /* Rotated, so a 26-character label costs ~170px of edge instead of 170px of
       content column. The pill's rounding is dropped on the two edges that meet
       the viewport, which is what makes it read as attached to the window
       rather than as a button that has drifted. */
    /* SOLID, NOT TINTED. The pill gets away with a white fill because it sits
       inside the content column, where a card-coloured box reads as a control.
       Out on the warm ground a pale tab is a rounded rectangle of nothing:
       `--orange-50` is #fff7ed and the page behind it is cream, which was the
       first attempt and was invisible in exactly the way the ticket is trying
       to fix. It takes `.btn-primary`'s fill so it belongs to the same control
       language as the Send button it opens onto, minus the lift on hover, which
       would have the tab crawling up the window. */
    .feedback-summary {
        writing-mode: vertical-rl;
        min-width: 44px;
        padding: 1.1rem 0.5rem;
        background: linear-gradient(135deg, var(--orange-500), var(--orange-600));
        border: none;
        border-radius: 12px 0 0 12px;
        color: white;
        box-shadow: 0 6px 20px rgba(249, 115, 22, 0.32);
    }

    .feedback-summary:hover {
        background: linear-gradient(135deg, var(--orange-600), var(--orange-700));
        box-shadow: 0 10px 28px rgba(249, 115, 22, 0.42);
    }

    /* No caret on the tab. The arrow would have to survive being rotated by the
       writing mode, and which way a triangle ends up pointing there is decided
       by the glyph's Unicode vertical-orientation rather than by this file. A
       tab welded to the edge of the window is its own affordance. */
    .feedback-summary::after,
    .feedback[open] > .feedback-summary::after {
        content: "";
    }

    .feedback-body {
        position: absolute;
        top: 50%;
        right: 100%;
        transform: translateY(-50%);
        width: 22rem;
        max-width: none;
        margin: 0;
        border-right: none;
        border-radius: 14px 0 0 14px;
        /* It floats over the page here rather than sitting under the heading, so
           it needs the card lift to separate from whatever it lands on. */
        box-shadow: var(--shadow-card);
        /* A short laptop in landscape: the panel is centred on the viewport, so
           a panel taller than the viewport would put its own top off-screen with
           nothing to scroll. It scrolls itself instead. */
        max-height: calc(100dvh - 2rem);
        overflow-y: auto;
    }
}

/* =========================================================================
   The end-of-testing form (SCI-193 PR2) — /feedback-form, the banner that
   leads to it and the "Before you go" page (SCI-217).

   Its own `endform-` prefix, never `feedback-`: the widget owns `.feedback`
   and its `.feedback-*` parts, and another surface owns `.feedback-row` and
   `.feedback-q`. The radio rows reuse the flow's `.options` / `.option` and
   the error banner is the flow's `.form-error`, so the form reads like the
   rest of the signed-in app.
   ========================================================================= */

/* --- the banner (SCI-217) ------------------------------------------------
   Full width under the sticky top bar, in the top bar's own side padding so
   its text lines up with the logo, and not sticky itself: it scrolls away.
   The widget's family: orange-50 ground, orange-700 link. One line on a wide
   screen; on a phone the text wraps and × stays top-right. */
.endform-banner {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem 1rem;
    padding-block: 0.35rem;
    padding-inline: max(var(--section-pad-x), calc((100% - 1100px) / 2 + var(--section-pad-x)));
    background: var(--orange-50);
    border-bottom: 1px solid var(--warm-300);
}

.endform-banner-text {
    margin: 0;
    padding-block: 0.6rem;
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--slate-800);
}

.endform-banner-text > a {
    font-weight: 600;
    color: var(--orange-700);
}

.endform-banner-tail {
    margin-left: 0.4rem;
    font-size: 0.85rem;
    /* slate-600, not 500: 500 on orange-50 is 4.48:1, under AA's 4.5:1. */
    color: var(--slate-600);
}

.endform-banner-tail a {
    color: inherit;
}

.endform-banner-close {
    flex-shrink: 0;
}

/* 44px by measurement (WCAG 2.5.5), the widget pill's rule. */
.endform-banner-close button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    background: none;
    border: 0;
    border-radius: 999px;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--slate-600);
    cursor: pointer;
}

.endform-banner-close button:hover {
    background: var(--orange-100);
}

.endform-banner-close button:focus-visible {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

@media (max-width: 40rem) {
    .endform-banner-tail {
        display: block;
        margin-left: 0;
    }
}

/* --- "Before you go" (SCI-217) ------------------------------------------- */
.before-you-go-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

/* Stacked on a phone, each full width, "Open the feedback form" on top. */
@media (max-width: 40rem) {
    .before-you-go-actions {
        flex-direction: column;
    }

    .before-you-go-actions .btn-primary,
    .before-you-go-actions .btn-secondary {
        width: 100%;
        text-align: center;
    }
}

.endform-page {
    max-width: 46rem;
}

.endform-thanks {
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--slate-700);
}

.endform-q {
    margin: 0 0 1.75rem;
    padding: 0;
    border: 0;
    min-width: 0;
}

.endform-question {
    display: block;
    padding: 0;
    margin-bottom: 0.6rem;
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.45;
    color: var(--slate-900);
}

/* SCI-217: more room between the intro and Q1. */
.endform {
    margin-top: 2rem;
}

.endform-star {
    margin-left: 0.2rem;
    color: var(--orange-700);
}

.endform-choose-all {
    font-weight: 400;
    color: var(--slate-500);
}

.endform-hint {
    margin: -0.25rem 0 0.6rem;
    color: var(--slate-500);
    font-size: 0.9rem;
    line-height: 1.5;
}

.endform-text,
.endform-which input,
.endform-follow input[type="text"] {
    width: 100%;
    padding: 0.75rem 1rem;
    background: var(--warm-50);
    border: 1px solid var(--slate-200);
    border-radius: 14px;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--slate-900);
}

.endform-text {
    resize: vertical;
}

.endform-text:focus,
.endform-which input:focus,
.endform-follow input[type="text"]:focus {
    outline: none;
    border-color: var(--orange-400);
    background: white;
    box-shadow: 0 0 0 4px rgba(249, 115, 22, 0.12);
}

/* A missing answer is marked on screen as well as for a screen reader. */
.endform-q[aria-invalid="true"] .endform-point span,
.endform-q[aria-invalid="true"] .option {
    border-color: #fca5a5;
}

/* Q1 and Q2 have no box to outline (SCI-221), so their question turns red. */
.endform-missing .endform-question {
    color: #b91c1c;
}

/* --- the 1 to 10 ratings ------------------------------------------------- */

/* SCI-221: ten equal columns that shrink to fit a phone, with the two end
   labels underneath rather than beside the row. The labels are cells of the
   same grid, each pinned to its own end, so they move with the points when
   the row wraps. Ten columns: `form.RATINGS`. */
.endform-scale {
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 0.35rem;
    max-width: 34rem;
}

.endform-scale-low {
    grid-row: 2;
    grid-column: 1 / span 5;
    justify-self: start;
}

.endform-scale-high {
    grid-row: 2;
    grid-column: 6 / -1;
    justify-self: end;
    text-align: right;
}

/* Below 360px wide, ten in a row would be under the 24px minimum touch
   target (WCAG 2.5.8), so the points go two rows of five, 1 to 5 then 6 to
   10. "Low" sits under the first row, starting at 1; "high" under the second,
   ending at 10. 22.4375rem is 359px: a media query's rem is the browser's
   16px, and 360px itself still fits ten (about 25.8px each). */
@media (max-width: 22.4375rem) {
    .endform-scale {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .endform-scale-low {
        grid-row: 2;
        grid-column: 1 / -1;
    }

    .endform-scale-high {
        grid-row: 4;
        grid-column: 1 / -1;
    }
}

.endform-scale-end {
    color: var(--slate-600);
    font-size: 0.88rem;
}

.endform-point {
    position: relative;
    cursor: pointer;
}

/* The radio stays in the accessibility tree and takes focus; the number is
   what the eye clicks. */
.endform-point input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}

.endform-point span {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 2.75rem;
    border: 1px solid var(--slate-200);
    border-radius: 12px;
    background: var(--warm-50);
    font-weight: 600;
    color: var(--slate-700);
}

.endform-point:hover span {
    border-color: var(--orange-300);
}

.endform-point input:checked + span {
    border-color: var(--orange-500);
    background: white;
    color: var(--orange-600);
    box-shadow: 0 0 0 3px rgba(249, 115, 22, 0.1);
}

.endform-point input:focus-visible + span {
    outline: 2px solid var(--orange-700);
    outline-offset: 2px;
}

.endform-optout {
    margin-top: 0.6rem;
}

/* --- Q1, Q2, Q7 and Q8: choices with an optional box --------------------- */

.endform-check-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
    padding: 0.35rem 0;
}

.endform-check {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    flex: 1 1 18rem;
    color: var(--slate-700);
    line-height: 1.5;
    cursor: pointer;
}

.endform-check input {
    flex-shrink: 0;
    margin-top: 0.25rem;
    width: 1.05rem;
    height: 1.05rem;
    accent-color: var(--orange-500);
}

.endform-which {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1 1 14rem;
}

.endform-which-label {
    color: var(--slate-600);
    font-size: 0.88rem;
    white-space: nowrap;
}

/* --- Q9 ------------------------------------------------------------------ */

.endform-inline {
    flex-direction: row;
    flex-wrap: wrap;
}

.endform-follow {
    margin: 1rem 0 0;
    padding: 0;
    border: 0;
    min-width: 0;
}

.endform-follow-label {
    display: block;
    padding: 0;
    margin-bottom: 0.4rem;
    color: var(--slate-700);
    font-size: 0.95rem;
}
