/*
 * Public task-type pages (/p/<section>/<type>.html).
 *
 * Standalone: tokens.css only, none of the SPA's stylesheets — this page must render instantly for a
 * crawler and has no app state to style. Everything visual comes from semantic tokens; the handful of
 * values the token system does not own (the marketing display type ramp) is declared once as local
 * custom properties on .public-page, never as scattered literals.
 *
 * The page borrows the app's atoms on purpose, so a stranger who lands here and then signs up
 * recognises the product: the shell width, the header (brand and sections left, Sign in right), the
 * practice action button (Check answer), the uppercase micro-label above every section
 * (practice-feedback.css .methodical-title), the metric strip split by vertical rules
 * (dashboard.css .dashboard-metrics), the green Strategy-tip callout (.methodical-tip-callout) and the
 * brand dot (app-shell.css .platform-brand-dot). Values are duplicated rather than shared because this
 * document cannot load the app's CSS.
 *
 * No framed surfaces: the product has no cards, so this page has none either. Structure comes from
 * hairline rules — horizontal between chapters and rows, vertical between parallel items.
 *
 * Weight ceiling: 500 for everything the page writes — headings included. The two exceptions are not
 * this page's typography but the app's own chrome, reproduced exactly: the brand mark and the header
 * Sign in link.
 */

/* This file is served only with the public pages, so the reset can be global. */
*,
*::before,
*::after {
    box-sizing: border-box;
}

.public-page {
    /* Local scale — values tokens.css does not own. */
    --public-wrap: var(--size-shell-max-width);             /* the app's shell width: this page must sit as wide as the product */
    --public-page-x: var(--space-56);                       /* one inset for the whole page: header, chapters and footer all start here */
    --public-section-y: var(--space-64);                    /* vertical rhythm between sections; halved on laptops below */
    --public-btn-size: 0.875rem;                            /* the app's practice action buttons (Check answer) */
    --public-bar-z: 20;                                     /* above the page, below nothing else — this document has no overlays */
    --public-column-gap: var(--space-56);
    --public-trait-gap: var(--space-32);                    /* space either side of the rule between traits */
    --public-trait-min: 230px;                              /* below this a trait's sentence goes ragged; it wraps instead */
    --public-row-min: 230px;                                /* a ruled row's column floor: below it, headings break badly */
    --public-row-gap: var(--space-40);                      /* between columns of a ruled row — tighter than the hero's, so more fit per row */
    --public-title-hero: clamp(2.2rem, 4.2vw, 3.1rem);      /* smaller than --text-hero-size: it shares its row with the chart */
    --public-title-section: clamp(1.45rem, 2.3vw, 1.75rem);
    --public-title-final: clamp(1.3rem, 2vw, 1.6rem);
    --public-deck-size: clamp(1.02rem, 1.5vw, 1.12rem);
    --public-stat-size: 1.3rem;
    --public-label-tracking: 0.14em;                        /* matches the app's feedback section labels */
    --public-focus-ring: var(--accent-action);              /* --border-focus is only ~1.37:1 on --bg-page, under the 3:1 floor */

    margin: 0;
    background: var(--bg-page);
    color: var(--text-primary);
    font-family: var(--font-family-ui);
    font-size: var(--text-body-size);
    line-height: var(--line-height-145);
    -webkit-text-size-adjust: 100%;
}

/* The example chart is 2108px wide intrinsically; without this it blows the layout out sideways. */
.public-page img {
    display: block;
    max-width: 100%;
    height: auto;
}

.public-page h1,
.public-page h2,
.public-page h3 {
    font-weight: var(--font-weight-medium);
}

.wrap {
    max-width: var(--public-wrap);
    margin: 0 auto;
    padding: 0 var(--public-page-x);
}

/* Clears the sticky header when an in-page anchor lands. */
.public-page section[id] {
    scroll-margin-top: calc(var(--space-64) + var(--space-16));
}

/* ==========================================================================
   Header
   ========================================================================== */

