/* ====================================================================
   NATIONAL PRINT SOURCING - Prototype Stylesheet
   Created:  2026-05-08
   Platform: WordPress (prototype is custom HTML/CSS)
   ====================================================================
   Reference: prototype/DESIGN_SYSTEM.md is the canonical rule book.
   All values here are derived from that document. If the design system
   updates, this file updates first.
   ==================================================================== */


/* ====================================================================
   1. DESIGN TOKENS
   ==================================================================== */
:root {

    /* Brand - primary navy stack */
    --navy-deep:    #0A2540;
    --navy:         #0F3358;
    --navy-soft:    #1A4870;

    /* Brand - action cyan (the C/"N" in the NPS logo).
       Michael's exact brand cyan is #16B3E4, but white text on it only clears
       2.4:1 (fails WCAG). So --cyan-action is a slightly darkened shade of the
       same hue that passes AA on white (4.68:1) for buttons/links/eyebrows,
       and --cyan-bright is the exact brand cyan, used for hovers and accents
       on dark surfaces where it reads against navy. */
    --brand-cyan:    #16B3E4;   /* logo "N" - exact brand cyan */
    --cyan-action:   #0B7DA4;   /* CTAs, links, active states (AA on white) */
    --cyan-bright:   #16B3E4;   /* hover, dark-surface accents */

    /* Brand - CMYK accents from the logo (P = yellow, S = magenta).
       Used in intentional small doses: step numbers, tag dots, accents.
       Never as a section flood or button background. */
    --brand-magenta: #E74298;   /* logo "S" */
    --brand-yellow:  #FEE728;   /* logo "P" */
    --magenta-tag:   #E74298;
    --yellow-tag:    #FEE728;

    /* Neutrals */
    --black-key:    #0F1419;
    --gray-900:     #1A1A1A;
    --gray-700:     #4A4A4A;
    --gray-500:     #6B7280;
    --gray-300:     #D1D5DB;
    --gray-200:     #E5E7EB;
    --gray-100:     #F3F4F6;
    --gray-50:      #F9FAFB;
    --white:        #FFFFFF;

    /* Surfaces */
    --tint-cool:    #EFF4F8;
    --surface:      var(--white);
    --surface-alt:  var(--tint-cool);
    --surface-dark: var(--navy-deep);

    /* Typography */
    --font:         'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

    /* Spacing scale */
    --s-1:  4px;
    --s-2:  8px;
    --s-3:  12px;
    --s-4:  16px;
    --s-5:  24px;
    --s-6:  32px;
    --s-7:  48px;
    --s-8:  64px;
    --s-9:  96px;
    --s-10: 128px;

    /* Layout */
    --max-w:        1200px;
    --pad-x:        24px;
    --nav-h:        72px;

    /* Motion */
    --t-fast:       150ms ease;
    --t-med:        200ms ease;
}


/* ====================================================================
   2. RESET & BASE
   ==================================================================== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
    font-size: 16px;
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

/* In-page anchor targets clear the fixed 72px nav when scrolled to. */
#how-it-works,
#what-we-source,
#why-nps {
    scroll-margin-top: calc(var(--nav-h) + 20px);
}

body {
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.65;
    color: var(--gray-900);
    background: var(--white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

img, svg, video { max-width: 100%; display: block; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }


/* ====================================================================
   3. TYPOGRAPHY
   ==================================================================== */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font);
    color: var(--navy);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -0.015em;
}

/* Display + section headings carry extrabold weight (800) at Michael's request
   for "stronger, bolder headlines, clearly different from the body text"
   (body is 400). Sub-headings stay at 600/700 so the hierarchy still steps
   down cleanly rather than everything shouting. */
h1 { font-size: 56px; font-weight: 800; line-height: 1.05; letter-spacing: -0.025em; }
h2 { font-size: 40px; font-weight: 800; line-height: 1.15; letter-spacing: -0.02em; }
h3 { font-size: 24px; font-weight: 700; line-height: 1.3; letter-spacing: -0.01em; }
h4 { font-size: 18px; font-weight: 600; line-height: 1.35; letter-spacing: 0; }

p { margin: 0; max-width: 65ch; }
p + p { margin-top: var(--s-4); }

.eyebrow {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cyan-action);
    margin-bottom: var(--s-3);
}

/* Eyebrow on dark surfaces uses a brighter cyan for legibility */
.dark .eyebrow,
.eyebrow--bright {
    color: var(--cyan-bright);
}

/* Body size variants */
.body-lg { font-size: 18px; line-height: 1.6; }
.body-sm { font-size: 14px; line-height: 1.5; color: var(--gray-700); }

/* Lede paragraph - slightly larger, used after heroes */
.lede { font-size: 18px; line-height: 1.6; max-width: 60ch; color: var(--gray-700); }

strong { font-weight: 600; }


/* ====================================================================
   4. LAYOUT - CONTAINER, SECTIONS
   ==================================================================== */
.container {
    width: 100%;
    max-width: var(--max-w);
    margin: 0 auto;
    padding: 0 var(--pad-x);
}

/* Section - default vertical rhythm. 96px top/bottom desktop. */
.section { padding: var(--s-9) 0; }
.section--compact { padding: var(--s-8) 0; }
.section--tall { padding: var(--s-10) 0 var(--s-9); }

/* Surface variants (alternation rule: never two adjacent same-bg sections) */
.section--alt   { background: var(--tint-cool); }

/* 08-12-2026 contrast fix. --cyan-action and --gray-500 were chosen to pass
   AA on WHITE (see the palette note above), and they do. On the cool tint they
   drop to 4.23:1 and 4.37:1, just under the 4.5:1 AA floor for normal text.
   Rather than darken the brand colours everywhere, each steps one shade darker
   only inside tinted surfaces, so every element that already passes on white
   keeps exactly the approved colour. Measured after the change: 5.01:1 and
   4.85:1. */
.section--alt,
.stats {
    --cyan-action: #0A7098;
    --gray-500:    #646B77;
}
.section--dark  { background: var(--navy-deep); color: rgba(255,255,255,0.9); }
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: var(--white); }

/* Section heading block - left-aligned by default */
.section__head {
    margin-bottom: var(--s-6);
    max-width: 720px;
}
.section__head .lede { margin-top: var(--s-4); }

/* Centered head variant (used for things like logo walls or stat strips) */
.section__head--center {
    text-align: center;
    margin-left: auto;
    margin-right: auto;
}


/* ====================================================================
   5. BUTTONS
   ==================================================================== */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: 14px 28px;
    border-radius: 4px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    border: 1.5px solid transparent;
    transition: background-color var(--t-fast), color var(--t-fast), border-color var(--t-fast);
    white-space: nowrap;
}

/* Primary - solid cyan */
.btn--primary {
    background: var(--cyan-action);
    color: var(--white);
    border-color: var(--cyan-action);
}
.btn--primary:hover {
    background: var(--cyan-bright);
    border-color: var(--cyan-bright);
}

/* Secondary on light - outlined navy */
.btn--secondary {
    background: transparent;
    color: var(--navy);
    border-color: var(--navy);
}
.btn--secondary:hover {
    background: rgba(15, 51, 88, 0.08);
}

/* Secondary on dark - outlined white, fills white on hover */
.btn--secondary-dark {
    background: transparent;
    color: var(--white);
    border-color: var(--white);
}
.btn--secondary-dark:hover {
    background: var(--white);
    color: var(--navy);
}

/* Tertiary text-only link with arrow.
   Explicitly zeros out the .btn padding/border so when the element has BOTH
   `btn` and `btn--text` classes the text aligns flush with surrounding copy. */
.btn--text {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--cyan-action);
    font-weight: 600;
    font-size: 15px;
    transition: color var(--t-fast);
    padding: 0;
    border: none;
    border-radius: 0;
    background: none;
}
.btn--text .arrow { transition: transform var(--t-fast); }
.btn--text:hover { color: var(--cyan-bright); }
.btn--text:hover .arrow { transform: translateX(4px); }

/* Smaller variant for nav CTA */
.btn--sm { padding: 10px 20px; font-size: 15px; }


/* ====================================================================
   6. NAVIGATION
   ==================================================================== */
.nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    height: var(--nav-h);
    display: flex;
    align-items: center;
    transition: background-color var(--t-med), border-color var(--t-med);
    background: var(--white);
    border-bottom: 1px solid var(--gray-200);
}

/* Transparent variant used on dark hero pages */
.nav--transparent {
    background: transparent;
    border-bottom-color: transparent;
}
.nav--transparent .nav__link { color: var(--white); }
.nav--transparent .nav__logo-text { color: var(--white); }

/* When scrolled, transparent nav becomes solid */
.nav--transparent.scrolled {
    background: var(--white);
    border-bottom-color: var(--gray-200);
}
.nav--transparent.scrolled .nav__link { color: var(--navy); }
.nav--transparent.scrolled .nav__logo-text { color: var(--navy); }

