/* ===================================================================
   NHEXIT Now — design system
   See docs/ART-DIRECTION.md.

   Palette is taken from the movement's own logo: NHEXIT navy #002A86 and
   torch gold #EFAE0F, sampled from wp-content/uploads/2024/04/logo.png.
   Granite and snow neutrals carry the rest, so the page reads as New
   Hampshire stone rather than a generic corporate white.

   Type   : Archivo (display, variable width+weight) · Source Serif 4 (body,
            variable optical size) · IBM Plex Mono (utility / roll-call data)
   Signature: "The Four Hundred" — a field of 400 marks, one per NH House seat.
   =================================================================== */

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

/* Images carry width/height attributes so the browser can reserve space and
   avoid layout shift. But aspect-ratio is ignored when BOTH dimensions are
   specified, so without height:auto the attribute height wins and every card
   image renders at its full intrinsic height. Elements that genuinely want a
   fixed height (the full-bleed hero and band media) set it explicitly below. */
img { max-width: 100%; height: auto; }
picture { display: block; }

/* ── Self-hosted variable fonts (latin subset) ── */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url('/fonts/archivo-var.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/sourceserif4-var.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/plexmono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/fonts/plexmono-500.woff2') format('woff2');
}

:root {
  /* ── Palette ── */
  --granite-900: #1B1E20;   /* primary dark field + display type (not navy) */
  --granite-800: #24292C;
  --granite-700: #383F44;   /* dark bands, secondary dark surfaces */
  --granite-500: #5C656B;   /* body text on snow */
  --granite-400: #61686C;   /* muted / metadata — 4.97:1 on snow, 4.54:1 on the inset band */
  --granite-200: #C8CBC7;   /* decorative hairline (borders that carry no state) */
  --line-control: #888A87;  /* form control borders — 3.48:1 on white, 3.05:1 on snow */
  --granite-100: #DEDFDA;

  --snow:        #F1F0EC;   /* page ground — cold off-white, NOT cream */
  --snow-2:      #E7E6E1;   /* inset / alternating bands */
  --birch:       #FFFFFF;   /* cards, raised surfaces */

  /* Brand, straight from the logo */
  --navy:        #002A86;   /* NHEXIT navy — structural brand colour */
  --navy-700:    #00215F;   /* navy pressed */
  --navy-500:    #1A429B;   /* navy hover / on-dark accent */
  --navy-100:    #D6DDEE;   /* navy tint for quiet fills */

  --gold:        #EFAE0F;   /* torch gold — CTA and accent */
  --gold-700:    #C98F06;   /* gold hover */
  --gold-ink:    #4A3400;   /* text on gold: 8.1:1, gold is too light for white */

  /* Legacy aliases so existing rules keep working after the rebrand */
  --pine:        var(--navy);
  --pine-700:    var(--navy-700);
  --pine-500:    var(--navy-500);
  --pine-100:    var(--navy-100);
  --ember:       var(--gold);
  --ember-700:   var(--gold-700);

  --focus:       #1A429B;

  /* Semantic aliases */
  --bg:            var(--snow);
  --surface:       var(--birch);
  --surface-inset: var(--snow-2);
  --text:          var(--granite-900);
  --text-2:        var(--granite-500);
  --text-3:        var(--granite-400);
  --line:          var(--granite-200);

  /* ── Spacing — 4/8 scale ── */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 88px; --s10: 128px;

  /* ── Radii — small and hard. Granite doesn't round. ── */
  --r-sm: 2px; --r-md: 4px; --r-lg: 6px;

  --shadow-card: 0 1px 2px rgba(27, 30, 32, .06), 0 12px 32px rgba(27, 30, 32, .07);
  --shadow-lift: 0 2px 4px rgba(27, 30, 32, .08), 0 20px 48px rgba(27, 30, 32, .12);

  /* ── Motion ── */
  --dur-fast: 160ms;
  --dur-base: 240ms;
  --dur-slow: 380ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* ── Fluid type scale ── */
  --fs-xs:   clamp(0.75rem, 0.73rem + 0.10vw, 0.8125rem);
  --fs-sm:   clamp(0.8125rem, 0.79rem + 0.14vw, 0.875rem);
  --fs-base: clamp(1.0625rem, 1.02rem + 0.20vw, 1.125rem);
  --fs-md:   clamp(1.1875rem, 1.12rem + 0.32vw, 1.3125rem);
  --fs-lg:   clamp(1.375rem, 1.26rem + 0.55vw, 1.75rem);
  --fs-xl:   clamp(1.75rem, 1.48rem + 1.20vw, 2.5rem);
  --fs-2xl:  clamp(2.25rem, 1.80rem + 2.00vw, 3.5rem);
  --fs-hero: clamp(2.375rem, 1.75rem + 2.60vw, 4rem);

  --maxw: 1200px;
  --measure: 66ch;

  --font-display: 'Archivo', system-ui, -apple-system, sans-serif;
  --font-body: 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

html {
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.65;
  background: var(--bg);
  color: var(--text);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: oldstyle-nums;
}

/* ── Display type: Archivo, tight, cut rather than drawn ── */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.03em;
  color: var(--granite-900);
  text-wrap: balance;
  font-variant-numeric: lining-nums tabular-nums;
}
h1 { font-size: var(--fs-hero); font-weight: 800; }
h2 { font-size: var(--fs-2xl); }
h3 { font-size: var(--fs-lg); line-height: 1.15; letter-spacing: -0.02em; }
h4 { font-size: var(--fs-md); line-height: 1.2; letter-spacing: -0.015em; }

p { max-width: var(--measure); }
p + p { margin-top: var(--s4); }

a { color: var(--pine); text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { color: var(--pine-500); }

strong { font-weight: 700; }

::selection { background: var(--navy); color: var(--snow); }

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

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: var(--s4); top: -100px; z-index: 200;
  background: var(--pine); color: var(--snow);
  padding: var(--s3) var(--s5);
  font-family: var(--font-mono); font-size: var(--fs-sm);
  text-decoration: none;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--s4); color: var(--snow); }

.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--s5);
}
@media (min-width: 768px)  { .container { padding-inline: var(--s7); } }
@media (min-width: 1200px) { .container { padding-inline: var(--s8); } }

/* ===================================================================
   Utility labels — mono, the "record" voice
   =================================================================== */
.label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pine-500);
  display: block;
}

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
  margin-block: var(--s7);
}

/* ===================================================================
   Navigation
   =================================================================== */
.nav {
  position: sticky; top: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s5);
  padding: var(--s4) var(--s5);
  background: rgba(241, 240, 236, 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 768px)  { .nav { padding: var(--s4) var(--s7); } }
@media (min-width: 1200px) { .nav { padding: var(--s4) var(--s8); } }

