/*
    The palette from docs/30 Brand/Brand Guide.md, and only that palette. Eight colours
    and no ninth: hairlines are slate at a quarter strength rather than another grey.

    The contrast rules in that guide are constraints on where each colour may be used, so
    they are written here as the only way to reach them. There is no orange text token and
    no white-on-orange button, because both fail WCAG AA and both are the obvious thing to
    reach for.
*/
:root {
    --charcoal: #1F2937;
    --accent: #F97316;
    --success: #22C55E;
    --warning: #F59E0B;
    --error: #EF4444;
    --background: #F8FAFC;
    --slate: #6B7280;
    --surface: #FFFFFF;

    --hairline: rgba(107, 114, 128, 0.25);

    --measure: 34rem;
    --page: 68rem;

    --step: clamp(1rem, 0.6rem + 1.4vw, 1.5rem);
    --gap: clamp(2.5rem, 1.5rem + 4vw, 5rem);

    --radius: 10px;
    --focus: 3px solid var(--charcoal);
}

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

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

body {
    margin: 0;
    background: var(--background);
    color: var(--charcoal);
    font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: 1.0625rem;
    line-height: 1.6;
    font-synthesis-weight: none;
}

/* Self-hosted, because a font host is a request to somebody else's server and this site
   is selling the promise that PYFFO does not make those. The licence sits beside them. */
@font-face {
    font-family: Inter; font-style: normal; font-weight: 400; font-display: swap;
    src: url("../fonts/Inter-Regular.woff2") format("woff2");
}
@font-face {
    font-family: Inter; font-style: normal; font-weight: 500; font-display: swap;
    src: url("../fonts/Inter-Medium.woff2") format("woff2");
}
@font-face {
    font-family: Inter; font-style: normal; font-weight: 600; font-display: swap;
    src: url("../fonts/Inter-SemiBold.woff2") format("woff2");
}
@font-face {
    font-family: Inter; font-style: normal; font-weight: 700; font-display: swap;
    src: url("../fonts/Inter-Bold.woff2") format("woff2");
}

h1, h2, h3, h4 { font-weight: 500; line-height: 1.15; margin: 0 0 0.5em; text-wrap: balance; }
h1 { font-size: clamp(2.25rem, 1.5rem + 3.4vw, 4rem); font-weight: 700; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.35rem); letter-spacing: -0.01em; }
h3 { font-size: 1.2rem; font-weight: 600; }
p { margin: 0 0 1rem; max-width: var(--measure); text-wrap: pretty; }
strong { font-weight: 600; }
ul, ol { max-width: var(--measure); }