/* Sticky from the first scroll: the sections are long, and the way back to the app should never be a
   scroll-to-top. Released on phones, where the bar takes two rows and would eat the viewport. */
.bar {
    position: sticky;
    top: 0;
    z-index: var(--public-bar-z);
    border-bottom: var(--border-width-hairline) solid var(--border-default);
    background: var(--bg-page);
}

/* Brand sits on the left, Sign in sits right — the app's header, not a centred marketing bar.
   Spacing is the app's own (app-shell.css .platform-header-bar / -left). */
.bar-in {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-12);
    min-height: var(--space-64);
}

.bar-left {
    display: flex;
    align-items: center;
    gap: var(--space-28);
    min-width: 0;
}

/* THE BRAND — copied atom for atom from app-shell.css .platform-brand and its parts. It is the mark,
   not page typography: the bold weight and the dot AFTER the wordmark are the identity, and neither
   the weight ceiling above nor any change here is this page's to make. */
.brand {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-5);
    color: var(--text-emphasis);
    font-size: var(--font-size-103);
    font-weight: var(--font-weight-bold);
    line-height: var(--line-height-1);
    white-space: nowrap;
    text-decoration: none;
}

.brand-wordmark {
    display: inline-flex;
    align-items: baseline;
    letter-spacing: var(--tracking-tight);
}

.brand-prefix {
    color: var(--color-ink-800);
    font-weight: var(--font-weight-semibold);
}

.brand-main {
    color: var(--text-emphasis);
    font-weight: var(--font-weight-bold);
}

.brand-dot {
    width: 0.72em;
    height: 0.72em;
    border-radius: var(--radius-pill-soft);
    background: var(--accent-brand);
    transform: translateY(-0.03em);
    box-shadow: var(--shadow-brand-dot);
}

/* The app's header Sign in (app-shell.css .auth-inline-button): an underlined text link in every
   chrome it appears in, weight and all.
   The font family is deliberately NOT --font-family-ui. In the app this control is a <button> that
   never sets a family, so the browser renders it in its default control font — Arial in Chrome — and
   at this weight the app's own stack reads visibly heavier beside it. This link reproduces what the
   app actually renders, not what its rule declares. (Fixing it at the source means giving
   .auth-inline-button `font: inherit`, which would change the app's header everywhere — the owner's
   call, not this page's.) */
.signin {
    padding: var(--space-0) var(--space-0) var(--space-2);
    border-bottom: var(--border-default-width) solid currentColor;
    color: var(--text-link);
    font-family: Arial, sans-serif;
    font-size: 0.96rem;
    font-weight: var(--font-weight-semibold);
    line-height: normal;
    text-decoration: none;
    transition: color var(--motion-duration-fast) var(--motion-ease-standard);
}

.signin:hover {
    color: var(--text-link-hover);
}

.signin:focus-visible,
.footer-about a:focus-visible,
.footer-nav a:focus-visible,
.footer-group-title:focus-visible,
.brand:focus-visible {
    outline: var(--border-focus-width) solid var(--public-focus-ring);
    outline-offset: var(--space-3);
    border-radius: var(--space-3);
}

/* ==========================================================================
   Buttons
   ========================================================================== */

/* Sized exactly like the app's practice action buttons (app-shell.css
   .question-primary-actions .btn-primary) — a visitor who signs up meets the same button. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-7) var(--space-16);
    border: 0;
    border-radius: var(--radius-button-compact);
    font-family: inherit;
    font-size: var(--public-btn-size);
    font-weight: var(--font-weight-medium);
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--motion-duration-fast) var(--motion-ease-standard);
}

.btn-primary {
    background: var(--accent-action);
    color: var(--text-on-emphasis);
}

.btn-primary:hover {
    background: var(--accent-action-hover);
}

.btn:focus-visible {
    outline: var(--border-focus-width) solid var(--public-focus-ring);
    outline-offset: var(--space-2);
}

/* ==========================================================================
   Hero
   ========================================================================== */

.hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: var(--public-column-gap);
    align-items: center;
    padding: var(--space-56) 0 var(--public-section-y);
}

.hero-copy {
    min-width: 0;
}

/* Shared micro-label language: eyebrow, section label, worked-example subheads. */
.eyebrow,
.sec-label,
.example-sub,
.fact-group {
    font-size: var(--font-size-0719);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-140);
    letter-spacing: var(--public-label-tracking);
    text-transform: uppercase;
}

.eyebrow,
.sec-label {
    margin: 0;
    color: var(--text-muted);
}

.hero-title {
    margin: var(--space-14) 0 0;
    color: var(--text-primary);
    font-size: var(--public-title-hero);
    line-height: var(--line-height-110);
    letter-spacing: var(--tracking-tight);
}

.hero-sub {
    margin: var(--space-14) 0 0;
    color: var(--text-primary);
    font-size: var(--public-deck-size);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-135);
}

.hero-lead {
    margin: var(--space-16) 0 0;
    max-width: var(--size-body-measure);
    color: var(--text-secondary);
    font-size: var(--text-body-large-size);
    line-height: var(--text-body-large-line-height);
}

/* The timing facts are the most scannable thing on the page, so they get a ruled band of their own
   rather than being buried in the lead paragraph. */
.stat-strip {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-20) var(--space-24);
    margin: var(--space-28) 0 0;
    padding: var(--space-20) 0;
    border-top: var(--border-width-hairline) solid var(--border-default);
    border-bottom: var(--border-width-hairline) solid var(--border-default);
}

.stat-v {
    color: var(--text-primary);
    font-size: var(--public-stat-size);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-120);
    letter-spacing: var(--tracking-soft-tight);
}

.stat-l {
    margin-top: var(--space-4);
    color: var(--text-muted);
    font-size: var(--font-size-084);
    line-height: var(--line-height-135);
}

.cta-row {
    margin: var(--space-28) 0 0;
}

.hero-figure {
    margin: 0;
    min-width: 0;
}

.hero-figure img {
    width: 100%;
    border: var(--border-width-hairline) solid var(--border-default);
    border-radius: var(--radius-card);
}

.hero-figure figcaption {
    margin-top: var(--space-10);
    color: var(--text-muted);
    font-size: var(--font-size-082);
    line-height: var(--line-height-140);
}

/* ==========================================================================
   Section rhythm
   ========================================================================== */

/* :not(.hero) keeps this off the hero, which sets its own top padding at class specificity. */
.public-page main > section:not(.hero) {
    padding: var(--public-section-y) 0;
}

/* A hairline rule between chapters — the welcome page's separator, not a card stack. */
.public-page main > section + section {
    border-top: var(--border-width-hairline) solid var(--border-default);
}

.sec-title {
    margin: var(--space-12) 0 0;
    max-width: var(--size-hero-measure);
    color: var(--text-strong);
    font-size: var(--public-title-section);
    line-height: var(--line-height-125);
    letter-spacing: var(--tracking-tight);
}

.sec-intro {
    margin: var(--space-14) 0 0;
    max-width: var(--size-body-measure);
    color: var(--text-secondary);
    font-size: var(--text-body-large-size);
    line-height: var(--text-body-large-line-height);
}

.steps,
.traits,
.ruled,
.faq,
.example {
    margin-top: var(--space-40);
}

/* ==========================================================================
   Steps — a sequence, so each one is ruled and time-stamped rather than boxed
   ========================================================================== */

.steps {
    display: grid;
    /* auto-fit rather than a hard-coded 3, so this stylesheet keeps working for task-type pages whose
       copy has a different step count. The floor is 240px, not 260px: at the 861px viewport where the
       single-column rule releases, the content box is 797px, so a 260px floor fitted only two columns
       and orphaned the third step on its own row until 908px. */
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: var(--space-32);
}

.step {
    padding-top: var(--space-16);
    border-top: var(--border-width-hairline) solid var(--border-default);
}