.nav__logo {
  display: flex; align-items: center; gap: var(--s3);
  text-decoration: none; color: var(--granite-900);
  flex-shrink: 0;
}
.nav__logo img { display: block; height: 42px; width: auto; }
@media (min-width: 900px) { .nav__logo img { height: 54px; } }
.nav__mark { width: 34px; height: 34px; flex-shrink: 0; display: block; }
.nav__wordmark {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 112;
  font-weight: 800;
  font-size: 1.1875rem;
  letter-spacing: -0.01em;
  line-height: 1;
  text-transform: uppercase;
}
.nav__tag {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--granite-400);
  margin-top: 3px;
}

.nav__toggle {
  display: grid; place-content: center; gap: 5px;
  width: 44px; height: 44px;
  background: none; border: 1px solid var(--line-control); border-radius: var(--r-sm);
  cursor: pointer;
}
.nav__toggle span {
  display: block; width: 18px; height: 1.5px;
  background: var(--granite-900);
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-fast);
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.nav__menu { display: flex; align-items: center; gap: var(--s5); }
.nav__link {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 500;
  font-size: 0.9375rem;
  color: var(--granite-700);
  text-decoration: none;
  padding: var(--s2) 0;
  position: relative;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav__link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1.5px; background: var(--pine);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__link:hover { color: var(--pine); }
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }
.nav__link[aria-current="page"] { color: var(--pine); }

@media (max-width: 899px) {
  .nav__menu {
    position: fixed; inset: 61px 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--snow);
    border-bottom: 1px solid var(--line);
    padding: var(--s3) var(--s5) var(--s6);
    max-height: calc(100dvh - 61px);
    overflow-y: auto;
    transform: translateY(-8px);
    opacity: 0; visibility: hidden; pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out),
                visibility var(--dur-base);
  }
  .nav__menu[data-open="true"] {
    opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0);
  }
  .nav__link {
    font-size: var(--fs-md);
    padding: var(--s4) 0;
    border-bottom: 1px solid var(--line);
  }
  .nav__link::after { display: none; }
  .nav__menu .btn { margin-top: var(--s5); justify-content: center; }
}
@media (min-width: 900px) { .nav__toggle { display: none; } }

/* ===================================================================
   Buttons — one ember CTA, everything else quiet
   =================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s6);
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 105;
  font-weight: 700;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  border: 1.5px solid transparent;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out);
}
.btn:active { transform: translateY(1px); }

.btn--ember { background: var(--gold); color: var(--gold-ink); border-color: var(--gold); }
.btn--ember:hover { background: var(--gold-700); border-color: var(--gold-700); color: var(--gold-ink); }

.btn--pine { background: var(--navy); color: var(--snow); border-color: var(--navy); }
.btn--pine:hover { background: var(--navy-500); border-color: var(--navy-500); color: var(--snow); }

.btn--ghost { background: transparent; color: var(--granite-900); border-color: var(--line-control); }
.btn--ghost:hover { border-color: var(--granite-900); color: var(--granite-900); background: transparent; }

.btn--onDark { background: transparent; color: var(--snow); border-color: rgba(241,240,236,.35); }
.btn--onDark:hover { border-color: var(--snow); color: var(--snow); background: rgba(241,240,236,.08); }

.btn--block { width: 100%; }

.cta-row { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }

/* ===================================================================
   Hero — asymmetric split, type lockup left, The Four Hundred right
   =================================================================== */