/* 3-column grid: logo / centered links / right-aligned CTA + mobile toggle.
   The links live in their own column at viewport center, not floating
   between siblings. With grid-column explicitly set, the layout still
   works when nav__links is hidden on mobile. */
.nav__inner {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    width: 100%;
}
.nav__logo  { grid-column: 1; justify-self: start; }
.nav__links { grid-column: 2; justify-self: center; }
.nav__right { grid-column: 3; justify-self: end; display: flex; align-items: center; gap: var(--s-3); }

.nav__logo {
    display: flex;
    align-items: center;
    gap: var(--s-3);
}
.nav__logo img { height: 48px; width: auto; }
.nav__logo-text {
    font-size: 16px;
    font-weight: 700;
    color: var(--navy);
    letter-spacing: -0.01em;
}

.nav__links {
    display: flex;
    align-items: center;
    gap: var(--s-6);
}

.nav__link {
    font-size: 15px;
    font-weight: 500;
    color: var(--navy);
    position: relative;
    padding: 8px 0;
    transition: color var(--t-fast);
}
.nav__link:hover { color: var(--cyan-action); }

/* Active state - restrained 2px cyan underline below baseline */
.nav__link--active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -2px;
    height: 2px;
    background: var(--cyan-action);
}
/* On transparent dark nav, active underline is bright */
.nav--transparent:not(.scrolled) .nav__link--active::after { background: var(--cyan-bright); }

.nav__cta { margin-left: 0; }

/* --------------------------------------------------------------------
   NAV DROPDOWN - "For Production Partners" (08-11-2026 review)
   The panel is hidden with visibility, not the hidden attribute, so the
   open state can animate and so its links leave the tab order while
   closed. visibility:hidden also keeps them out of the a11y tree.
   -------------------------------------------------------------------- */
.nav__item--has-menu { position: relative; display: flex; align-items: center; }

.nav__link--menu {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: none;
    border: 0;
    cursor: pointer;
    font-family: inherit;
}
.nav__caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid currentColor;
    transition: transform var(--t-fast);
}
.nav__item--open .nav__caret { transform: rotate(180deg); }

.nav__submenu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translate(-50%, -4px);
    min-width: 220px;
    margin-top: 10px;
    padding: 8px 0;
    background: var(--white);
    border: 1px solid var(--gray-200);
    box-shadow: 0 8px 24px rgba(2, 10, 22, 0.12);
    display: flex;
    flex-direction: column;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-fast), transform var(--t-fast), visibility var(--t-fast);
    z-index: 210;
}
.nav__item--open .nav__submenu {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}
/* A hover gap between the button and the panel would close the menu as the
   pointer crosses it, so the panel's own padding reaches back up to the nav. */
.nav__submenu::before {
    content: "";
    position: absolute;
    top: -10px;
    left: 0;
    right: 0;
    height: 10px;
}
.nav__submenu a {
    display: block;
    padding: 10px 18px;
    font-size: 15px;
    font-weight: 500;
    color: var(--navy);
    white-space: nowrap;
    transition: background var(--t-fast), color var(--t-fast);
}
.nav__submenu a:hover,
.nav__submenu a:focus-visible {
    background: var(--tint-cool);
    color: var(--cyan-action);
}
/* The panel is always white, so its links stay navy even under the
   transparent dark nav on the homepage. */
.nav--transparent .nav__submenu a { color: var(--navy); }

/* Four buyer-side items plus a long parent label need a tighter gap before
   the links row would collide with the logo and the CTA. */
@media (max-width: 1180px) {
    .nav__links { gap: var(--s-5); }
    .nav__link  { font-size: 14px; }
}
/* Below ~1024px the four buyer-side items plus the long parent label reached
   the Submit a Project button with no gap left. Nothing overlapped, but it
   read as cramped on tablet-landscape widths. */
@media (max-width: 1024px) {
    .nav__links { gap: var(--s-4); }
    .nav__link  { font-size: 13px; }
    /* Keep the three nav columns from meeting edge to edge on tablet widths. */
    .nav__inner { column-gap: var(--s-4); }
}

/* Mobile overlay grouping for the same two partner links. */
.nav__overlay-group { display: flex; flex-direction: column; gap: var(--s-4); }
.nav__overlay-label {
    display: block;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
}
.nav__overlay-group ul {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
    padding-left: var(--s-4);
    border-left: 2px solid rgba(255, 255, 255, 0.18);
}
.nav__overlay-group ul a { font-size: 20px; }

/* Hamburger (mobile) */
.nav__toggle {
    display: none;
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
}
.nav__toggle span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--navy);
    position: relative;
}
.nav__toggle span::before,
.nav__toggle span::after {
    content: "";
    position: absolute;
    left: 0;
    width: 22px;
    height: 2px;
    background: var(--navy);
}
.nav__toggle span::before { top: -7px; }
.nav__toggle span::after  { top: 7px; }

.nav--transparent:not(.scrolled) .nav__toggle span,
.nav--transparent:not(.scrolled) .nav__toggle span::before,
.nav--transparent:not(.scrolled) .nav__toggle span::after { background: var(--white); }


/* Mobile overlay menu */
.nav__overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 200;
    background: var(--navy-deep);
    color: var(--white);
    padding: var(--s-7) var(--pad-x);
    flex-direction: column;
}
.nav__overlay.is-open { display: flex; }

/* The X button must overlap the hamburger so a user tapping the same spot
   closes the menu. Hamburger is a 40x40 button living in a 72px-tall fixed
   nav, with the .container's 24px horizontal padding. The numbers below
   match so the X sits exactly where the hamburger was. */
.nav__overlay-close {
    position: absolute;
    top: calc((var(--nav-h) - 40px) / 2);   /* vertically center within nav strip */
    right: var(--pad-x);
    width: 40px;
    height: 40px;
    color: var(--white);
    font-size: 32px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}
.nav__overlay-links {
    margin-top: var(--nav-h);              /* clear the X button row */
    display: flex;
    flex-direction: column;
    gap: var(--s-6);
}
.nav__overlay-links a {
    font-size: 24px;
    font-weight: 600;
    color: var(--white);
}


/* Page padding to clear fixed nav */
main { padding-top: var(--nav-h); }
.has-dark-hero main { padding-top: 0; }


/* ====================================================================
   7. HERO - PATTERN B (DARK + DOT PATTERN)
   ==================================================================== */
.hero-b {
    position: relative;
    background: var(--navy-deep);
    color: var(--white);
    padding: calc(var(--nav-h) + var(--s-9)) 0 var(--s-9);
    overflow: hidden;
    isolation: isolate;
}

/* Background photo of the North American partner network. The image fills
   the entire hero and lives behind the content. A gradient overlay on top
   ensures the headline and CTAs stay legible at every viewport size. */
.hero-b__bg {
    position: absolute;
    inset: 0;
    z-index: -2;
    /* 08-12-2026: JPEG, not PNG. This is a photograph, and as a PNG it was
       2.2 MB, which was most of a 3.2 MB homepage. Its alpha channel was 100%
       opaque, and it sits under the dark gradient below, so nothing is lost.
       301 KB at quality 88. */
    background-image: url('../img/hero-bg.jpg');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

/* Gradient overlay - heavier on the left where the text sits, lighter on
   the right so more of the underlying map visual remains visible. Uses a
   very deep blue (close to midnight) so the tint reads as darker than the
   default navy without losing the blue undertone. */
.hero-b::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(
        90deg,
        rgba(2, 10, 22, 0.94) 0%,
        rgba(2, 10, 22, 0.82) 35%,
        rgba(2, 10, 22, 0.55) 70%,
        rgba(2, 10, 22, 0.38) 100%
    );
    pointer-events: none;
}

.hero-b__inner {
    position: relative;
}
.hero-b__text { max-width: 620px; }
.hero-b h1 { color: var(--white); margin-bottom: var(--s-4); }
.hero-b .lede { color: rgba(255,255,255,0.92); max-width: 60ch; margin-bottom: var(--s-7); }
.hero-b__ctas {
    display: flex;
    gap: var(--s-4);
    flex-wrap: wrap;
}


/* ====================================================================
   8. HERO - PATTERN A (LIGHT SPLIT, INTERIOR PAGES)
   ==================================================================== */
.hero-a {
    background: var(--white);
    padding: calc(var(--nav-h) + var(--s-8)) 0 var(--s-8);
}
.hero-a__grid {
    display: grid;
    grid-template-columns: 6fr 4fr;
    gap: var(--s-8);
    align-items: center;
}
.hero-a h1 { margin-bottom: var(--s-4); }
.hero-a .lede { margin-bottom: var(--s-7); }
.hero-a__visual {
    background: var(--tint-cool);
    aspect-ratio: 4 / 3;
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: 14px;
    /* Placeholder; replaced with illustration in production */
}
.hero-a__ctas {
    display: flex;
    gap: var(--s-4);
    flex-wrap: wrap;
}