.step-n {
    color: var(--text-muted);
    font-size: var(--font-size-082);
    letter-spacing: var(--tracking-soft);
}

.step h3,
.ruled-item h3,
.trait h3 {
    margin: var(--space-8) 0 var(--space-8);
    color: var(--text-primary);
    font-size: var(--font-size-102);
    line-height: var(--line-height-130);
}

.step p,
.ruled-item p,
.trait p,
.qa p {
    margin: 0;
    color: var(--text-secondary);
    font-size: var(--font-size-094);
    line-height: var(--line-height-162);
}

/* ==========================================================================
   Marking traits — one strip split by vertical rules, the dashboard's metric
   band (dashboard.css .dashboard-metrics + .dashboard-vrule). Parallel facts
   about a single thing: dividing them is enough, boxing them would oversell
   ========================================================================== */

/* One row that shrinks rather than wraps: a wrapped row would start with a vertical rule floating at
   its left edge. Below 860px the strip stacks and the rules turn horizontal instead. */
.traits {
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
}

.trait {
    /* Count-agnostic: three traits today, a different number on another task type. */
    flex: 1 1 var(--public-trait-min);
    min-width: 0;
    padding-right: var(--public-trait-gap);
}

.trait + .trait {
    padding-left: var(--public-trait-gap);
    border-left: var(--border-width-hairline) solid var(--border-default);
}

.trait:last-child {
    padding-right: 0;
}

.trait h3 {
    margin-top: 0;
}

/* The "not scored here" clarification: an aside carrying the page's other left-ruled
   quotation mark (.model-answer, .tip), quieter than both. */
.callout {
    margin: var(--space-32) 0 0;
    max-width: var(--size-body-measure);
    padding-left: var(--space-20);
    border-left: var(--border-width-strong) solid var(--border-default);
    color: var(--text-secondary);
    font-size: var(--font-size-094);
    line-height: var(--line-height-162);
}

/* ==========================================================================
   Ruled grid — parallel items that each carry their own hairline: the common
   mistakes and what practice here adds. No danger colour on the mistakes:
   these are pitfalls in general, not this learner's errors, and red is
   reserved for real feedback
   ========================================================================== */

/* Flex, not grid, and every column grows: a grid's tracks are fixed, so an item count that does not
   divide by the column count — five items over four columns — leaves the last one hanging at the left
   under empty tracks. Growing columns spread across the whole row instead, so a row is always full
   from edge to edge whatever the count. */
.ruled,
.faq {
    display: flex;
    flex-wrap: wrap;
}

.ruled {
    gap: var(--space-32) var(--public-row-gap);
}

.ruled-item,
.qa {
    /* Count-agnostic: the row fits as many as the width allows and the rest wrap underneath. */
    flex: 1 1 var(--public-row-min);
    min-width: 0;
}

/* A row that ends up wide — the last one, when the count leaves a single item on it — must not turn
   its sentence into a full-width line. */
.ruled-item p,
.qa p {
    max-width: var(--size-body-measure);
}

.ruled-item {
    padding-top: var(--space-16);
    border-top: var(--border-width-hairline) solid var(--border-default);
}

.ruled-item h3 {
    margin-top: 0;
}

/* ==========================================================================
   Worked example — deliberately shaped like the app's feedback panel
   ========================================================================== */

/* Not a panel: the worked example runs as page content, held together by its own subheads and the
   rules inside it. Only the chart keeps a frame, because a chart on the page background reads as
   decoration rather than as the thing being described. */
.example > img {
    width: 100%;
    /* The source chart is 2108px wide; on a shell-width page it would otherwise dominate the section. */
    max-width: var(--size-hero-measure);
    border: var(--border-width-hairline) solid var(--border-default);
    border-radius: var(--radius-field);
}

.example-sub {
    margin: var(--space-32) 0 var(--space-16);
    color: var(--text-secondary);
}