.hero {
  position: relative;
  padding-block: var(--s8) var(--s9);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.hero__grid { display: grid; gap: var(--s8); align-items: center; }
@media (min-width: 1000px) {
  .hero__grid { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: var(--s7); }
}

.hero h1 { margin-bottom: var(--s5); }
.hero h1 em {
  font-style: normal;
  color: var(--pine);
}
.hero__lede {
  font-size: var(--fs-md);
  color: var(--granite-500);
  max-width: 52ch;
}

/* ── Signature: The Four Hundred ── */
.seats { --seat: 9px; --seat-gap: 5px; }
.seats__frame {
  display: grid;
  grid-template-columns: repeat(20, var(--seat));
  gap: var(--seat-gap);
  justify-content: start;
}
@media (max-width: 999px) { .seats { --seat: 11px; --seat-gap: 6px; } }
@media (max-width: 420px) { .seats { --seat: 8px; --seat-gap: 4px; } }

.seat {
  width: var(--seat); height: var(--seat);
  background: var(--granite-200);
  border-radius: 1px;
  transition: background-color var(--dur-base) var(--ease-out);
}
.seat--nay   { background: #B4341F; }
.seat--yea   { background: var(--granite-700); }
.seat--absent { background: transparent; box-shadow: inset 0 0 0 1px var(--line-control); }

.seats__caption {
  margin-top: var(--s5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--granite-400);
  max-width: 40ch;
}
.seats__legend {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
  margin-top: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--granite-500);
}
.seats__legend span { display: inline-flex; align-items: center; gap: var(--s2); }
.seats__legend i {
  width: 9px; height: 9px; border-radius: 1px; flex-shrink: 0;
  font-style: normal;
}

/* ===================================================================
   Sections
   =================================================================== */
.section { padding-block: var(--s9); }
.section--tight { padding-block: var(--s8); }
.section--inset { background: var(--surface-inset); }
.section--dark {
  background: var(--granite-900);
  color: var(--snow-2);
}
.section--dark h2, .section--dark h3, .section--dark h4 { color: var(--snow); }
.section--dark p { color: #B9BDBA; }
/* Muted utility text and links have to be re-tinted on the dark bands: the
   light-mode greys and the brand navy both fall under 3:1 against granite-900. */
.section--dark .form-note, .section--pine .form-note { color: #AEB3B0; }
.section--dark .form-note a, .section--dark a:not(.btn) { color: #E3E5E2; }
.section--pine .form-note { color: #B2BFDE; }
.section--pine .form-note a, .section--pine a:not(.btn) { color: #E6EBF6; }
.section--dark .seats__caption, .section--pine .seats__caption { color: #AEB3B0; }
.section--pine { background: var(--pine); color: #CFDDD5; }
.section--pine h2, .section--pine h3 { color: var(--snow); }
.section--pine p { color: #B2BFDE; }

.section__head { max-width: 62ch; margin-bottom: var(--s7); }
.section__head h2 { margin-bottom: var(--s4); }
.section__head p { font-size: var(--fs-md); color: var(--text-2); }
.section--dark .section__head p,
.section--pine .section__head p { color: #B9BDBA; }

/* Asymmetric two-column editorial block */
.split { display: grid; gap: var(--s7); }
@media (min-width: 900px) {
  .split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--s8); align-items: start; }
  .split--reverse { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ===================================================================
   Cards
   =================================================================== */
.cards { display: grid; gap: var(--s5); }
@media (min-width: 700px)  { .cards--2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 900px)  { .cards--3 { grid-template-columns: repeat(3, 1fr); } }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s6);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.card h3 { margin-bottom: var(--s3); }
.card p { color: var(--text-2); }

a.card { text-decoration: none; display: block; }
a.card:hover {
  border-color: var(--pine);
  box-shadow: var(--shadow-card);
  transform: translateY(-2px);
}
.card__more {
  display: inline-block;
  margin-top: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pine);
}

/* Numbered stat — mono, tabular, no gradient */
.stat { border-top: 2px solid var(--granite-900); padding-top: var(--s4); }
.stat__num {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 800;
  font-size: clamp(2.5rem, 1.9rem + 2.6vw, 4rem);
  line-height: 0.95;
  letter-spacing: -0.04em;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--granite-900);
}
.stat__label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--granite-400);
  margin-top: var(--s3);
}
.stat__note { font-size: var(--fs-sm); color: var(--text-2); margin-top: var(--s3); }
.section--dark .stat { border-top-color: var(--snow); }
.section--dark .stat__num { color: var(--snow); }
.section--dark .stat__label { color: #8E9491; }

/* ===================================================================
   Prose — long-form argument
   =================================================================== */
.prose { max-width: var(--measure); }
.prose h2 { margin-top: var(--s8); margin-bottom: var(--s4); }
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin-top: var(--s6); margin-bottom: var(--s3); }
.prose p { margin-bottom: var(--s4); color: var(--granite-700); }
.prose ul, .prose ol { margin: 0 0 var(--s4) var(--s5); color: var(--granite-700); }
.prose li { margin-bottom: var(--s2); max-width: var(--measure); }
.prose blockquote {
  border-left: 2px solid var(--pine);
  padding-left: var(--s5);
  margin-block: var(--s6);
  font-size: var(--fs-md);
  color: var(--granite-700);
}
.prose cite {
  display: block;
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-style: normal;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--granite-400);
}

/* ── Accordion FAQ ── */
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item summary {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s5);
  padding: var(--s5) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 600;
  font-size: var(--fs-md);
  letter-spacing: -0.015em;
  color: var(--granite-900);
  transition: color var(--dur-fast) var(--ease-out);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:hover { color: var(--pine); }
.faq-item summary::after {
  content: '+';
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 1.375rem;
  line-height: 1;
  color: var(--pine);
  flex-shrink: 0;
  transition: transform var(--dur-base) var(--ease-out);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item__body { padding-bottom: var(--s5); }
.faq-item__body p { color: var(--granite-700); }

/* ===================================================================
   Forms
   =================================================================== */
.form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--s6);
  box-shadow: var(--shadow-card);
}
@media (min-width: 700px) { .form-card { padding: var(--s7); } }

.form-card__head { margin-bottom: var(--s5); }
.form-card__head h2 { font-size: var(--fs-xl); margin-bottom: var(--s3); }
.form-card__head p { font-size: var(--fs-sm); color: var(--text-2); }

.field { display: flex; flex-direction: column; gap: var(--s2); margin-bottom: var(--s4); }
.field label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--granite-500);
}
.field .req { color: #B4341F; }
.field .opt { color: var(--granite-400); text-transform: none; letter-spacing: 0.02em; }

.field input,
.field textarea,
.field select {
  font-family: var(--font-body);
  font-size: 1rem; /* >=16px: stops iOS zoom-on-focus */
  line-height: 1.5;
  color: var(--granite-900);
  background: var(--birch);
  border: 1.5px solid var(--line-control);
  border-radius: var(--r-sm);
  padding: var(--s3) var(--s4);
  min-height: 48px;
  width: 100%;
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}
.field textarea { min-height: 132px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: #A3A9A6; }
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--granite-500); }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-color: var(--pine);
  box-shadow: 0 0 0 3px rgba(0, 42, 134, .18);
}
.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea { border-color: #B4341F; }

.field__error {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: #B4341F;
}

.form-row { display: grid; gap: var(--s4); }
@media (min-width: 560px) { .form-row { grid-template-columns: 1fr 1fr; } }

.checks { display: flex; flex-direction: column; gap: var(--s3); margin-bottom: var(--s5); }
.check {
  display: flex; align-items: flex-start; gap: var(--s3);
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--granite-700);
  cursor: pointer;
  min-height: 44px;
  padding-block: var(--s1);
}
.check input[type="checkbox"] {
  width: 20px; height: 20px; margin-top: 2px; flex-shrink: 0;
  accent-color: var(--pine);
  cursor: pointer;
}

.form-note {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--granite-400);
  margin-top: var(--s4);
}

.cf-turnstile { margin-block: var(--s4); }

.form-status { margin-top: var(--s4); font-size: var(--fs-sm); }
.form-status[data-state="error"] { color: #B4341F; }

/* Post-submit — the payoff */
.form-done { display: none; text-align: left; padding-block: var(--s5); }
.form-done h3 { margin-bottom: var(--s3); }
.form-done p { color: var(--text-2); }
.form-card[data-done="true"] .form-body { display: none; }
.form-card[data-done="true"] .form-done { display: block; }
.form-done__mark {
  width: 44px; height: 44px; margin-bottom: var(--s4);
  border-radius: 50%;
  background: var(--pine);
  display: grid; place-content: center;
}
.form-done__mark svg { width: 22px; height: 22px; stroke: var(--snow); }

/* ===================================================================
   Footer
   =================================================================== */
.footer {
  background: var(--granite-900);
  color: #9AA09D;
  padding-block: var(--s8) var(--s6);
  font-size: var(--fs-sm);
}
.footer a { color: #C9CECB; text-decoration: none; }
.footer a:hover { color: var(--snow); text-decoration: underline; }

.footer__top { display: grid; gap: var(--s7); margin-bottom: var(--s8); }
@media (min-width: 800px) {
  .footer__top { grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)); gap: var(--s6); }
}
.footer__brand .nav__wordmark { color: var(--snow); }
.footer__brand p { margin-top: var(--s4); color: #878D8A; max-width: 34ch; }

.footer__col h4 {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #949A97;
  margin-bottom: var(--s4);
}
.footer__col ul { list-style: none; display: flex; flex-direction: column; gap: var(--s3); }


/* Touch targets. The footer column links render at 18px tall, which is a
   mis-tap waiting to happen on a phone; the same is true of the laddered
   links under the hero. Pad them into a 44px target without moving the text,
   using a negative margin so the visual rhythm of the list is unchanged. */
@media (max-width: 999px) {
  .footer__col ul { gap: 0; }
  .footer__col ul a,
  .footer__legal nav a {
    display: inline-block;
    padding-block: 13px;
    margin-block: -5px;
  }
  .hero__ladder a { padding-block: 9px; }
  .person__links a { padding-block: 12px; }
  .hero-form__alt { padding-block: 12px; }
}

.footer__social { display: flex; gap: var(--s3); margin-top: var(--s5); }
.footer__social a {
  width: 44px; height: 44px;
  display: grid; place-content: center;
  border: 1px solid #363B3D;
  border-radius: var(--r-sm);
  transition: border-color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}
.footer__social a:hover { border-color: var(--snow); background: rgba(241,240,236,.06); }
.footer__social svg { width: 17px; height: 17px; fill: currentColor; }

.footer__legal {
  border-top: 1px solid #2E3335;
  padding-top: var(--s5);
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5);
  align-items: baseline; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.03em;
  color: #949A97;
}
.footer__legal nav { display: flex; flex-wrap: wrap; gap: var(--s5); }
.footer__consent {
  color: #949A97;
  font-size: var(--fs-xs);
  line-height: 1.6;
  max-width: 78ch;
  margin-bottom: var(--s5);
}