/* ====================================================================
   9. STAT STRIP
   ==================================================================== */
.stats {
    padding: var(--s-8) 0;
    background: var(--tint-cool);
}
.stats--dark { background: var(--navy-deep); color: var(--white); }

.stats__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-7);
}
.stats--3 .stats__grid { grid-template-columns: repeat(3, 1fr); }

.stat {
    text-align: left;
    padding-right: var(--s-4);
}
.stat__num {
    font-size: 56px;
    font-weight: 800;
    line-height: 1;
    color: var(--navy);
    letter-spacing: -0.025em;
    margin-bottom: var(--s-2);
}
.stats--dark .stat__num { color: var(--white); }

/* Promises variant - the "num" slot holds word phrases (Manual, 1 Day,
   USA & Canada) rather than scale numbers, so the type size drops to keep
   the longer strings on one line and the label gets a touch more weight. */
.stats--promises .stat__num {
    font-size: 32px;
    line-height: 1.1;
    letter-spacing: -0.015em;
}
.stats--promises .stat__label {
    font-size: 14px;
    color: var(--gray-700);
    line-height: 1.4;
}

.stat__label {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gray-500);
}
.stats--dark .stat__label { color: rgba(255,255,255,0.7); }


/* ====================================================================
   10. 3-COLUMN CARD GRID
   ==================================================================== */
.cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-6);
}

/* Two-up variant for four-item groups, so the fourth card does not strand
   itself on a row of its own. Added 08-11-2026 for the Why NPS buyer-benefit
   section. The 1024px and 768px rules below already narrow .cards to 2 and 1
   column, and they come later in the file, so they still win. */
.cards--2up { grid-template-columns: repeat(2, 1fr); }

/* --------------------------------------------------------------------
   INLINE PROSE LINKS
   Links inside body copy inherited the paragraph colour with no underline,
   which made them indistinguishable from ordinary words. Buttons and the
   .btn--text arrow links carry their own styling and are excluded.
   Added 08-11-2026.
   -------------------------------------------------------------------- */
main p a:not([class]),
main .lede a:not([class]) {
    color: var(--cyan-action);
    text-decoration: underline;
    text-underline-offset: 2px;
    text-decoration-thickness: 1px;
}
main p a:not([class]):hover,
main .lede a:not([class]):hover {
    color: var(--navy);
}
/* On the dark CTA band the action cyan would not carry enough contrast. */
.cta-dark p a:not([class]) { color: var(--cyan-bright); }
.cta-dark p a:not([class]):hover { color: var(--white); }

/* Cards on a WHITE section lose their border and padding by house rule (see
   .section:not(.section--alt) .card below). That reads as loose text when the
   cards carry no artwork, so this modifier opts a group back into the boxed
   treatment. Added 08-11-2026 for the Why NPS buyer-benefit section. */
.section:not(.section--alt) .cards--boxed .card {
    border: 1px solid var(--gray-200);
    background: var(--white);
}
.section:not(.section--alt) .cards--boxed .card .card__body {
    padding-left: var(--s-5);
    padding-right: var(--s-5);
}

/* A section that is a bare strip of cards with no heading above them. Without
   this the standard section padding reads as a hole where a title should be.
   Added 08-11-2026 when the review removed the redundant "What Makes Us
   Different" heading from Why NPS but kept its three cards. */
.section--strip { padding-top: var(--s-6); padding-bottom: var(--s-7); }

.card {
    background: var(--white);
    border: 1px solid var(--gray-200);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
/* On already-light section, cards have no border */
.section:not(.section--alt) .card { border: none; background: transparent; }
.section:not(.section--alt) .card .card__body { padding-left: 0; padding-right: 0; }

/* Photographic variant of .card__img - the img inside fills the 16:9
   container with cover-fit so we never get letterboxing. */
.card__img--img {
    padding: 0;
}
.card__img--img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.card__img {
    aspect-ratio: 16 / 9;
    background: var(--tint-cool);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: 13px;
    overflow: hidden;
    /* Placeholder; swap in real images later */
}

.card__body {
    padding: var(--s-5);
    display: flex;
    flex-direction: column;
    flex: 1;
}
.card__body h3 {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: var(--s-3);
    color: var(--navy);
}
.card__body p {
    font-size: 15px;
    color: var(--gray-700);
    line-height: 1.6;
    margin-bottom: var(--s-4);
    flex: 1;
}
.card__body .btn--text { margin-top: auto; align-self: flex-start; }

/* Content cards have NO hover lift: the card itself is not a link (only any
   button/link inside it is clickable), and a hover animation on a non-clickable
   element falsely signals interactivity. Re-add only if a whole card becomes a
   link. The interactive form cards (.choice-card / .radio-card) keep their hover. */


/* ====================================================================
   11. 2-COLUMN IMAGE + TEXT SPLIT
   ==================================================================== */
.split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-8);
    align-items: center;
}

.split--reverse .split__visual { order: 2; }
.split--reverse .split__text   { order: 1; }

/* Photographic variant of .split__visual - the img fills the 4:3
   container with cover-fit. Same pattern as .card__img--img. */
.split__visual--img {
    padding: 0;
}
.split__visual--img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.split__visual {
    aspect-ratio: 4 / 3;
    background: var(--tint-cool);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: 13px;
    overflow: hidden;
}
.split__text { max-width: 540px; }
/* h2 as well as h3: split section titles are h2 so the page keeps a valid
   h1 -> h2 -> h3 outline, and they need the same gap above their copy. */
.split__text h2,
.split__text h3 { margin-bottom: var(--s-4); }
.split__text p { color: var(--gray-700); margin-bottom: var(--s-4); }


/* ====================================================================
   11b. LOCATIONS COVERAGE LISTS (states / provinces)
   Column-major name lists. column-width 140px (a MIN width) caps how narrow
   a column can get, so a long single name (e.g. "Massachusetts") can never be
   wider than its column and overflow; the count (4 for US, 3 for Canada) is
   the MAX. The Canada list is width-constrained to exactly three US-column
   widths (75% - one quarter of the gap), so its 3 columns are the SAME width
   as the US 4 and line up under the first three (the 4th slot stays empty).
   Below ~704px, where the US list itself drops under 4 columns, Canada goes
   full width so the two keep matching column widths.
   ==================================================================== */
.loc-list {
    columns: 140px 4;
    column-gap: var(--s-6);
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 15px;
    color: var(--gray-700);
}
.loc-list li { padding: 6px 0; break-inside: avoid; }
.loc-list--ca { column-count: 3; width: calc(75% - 8px); }   /* 8px = column-gap (32) / 4 */
@media (max-width: 703px) {
    .loc-list--ca { width: 100%; }
}


/* ====================================================================
   12. TABBED CONTENT (HOW WE MATCH)
   ==================================================================== */
.tabs__head {
    display: flex;
    gap: var(--s-6);
    border-bottom: 1px solid var(--gray-200);
    margin-bottom: var(--s-7);
    overflow-x: auto;
    overflow-y: hidden;       /* explicit - overflow-x: auto can trigger an implicit vertical scrollbar */
}
.tab {
    padding: var(--s-3) 0;
    font-size: 15px;
    font-weight: 500;
    color: var(--gray-500);
    border-bottom: 3px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
    transition: color var(--t-fast), border-color var(--t-fast);
}
.tab:hover { color: var(--navy); }
.tab--active {
    color: var(--navy);
    font-weight: 600;
    border-bottom-color: var(--cyan-action);
}

.tabs__panel { display: none; }
.tabs__panel--active { display: block; }


/* ====================================================================
   12b. ACCORDION + SYNCED IMAGE (How It Works "Match" step)
   A vertical expand/collapse list paired with an image that swaps to the
   open item. Deliberately a different interactive pattern from the
   horizontal .tabs used on the homepage.
   ==================================================================== */
.match {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-8);
    align-items: center;
}
.match__visual {
    position: relative;
    aspect-ratio: 4 / 3;
    border-radius: 4px;
    overflow: hidden;
    background: var(--tint-cool);
}
.match__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity var(--t-med);
}
.match__img--active { opacity: 1; }

.accordion { border-top: 1px solid var(--gray-300); }
.accordion__item { border-bottom: 1px solid var(--gray-300); }
.accordion__header {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-4) 0;
    text-align: left;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 17px;
    font-weight: 600;
    color: var(--navy);
    transition: color var(--t-fast);
}
.accordion__header:hover,
.accordion__item--open .accordion__header { color: var(--cyan-action); }
/* Caret (chevron): points down when closed, rotates to point up when open. */
.accordion__icon {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230B7DA4' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    transition: transform 300ms ease;
}
.accordion__item--open .accordion__icon { transform: rotate(180deg); }
/* Smooth reveal: a 0fr -> 1fr grid row eases to the body's real content height
   (text-only on desktop, text + image on mobile), with the content fading in.
   The .accordion__body-inner wrapper + overflow:hidden is what lets the row
   collapse cleanly to zero. */