a { color: inherit; text-underline-offset: 0.2em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

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

/* The router moves focus to the heading on navigation so a screen reader announces the
   new page. Nobody tabbed there, so a visible ring would only puzzle people who can
   see it. The focus itself — the part that does the work — stays. */
[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible { outline: none; }

.skip {
    position: absolute; left: -9999px; top: 0; z-index: 10;
    background: var(--charcoal); color: var(--background);
    padding: 0.75rem 1rem; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; }

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

.shell { max-width: var(--page); margin-inline: auto; padding-inline: var(--step); }

.band { padding-block: var(--gap); border-top: 1px solid var(--hairline); }
.band:first-of-type { border-top: 0; }
.band--inverted { background: var(--charcoal); color: var(--background); border-top: 0; }
.band--inverted .lede, .band--inverted .caption { color: #CBD5E1; }

.lede { font-size: 1.2rem; color: var(--slate); max-width: var(--measure); }

/* The core promise sits directly under the hero headline. As a .lede it rendered in the
   muted grey and read as weaker than the plain paragraph beneath it, which is backwards:
   this is the line the brand is built on. */
.promise {
    font-size: clamp(1.25rem, 1.05rem + 0.8vw, 1.6rem);
    color: var(--charcoal); font-weight: 500;
    /* Slightly wider than the body measure: at this size the promise is a few
       characters too long for it and breaks after "Measure", which splits the third
       clause across two lines. */
    max-width: 42rem; margin-bottom: 0.75rem; text-wrap: balance;
}
.caption { font-size: 0.9375rem; color: var(--slate); }

/* Slate on charcoal is 3.04:1 — large text and interface elements only, never body. */
.eyebrow {
    font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--slate); margin: 0 0 0.75rem;
}

.grid { display: grid; gap: 1.25rem; }
@media (min-width: 40rem) { .grid--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 52rem) { .grid--3 { grid-template-columns: repeat(3, 1fr); } }

.card {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    padding: 1.5rem;
}
.card h3 { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

/* Wordmark --------------------------------------------------------------------------- */

/* PYFFO. — charcoal letters, orange full stop. A wordmark, never a logo, and the dot is
   never used on its own. The orange carries no meaning here, so it need not be readable
   as text; the word beside it is. */
.wordmark { font-weight: 700; letter-spacing: -0.01em; color: var(--charcoal); }
.wordmark__dot { color: var(--accent); }
.band--inverted .wordmark, footer .wordmark { color: var(--background); }

/* Header and footer ------------------------------------------------------------------ */

.masthead { border-bottom: 1px solid var(--hairline); background: var(--background); }
.masthead__inner {
    display: flex; align-items: center; justify-content: space-between;
    gap: 1rem; padding-block: 1rem; flex-wrap: wrap;
}
.masthead__nav { display: flex; gap: 0.25rem 1rem; align-items: center; flex-wrap: wrap; }

/* Each link owns a 44px target. On a phone these wrap to two rows, and a 24px line of
   text is not something anyone should have to aim a thumb at. The negative inline margin
   keeps the visual gap looking like the original 1.25rem while the tappable box is
   larger than the text it contains. */
.masthead__nav a {
    text-decoration: none; font-size: 0.9375rem; font-weight: 500;
    display: inline-flex; align-items: center;
    min-height: 44px; padding-inline: 0.375rem; margin-inline: -0.375rem;
}
.masthead__nav a:hover { text-decoration: underline; }
.masthead .wordmark { font-size: 1.375rem; text-decoration: none; }

/* Once the links wrap, the 44px targets already provide the breathing room the block
   padding was giving, and on a 320px screen the header should not take a quarter of the
   viewport before the page has said anything. */
@media (max-width: 33.99rem) {
    .masthead__inner { padding-block: 0.5rem; gap: 0.25rem; }
}

footer { background: var(--charcoal); color: var(--background); padding-block: var(--gap); }
footer a { color: var(--background); }
footer .caption { color: #CBD5E1; }
footer .eyebrow { color: #94A3B8; }

.footer__grid { display: grid; gap: 2rem; }
@media (min-width: 40rem) { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 58rem) { .footer__grid { grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 2.5rem; } }

.footer__links { list-style: none; margin: 0; padding: 0; }
.footer__links li { margin-bottom: 0.5rem; }
.footer__links a { font-size: 0.9375rem; text-decoration: none; }
.footer__links a:hover { text-decoration: underline; }

.footer__legal { margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid rgba(203, 213, 225, 0.2); }

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

.button {
    display: inline-block; font: inherit; font-weight: 600; text-align: center;
    padding: 0.8rem 1.5rem; border-radius: var(--radius); border: 1px solid transparent;
    cursor: pointer; text-decoration: none;
}
.button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Charcoal on orange is 5.24:1. White on orange is 2.80:1 and is never used. */
.button--primary { background: var(--accent); color: var(--charcoal); }
.button--primary:hover:not(:disabled) { background: #EA6A0B; }

.button--secondary { background: transparent; color: var(--charcoal); border-color: var(--charcoal); }
.button--secondary:hover:not(:disabled) { background: rgba(31, 41, 55, 0.06); }

.button--quiet { background: transparent; color: var(--slate); padding-inline: 0.5rem; }
.button--quiet:hover:not(:disabled) { color: var(--charcoal); }

.band--inverted .button--secondary { color: var(--background); border-color: var(--background); }

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

/* Figures ---------------------------------------------------------------------------- */

.figure { font-weight: 700; font-size: clamp(2rem, 1.4rem + 2.4vw, 3rem); line-height: 1; font-variant-numeric: tabular-nums; }
.figure__label { color: var(--slate); font-size: 0.9375rem; margin-top: 0.35rem; }

.sum {
    font-variant-numeric: tabular-nums;
    background: var(--surface); border: 1px solid var(--hairline);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius); padding: 1rem 1.25rem;
}
.sum p { margin-bottom: 0.35rem; }
.sum p:last-child { margin-bottom: 0; }

/* Method ----------------------------------------------------------------------------- */

.stages { list-style: none; margin: 0; padding: 0; max-width: none; display: grid; gap: 1rem; counter-reset: stage; }
@media (min-width: 40rem) { .stages { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 60rem) { .stages { grid-template-columns: repeat(3, 1fr); } }
.stages li { counter-increment: stage; background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 1.25rem; }
.stages li::before {
    content: counter(stage); display: block; font-weight: 700; font-size: 0.875rem;
    color: var(--slate); margin-bottom: 0.35rem;
}
.stages h3 { margin-bottom: 0.25rem; }
.stages p { margin: 0; font-size: 0.9375rem; color: var(--slate); }

/* The method, at length: one stage per row rather than a card grid. */
.stages--full { grid-template-columns: 1fr !important; counter-reset: stage; gap: 1.25rem; }
.stages--full li { padding: 1.5rem 1.75rem; }
.stages--full h2 { font-size: 1.35rem; margin: 0.15rem 0 0.35rem; }
.stages--full p { font-size: 1rem; color: var(--charcoal); margin-bottom: 0.75rem; }
.stages--full .caption { color: var(--slate); font-size: 0.9375rem; }
.stages__aim { font-weight: 600; }
.stages__outcome {
    margin: 1rem 0 0 !important; padding-top: 0.75rem; border-top: 1px solid var(--hairline);
    font-weight: 600;
}

/* Editions --------------------------------------------------------------------------- */

.edition--lead { border-color: var(--accent); border-width: 2px; }
.edition__price { font-weight: 700; font-size: 1.75rem; font-variant-numeric: tabular-nums; }
.edition__note { font-size: 0.9375rem; color: var(--slate); }
.edition ul { padding-left: 1.1rem; font-size: 0.9375rem; }
.edition li { margin-bottom: 0.35rem; }

/* A word, never a colour on its own. */
.flag {
    display: inline-block; font-size: 0.75rem; font-weight: 700; letter-spacing: 0.06em;
    text-transform: uppercase; background: var(--accent); color: var(--charcoal);
    padding: 0.15rem 0.5rem; border-radius: 999px; margin-bottom: 0.75rem;
}

/* Screenshots ------------------------------------------------------------------------ */

/* The product is the hero, so the screens get room rather than a decorative frame. */
.shots { display: grid; gap: 2rem; margin-top: 2rem; }
/* Four phone screens read as one pass through the product, so they get one row where
   there is space rather than three and an orphan. */
@media (min-width: 46rem) { .shots { grid-template-columns: repeat(2, 1fr); gap: 2rem; } }
@media (min-width: 62rem) { .shots { grid-template-columns: repeat(5, 1fr); gap: 1rem; } }

/* Where there is room beside the text column, the screens take it. Five phones inside a
   measure meant for prose leaves each one at about half its real size, and the product is
   supposed to be the hero here. Only past the width where the margin can absorb it. */
@media (min-width: 82rem) { .shots { margin-inline: -6rem; } }
.shots figure { margin: 0; }
.shots img {
    display: block; width: 100%; height: auto; max-width: 368px;
    border: 1px solid var(--hairline); border-radius: var(--radius); background: var(--surface);
}
.shots figcaption { margin-top: 0.75rem; max-width: 24rem; }

/* Comparison ------------------------------------------------------------------------- */

/* Wide content scrolls inside its own box; the page itself never scrolls sideways. */
.table-scroll { overflow-x: auto; margin-top: 1.5rem; }

/* Only worth saying where the table actually overflows. */
.table-hint { display: none; margin-bottom: 0; }
@media (max-width: 48rem) {
    .table-hint { display: block; margin-top: 1.5rem; }
    .table-scroll { margin-top: 0.5rem; }
}

.compare { border-collapse: collapse; width: 100%; min-width: 44rem; font-size: 0.9375rem; }
.compare caption { caption-side: bottom; text-align: left; padding-top: 1rem; }
.compare th, .compare td {
    text-align: left; vertical-align: top; padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--hairline);
}
.compare thead th { font-weight: 600; font-size: 1rem; border-bottom-width: 2px; }
.compare thead th:nth-child(2) { color: var(--charcoal); }
.compare tbody th { font-weight: 500; color: var(--slate); width: 11rem; }
.compare code { font-size: 0.8125rem; }

/* Question and answer, as prose rather than an accordion: there is no reason to make
   somebody click to read four lines. */
.qa { padding-block: 1.25rem; border-top: 1px solid var(--hairline); max-width: 44rem; }
.qa h3 { margin-bottom: 0.4rem; }
.qa p { margin-bottom: 0; max-width: none; }

/* The three context cards are headings so the page has no gap between h1 and h3, and
   sized like the card headings they sit beside. */
.choice__name { font-size: 1.2rem; font-weight: 600; margin: 0 0 0.5em; }

/* Questions -------------------------------------------------------------------------- */

fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
legend { padding: 0; }

.choices { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 1.25rem; }

.progress { font-size: 0.875rem; color: var(--slate); font-variant-numeric: tabular-nums; }

.quantities { display: grid; gap: 0.75rem; margin-top: 1rem; }
@media (min-width: 34rem) { .quantities { grid-template-columns: repeat(3, 1fr); } }
.quantities label { display: block; font-size: 0.875rem; color: var(--slate); margin-bottom: 0.25rem; }

/* The question step holds one height for the whole run. Answering a question used to
   resize the page under the pointer: the recognition questions are short, the quantity
   questions are tall, and the running total appeared mid-keystroke and shoved the
   buttons down. These are floors, not fixed heights — longer content still grows. */
.ask { min-height: 30rem; animation: ask-in 200ms ease-out both; }
.ask__note { min-height: 3.25rem; }
.ask__sum { min-height: 4rem; margin-top: 1rem; }
.ask__back { min-height: 2.75rem; }

/* Below the quantity fields' three-column breakpoint they stack, so that step grows
   by roughly two field heights and the floor has to rise with it. */
@media (max-width: 33.99rem) {
    .ask { min-height: 44rem; }
    .ask__sum { min-height: 5.75rem; }
}

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

@media (prefers-reduced-motion: reduce) {
    .ask { animation: none; }
}

input[type="number"], input[type="text"], input[type="email"] {
    font: inherit; width: 100%; padding: 0.6rem 0.7rem;
    border: 1px solid var(--hairline); border-radius: var(--radius);
    background: var(--surface); color: var(--charcoal);
}

/* A label above its field, and a tick box beside its words. */
.field { margin-bottom: 1rem; }
.field > label { display: block; font-size: 0.875rem; color: var(--slate); margin-bottom: 0.25rem; }

.consent { display: flex; gap: 0.65rem; align-items: flex-start; cursor: pointer; }
.consent input[type="checkbox"] { width: 1.15rem; height: 1.15rem; margin: 0.2rem 0 0; accent-color: var(--charcoal); flex: none; }
.consent span { font-size: 0.9375rem; }

.problem { border-left: 4px solid var(--error); }

.finding { border-top: 1px solid var(--hairline); padding-block: 1.25rem; }
.finding:first-of-type { border-top: 0; }
.finding__head { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; align-items: baseline; }
.finding__hours { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
.finding__question { font-style: italic; }

.note { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 1rem 1.25rem; }
.note p:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