/* ===================================================================
   Motion — scroll reveal, one orchestrated moment
   =================================================================== */
/* Scoped to .js, set by an inline script in the head. Without that guard a
   JavaScript failure, a blocked script, or an IntersectionObserver that never
   fires leaves the whole page at opacity 0 with no way back. Content must be
   visible by default and hidden only once something is definitely able to
   reveal it again. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.js .reveal.is-in { opacity: 1; transform: none; }
.js .reveal-group > * {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
}
.js .reveal-group.is-in > * { opacity: 1; transform: none; }
.js .reveal-group.is-in > *:nth-child(1) { transition-delay: 0ms; }
.js .reveal-group.is-in > *:nth-child(2) { transition-delay: 60ms; }
.js .reveal-group.is-in > *:nth-child(3) { transition-delay: 120ms; }
.js .reveal-group.is-in > *:nth-child(4) { transition-delay: 180ms; }

@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;
  }
  .reveal, .reveal-group > *, .js .reveal, .js .reveal-group > * { opacity: 1 !important; transform: none !important; }
}

/* ===================================================================
   Print
   =================================================================== */
@media print {
  .nav, .footer__social, .cta-row, .form-card { display: none; }
  body { background: #fff; color: #000; }
}

/* ===================================================================
   Photography
   The site is image-led. Type sits on photographs, so every image that
   carries text also carries a scrim heavy enough to hold AA contrast at
   the top of its range, not just on the lucky part of the frame.
   =================================================================== */

.photo-hero {
  position: relative;
  isolation: isolate;
  min-height: min(88vh, 780px);
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--granite-900);
}
.photo-hero__media,
.photo-band__media {
  position: absolute; inset: 0;
  width: 100%; height: 100% !important;
  object-fit: cover;
  z-index: -2;
}
/* One knob, not a set of tiers. Every hero photograph was sampled behind the
   type it actually carries, and --veil is the alpha that holds the worst
   element at WCAG AA with a little headroom. The ramp shape below is fixed:
   full strength at the foot where the type sits, releasing up the frame.
   Mobile crops the same frame differently, so it carries its own measurement
   in --veil-sm. Set --veil / --veil-sm on the section, never the stops. */
.photo-hero { --veil: .84; }
.photo-hero::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  --v: var(--veil);
  background:
    linear-gradient(to top,
      rgba(9,11,12,calc(var(--v) * 1.00))   0%,
      rgba(9,11,12,calc(var(--v) * 0.95))  24%,
      rgba(9,11,12,calc(var(--v) * 0.90))  46%,
      rgba(9,11,12,calc(var(--v) * 0.79))  62%,
      rgba(9,11,12,calc(var(--v) * 0.52))  82%,
      rgba(9,11,12,calc(var(--v) * 0.38)) 100%),
    linear-gradient(to right, rgba(0,42,134,.30) 0%, rgba(0,42,134,0) 68%);
}

/* The split hero carries its type in the LEFT column and a light form panel on
   the right, so a bottom-weighted scrim just blacks the photograph out. Shaped
   to the statehouse frame instead: sampled in eight vertical strips it needs
   .42 .44 .75 .85 .85 .83 .64 .35, dark at both edges and blazing across the
   dome. A left-heavy ramp had it exactly backwards.
   Scoped to the wide layout only. Below 1000px the columns stack and the type
   spans the full width, so the plain foot ramp above is the correct shape. */
@media (min-width: 1000px) {
  .photo-hero--split::after {
    background:
      linear-gradient(100deg, rgba(9,11,12,.50) 0%, rgba(9,11,12,.54) 14%,
                      rgba(9,11,12,.82) 27%, rgba(9,11,12,.91) 40%,
                      rgba(9,11,12,.90) 54%, rgba(9,11,12,.86) 66%,
                      rgba(9,11,12,.70) 79%, rgba(9,11,12,.44) 100%),
      linear-gradient(to top, rgba(9,11,12,.30) 0%, rgba(9,11,12,.08) 40%, rgba(9,11,12,.18) 100%);
  }
}

@media (max-width: 999px) {
  .photo-hero::after { --v: var(--veil-sm, var(--veil)); }
}

.photo-hero__inner { width: 100%; padding-block: var(--s9) var(--s8); }