.accordion__body {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 300ms ease;
}
.accordion__item--open .accordion__body { grid-template-rows: 1fr; }
.accordion__body-inner {
    overflow: hidden;
    opacity: 0;
    transition: opacity 300ms ease;
}
.accordion__item--open .accordion__body-inner { opacity: 1; }
.accordion__body p {
    color: var(--gray-700);
    font-size: 15px;
    line-height: 1.6;
    max-width: none;
    padding-bottom: var(--s-4);
}
/* Inline per-item image: hidden on desktop (the synced side panel shows it),
   revealed INSIDE the open item on mobile so the image sits right next to its
   own label (Gestalt proximity) instead of in a far-off panel at the top. */
.accordion__body img { display: none; }
@media (max-width: 768px) {
    .match { grid-template-columns: 1fr; gap: var(--s-6); }
    .match__visual { display: none; }                  /* drop the synced side panel on mobile */
    .accordion__item--open .accordion__body img {
        display: block;
        width: 100%;
        border-radius: 4px;
        margin-top: var(--s-3);
    }
}


/* ====================================================================
   13. QUALIFICATION FUNNEL
   Five-step horizontal partner-vetting visual. Replaces the logo wall
   for a brand-new business: shows the rigor of the gate process
   instead of pretending to have partners.
   ==================================================================== */
.qual-funnel .section__head { max-width: 760px; }
.qual-funnel .section__head .lede { margin-left: auto; margin-right: auto; }

.funnel {
    margin-top: var(--s-7);
    display: grid;
    /* 5 step columns separated by 4 connector columns. The "auto" tracks
       collapse to the connector width; the "1fr" tracks size to share
       the remaining space evenly across the 5 steps. */
    grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr auto 1fr;
    align-items: start;
    gap: 0;
}

.funnel__step {
    text-align: center;
    padding: 0 var(--s-3);
}

.funnel__num {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--white);
    border: 2px solid var(--cyan-action);
    color: var(--cyan-action);
    font-weight: 800;
    font-size: 18px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto var(--s-4) auto;
}

.funnel__step h3 {
    font-size: 15px;
    font-weight: 700;
    color: var(--navy);
    margin-bottom: var(--s-2);
    line-height: 1.3;
}

.funnel__step p {
    font-size: 13px;
    color: var(--gray-700);
    line-height: 1.5;
    margin: 0 auto;
    max-width: 180px;
}

/* Connector line - thin horizontal rule that aligns to the vertical
   center of the numbered circles (the circles are 48px tall). */
.funnel__connector {
    width: var(--s-6);              /* 32px */
    height: 2px;
    background: var(--gray-300);
    margin-top: 23px;               /* (48px circle - 2px line) / 2 */
}


/* ====================================================================
   14. DARK CTA STRIP
   ==================================================================== */
.cta-dark {
    position: relative;
    background: var(--navy);              /* lighter than footer's navy-deep so they don't blend */
    color: var(--white);
    padding: var(--s-9) 0;
    overflow: hidden;
    text-align: center;
}
.cta-dark::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(circle, rgba(22, 179, 228, 0.18) 1.2px, transparent 1.4px);
    background-size: 28px 28px;
    pointer-events: none;
    opacity: 0.6;
}
.cta-dark__inner { position: relative; max-width: 720px; margin: 0 auto; }
.cta-dark h2 { color: var(--white); margin-bottom: var(--s-3); }
.cta-dark p { color: rgba(255,255,255,0.85); margin: 0 auto var(--s-6); }

/* Photo-backed variant: a darkened production photo behind the CTA text, so the
   strip reads as more than a flat panel. The image is passed per instance via
   the --cta-photo custom property.

   The dark tint and the photo are painted as ONE background stack (a flat 80%
   bluish-black gradient layered over the image), NOT as a separate ::before
   overlay. This is deliberate: an overlay drawn on a separate box (a ::before,
   or an absolutely-positioned child) is rounded to the device-pixel grid
   independently of the photo, so on some DPR/viewport combinations it lands
   ~1px short at the bottom and exposes a lighter, un-tinted strip of the photo.
   An earlier inset:-2px + overflow:hidden attempt did not cure it, because the
   overflow clip snaps the overlay right back to the same short edge. With one
   background stack the tint and photo occupy the exact same painted box, so a
   sub-pixel seam is impossible at any DPR or size. (Same technique as the
   Locations globe section.) */
.cta-dark--photo {
    background-color: #020a16;           /* bluish-black base, shown only if the photo fails to load */
    background-image: linear-gradient(rgba(2, 10, 22, 0.80), rgba(2, 10, 22, 0.80)), var(--cta-photo);
    background-size: cover;
    background-position: center;
}
/* The photo variant does not use the base dot-pattern overlay; the tint above
   replaces it, so neutralize the ::before entirely (no second box to seam). */
.cta-dark--photo::before { content: none; }


/* ====================================================================
   15. FORMS
   ==================================================================== */
/* The form fills its parent width. Outer width is set by .submit-form-inner
   on the submit page (760px max-width with 24px padding => 712px content). */
.form {
    max-width: none;
    width: 100%;
}
/* Centered narrow wrapper for a form that sits inside a normal page section
   (the M4 Join the Network application), as opposed to the full-viewport
   Submit a Project app. Matches the submit form's 760px content column. */
.form-narrow { max-width: 760px; margin: 0 auto; }
.field { margin-bottom: var(--s-5); }
/* When .field is rendered as a fieldset (for groups of checkboxes or radios)
   strip the browser's default border, padding, and minimum-content width so
   it matches a plain <div class="field">. */
fieldset.field {
    border: 0;
    padding: 0;
    margin-inline: 0;
    min-width: 0;
}
/* Direct-child only - must not bleed into nested labels like .checkbox-item,
   which need display:flex and a different font-weight. <legend> inside a
   fieldset is treated as the equivalent of the top-level .field label. */
/* The :not(.file-upload) is critical: the upload dropzone is also a
   <label> directly inside .field, and without this exclusion this rule's
   `display: block` and `padding: 0` (higher specificity than `.file-upload`)
   silently override the dropzone's own flex layout and padding. */
.field > label:not(.file-upload),
.field > legend {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: var(--gray-900);
    margin-bottom: var(--s-2);
    padding: 0;        /* legend has browser-default padding; strip it */
}
.field > label .req { color: var(--cyan-action); margin-left: 2px; }

/* Consent/confirmation checkbox that IS a field's whole content (a <label> directly
   inside .field, e.g. the Join the Network NPSOA box). The generic ".field > label"
   rule above would force it to display:block + bold, which dumps the wrapped text
   UNDER the box. Restore a flex row so wrapped lines stay beside the box, keep the
   text normal weight, and sit the box on the first text line. */
.field > label.checkbox-item {
    display: flex;
    align-items: flex-start;
    gap: var(--s-3);
    font-weight: 400;
    color: var(--gray-700);
    line-height: 1.5;
    margin-bottom: 0;
}
.field > label.checkbox-item input[type="checkbox"] {
    margin-top: 2px;
}
/* Form-control styling - explicitly excludes checkboxes and radios so it
   doesn't fight with the .checkbox-item layout (the padding here was being
   silently applied to checkboxes, eating the flex gap). */
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea {
    width: 100%;
    border: 1px solid var(--gray-300);
    border-radius: 4px;
    padding: 12px 16px;
    font-family: inherit;
    font-size: 14px;            /* matches labels; placeholders inherit this size */
    color: var(--gray-900);
    background: var(--white);
    transition: border-color var(--t-fast);
}
.field input:not([type="checkbox"]):not([type="radio"]):focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--cyan-action);
}
.field textarea { resize: vertical; min-height: 96px; }

/* Custom dropdown arrow with proper right-edge spacing.
   Browser-default arrows sit too close to the input edge - we replace
   with an inline SVG chevron and add right padding equal to the left padding. */
.field select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    background-size: 14px;
    padding-right: 44px;
    cursor: pointer;
}
.field__help {
    margin-top: 4px;
    font-size: 13px;
    color: var(--gray-500);
}

/* Form group heading */
.form__group { margin-bottom: var(--s-7); }
.form__group h3 {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: var(--s-4);
}


/* ====================================================================
   16. FOOTER
   ==================================================================== */
.footer {
    background: var(--navy-deep);
    color: var(--white);
    padding: var(--s-9) 0 var(--s-6);
}
.footer__grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: var(--s-7);
    margin-bottom: var(--s-7);
}
.footer__brand img { height: 48px; margin-bottom: var(--s-3); }
.footer__brand p {
    font-size: 14px;
    color: rgba(255,255,255,0.7);
    max-width: 320px;
}
.footer__col h3 {
    font-size: 13px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--white);
    margin-bottom: var(--s-4);
}
.footer__col ul { display: flex; flex-direction: column; gap: var(--s-3); }
.footer__col a {
    font-size: 14px;
    color: rgba(255,255,255,0.7);
    transition: color var(--t-fast);
}
.footer__col a:hover { color: var(--white); }