/* Capped like the prose it stands in for: unbounded, a fact's sentence would run the full shell width. */
.facts {
    margin: 0;
    padding: 0;
    max-width: var(--size-hero-measure);
    list-style: none;
}

/* group tag | label over sentence — reads as a list, the way the key points come back after a real
   attempt: what the point is about, what it is, and how you would say it. */
.fact {
    display: grid;
    grid-template-columns: var(--space-128) minmax(0, 1fr);
    column-gap: var(--space-24);
    padding: var(--space-14) 0;
    border-top: var(--border-width-hairline) solid var(--border-default);
}

.fact:first-child {
    border-top: 0;
    padding-top: 0;
}

.fact-group {
    grid-row: span 2;
    padding-top: var(--space-3);
    color: var(--text-muted);
}

.fact-label {
    color: var(--text-primary);
    font-size: var(--font-size-097);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-140);
}

.fact-text {
    margin-top: var(--space-4);
    color: var(--text-secondary);
    font-size: var(--font-size-094);
    line-height: var(--line-height-162);
}

/* Long-form prose inside the card keeps the reading measure the app uses; the card itself is wider
   because the chart needs the room. */
.model-answer {
    margin: 0;
    max-width: var(--size-body-measure);
    padding-left: var(--space-20);
    border-left: var(--border-width-strong) solid var(--border-strong);
    color: var(--text-primary);
    font-size: var(--font-size-102);
    line-height: 1.7;
}

/* The app's shared Strategy-tip callout, re-declared (this page cannot load practice-feedback.css). */
.tip {
    margin: var(--space-24) 0 0;
    max-width: var(--size-body-measure);
    border-left: var(--space-2) solid var(--success-text);
    border-radius: 0 var(--space-6) var(--space-6) 0;
    padding: var(--space-12) var(--space-15);
    background: var(--success-fill);
    color: var(--success-text-dark);
    font-size: var(--font-size-0905);
    line-height: 1.65;
}

.tip-label {
    margin-right: var(--space-4);
    color: var(--success-text);
    font-weight: var(--font-weight-medium);
}

.example-closing {
    margin: var(--space-28) 0 0;
    max-width: var(--size-body-measure);
    padding-top: var(--space-20);
    border-top: var(--border-width-hairline) solid var(--border-default);
    color: var(--text-muted);
    font-size: var(--font-size-094);
    line-height: 1.7;
}

/* ==========================================================================
   FAQ
   ========================================================================== */

/* Wider columns than the ruled rows: an answer is a paragraph, not a caption. */
.faq {
    --public-row-min: 340px;

    gap: var(--space-28) var(--public-row-gap);
}

.qa {
    padding-top: var(--space-16);
    border-top: var(--border-width-hairline) solid var(--border-default);
}

.qa h3 {
    margin: 0 0 var(--space-8);
    color: var(--text-primary);
    font-size: var(--font-size-100);
    line-height: var(--line-height-135);
}

/* ==========================================================================
   Closing call to action
   ========================================================================== */

/* The closing invitation is a chapter like the others: separated by the same hairline, not framed. */
.final {
    display: grid;
    justify-items: center;
    gap: var(--space-12);
    margin: 0;
    padding: var(--public-section-y) 0;
    border-top: var(--border-width-hairline) solid var(--border-default);
    text-align: center;
}

.final h2 {
    margin: 0;
    color: var(--text-strong);
    font-size: var(--public-title-final);
    line-height: var(--line-height-125);
    letter-spacing: var(--tracking-tight);
}

.final p {
    margin: 0;
    max-width: var(--size-body-measure);
    color: var(--text-secondary);
    font-size: var(--text-body-large-size);
    line-height: var(--text-body-large-line-height);
}

.final p:last-child {
    margin-top: var(--space-10);
}

/* ==========================================================================
   Footer
   ========================================================================== */

.public-page footer {
    border-top: var(--border-width-hairline) solid var(--border-default);
    padding: var(--space-28) 0 var(--space-48);
    color: var(--text-muted);
    font-size: var(--font-size-084);
}