.photo-hero h1 { color: #FFF; }
.photo-hero h1 em { font-style: normal; color: #EFC037; }
.photo-hero h1 { margin-bottom: var(--s5); }
.photo-hero .hero__lede { color: #E4E6E8; max-width: 56ch; }

/* Figures under the hero: the standing, not a scoreboard */
.factbar {
  display: grid;
  gap: var(--s5);
  margin-top: var(--s8);
  padding-top: var(--s6);
  border-top: 1px solid rgba(255,255,255,.22);
}
@media (min-width: 760px) { .factbar { grid-template-columns: repeat(3, 1fr); gap: var(--s7); } }
.factbar__num {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 800;
  font-size: clamp(2rem, 1.5rem + 1.9vw, 3rem);
  line-height: 1;
  letter-spacing: -0.035em;
  font-variant-numeric: lining-nums tabular-nums;
  color: #FFF;
}
.factbar__label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #EFC037;
  margin-top: var(--s3);
}
.factbar__note { font-size: var(--fs-sm); color: #C3C7CA; margin-top: var(--s2); max-width: 34ch; }

/* Full-bleed band between sections */
.photo-band {
  position: relative;
  isolation: isolate;
  min-height: min(62vh, 520px);
  display: flex;
  align-items: center;
  overflow: hidden;
  background: var(--granite-900);
}
.photo-band::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to right, rgba(9,11,12,.90) 0%, rgba(9,11,12,.72) 42%,
                              rgba(9,11,12,.34) 78%, rgba(9,11,12,.28) 100%);
}
/* Representatives Hall is lit end to end: measured across six strips it needs
   .88 .87 .86 .85 .83 .84, so the standard release at 42% drops the quote
   under contrast. Hold it flat, then let go late. */
.photo-band--dense::after {
  background: linear-gradient(to right, rgba(9,11,12,.93) 0%, rgba(9,11,12,.91) 34%,
                              rgba(9,11,12,.78) 62%, rgba(9,11,12,.46) 88%,
                              rgba(9,11,12,.38) 100%);
}

@media (max-width: 999px) {
  /* Narrow: stack instead of overlaying. The meeting house is a white
     clapboard building, and holding a caption over it at AA needs alpha .95,
     which turns the photograph into a black rectangle. Below 1000px the image
     sits at full strength above the quote and the quote gets a solid ground,
     so there is no contrast tax and the picture is actually visible. */
  .photo-band { display: block; min-height: 0; }
  .photo-band::after { content: none; }
  .photo-band picture { display: block; }
  .photo-band__media {
    /* Back into normal flow, and out of the z-index:-2 layer the overlay
       version needs, which would otherwise bury it behind the band's own
       background colour. */
    position: relative;
    z-index: 0;
    height: auto !important;
    aspect-ratio: 16 / 10;
    object-fit: cover;
  }
  .photo-band .container { padding-block: var(--s7); }
}
.photo-band__quote {
  max-width: 30ch;
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  font-size: var(--fs-xl);
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: #FFF;
  text-wrap: balance;
}
.photo-band__attrib {
  margin-top: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #EFC037;
}

/* Card that leads with an image */
.card--photo { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.card--photo img { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; display: block; }
.card--photo .card__body { padding: var(--s6); }

/* The three-wording comparison. Bars, not a confession. */
.wording { display: grid; gap: var(--s5); margin-top: var(--s6); }
.wording__row { display: grid; gap: var(--s3); }
.wording__q {
  font-family: var(--font-body);
  font-size: var(--fs-md);
  color: var(--granite-900);
  max-width: 46ch;
}
.wording__bar {
  position: relative;
  height: 46px;
  background: var(--snow-2);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.wording__fill {
  position: absolute; inset: 0;
  background: var(--navy);
  border-radius: var(--r-sm);
  transform-origin: left;
  transform: scaleX(var(--pct, 0));
  transition: transform 900ms var(--ease-out);
}
.wording__fill--gold { background: var(--gold); }
.wording__val {
  position: absolute; top: 50%; left: calc(var(--pct) * 100% + var(--s4));
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.375rem;
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--granite-900);
  white-space: nowrap;
}
.wording__val--ink { color: var(--granite-900); }
@media (prefers-reduced-motion: reduce) { .wording__fill { transition: none; } }

/* ===================================================================
   Document pages — privacy, terms, accessibility, credits
   No photograph. These are documents, and a navy plate reads as
   deliberate where a stock landscape would read as filler.
   =================================================================== */
.doc-header {
  background: var(--navy);
  color: #C6D0E8;
  padding-block: var(--s9) var(--s8);
  border-bottom: 4px solid var(--gold);
}
.doc-header h1 {
  color: #FFF;
  font-size: var(--fs-2xl);
  max-width: 20ch;
}
.doc-header p {
  margin-top: var(--s4);
  font-size: var(--fs-md);
  color: #B2BFDE;
  max-width: 54ch;
}
.doc-header__meta {
  margin-top: var(--s6);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8FA3CE;
}

/* Long-form document body: a quiet left rule marks each section */
.doc-body { padding-block: var(--s8); }
.doc-body .prose h3 {
  margin-top: var(--s7);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}
.doc-body .prose h3:first-of-type { margin-top: 0; }

/* Credits table */
.credits { display: grid; gap: var(--s5); margin-top: var(--s6); }
.credit {
  display: grid; gap: var(--s4);
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--line);
  align-items: center;
}
@media (min-width: 700px) { .credit { grid-template-columns: 200px 1fr; } }
.credit img {
  width: 100%; height: auto; aspect-ratio: 16/9; object-fit: cover;
  border-radius: var(--r-sm); display: block;
}
.credit__meta { font-size: var(--fs-sm); color: var(--granite-500); }
.credit__meta strong { display: block; color: var(--granite-900); font-size: var(--fs-base); margin-bottom: var(--s2); }
.credit__lic {
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.06em; color: var(--granite-400); margin-top: var(--s2);
}

/* ===================================================================
   Hero conversion layout
   The ask belongs in the hero, not one click away behind a button.
   =================================================================== */
.photo-hero--split .photo-hero__inner { padding-block: var(--s8) var(--s7); }
/* The form card runs ~630px against ~470px of headline, so bottom-aligning
   them dropped the type 163px below the top of the card and the two blocks
   read as unrelated. Centre them: the leftover space splits evenly and the
   pair sits as one object. */
.hero__split { display: grid; gap: var(--s7); align-items: center; }
@media (min-width: 1000px) {
  .hero__split { grid-template-columns: minmax(0, 1.05fr) minmax(380px, 0.95fr); gap: var(--s8); }
}

.hero-form {
  background: var(--snow);
  border-radius: var(--r-md);
  padding: var(--s6);
  box-shadow: 0 24px 60px rgba(9, 11, 12, .34);
}
@media (min-width: 700px) { .hero-form { padding: var(--s7); } }
.hero-form h2 { font-size: var(--fs-lg); margin-bottom: var(--s3); text-wrap: balance; }
.hero-form__sub { font-size: var(--fs-sm); color: var(--granite-500); margin-bottom: var(--s5); }
.hero-form .field { margin-bottom: var(--s3); }
.hero-form .form-note { margin-top: var(--s3); }
.hero-form__alt {
  display: block; margin-top: var(--s4); text-align: center;
  font-family: var(--font-mono); font-size: var(--fs-xs);
  letter-spacing: 0.04em; color: var(--granite-500);
}

/* Secondary hero links, laddered under the primary ask */
.hero__ladder { display: flex; flex-direction: column; gap: var(--s3); margin-top: var(--s6); }
.hero__ladder a {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 600;
  font-size: var(--fs-base);
  color: #FFF;
  text-decoration: none;
  display: inline-flex; align-items: center; gap: var(--s2);
  width: fit-content;
  border-bottom: 1px solid rgba(255,255,255,.35);
  padding-bottom: 2px;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.hero__ladder a:hover { color: #EFC037; border-color: #EFC037; }

/* ===================================================================
   Proof band — what the organisation has actually done
   =================================================================== */
.proof {
  background: var(--navy);
  color: #C6D0E8;
  padding-block: var(--s8);
}
.proof__grid { display: grid; gap: var(--s6); }
@media (min-width: 640px) { .proof__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .proof__grid { grid-template-columns: repeat(4, 1fr); } }
.proof__num {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 800;
  font-size: clamp(2.125rem, 1.7rem + 1.9vw, 3.125rem);
  line-height: 1;
  letter-spacing: -0.035em;
  font-variant-numeric: lining-nums tabular-nums;
  color: #FFF;
}
.proof__label {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #EFC037;
  margin-top: var(--s3);
}
.proof__note { font-size: var(--fs-sm); color: #A9B8DC; margin-top: var(--s2); max-width: 30ch; }

/* ===================================================================
   Comparison rows — how NH stands against movements that won
   =================================================================== */
.compare { display: grid; gap: var(--s5); margin-top: var(--s6); }
.compare__row { display: grid; gap: var(--s3); }
.compare__head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4);
}
.compare__name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  font-size: var(--fs-md);
  letter-spacing: -0.015em;
  color: var(--granite-900);
}
.compare__val {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--fs-lg);
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--navy);
  flex-shrink: 0;
}
.compare__row--lead .compare__val { color: var(--gold-ink); }
.compare__track { height: 12px; background: var(--snow-2); border-radius: 99px; overflow: hidden; }
.compare__fill {
  /* A span is inline by default: height and scaleX act on nothing, so the bar
     renders empty. Same trap that hid the wording bars. */
  display: block;
  width: 100%;
  height: 100%;
  background: var(--granite-400);
  border-radius: 99px;
  transform-origin: left;
  transform: scaleX(var(--pct, 0));
  transition: transform 900ms var(--ease-out);
}
.compare__row--lead .compare__fill { background: var(--gold); }
.compare__note { font-size: var(--fs-sm); color: var(--granite-500); }
@media (prefers-reduced-motion: reduce) { .compare__fill { transition: none; } }