.footer__bottom {
    border-top: 1px solid rgba(255,255,255,0.15);
    padding-top: var(--s-5);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--s-4);
    font-size: 12px;
    color: rgba(255,255,255,0.7);
}
.footer__bottom a {
    color: rgba(255,255,255,0.5);
    margin-left: var(--s-5);
}
.footer__bottom a:hover { color: var(--white); }


/* ====================================================================
   16b. SUBMIT-A-PROJECT PAGE - viewport-locked, full-width form
   Page chrome is page-locked (not card-locked). The step indicator strip
   sits directly beneath the nav. The action bar (Back / Continue / Submit)
   sits at the very bottom of the viewport. Form fields fill the middle
   and scroll if needed. No right-side context panel.
   ==================================================================== */

/* Lock body scroll on desktop; release on mobile (viewport too short) */
@media (min-width: 768px) {
    body.submit-page { overflow: hidden; height: 100vh; }
}

/* The Submit a Project page is a full-screen, app-like form (matching the
   approved demo, which has no footer). Hide the site footer on this page so it
   never appears below the locked viewport. Remove this rule if a footer is
   wanted here (and switch the form to a normal scrolling layout). */
body.submit-page .footer { display: none; }

/* Main fills the viewport below the nav and stacks: step bar / body / action bar.
   padding-top: 0 here overrides the global `main { padding-top: var(--nav-h) }`
   rule, so we don't double up clearance with margin-top. */
.submit-main {
    height: 100vh;                 /* full viewport; the action bar pins to the bottom of this box */
    padding-top: var(--nav-h);     /* clear the fixed nav. With the global border-box, this stays INSIDE
                                      the 100vh, so total height never exceeds the viewport. This replaces
                                      the old margin-top + calc(100vh - nav) pattern, which left a nav-height
                                      gap below the action bar whenever the body's scroll-lock didn't engage. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--white);
}

/* TOP STRIP - step indicator, locked just beneath nav.
   The .steps element has a default margin-bottom (left over from the old
   card layout); we zero it here so the strip is sized to its content. */
.submit-step-bar {
    flex-shrink: 0;
    background: var(--gray-50);
    border-bottom: 1px solid var(--gray-200);
    padding: var(--s-3) 0;
}
.submit-step-bar__inner {
    max-width: 760px;
    margin: 0 auto;
    padding: 0 var(--pad-x);
}
.submit-step-bar .steps { margin-bottom: 0; }

/* MIDDLE - form scrolls here if needed; everything else is page-locked */
.submit-body {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0;
}
.submit-form-inner {
    max-width: 760px;
    margin: 0 auto;
    padding: var(--s-7) var(--pad-x) var(--s-7);
}

/* BOTTOM STRIP - action buttons, locked to viewport bottom */
.submit-action-bar {
    flex-shrink: 0;
    background: var(--gray-50);
    border-top: 1px solid var(--gray-200);
    padding: var(--s-4) 0;
}
.submit-action-bar__inner {
    max-width: 760px;
    margin: 0 auto;
    padding: 0 var(--pad-x);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4);
}

/* Step indicator */
.steps {
    display: flex;
    align-items: center;
    justify-content: center;        /* center the group so a 2-step bar isn't stretched apart */
    margin-bottom: var(--s-7);
    gap: var(--s-3);
}
.steps__item {
    display: flex;
    align-items: center;
    gap: var(--s-3);
}
.steps__num {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid var(--gray-300);
    color: var(--gray-500);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    flex-shrink: 0;
    transition: background-color var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.steps__label {
    font-size: 11px;
    font-weight: 600;
    color: var(--gray-500);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    transition: color var(--t-fast);
}
.steps__connector {
    flex: 0 0 64px;                 /* fixed short connector; with only two steps a flex:1 line spread them across the whole bar */
    width: 64px;
    height: 2px;
    background: var(--gray-300);
    transition: background-color var(--t-fast);
}
.steps__item--active .steps__num {
    background: var(--cyan-action);
    border-color: var(--cyan-action);
    color: var(--white);
}
.steps__item--active .steps__label { color: var(--navy); }
.steps__item--complete .steps__num {
    background: var(--navy);
    border-color: var(--navy);
    color: var(--white);
}
.steps__item--complete .steps__label { color: var(--navy); }
.steps__connector--complete { background: var(--navy); }

/* Step panels */
.form-step { display: none; }
.form-step--active { display: block; }

.form-step h3 {
    margin-bottom: var(--s-5);
    color: var(--navy);
}
/* The two step titles became <h2> on 08-11-2026 so Submit a Project has a
   proper h1 -> h2 -> h3 outline under its visually-hidden h1. These values are
   the base h3 rendering (24px / 700 / 1.3 / -0.01em) plus the .form-step h3
   margin and colour above, so the change is structural only and the page looks
   exactly as it did. */
.form-step > h2 {
    font-size: 24px;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.01em;
    margin-bottom: var(--s-5);
    color: var(--navy);
}

/* Radio-card grid (project type chooser) */
.radio-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-3);
    margin-bottom: var(--s-6);
}
.radio-card {
    position: relative;
    border: 1.5px solid var(--gray-300);
    border-radius: 4px;
    padding: var(--s-4);
    cursor: pointer;
    background: var(--white);
    transition: border-color var(--t-fast), background-color var(--t-fast);
}
.radio-card input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.radio-card__title {
    font-weight: 600;
    color: var(--navy);
    font-size: 15px;
    margin-bottom: 4px;
}
.radio-card__hint {
    font-size: 13px;
    color: var(--gray-500);
    line-height: 1.4;
}
.radio-card:hover { border-color: var(--navy-soft); }
.radio-card--selected {
    border-color: var(--cyan-action);
    background: rgba(0, 145, 184, 0.04);
}

/* Choice-card grid - visually identical to .radio-cards but holds checkboxes
   for multi-select choices (project type, etc.). The JS toggles
   .choice-card--selected on the wrapper to match the checkbox state. */
.choice-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--s-3);
    margin-bottom: var(--s-6);
}
.choice-card {
    position: relative;
    border: 1.5px solid var(--gray-300);
    border-radius: 4px;
    padding: var(--s-4);
    cursor: pointer;
    background: var(--white);
    transition: border-color var(--t-fast), background-color var(--t-fast);
}
.choice-card input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.choice-card__title {
    font-weight: 600;
    color: var(--navy);
    font-size: 15px;
    margin-bottom: 4px;
}
.choice-card__hint {
    font-size: 13px;
    color: var(--gray-500);
    line-height: 1.4;
}
.choice-card:hover { border-color: var(--navy-soft); }
.choice-card--selected {
    border-color: var(--cyan-action);
    background: rgba(0, 145, 184, 0.04);
}

/* Two-up field row inside a step */
.field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-4);
}

/* Three-up field row for grouped short fields (city/state/zip, qty/size/versions) */
.field-row--3 {
    grid-template-columns: 1fr 1fr 1fr;
}

/* Inline choice row - small checkbox or radio set used inside a .field block.
   Default 3-col layout for short choices like Yes/No/Flexible. Use
   .choice-row--2col for the 4-up artwork-status grid. */
.choice-row {
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
    gap: var(--s-3) var(--s-5);
    margin-top: var(--s-2);
}
.choice-row--2col {
    grid-template-columns: repeat(2, 1fr);
    justify-content: stretch;
}
.choice-row label {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    font-size: 14px;
    color: var(--gray-700);
    cursor: pointer;
    line-height: 1;
}
.choice-row input[type="checkbox"],
.choice-row input[type="radio"] {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
    accent-color: var(--cyan-action);
}

/* Back button used in the locked form-card foot. The primary Continue/Submit
   button uses the standard .btn / .btn--primary classes from §5. */
.form-actions__back {
    color: var(--gray-700);
    font-size: 15px;
    font-weight: 600;
    background: none;
    padding: 10px 0;
    transition: color var(--t-fast);
}
.form-actions__back:hover { color: var(--navy); }
.form-actions__back[hidden],
.form-actions__back.is-hidden { visibility: hidden; pointer-events: none; }

/* Checkbox grid for "any of these apply" - fixes the awkward inline-flex
   wrapping that compressed multi-word labels into 1-word-wide columns. */
.checkbox-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-3) var(--s-5);
    margin-top: var(--s-2);
}
.checkbox-item {
    display: flex;
    align-items: center;          /* geometric centers align - most visually predictable */
    gap: var(--s-3);              /* 12px - comfortable but not stretched */
    font-size: 14px;
    color: var(--gray-700);
    cursor: pointer;
    line-height: 1;
}
.checkbox-item input[type="checkbox"] {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin: 0;                    /* remove browser default margin on form controls */
    padding: 0;                   /* defensively zero padding (the .field input rule used to leak through) */
    accent-color: var(--cyan-action);
}