.footer-in {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-12) var(--space-32);
}

.footer-about {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

.footer-note {
    margin: 0;
}

/* Sibling task-type pages: the crawl path between them, and the only way a reader gets from one to
   the next without going back to the app. One column per section, in the order the generator sets. */
.footer-nav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-20) var(--space-48);
}

/* `<details>` wraps its non-summary children in the UA's own internal box (the spec calls it
   ::details-content); some browsers give that box block layout of its own, which a `display:flex`
   rule on `<details>` itself cannot reach — the links end up run together as one paragraph instead
   of a column. The column lives on this explicit wrapper instead, never on `.footer-group`. */
.footer-group-links {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

.footer-group-title {
    margin: 0 0 var(--space-4);
    color: var(--text-primary);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    list-style: none;
}

.footer-group-title::-webkit-details-marker {
    display: none;
}

.footer-group-title::after {
    content: "+";
    margin-left: var(--space-8);
    color: var(--text-muted);
}

.footer-group[open] > .footer-group-title::after {
    content: "\2212";
}

.footer-about a,
.footer-nav a {
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--motion-duration-fast) var(--motion-ease-standard);
}

.footer-about a:hover,
.footer-nav a:hover {
    color: var(--text-link-hover);
}

.footer-nav a[aria-current="page"] {
    color: var(--text-primary);
}

/* ==========================================================================
   Responsive. The SPA's breakpoints live in tokens.css, but this page is not the
   SPA: overriding shared tokens there would move app surfaces, so the public
   page's own scale is overridden here.
   ========================================================================== */

/* Laptops. A rhythm tuned on a 27" display reads as an endless scroll on a 14" one, where the same
   64px of padding above and below every chapter costs a fifth of the viewport. */
@media (max-width: 1500px) {
    .public-page {
        --public-section-y: var(--space-40);
    }
}

@media (max-width: 1024px) {
    .public-page {
        --public-page-x: var(--space-32);
        --public-section-y: var(--space-36);
        --public-column-gap: var(--space-40);
        --public-row-gap: var(--space-32);
    }
}

/* Single column: the hero's chart drops under the copy, the grids stack. */
@media (max-width: 860px) {
    .hero,
    .steps {
        grid-template-columns: minmax(0, 1fr);
    }

    /* One item per row, whatever the floor above says. */
    .ruled-item,
    .qa {
        flex-basis: 100%;
    }

    .hero {
        gap: var(--space-32);
        padding-top: var(--space-36);
    }

    .steps,
    .ruled,
    .faq {
        gap: var(--space-28);
    }

    /* Stacked, the rule between traits turns horizontal — a wrapped flex row would otherwise leave
       a vertical rule floating at the start of a line. */
    .traits {
        display: grid;
        gap: var(--space-24);
    }

    .trait,
    .trait:last-child {
        padding-right: 0;
    }

    .trait + .trait {
        padding-left: 0;
        padding-top: var(--space-24);
        border-left: 0;
        border-top: var(--border-width-hairline) solid var(--border-default);
    }
}

/* The fact table's tag column stops earning its width before the phone breakpoint. */
@media (max-width: 720px) {
    .fact {
        grid-template-columns: minmax(0, 1fr);
    }

    .fact-group {
        grid-row: auto;
        padding-top: 0;
        margin-bottom: var(--space-6);
    }
}

@media (max-width: 640px) {
    .public-page {
        --public-page-x: var(--space-20);
        --public-section-y: var(--space-32);
    }

    .bar-in {
        padding-top: var(--space-12);
        padding-bottom: var(--space-12);
        min-height: 0;
    }

    .hero {
        padding-top: var(--space-28);
    }

    .stat-strip {
        gap: var(--space-16);
    }

    /* Touch target on phones; the desktop button stays light on purpose. */
    .btn {
        min-height: var(--space-44);
    }

    .callout {
        padding-left: var(--space-16);
    }
}