/* Pull-quote callout used to land an argument */
.callout {
  border-left: 3px solid var(--gold);
  padding: var(--s2) 0 var(--s2) var(--s5);
  margin-block: var(--s6);
}
.callout p {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 600;
  font-size: var(--fs-lg);
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--granite-900);
  max-width: 38ch;
}
.section--dark .callout p, .section--pine .callout p { color: #FFF; }

/* A prose block sitting directly in a container (not inside a .split) was
   left-aligning at 66ch and leaving half the width dead. Centre it so the
   narrow measure reads as an editorial choice rather than a layout hole. */
.container > .prose { margin-inline: auto; }
.container > .prose.prose--wide { max-width: 82ch; }

/* Section heads and standalone prose share the same optical centre */
.section__head--center { margin-inline: auto; text-align: left; }

/* ===================================================================
   The audience — who the movement is organising
   Deliberately NOT a signup counter. A young movement's own tally is
   negative social proof; the size of the constituency it exists to
   reach is the opposite, and it is the honest framing of the work.
   =================================================================== */
.audience { position: relative; overflow: hidden; }
.audience__figure {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 800;
  font-size: clamp(3.5rem, 1.9rem + 6.4vw, 8rem);
  line-height: 0.92;
  letter-spacing: -0.045em;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--navy);
  margin-bottom: var(--s4);
}
.section--dark .audience__figure, .section--pine .audience__figure { color: #FFF; }
.audience__caption {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 600;
  font-size: var(--fs-lg);
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--granite-900);
  max-width: 26ch;
}
.section--dark .audience__caption { color: #FFF; }

/* A dotted field where each mark stands for a block of people. Rendered from
   CSS, so it costs nothing and scales with the container. */
.field-dots {
  --dot: 7px; --dot-gap: 6px;
  display: grid;
  grid-template-columns: repeat(auto-fill, var(--dot));
  gap: var(--dot-gap);
  justify-content: space-between;
  margin-top: var(--s6);
}
.field-dots span {
  width: var(--dot); height: var(--dot);
  border-radius: 50%;
  background: var(--navy-100);
}
.field-dots span.is-on { background: var(--gold); }
.section--dark .field-dots span { background: rgba(255,255,255,.16); }
.section--dark .field-dots span.is-on { background: var(--gold); }
.field-dots__key {
  margin-top: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--granite-400);
}
.section--dark .field-dots__key { color: #A9B8DC; }

/* ===================================================================
   Press wall
   Outlet names set as a typographic wall rather than scraped logo files:
   no third-party image rights, no broken remote assets, and it holds up
   at any size. Every name here must map to a real, cited article.
   =================================================================== */
/* Individual coverage entries */
.clips { display: grid; gap: 0; margin-top: var(--s6); }
.clip {
  display: grid; gap: var(--s2);
  padding-block: var(--s5);
  border-top: 1px solid var(--line);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}
@media (min-width: 760px) {
  .clip { grid-template-columns: 190px 1fr auto; gap: var(--s5); align-items: baseline; }
}
.clip:last-child { border-bottom: 1px solid var(--line); }
.clip__outlet {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy-500);
}
.clip__title {
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: 1.35;
  color: var(--granite-900);
}
a.clip:hover .clip__title { color: var(--navy); text-decoration: underline; text-underline-offset: 3px; }
.clip__date {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  color: var(--granite-400);
  white-space: nowrap;
}

/* ===================================================================
   Who speaks for us
   =================================================================== */
.person { display: grid; gap: var(--s5); align-items: start; }
@media (min-width: 700px) { .person { grid-template-columns: 200px 1fr; gap: var(--s6); } }
.person__portrait {
  width: 100%; max-width: 200px;
  height: auto;
  aspect-ratio: 1;
  border-radius: var(--r-md);
  object-fit: cover;
  display: block;
  background: var(--snow-2);
}
.person__mark {
  width: 100%; max-width: 200px; aspect-ratio: 1;
  border-radius: var(--r-md);
  background: var(--navy);
  display: grid; place-content: center;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 3.5rem;
  letter-spacing: -0.04em;
  color: var(--gold);
}
.person__name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 800;
  font-size: var(--fs-xl);
  letter-spacing: -0.025em;
  color: var(--granite-900);
}
.section--dark .person__name { color: #FFF; }
.person__role {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy-500);
  margin-top: var(--s2);
  margin-bottom: var(--s4);
}
.section--dark .person__role { color: #EFC037; }
.person__links {
  display: flex; flex-wrap: wrap; gap: var(--s4);
  margin-top: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
}

/* ===================================================================
   The New Hampshire First Pledge
   A candidate and officeholder instrument. Styled as a document, not a
   marketing block, because that is what a signer is putting a name to.
   =================================================================== */
.pledge { counter-reset: commitment; margin-top: var(--s6); }
.pledge__item {
  position: relative;
  display: grid;
  gap: var(--s3);
  grid-template-columns: 44px 1fr;
  align-items: start;
  padding: var(--s5) 0;
  border-top: 1px solid var(--line);
}
.pledge__item:last-child { border-bottom: 1px solid var(--line); }
.pledge__item::before {
  counter-increment: commitment;
  content: counter(commitment);
  display: grid; place-content: center;
  width: 32px; height: 32px;
  border: 1.5px solid var(--navy);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--navy);
}
.pledge__text {
  font-family: var(--font-body);
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--granite-900);
  max-width: 62ch;
}
.pledge__gloss {
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.6;
  letter-spacing: 0.02em;
  color: var(--granite-400);
  max-width: 60ch;
}