/* 08-12-2026 touch targets. Clicking the label toggles the control, so the
   LABEL is the target, and these rows measured 21px tall stacked 21px apart on
   a phone: under the 24px WCAG 2.5.8 minimum and too close together to earn the
   spacing exception, on the form partners actually fill in. Vertical padding
   only, applied at touch widths, so the desktop form keeps the reviewed
   density and the row grows to a comfortable 37px on a phone. */
@media (max-width: 768px) {
    .checkbox-item,
    .field > label.checkbox-item {
        padding-top: 8px;
        padding-bottom: 8px;
    }
}

/* File list - rendered after a user picks files via the real <input type=file>.
   Sits below the .file-upload tile so they see what's queued for upload. */
.file-list {
    list-style: none;
    margin: var(--s-3) 0 0 0;
    padding: 0;
    border: 1px solid var(--gray-200);
    border-radius: 4px;
    background: var(--white);
}
.file-list[hidden] { display: none; }
.file-list__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    padding: 8px 12px;
    border-bottom: 1px solid var(--gray-200);
    font-size: 13px;
    color: var(--navy);
}
.file-list__item:last-child { border-bottom: none; }
.file-list__name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}
.file-list__size {
    flex-shrink: 0;
    color: var(--gray-500);
    font-size: 12px;
}
/* Per-file status + an always-visible remove (X) with a subtle hover cue, so a
   buyer can drop an individual file (Michael P2M4 item 10). */
.file-list__status {
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--gray-500);
}
.file-list__item--bad { background: #fdecea; }
.file-list__item--bad .file-list__name,
.file-list__item--bad .file-list__status { color: #8a1c14; }
.file-list__remove {
    flex-shrink: 0;
    border: 0;
    background: transparent;
    color: var(--gray-500);
    width: 30px;
    height: 30px;
    border-radius: 6px;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color .15s ease, background .15s ease, transform .12s ease;
}
.file-list__remove:hover,
.file-list__remove:focus-visible {
    color: #b3261e;
    background: #fdecea;
    transform: scale(1.12);
    outline: none;
}
.file-list__remove:active { transform: scale(0.95); }

/* File upload tile - styled <label> that triggers the hidden <input type=file>.
   Click opens the OS file picker. Selected files render below in .file-list. */
.file-upload {
    width: 100%;
    margin-bottom: var(--s-2);        /* preserved from the .field > label rule it's now excluded from */
    border: 1.5px dashed var(--gray-300);
    border-radius: 4px;
    padding: 20px;                    /* even 20px all around (the value confirmed in the inspector) */
    background: var(--gray-50);
    cursor: pointer;
    text-align: center;
    transition: border-color var(--t-fast), background-color var(--t-fast);
    display: flex;
    flex-direction: column;
    align-items: center;              /* keeps the icon, title, and hint centered */
    gap: var(--s-2);                  /* small gap so the file types sit just under the title */
    font-family: inherit;
}
.file-upload:hover {
    border-color: var(--cyan-action);
    background: rgba(0, 145, 184, 0.04);
}
.file-upload__icon {
    width: 36px;
    height: 36px;
    color: var(--cyan-action);
    margin: 0 auto 9px;               /* centered; icon-to-title gap is 9px + 8px flex gap = ~17px (~30% tighter than before) */
}
.file-upload__title {
    display: block;
    width: 100%;
    text-align: center;               /* "Click to add files" on its own centered line */
    font-weight: 600;
    color: var(--navy);
    font-size: 15px;
}
.file-upload__hint {
    display: block;
    width: 100%;
    max-width: 360px;                 /* wrap the file-type list onto ~2 centered lines, like the reference */
    margin: 0 auto;
    text-align: center;               /* file types on the next centered line(s) */
    font-size: 13px;
    color: var(--gray-500);
    line-height: 1.5;
}

/* Match interstitial - between submit click and success state.
   Demonstrates the platform's match step visually without any back end. */
.matching {
    text-align: center;
    padding: var(--s-9) var(--s-5);
}
.matching__pulse {
    width: 56px;
    height: 56px;
    margin: 0 auto var(--s-5);
    border-radius: 50%;
    background: var(--cyan-action);
    animation: matchPulse 1.2s ease-in-out infinite;
}
@keyframes matchPulse {
    0%, 100% { transform: scale(1);    opacity: 1;    box-shadow: 0 0  0   rgba(0, 145, 184, 0.4); }
    50%      { transform: scale(1.1);  opacity: 0.85; box-shadow: 0 0 24px rgba(0, 145, 184, 0.4); }
}
/* Respect users who prefer reduced motion: pause the pulse and let the
   transitions fall back to instant changes throughout the page. */
@media (prefers-reduced-motion: reduce) {
    .matching__pulse { animation: none; }
    *, *::before, *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}
.matching h3 {
    margin-bottom: var(--s-6);
    color: var(--navy);
}
.matching__steps {
    list-style: none;
    padding: 0;
    width: fit-content;       /* hug the widest item so the block can truly center */
    max-width: 320px;
    margin: 0 auto;
    text-align: left;         /* items stay left-aligned within the centered block, so the dots line up */
}
.matching__step {
    padding: var(--s-3) 0;
    color: var(--gray-500);
    font-size: 15px;
    transition: color 200ms ease;
    display: flex;
    align-items: center;
    gap: var(--s-3);
}
.matching__step::before {
    content: "";
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid var(--gray-300);
    flex-shrink: 0;
    transition: all 200ms ease;
}
.matching__step--active { color: var(--navy); font-weight: 600; }
.matching__step--active::before {
    border-color: var(--cyan-action);
    background: var(--cyan-action);
}
.matching__step--complete { color: var(--gray-700); }
.matching__step--complete::before {
    border-color: var(--navy);
    background: var(--navy);
}

/* Email preview - appended to the success state to demonstrate the
   confirmation email the buyer would receive in production. */
.email-preview {
    max-width: 480px;
    margin: 0 auto;
    text-align: left;
    border: 1px solid var(--gray-200);
    border-radius: 4px;
    overflow: hidden;
    background: var(--white);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
}
.email-preview__label {
    display: block;
    text-transform: uppercase;
    font-size: 12px;
    letter-spacing: 0.08em;
    color: var(--gray-500);
    text-align: center;
    font-weight: 600;
    margin-top: var(--s-6);
    margin-bottom: var(--s-3);
}
.email-preview__head {
    padding: var(--s-3) var(--s-4);
    border-bottom: 1px solid var(--gray-100);
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    background: var(--gray-50);
    gap: var(--s-3);
}
.email-preview__from strong {
    display: block;
    color: var(--navy);
    font-size: 13px;
    margin-bottom: 1px;
}
.email-preview__from span { color: var(--gray-500); font-size: 12px; }
.email-preview__time { color: var(--gray-500); font-size: 12px; flex-shrink: 0; }
.email-preview__subject {
    padding: var(--s-3) var(--s-4);
    font-weight: 600;
    color: var(--navy);
    font-size: 13px;
    border-bottom: 1px solid var(--gray-100);
}
.email-preview__body {
    padding: var(--s-4);
    font-size: 13px;
    color: var(--gray-700);
    line-height: 1.55;
}

/* ====================================================================
   16i. HOW IT WORKS - 3-step "Submit / Match / Deliver" home-page section
   ==================================================================== */
.process {
    display: flex;
    align-items: flex-start;
    max-width: 980px;
    margin: 0 auto;
}
.process__step {
    flex: 1;
    text-align: center;
    position: relative;
    padding: 0 var(--s-3);
}
/* Connector line between adjacent steps. Positioned absolutely so it spans
   from the right edge of one numbered circle to the left edge of the next. */
.process__step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 27px;                        /* center of the 56px circle minus 1 */
    left: calc(50% + 32px);           /* circle radius + small visual gap */
    right: calc(-50% + 32px);
    height: 2px;
    background: var(--gray-300);
    z-index: 0;
}
.process__num {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--cyan-action);
    color: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 800;
    margin: 0 auto var(--s-4);
    line-height: 1;
    position: relative;
    z-index: 1;
}
/* Tri-color the three step numbers to echo the NPS logo (N cyan, S magenta,
   P yellow). Adds intentional brand color to the most-scanned section without
   flooding any background. Yellow takes navy text for contrast. */
.process__step:nth-child(2) .process__num { background: var(--brand-magenta); }
.process__step:nth-child(3) .process__num { background: var(--brand-yellow); color: var(--navy); }
.process__step h3 {
    font-size: 18px;
    font-weight: 600;
    margin-bottom: var(--s-3);
    color: var(--navy);
}
.process__step p {
    color: var(--gray-700);
    font-size: 15px;
    line-height: 1.55;
    margin: 0 auto;
    max-width: 32ch;
}

/* Centered section heads should also center the lede paragraph horizontally. */
.section__head--center .lede {
    margin-left: auto;
    margin-right: auto;
}

/* Success state - uses available vertical space via flex centering, with
   a min-height so the content spreads out instead of bunching at the top.
   Paragraph max-width matches the email-preview card (480px) so the text
   column doesn't extend beyond the card below it. */
.success {
    text-align: center;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: calc(100vh - var(--nav-h) - var(--s-9));
}
/* Critical: explicitly honor the HTML `hidden` attribute. Without this,
   `display: flex` above wins over the browser's default styling for [hidden]
   and the success state shows up below the form on initial page load. */
.success[hidden] { display: none; }
.success__check {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--cyan-action);
    color: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    margin: 0 auto var(--s-5);
    line-height: 1;
}

/* Join the Network success panel: once revealed (the form AND the intro heading
   are hidden by JS), fill a comfortable area and center the confirmation both
   vertically and horizontally, so "Application received" sits centered instead of
   collapsing to a thin strip at the top. align-items:center also centers each line
   (including the reference number) on its own. :not([hidden]) keeps it
   display:none until the JS reveals it. */
.form-success:not([hidden]) {
    min-height: 60vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--s-8) var(--s-4);
}
.success h2 {
    margin-bottom: var(--s-3);
    color: var(--navy);
    font-size: 28px;
}
.success p {
    color: var(--gray-700);
    max-width: 480px;            /* matches email-preview width - no more overhang */
    margin: 0 auto var(--s-4);
    font-size: 15px;
    line-height: 1.55;
}

/* Sidebar "what happens next" card list */
.info-list {
    display: flex;
    flex-direction: column;
    gap: var(--s-5);
}
.info-list__item {
    display: flex;
    gap: var(--s-4);
    align-items: flex-start;
}
.info-list__num {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--cyan-action);
    color: var(--white);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    flex-shrink: 0;
    line-height: 1;
}
.info-list__body {
    font-size: 14px;
    line-height: 1.5;
    color: var(--gray-700);
}
.info-list__body strong {
    display: block;
    color: var(--navy);
    margin-bottom: 2px;
    font-size: 14px;
}

/* Sidebar trust footer */
.sidebar__trust {
    margin-top: var(--s-6);
    padding-top: var(--s-5);
    border-top: 1px solid var(--gray-300);
    font-size: 13px;
    color: var(--gray-500);
    line-height: 1.5;
}
.sidebar__trust strong { color: var(--navy); display: block; margin-bottom: 4px; font-size: 13px; }


/* ====================================================================
   16j. CLIENT-FEEDBACK COMPONENTS (added 2026-06-22 per Michael's notes)
   - Tri-color brand rule  (Item 3: more intentional brand color)
   - Stakes band           (Item 2: stakes line + "right list" tagline near top)
   - Plain-language callout (Item 4: explain "Submit a Project" in plain words)
   - Category chip grid     (Item 10: show all twelve categories, count matches)
   - CTA logo stamp         (Item 2: bigger, intentional use of the NPS logo)
   ==================================================================== */

/* Tri-color accent motif drawn from the logo's three CMY colors. A small,
   restrained brand signal placed above key statements, never a flood. */
.brand-rule {
    display: inline-flex;
    gap: 5px;
    margin-bottom: var(--s-5);
}
.brand-rule span {
    display: block;
    width: 28px;
    height: 4px;
    border-radius: 2px;
}
.brand-rule span:nth-child(1) { background: var(--cyan-action); }
.brand-rule span:nth-child(2) { background: var(--brand-magenta); }
.brand-rule span:nth-child(3) { background: var(--brand-yellow); }

/* STAKES BAND - the emotional hook near the top of the homepage. White band so
   it alternates off the dark hero above and the tint promises strip below. */
.stakes { background: var(--white); padding: var(--s-9) 0; }
.stakes__inner { max-width: 860px; margin: 0 auto; text-align: center; }
.stakes__lead {
    font-size: 22px;
    line-height: 1.5;
    color: var(--gray-900);
    max-width: 760px;
    margin: 0 auto;
}
.stakes__lead strong { color: var(--navy); font-weight: 700; }
.stakes__tag {
    margin-top: var(--s-6);
    font-size: 28px;
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: var(--navy);
}
.stakes__tag em { color: var(--cyan-action); font-style: normal; }

/* PLAIN-LANGUAGE CALLOUT - a tinted box that explains, in everyday words, what
   "Submit a Project" means. Left accent bar matches the pull-quote pattern. */
.plain-note {
    max-width: 760px;
    background: var(--white);
    border: 1px solid var(--gray-200);
    border-left: 4px solid var(--cyan-action);
    border-radius: 4px;
    padding: var(--s-5) var(--s-6);
    font-size: 17px;
    line-height: 1.55;
    color: var(--navy);
}
.plain-note strong { color: var(--navy); font-weight: 700; }
/* Centered variant for use under a centered section head */
.plain-note--center { margin-left: auto; margin-right: auto; }

/* CATEGORY CHIP GRID - lists every category as a small tag so the count on the
   page always matches the number stated in the copy. The leading dot rotates
   through the three brand colors for quiet color variation. */
.cat-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
    margin-top: var(--s-6);
}
.cat-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: 8px 16px;
    border: 1px solid var(--gray-300);
    border-radius: 4px;
    background: var(--white);
    font-size: 14px;
    font-weight: 600;
    color: var(--navy);
}
.cat-chip::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--cyan-action);
    flex-shrink: 0;
}
.cat-chip:nth-child(3n+2)::before { background: var(--brand-magenta); }
.cat-chip:nth-child(3n+3)::before { background: var(--brand-yellow); }

/* Logo stamp on the dark philosophy CTA - a bigger, brand-forward use of the
   logo where the colored letters read well against the navy. */
.cta-dark__logo {
    height: 72px;
    width: auto;
    margin: 0 auto var(--s-5);
}


/* ====================================================================
   17. UTILITIES
   ==================================================================== */
.text-center { text-align: center; }
.mt-2 { margin-top: var(--s-2); }
.mt-4 { margin-top: var(--s-4); }
.mt-6 { margin-top: var(--s-6); }

/* Skip-to-content link. Hidden offscreen until a keyboard user focuses it
   (tab from the address bar lands here first), then it slides into view at
   the top of the page so the user can jump past the nav directly to <main>. */
.skip-link {
    position: absolute;
    top: -100px;
    left: var(--s-4);
    z-index: 1000;
    background: var(--navy);
    color: var(--white);
    padding: 10px 16px;
    border-radius: 4px;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: top var(--t-med);
}
.skip-link:focus {
    top: var(--s-3);
    outline: 2px solid var(--cyan-bright);
    outline-offset: 2px;
}

/* 08-12-2026: the skip link's target carries tabindex="-1" so activating it
   actually moves focus, instead of only scrolling and leaving the next Tab in
   the navigation. It is not in the tab order, so it needs no focus ring; the
   ring would otherwise draw a box around the whole page. */
main[tabindex="-1"]:focus {
    outline: none;
}

/* Hide content visually but keep it available to screen readers.
   Used for supplementary instructions on grouped controls. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}


/* ====================================================================
   18. RESPONSIVE
   Breakpoints:
   - 1024px: tablet
   - 768px:  mobile-large
   - 480px:  mobile-small
   ==================================================================== */