/* Who it is for / who it is not for */
.audience-split { display: grid; gap: var(--s5); margin-top: var(--s6); }
@media (min-width: 760px) { .audience-split { grid-template-columns: 1fr 1fr; gap: var(--s6); } }
.audience-split__card {
  padding: var(--s6);
  border-radius: var(--r-md);
  border: 1px solid var(--line);
  background: var(--birch);
}
.audience-split__card--yes { border-color: var(--navy); border-width: 2px; }
.audience-split__card h3 { margin-bottom: var(--s3); }
.audience-split__card p { color: var(--text-2); }

/* Debt clock — the $50 trillion trigger, rendered honestly as a bar */
.trigger { margin-top: var(--s6); }
.trigger__bar {
  position: relative;
  height: 56px;
  background: var(--snow-2);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.trigger__fill {
  position: absolute; inset: 0;
  background: var(--navy);
  transform-origin: left;
  transform: scaleX(var(--pct, 0));
  transition: transform 1100ms var(--ease-out);
}
.trigger__now, .trigger__cap {
  position: absolute; top: 50%; transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.125rem;
  letter-spacing: -0.02em;
  font-variant-numeric: lining-nums tabular-nums;
}
.trigger__now { left: var(--s4); color: #FFF; }
.trigger__cap { right: var(--s4); color: var(--granite-500); }
.trigger__key {
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--granite-400);
}
@media (prefers-reduced-motion: reduce) { .trigger__fill { transition: none; } }

/* ===================================================================
   Pledge sign-up form + roster
   =================================================================== */
.signform { max-width: 760px; }
.signform fieldset { border: 0; margin-bottom: var(--s7); }
.signform legend {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--navy-500);
  margin-bottom: var(--s4);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
  width: 100%;
}
.signform__commit {
  display: flex; align-items: flex-start; gap: var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.signform__commit:first-of-type { border-top: 1px solid var(--line); }
.signform__commit input[type="checkbox"] {
  width: 22px; height: 22px; margin-top: 3px; flex-shrink: 0;
  accent-color: var(--navy); cursor: pointer;
}
.signform__commit span {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--granite-900);
}
.legal {
  margin-top: var(--s6);
  padding: var(--s5);
  background: var(--snow-2);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  line-height: 1.7;
  letter-spacing: 0.01em;
  color: var(--granite-500);
}

/* Roster */
.roster { display: grid; gap: var(--s4); margin-top: var(--s6); }
@media (min-width: 700px)  { .roster { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1050px) { .roster { grid-template-columns: repeat(3, 1fr); } }
.signer {
  background: var(--birch);
  border: 1px solid var(--line);
  border-left: 3px solid var(--navy);
  border-radius: var(--r-sm);
  padding: var(--s5);
}
.signer__office {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy-500);
  margin-bottom: var(--s3);
}
.signer__name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 100;
  font-weight: 700;
  font-size: var(--fs-lg);
  letter-spacing: -0.02em;
  color: var(--granite-900);
}
.signer__meta {
  margin-top: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.04em;
  color: var(--granite-400);
}
.signer__flag {
  display: inline-block;
  margin-top: var(--s3);
  padding: 2px var(--s3);
  border-radius: var(--r-sm);
  background: var(--snow-2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--granite-500);
}
.signer--flagged { border-left-color: #B4341F; }

.roster-tools {
  display: grid; gap: var(--s3);
  margin-top: var(--s6);
}
@media (min-width: 700px) { .roster-tools { grid-template-columns: 2fr 1fr 1fr; } }
.roster-tools input, .roster-tools select {
  font-family: var(--font-body); font-size: 1rem;
  min-height: 48px; width: 100%;
  padding: var(--s3) var(--s4);
  background: var(--birch);
  border: 1.5px solid var(--line-control);
  border-radius: var(--r-sm);
  color: var(--granite-900);
}
.roster-tools input:focus, .roster-tools select:focus {
  outline: none; border-color: var(--navy);
  box-shadow: 0 0 0 3px rgba(0,42,134,.18);
}
.roster-empty {
  margin-top: var(--s6);
  padding: var(--s8) var(--s6);
  border: 1px dashed var(--line-control);
  border-radius: var(--r-md);
  text-align: left;
}
.roster-empty h3 { margin-bottom: var(--s3); }
.roster-empty p { color: var(--text-2); max-width: 52ch; }
.roster-count {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--granite-400);
  margin-top: var(--s5);
}

/* ---------------------------------------------------------------------------
   Where this is happening

   Counties carry the fill and towns carry the marks. Presence, never density:
   one mark per town however many people signed there, and no per-county count
   anywhere. Fifty people reads as "almost nobody" if you publish the counts,
   and as "every county in the state" if you publish reach. Both are true.
   Rendered server-side as plain SVG, so it needs no library and draws with
   JavaScript switched off.
   --------------------------------------------------------------------------- */
.split--map {
  align-items: center;
  gap: var(--s8);
}

.nhmap { margin: 0; }
.nhmap svg {
  display: block;
  width: 100%;
  max-width: 400px;
  height: auto;
  margin-inline: auto;
  overflow: visible;
}

.nhmap__county {
  fill: var(--granite-100);
  stroke: var(--snow);
  stroke-width: 1.6;
  stroke-linejoin: round;
}
.nhmap__county.is-on { fill: var(--navy); }

/* The marks sit on navy, so they need to be the brand's other colour and
   carry a hairline of the page ground to keep them separate where towns
   cluster along the Merrimack. */
.nhmap__town {
  fill: var(--gold);
  stroke: var(--navy-700);
  stroke-width: 1.5;
  paint-order: stroke;
}

.nhmap__caption {
  margin-top: var(--s6);
  margin-inline: auto;
  max-width: 46ch;
  text-align: center;
  /* Set explicitly: figcaption inherits the mono face from further up, which
     reads as a data label rather than a sentence. */
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--granite-500);
}