@media (max-width: 1024px) {
    .cards { grid-template-columns: repeat(2, 1fr); }
    .stats__grid { grid-template-columns: repeat(2, 1fr); gap: var(--s-6); }
    .footer__grid { grid-template-columns: 1fr 1fr; }
    .radio-cards  { grid-template-columns: repeat(2, 1fr); }
    .choice-cards { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
    :root { --pad-x: 16px; }

    h1 { font-size: 36px; }
    h2 { font-size: 28px; }
    h3 { font-size: 20px; }

    .section { padding: var(--s-8) 0; }

    /* Hide desktop nav links, show hamburger */
    .nav__links { display: none; }
    .nav__toggle { display: flex; }

    /* On the Submit a Project page, hide the nav's "Submit a Project" button on
       mobile so it doesn't compete with the Back / Continue / Submit action bar
       locked to the bottom of the form. It stays available inside the hamburger
       menu (that overlay link is separate from .nav__cta). */
    body.submit-page .nav__cta { display: none; }

    /* Hero variants stack */
    .hero-a__grid { grid-template-columns: 1fr; gap: var(--s-7); }
    .hero-b__text { max-width: none; }
    /* On mobile, push the gradient overlay to be more even so the photo
       still reads but the text on top stays high-contrast. */
    .hero-b::after {
        background: linear-gradient(
            180deg,
            rgba(2, 10, 22, 0.90) 0%,
            rgba(2, 10, 22, 0.75) 100%
        );
    }

    /* Cards stack to single column */
    .cards { grid-template-columns: 1fr; }

    /* Stat strip stacks 2x2 then to 1 col, content center-aligned on mobile */
    .stats__grid { grid-template-columns: repeat(2, 1fr); }
    .stat { text-align: center; padding-right: 0; }
    .stat__num { font-size: 40px; }
    .stats--promises .stat__num { font-size: 26px; }

    /* How It Works: stack the 3 steps vertically and explicitly center each
       one on the page. Connector lines hidden (they only make sense as
       horizontal links between side-by-side steps). */
    .process {
        flex-direction: column;
        align-items: center;
        gap: var(--s-7);
    }
    .process__step {
        padding: 0;
        width: 100%;
        max-width: 480px;
        text-align: center;
    }
    .process__step:not(:last-child)::after { display: none; }

    /* On mobile, center-aligned section heads fall back to left-aligned to
       match every other section's eyebrow / heading / lede treatment. */
    .section__head--center {
        text-align: left;
        margin-left: 0;
        margin-right: 0;
    }
    .section__head--center .lede {
        margin-left: 0;
        margin-right: 0;
    }

    /* Splits stack, image always above text on mobile */
    .split { grid-template-columns: 1fr; gap: var(--s-6); }
    .split--reverse .split__visual { order: 0; }
    .split--reverse .split__text   { order: 1; }

    /* Footer stacks to single column */
    .footer__grid { grid-template-columns: 1fr; gap: var(--s-6); }
    .footer__bottom { flex-direction: column; align-items: flex-start; }
    .footer__bottom a { margin-left: 0; }

    /* Submit page on mobile - release the viewport lock, allow page scroll.
       Step bar and action bar use sticky positioning so they still feel
       anchored without breaking when the keyboard opens. */
    .submit-main { height: auto; overflow: visible; }
    .submit-body { overflow-y: visible; }
    .submit-step-bar {
        position: sticky;
        top: var(--nav-h);
        z-index: 10;
    }
    .submit-action-bar {
        position: sticky;
        bottom: 0;
        z-index: 10;
    }
    .submit-form-inner { padding: var(--s-6) var(--pad-x); }

    .radio-cards   { grid-template-columns: 1fr; }
    .choice-cards  { grid-template-columns: 1fr; }
    .field-row     { grid-template-columns: 1fr; }
    .field-row--3  { grid-template-columns: 1fr; }
    .checkbox-grid { grid-template-columns: 1fr; gap: var(--s-3); }
    .choice-row    { grid-template-columns: 1fr; gap: var(--s-3); }
    .choice-row--2col { grid-template-columns: 1fr; }

    /* Qualification funnel stacks vertically on mobile. Connectors
       become short vertical lines between each step. */
    .funnel {
        grid-template-columns: 1fr;
        gap: 0;
    }
    .funnel__step { padding: 0; }
    .funnel__connector {
        width: 2px;
        height: var(--s-5);          /* 24px */
        margin: var(--s-3) auto;     /* center under the step above */
    }
    .funnel__step p { max-width: none; }

    /* Steps indicator on mobile: show the CURRENT step's label in smaller text,
       positioned just beneath its number. The label is absolutely placed so it
       does not shift the numbers out of alignment. The step bar gets extra
       bottom room to hold the label. */
    .steps__item { position: relative; }
    .steps__label { display: none; }
    .steps__item--active .steps__label {
        display: block;
        position: absolute;
        top: calc(100% + 5px);
        left: 50%;
        transform: translateX(-50%);
        font-size: 10px;
        line-height: 1.2;
        white-space: nowrap;
        text-align: center;
        color: var(--navy);
    }
    .submit-step-bar { padding: var(--s-3) 0 var(--s-6); }

    /* Client-feedback components scale down on mobile (Item 11) */
    .stakes      { padding: var(--s-8) 0; }
    .stakes__lead { font-size: 18px; }
    .stakes__tag  { font-size: 22px; }
    .plain-note   { font-size: 15px; padding: var(--s-4) var(--s-5); }
}

@media (max-width: 480px) {
    .stats__grid { grid-template-columns: 1fr; }
    .hero-b__ctas .btn,
    .hero-a__ctas .btn { width: 100%; }
}

/* ==========================================================================
   FORM VALIDATION (P2M1, 07-28 review item 3)
   An invalid field turns its label and border bold red and shows the reason
   directly beneath it, so the problem is identified where it happened rather
   than only in a summary. Applied by the page scripts via .is-invalid.
   ========================================================================== */
.field.is-invalid > label,
.field.is-invalid > legend,
.form__group .field.is-invalid > label { color: var(--error, #B00020); font-weight: 700; }
.field.is-invalid input[type="text"],
.field.is-invalid input[type="email"],
.field.is-invalid input[type="tel"],
.field.is-invalid input[type="url"],
.field.is-invalid input[type="date"],
.field.is-invalid select,
.field.is-invalid textarea {
    border-color: var(--error, #B00020);
    border-width: 2px;
    background: #FFF7F7;
}
.field.is-invalid .choice-cards,
.field.is-invalid .choice-row {
    border: 2px solid var(--error, #B00020);
    border-radius: 3px;
    padding: 10px;
    background: #FFF7F7;
}
.field-error {
    display: block;
    color: var(--error, #B00020);
    font-weight: 600;
    font-size: 13.5px;
    line-height: 1.45;
    margin-top: 6px;
}
:root { --error: #B00020; }

/* Mobile: keep the fixed action bar clear of the field being typed into
   (07-28 review item 6). The bar hides while an input has focus on small
   screens, and the scroll area keeps bottom room so nothing sits under it. */
@media (max-width: 780px) {
    .submit-body { padding-bottom: 96px; }
    /* Hide by sliding, never by display:none: the page must not reflow while
       the keyboard opens/closes, or a tap aimed at the bar can land on the
       content underneath it (07-28: this toggled a HOT checkbox by accident). */
    .submit-action-bar { transition: transform .18s ease; }
    body.nps-keyboard-open .submit-action-bar { transform: translateY(110%); pointer-events: none; }
}

/* A selected checkbox-item is unmistakable, so an accidental toggle is seen. */
.checkbox-item:has(> input:checked) { color: var(--navy); font-weight: 600; }
.checkbox-item:has(> input:checked) > span strong { color: var(--cyan-action); }

/* Error summary: white box, red border, red warning triangle on the right.
   Black bold title, then the field NAMES as a plain bulleted list of jump
   links (underline on hover only). Complements the on-field messages. */
.error-summary {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    border: 2px solid var(--error, #B00020);
    border-radius: 3px;
    background: #FFFFFF;
    padding: 14px 18px;
    margin-bottom: 22px;
}
/* display: flex above would defeat the hidden attribute; these boxes start
   hidden and only appear on a failed Continue/Submit. */
.error-summary[hidden],
.net-banner[hidden],
/* Same trap on the conditional ship-to row: .field-row is display:grid, which
   would paint the block even while the hidden attribute is set. */
.field-row[hidden] { display: none !important; }
.error-summary__title {
    color: #1A1A1A;
    font-weight: 700;
    margin: 0 0 8px;
}
.error-summary__list {
    margin: 0 0 0 20px;
    padding: 0;
    list-style: disc;
}
.error-summary__list li { margin-bottom: 5px; }
.error-summary__list a {
    color: inherit;
    font-weight: 400;
    text-decoration: none;
}
.error-summary__list a:hover,
.error-summary__list a:focus {
    text-decoration: underline;
}
.error-summary__icon { flex: none; line-height: 0; }

/* Connection-failure banner: inline and persistent, never a popup, and the
   typed answers stay on the page behind it. */
.net-banner {
    border: 2px solid var(--error, #B00020);
    border-radius: 3px;
    background: #FFF7F7;
    color: var(--error, #B00020);
    font-weight: 600;
    padding: 12px 16px;
    margin: 0 0 16px;
}

/* ---------------------------------------------------------------------------
 * P2M3 (08-18-2026): subtle hover lift on clickable cards (requested by NPS).
 * A card that contains a link gently rises with a light shadow on hover, the
 * way the NPSOA magazine covers do. No mouse-tracking tilt. Reduced-motion
 * users get the lighter shadow without the movement.
 * ------------------------------------------------------------------------- */
.card:has(a[href]) {
    transition: transform var(--t-med), box-shadow var(--t-med);
}
.card:has(a[href]):hover {
    transform: translateY(-4px);
    box-shadow: 0 10px 24px rgba(2, 10, 22, 0.10);
}
.section:not(.section--alt) .card:has(a[href]):hover {
    background: var(--white);
}
@media (prefers-reduced-motion: reduce) {
    .card:has(a[href]) { transition: box-shadow var(--t-med); }
    .card:has(a[href]):hover { transform: none; box-shadow: 0 6px 16px rgba(2, 10, 22, 0.08); }
}