@media (max-width: 999px) {
  .split--map { gap: var(--s6); }
  .nhmap svg { max-width: 300px; }
}

/* Where a signer actually lives, filled in after the petition posts. */
.form-done__where { margin: 0 0 var(--s3); font-size: var(--fs-sm); }
.form-done__where strong { color: var(--navy); }
.form-done [data-districts] { margin-block: var(--s4) var(--s5); text-align: left; }

/* The audience split ran 235px on the left against 656px on the right, which
   left a 421px hole under the figure. The dot field belongs with the number it
   illustrates, not at the foot of the prose, and moving it closes the gap. A
   128px figure also needs more than the standard gutter between it and body
   text. */
.audience .split { gap: var(--s9); align-items: start; }
.audience .field-dots { margin-top: var(--s7); }
@media (max-width: 999px) {
  .audience .split { gap: var(--s6); }
}

/* ---------------------------------------------------------------------------
   Inverted sections beat .prose

   `.prose p` sets granite-700 and is defined below `.section--dark p`, at the
   same specificity, so it won every dark section: 1.57:1 on granite and
   1.17:1 on navy. Effectively invisible body copy on three pages. These
   selectors carry an extra class so they win regardless of source order.
   --------------------------------------------------------------------------- */
.section--dark .prose p,
.section--dark .prose li,
.section--dark .prose ul,
.section--dark .prose ol,
.section--dark .prose blockquote { color: #B9BDBA; }

.section--pine .prose p,
.section--pine .prose li,
.section--pine .prose ul,
.section--pine .prose ol,
.section--pine .prose blockquote { color: #CBD5EC; }

.section--dark .prose strong,
.section--pine .prose strong { color: var(--snow); }

/* ---------------------------------------------------------------------------
   Press video

   Each card is a plain link to YouTube until somebody presses play, so the
   page ships no third-party request and works with JavaScript off. On click
   app.js swaps the still for a youtube-nocookie player in place.
   --------------------------------------------------------------------------- */
.vids {
  display: grid;
  gap: var(--s7);
  grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .vids { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .vids { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.vid { margin: 0; }
.vid__link {
  display: block;
  text-decoration: none;
  color: inherit;
}
.vid__shot {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--granite-900);
  border-radius: 2px;
}
.vid__shot img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.vid__link:hover .vid__shot img,
.vid__link:focus-visible .vid__shot img { transform: scale(1.03); }

.vid__play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--snow);
  background: rgba(9, 11, 12, .28);
  transition: background var(--dur-fast) var(--ease-out);
}
.vid__play svg {
  width: 34px; height: 34px;
  padding: 14px;
  border-radius: 50%;
  background: rgba(9, 11, 12, .72);
  box-sizing: content-box;
}
.vid__link:hover .vid__play,
.vid__link:focus-visible .vid__play { background: rgba(9, 11, 12, .12); }
.vid__link:hover .vid__play svg { background: var(--gold); color: var(--gold-ink); }

.vid__player {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: 2px;
  background: var(--granite-900);
}

.vid__outlet {
  display: block;
  margin-top: var(--s5);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--navy-500);
}
.vid__title {
  display: block;
  margin-top: var(--s2);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-md);
  line-height: 1.25;
  color: var(--granite-900);
}
.vid__link:hover .vid__title { text-decoration: underline; text-underline-offset: 3px; }
.vid__date {
  display: block;
  margin-top: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--granite-500);
}
.vid__blurb {
  margin: var(--s4) 0 0;
  font-size: var(--fs-sm);
  color: var(--granite-500);
}

@media (prefers-reduced-motion: reduce) {
  .vid__shot img { transition: none; }
  .vid__link:hover .vid__shot img { transform: none; }
}

/* ---------------------------------------------------------------------------
   Press logo wall

   Marks are the outlets' own trademarks, shown nominatively to identify who
   reported. Assets are the prepared set from thetnm.org, which had already
   solved the hard part: grayscale(1) rather than brightness(0), because a
   white-on-colour mark like Newsweek's flattens to a solid black block under
   brightness and stays legible under grayscale. Height is fixed, width is
   free, so each mark keeps its own proportions.
   --------------------------------------------------------------------------- */
.press-logos {
  list-style: none;
  margin: var(--s7) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s7) var(--s8);
}
.press-logos__item { display: flex; align-items: center; height: 30px; }
.press-logos__item img {
  display: block;
  max-height: 100%;
  width: auto;
  object-fit: contain;
}
.press-logo {
  filter: grayscale(1);
  opacity: .7;
  transition: filter var(--dur-fast) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.press-logos__item:hover .press-logo { filter: grayscale(0); opacity: 1; }

/* White or pale marks: a Newsweek-style white-on-colour lockup goes to a flat
   pale smear under grayscale alone. Flip it to a dark silhouette instead. */
.press-logo--invert { filter: grayscale(1) invert(1); }

/* A mid-tone mark like NHPR's red goes to a pale grey that sits lighter than
   the black wordmarks beside it. Bring it down to the same weight. */
.press-logo--deepen { filter: grayscale(1) brightness(.55); }
.press-logos__item:hover .press-logo--deepen { filter: grayscale(0); opacity: 1; }
.press-logos__item:hover .press-logo--invert { filter: grayscale(1) invert(1); opacity: 1; }

.press-logos__more {
  margin: var(--s8) 0 var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--granite-500);
}
.press-names {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s6);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-md);
  color: var(--granite-700);
}

@media (prefers-reduced-motion: reduce) { .press-logo { transition: none; } }
@media (max-width: 699px) {
  .press-logos { gap: var(--s6) var(--s7); }
  .press-logos__item { height: 24px; }
  .press-names { font-size: var(--fs-sm); }
}

/* ---------------------------------------------------------------------------
   Representative lookup

   One block per House district, because most Granite Staters sit in two.
   --------------------------------------------------------------------------- */
.rep-group + .rep-group { margin-top: var(--s6); }
.rep-group__name {
  margin: 0 0 var(--s3);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--granite-500);
}
.rep-list { list-style: none; margin: 0; padding: 0; }
.rep {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s4);
  padding-block: var(--s4);
  border-top: 1px solid var(--line);
}
.rep:last-child { border-bottom: 1px solid var(--line); }
.rep__name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-md);
  color: var(--granite-900);
}
.rep__party { font-size: var(--fs-sm); color: var(--granite-500); margin-right: auto; }
.rep__nomail { font-size: var(--fs-sm); color: var(--granite-500); }
.rep-vacant { margin: 0; font-size: var(--fs-sm); color: var(--granite-500); }

.btn--sm { padding: var(--s2) var(--s4); font-size: var(--fs-sm); }

@media (max-width: 699px) {
  .rep__party { margin-right: 0; width: 100%; }
}
