/* ==========================================================================
   50 States for Ukraine — replication of https://www.50statesforukraine.com
   Every value below is measured from the live site (see NOTES.md extraction
   sheets). Do not round: sizes like 47px / 37px / 34px are the real values.
   ========================================================================== */

/* --- Webfonts: the same faces the live site serves ---------------------- */
@font-face {
  font-family: 'aether';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/aether-400.woff2') format('woff2');
}
@font-face {
  font-family: 'aether';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/aether-700.woff2') format('woff2');
}
@font-face {
  font-family: 'helvetica-w01-bold';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/helvetica-bold.woff2') format('woff2');
}
@font-face {
  font-family: 'helvetica-w01-light';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/helvetica-light.woff2') format('woff2');
}
@font-face {
  font-family: 'avenir-lt-w01_35-light';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/avenir-35-light.woff2') format('woff2');
}
@font-face {
  font-family: 'madefor-text';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/madefor-text.woff2') format('woff2');
}

/* --- Design tokens (Layer 3 + 4 extraction) ----------------------------- */
:root {
  --c-page: #ffffff;
  --c-bg: #fafafa;
  --c-cream: #f9f8e7;
  --c-ink: #000000;
  --c-ink-2: #3f3f3f;

  --c-hero: #3d3d55;
  --c-band: #324158;
  --c-navy: #152859;
  --c-blue: #008afc;
  --c-blue-glass: rgba(29, 103, 205, 0.89);
  --c-gold: rgba(255, 212, 6, 0.82);
  --c-white: #ffffff;
  --c-offwhite: #fafafa;

  --font-display: 'aether', Arial, sans-serif;
  --font-helv-bold: 'helvetica-w01-bold', 'Helvetica Neue', Arial, sans-serif;
  --font-helv-light: 'helvetica-w01-light', 'Helvetica Neue', Arial, sans-serif;
  --font-madefor: 'madefor-text', 'Helvetica Neue', Arial, sans-serif;
  --font-avenir: 'avenir-lt-w01_35-light', 'Helvetica Neue', Arial, sans-serif;

  --r-pill: 60px;
  --r-pill-sm: 30px;
  --r-glass: 30px;

  --page-max: 1440px;
  --content-max: 980px;
}

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

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

body {
  margin: 0;
  background: var(--c-page);
  color: var(--c-ink);
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; border: 0; }
a { color: inherit; text-decoration: none; }
button { font: inherit; border: 0; background: none; cursor: pointer; }

/* --- Header: 1440x70, #FAFAFA, logo 47x51 at x=122 --------------------- */
.site-header {
  height: 70px;
  position: sticky;
  top: 0;
  z-index: 51;
  background: var(--c-bg);
  display: flex;
  align-items: center;
  padding: 0 122px;
  gap: 10px;
  transition: transform 0.2s ease;
}
.site-header.is-hidden { transform: translateY(-100%); transition-timing-function: ease-in; }
.site-header__logo {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  /* The header centres the 51 px crest in a 70 px row, which puts its top at 9.5 px: 19 device pixels
     at 2x (whole, pixel-for-pixel) but 28.5 at 3x, where the browser filters the image and the crest
     goes soft on an iPhone. Nudge the whole lockup to 10 px, which is whole at 1x, 2x and 3x (10/20/30
     device px). Half a CSS pixel lower than the row's centre is invisible, but it is the difference
     between a resampled 3x crest and a sharp one; e2e/header.spec.js asserts the device-pixel top at
     DPR 3. */
  position: relative;
  top: 0.5px;
}
.site-header__logo img {
  width: 47px;
  height: 51px;
  object-fit: contain;
}
.site-header__wordmark {
  display: inline-block;
  position: relative;
  top: 3px;
  font-size: 17px;
  line-height: 1;
  letter-spacing: -0.17px;
  white-space: nowrap;
}
.site-header__wordmark::first-line { line-height: 1; }
.site-nav {
  display: flex;
  align-items: center;
  margin: 3px 88px 0 auto;
}
.site-nav__link {
  display: block;
  flex: 0 0 auto;
  padding: 0;
  font-size: 16px;
  line-height: 30px;
  text-align: center;
  color: #000;
  transition: color 0.4s ease;
}
.site-nav__link:nth-child(1) { width: 73px; }
.site-nav__link:nth-child(2) { width: 96px; }
.site-nav__link:nth-child(3) { width: 151px; }
.site-nav__link:nth-child(4) { width: 157px; }
.site-nav__link:nth-child(5) { width: 124px; }
.site-nav__link:nth-child(6) { width: 114px; }
.site-nav__link:hover,
.site-nav__link.is-current { color: #3f3f3f; }
/* The shop, not a section anchor: it keeps its own class so the scroll-spy (scroll.js) still sees exactly
   live's six anchors, and so the hover/current colour those six share does not apply to a filled pill. */
.site-nav__merch {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 84px;
  height: 36px;
  margin-left: 14px;
  border-radius: var(--r-pill);
  background: var(--c-navy);
  color: var(--c-white);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: normal;
  transition: background-color 0.2s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.site-nav__merch:hover { background: #21407f; }
.site-nav__merch:active { transform: scale(0.98); }
.site-nav__toggle { display: none; }

/* --- Hero: full-bleed 1440x467 image, then a 234px #3D3D55 stat band --- */
.hero__visual { position: relative; }
/* The map's own backdrop, painted before the image arrives so the title never sits on white. Sampled from
   s50-02.png: rgb(22, 23, 44) at the top to rgb(58, 59, 83) at the bottom. */
.hero__image { width: 100%; background: linear-gradient(to bottom, rgb(22, 23, 44), rgb(58, 59, 83)); }
.hero__image picture { display: block; }
.hero__image img { width: 100%; height: auto; }

/* Glass box over the map: 440px wide at x=500, 155px down, radius 30. */
.hero__glass {
  position: absolute;
  top: 155px;
  left: 50%;
  transform: translateX(-50%);
  width: 440px;
  padding: 16px 0;
  border-radius: var(--r-glass);
  background: var(--c-blue-glass);
  text-align: center;
}
.hero__title {
  font-size: 38px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--c-white);
  margin: 0;
}
.hero__title em { font-style: normal; letter-spacing: normal; color: #ffd406; }

.hero__band {
  background: var(--c-hero);
  padding: 29px 0 31.61px;
}
.stats {
  display: flex;
  justify-content: center;
  gap: 0;
  margin: 0 auto;
}
.stat {
  width: 284px;
  text-align: center;
}
.stat__value {
  display: block;
  font-size: 56px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--c-white);
}
.stat__label {
  display: block;
  margin-top: 6px;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.8;
  letter-spacing: -0.01em;
  color: var(--c-offwhite);
}

/* --- Buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 16px;
  border-radius: var(--r-pill);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.05em;
  white-space: nowrap;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.2s ease;
}
/* Hover states measured on live Wix, 2026-10-20. */
.btn--hero:hover,
.btn--wide-lg:hover { background-color: rgb(104, 154, 222); }
.btn--wide:hover { background-image: linear-gradient(rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1)); }
.btn:active { transform: scale(0.98); }
.btn--gold { background: var(--c-gold); color: var(--c-white); }
.btn--navy { background: var(--c-navy); color: var(--c-white); }
.btn--blue { background: var(--c-blue); color: var(--c-white); }
.btn--wide { width: 190px; height: 45px; font-family: var(--font-madefor); font-size: 15px; font-weight: 400; letter-spacing: normal; }

.hero__cta { display: flex; justify-content: center; margin-top: 37px; }
.btn--hero {
  width: 142px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: 0.8px;
}

/* --- "These cars save lives": 50/50 split, left #FAFAFA ----------------- */
.split { display: flex; align-items: stretch; }
.split__text {
  /* Flex-basis is content-box sized. Match the measured live split at 1440px. */
  flex: 0 0 616.76px;
  background: var(--c-bg);
  padding: 50px 0 0 101.77px;
}
.split__media { flex: 1 1 auto; background: var(--c-bg); }
.split__media img { width: 100%; height: 478px; object-fit: cover; }

.h-display {
  font-size: 47px;
  font-weight: 700;
  line-height: normal;
  letter-spacing: normal;
  /* Live text box is 539px, centered at x=360 on the 1440px reference. */
  width: 539px;
  margin: 0 0 23px -11px;
  text-align: center;
}
.body-lg {
  font-size: 18px;
  line-height: 1.4;
  letter-spacing: -0.01em;
  width: 502px;
  margin: 0 0 0 7px;
}
.split__cta { display: flex; justify-content: center;  width: 718.53px; margin: 45px 0 0 -101.77px; padding-bottom: 98.63px; }

/* --- Blue-grey bands --------------------------------------------------- */
.band {
  background: var(--c-band);
  color: var(--c-white);
  text-align: center;
}
.band--goal { padding: 61px 40px 54px; }
.band--start { padding: 57px 40px 67px; }
.band__title {
  font-size: 37px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 25px;
}
.band__title--sm { font-size: 34px; letter-spacing: -0.02em; margin-bottom: 33px; }
.band__body {
  font-size: 18px;
  line-height: 1.5;
  letter-spacing: -0.01em;
  margin: 0 auto;
  /* Live box is 764px and the second line measures 764.13 — allow the slack. */
  max-width: 766px;
}
.band--start .band__body { text-align: left; max-width: 816px; }
#missing-states { padding-top: 2px; }
.band__cta { margin-top: 48px; }
.btn--wide-lg { width: 258px; }

/* --- Battalion grid: 4 cols of 223px, 29px gaps, 980px content width ----
   Shorter than live's 3,742 px grid, deliberately, but the crests are live's own size again: 223 px of
   artwork at 1440 and a full 157 on a phone. What makes the band shorter is the space around them - rows
   30 px apart instead of 47, name and Donate 10/12 from their neighbours instead of 15/17, a tighter
   heading and section padding. At 223 px the crest is as large as the file is drawn for. */
.battalions { background: var(--c-page); padding: 40px 0 36px; }
.battalions__inner { width: var(--content-max); margin: 0 auto; }
.h-section {
  font-size: 34px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-align: center;
  /* 940 of the 980 container: the live site centres this heading on 700, not 720. */
  width: 940px;
  max-width: 100%;
  margin: 0 0 34px;
}
.battalion-grid {
  display: grid;
  grid-template-columns: repeat(4, 223px);
  column-gap: 29.33px;
  row-gap: 30px;
}
.battalion {
  width: 223px;
  text-align: center;
  /* A column, so the status line and the button can hang off the card's bottom instead of following the
     name one line at a time: a name that wraps to two lines used to push that card's status line and
     Donate down while its neighbours in the row stayed put. The grid row stretches every card to the
     tallest, and the space a short name leaves is taken above the status line, not below it. */
  display: flex;
  flex-direction: column;
  align-items: center;
}
.battalion__crest {
  width: 223px;
  height: 223px;
  object-fit: contain;
}
.battalion__name {
  font-family: var(--font-helv-bold);
  font-weight: 400;
  font-size: 18px;
  line-height: 22px;
  margin: 10px 0 0;
}
/* The dot and the word are two boxes, so the pair centres as a pair rather than by the emoji's advance
   width, which on iOS draws wider than it occupies and left the line looking a few pixels off centre. */
.battalion__status {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--font-helv-light);
  font-weight: 400;
  font-size: 15px;
  line-height: 18px;
  /* Pushed down to sit directly above the button at the card's bottom, with the 5 px it always had under
     the name kept as its own padding. */
  margin: auto 0 0;
  padding-top: 5px;
}
/* The 12 px the button used to have above it is now the only gap between the status line and the button;
   on a phone the emoji's edge had been landing on the button itself. */
.battalion__cta { margin-top: 12px; }
.battalions__join { display: flex; justify-content: center; margin-top: 32px; }

/* --- Leaderboard -------------------------------------------------------
   The band is the widget plus the State of the Union map, and it was 1,905 px at 1440 - two screens
   before the map even starts. The widget reserved live's fixed 1,051 px iframe, which is 19 px taller
   than the board it holds, so that reservation is gone; the table window is 620 rather than 700 (it still
   shows fourteen rows, because the rows are 44 apart now, not 50), and the air around the heading, the
   progress card and the map's own heading is a third tighter. */
.leaderboard { background: var(--c-page); padding: 44px 0 40px; }
.leaderboard__inner { width: var(--content-max); margin: 0 auto; }
.leaderboard__title { font-size: 34px; font-weight: 700; line-height: normal; text-align: center; letter-spacing: -0.02em; margin: 0 0 10px; }
.leaderboard__sub { font-size: 16px; line-height: 1.8; letter-spacing: -0.01em; text-align: center; margin: 0 0 18px; }
.leaderboard__widget { max-width: 860px; margin: 0 auto; }

.sotu__title { font-size: 34px; font-weight: 700; line-height: 1; text-align: center; letter-spacing: -0.02em; margin: 26px 0 14px; }
.sotu__sub { font-size: 16px; line-height: 1.8; letter-spacing: -0.01em; text-align: center; width: 591px; max-width: 100%; margin: 0 auto 10px; }
/* `height: auto` is load-bearing: the img carries height="464", so `max-width: 100%` alone shrank the
   width and left the height at 464 - a 390 px phone drew the 830x464 map at 330x464, squashing every
   state. The phone sheet used to pin its own 280x157; this is the rule that survives it. */
.sotu__map { width: 830px; max-width: 100%; height: auto; margin: 0 auto; }

/* --- News: 64px heading + hairline rule, then the feed embed ----------- */
.news { position: relative; background: var(--c-bg); padding: 67px 0 39px; }
/* Nav anchors that sit where live's Wix anchors do, rather than at a section's top. */
.nav-anchor { position: absolute; top: -294px; left: 0; width: 1px; height: 1px; }
.news__inner { width: 1204px; max-width: calc(100% - 80px); margin: 0 auto; }
.news__head {
  font-size: 64px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 27px;
}
.news__rule { height: 1px; background: rgba(0, 0, 0, 0.25); border: 0; margin: 0 0 49px; }
/* The feed replaces live's 852x895 socialstream iframe: three 277 px tiles, 5 px apart, over 895 px (the
   iframe's height, so the sections below it do not move). Measured 2026-10-21.
   The reserved 895 px is a desktop measure and only holds where the fixed 277 px columns do; the rule
   below releases it once the grid reflows, or the tiles leave a screen of white under the footer. */
.news__strip { width: 852px; max-width: 100%; min-height: 895px; margin: 0 auto; }
.news__feed {
  display: grid;
  grid-template-columns: repeat(3, 277px);
  /* Live's tiles are absolutely placed by the widget's masonry, so the 14 px margin on its <li> is inert
     and the gap it actually draws is one 5 px spacing, across and down (measured 2026-10-25). */
  gap: 5px;
  align-content: start;
  /* Live's tiles keep their own height: a three-line title makes a 417 px tile, two lines 393, one 369. */
  align-items: start;
  margin: 0;
  padding: 0;
  list-style: none;
  /* Live's widget asks for `aether, sans-serif`, and aether is one of the faces Wix's own font library
     ships, so it is the face that actually renders - not the Helvetica fallback. It is ~8% wider, which
     is what makes live's titles break a line earlier than ours did (measured 2026-10-25). */
  font-family: 'aether', sans-serif;
}
.news-card__link { display: block; color: inherit; text-decoration: none; }
/* Live's tile is a 277 px black square around a 277x208 crop of the frame - a 4:3 slice, so 34 px of
   black above and below (measured 2026-10-25). The crop comes from the frame itself, never from
   hqdefault, which is a 4:3 canvas with black bars baked into a 16:9 still. */
.news-card__thumb { display: block; position: relative; padding-top: 100%; background: #000; overflow: hidden; }
.news-card__thumb img {
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: 75%;
  transform: translateY(-50%);
  object-fit: cover;
}
/* Live's details block is `padding: 20px` all round - so the title column is 277 - 40 = 237.3 px, and the
   card ends 20 px under the age line. Measured from the widget's own boxes, 2026-10-25. */
.news-card__body { display: block; background: #e8e6e6; padding: 20px; }
.news-card__title {
  /* Live's title rule is `overflow: hidden` and nothing else - no clamp - so a long one grows the card
     rather than being cut. Regular weight: the width comes from aether, not from bolding. */
  display: block;
  overflow: hidden;
  font-size: 16px;
  line-height: 24px;
  font-weight: 400;
  letter-spacing: normal;
  color: #000;
}
/* The age line is the next 24 px line in the same block, 4 px under the title, also 16 px aether. */
.news-card__age { display: block; margin-top: 4px; font-size: 16px; line-height: 24px; letter-spacing: normal; color: #000; }
.news-card__link:hover .news-card__title { text-decoration: underline; }
/* Live's widget footer: the purple band the iframe drew, with a working link where its credit was. */
.news__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0 10px;
  /* 50 px under the grid's 747 px box, where live draws it. */
  margin: 50px 0 0;
  background: #8d008b;
  color: #fff;
  padding: 6px;
  font-family: Helvetica, Arial, sans-serif;
  font-size: 12px;
  font-weight: 700;
  line-height: 17.1429px;
  letter-spacing: normal;
}
.news__updated { padding-left: 20px; }
.news__more { color: inherit; padding-right: 10px; text-decoration: none; }
.news__more:hover { text-decoration: underline; }
/* Three 277 px tiles need 841 px, and below 960 the section's inner width (100% - 80px) is narrower than
   that. Live's iframe simply clipped its desktop layout there, which on a phone cuts words off mid-word.
   The strip reflows instead: three tiles per row on a tablet, two on a phone. The reserved 895 px goes
   with it - nothing fills live's iframe box once the columns reflow, and keeping it leaves a screen of
   white under the footer. */
@media (max-width: 960px) {
  .news__feed { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .news__strip { min-height: 0; }
}
/* A phone at 390 leaves a 310 px strip, so two tiles are 152 px across and 124 px of that is text. Live's
   16 px type wraps to a word a line there, so the details block steps down to 14 px on a 20 px line. */
@media (max-width: 700px) {
  .news__feed { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .news-card__body { padding: 14px; }
  .news-card__title { font-size: 14px; line-height: 20px; }
  .news-card__age { margin-top: 6px; font-size: 14px; line-height: 20px; }
}

/* --- Partners: cream band, 4 logos ------------------------------------ */
/* Denser than live, deliberately: live's 56 px title, 313 px gaps and 41/76 padding made a 370 px band
   for three logos. The cream, the centred row and the same art stay; the band is a credit strip now. */
.partners { background: var(--c-cream); padding: 32px 0 40px; text-align: center; }
.partners__title { font-size: 32px; font-weight: 700; line-height: normal; letter-spacing: -0.02em; margin: 0 0 20px; }
.partners__row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 96px;
}
/* Sized to sit under a 32 px heading beside a 72 px social row rather than as three postage stamps, and
   above live's 112/130/116 wherever the artwork allows it. The crest is 180 of its 226 px original (and
   its 306 px Wix render), Help99 220 of a 316 px render of a 125 px original - already the softest of the
   three - and NAFO 240, re-cut from Wix's 2554x1140 original instead of the 177 px thumbnail live used.
   The crest is the row's measure and does not shrink: Piece & Freedom is drawn at that same 180, not the
   150 it started on, so the round badge sits beside the square rather than under it. */
/* The logo is the link. It carries no underline and no line box of its own, so the row measures the art
   and not the anchor's inline leading. */
.partners__row a { display: block; line-height: 0; border-radius: 4px; }
/* Each width is capped by the window as well as by its own size: four logos with the 96 px gaps need
   1,078 px, and the 6vw gaps below 1330 only buy so much, so 17/22/20/14vw keep the row on one line from
   a 900 px window up instead of spilling. Above 1,058 px the caps never bind. */
.partners__row a:nth-child(1) img { width: min(180px, 17vw); height: 178px; object-fit: contain; }
.partners__row a:nth-child(2) img { width: min(240px, 22vw); height: 113px; object-fit: contain; }
.partners__row a:nth-child(3) img { width: min(220px, 20vw); height: 67px; object-fit: contain; }
/* The badge at the crest's own 180: 180 of its 400 px original puts the drawn circle at ~133, and the
   lockup is 185 tall, which is what the row now measures (the crest is 178). `height: auto` is the point:
   with a pinned height the art is `contain`-fitted and a width change silently does nothing, which is how
   it stayed at 150 through the first desktop pass. */
.partners__row a:nth-child(4) img { width: min(180px, 14vw); height: auto; object-fit: contain; }

/* --- Social icons ----------------------------------------------------- */
/* Denser than live, like the partners band above it: 128 px icons in a 297 px strip read as a second
   billboard under a three-logo band. The heading centres over the smaller icons, since live's 507 px
   measure was sized for a 30 px line and leaves a 22 px one hanging at the left edge. */
.social { background: var(--c-bg); padding: 26px 0 30px; text-align: center; }
.social__title { font-size: 22px; font-weight: 700; line-height: normal; letter-spacing: -0.03em; width: auto; max-width: 100%; margin: 0 auto 18px; text-align: center; }
.social__row { display: flex; justify-content: center; gap: 24px; }
.social__row img { width: 72px; height: 72px; }

/* --- Contact: field photo background, 809px card ---------------------- */
.contact {
  position: relative;
  /* Live's 955 px section put the card bottom under a laptop's window. The section is now the card plus a
     band of photo, so the whole form is one screen at 1440x900. */
  padding: 40px 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.contact__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.contact__card {
  position: relative;
  width: 720px;
  background: var(--c-bg);
  padding: 44px 88px 48px 80px;
  text-align: center;
}
.contact__title { font-size: 30px; font-weight: 700; line-height: normal; letter-spacing: -0.02em; width: 520px; max-width: 100%; margin: 0 auto 16px; }
.contact__lede { font-size: 16px; line-height: 1.6; width: 420px; max-width: 100%; margin: 0 auto 26px; }
.form__row { display: flex; gap: 28px; text-align: left; }
.form__field { flex: 1 1 0; text-align: left; }
.form__field--email { width: 270px; max-width: 100%; }
.form__field--full { flex: 0 0 510px; }
/* The contact form's honeypot: collapsed rather than `display: none`, which the bots that fill these
   fields skip, and kept in the flow rather than hung off-screen, because nothing on this page may sit
   outside the window (e2e/mobile-viewport.spec.js). It takes no space and is skipped by the keyboard
   and by screen readers. */
.form__field--honeypot { height: 0; overflow: hidden; opacity: 0; pointer-events: none; }
.form__label {
  display: block;
  font-family: var(--font-avenir);
  font-size: 14px;
  line-height: 14px;
  padding: 0 20px 0 1px;
  margin-bottom: 6px;
}
.form__row + .form__field { margin-top: 24px; }
.form__field--message { margin-top: 16px; }
.form__textarea::placeholder { color: #6f6f6f; }
.form__input {
  width: 100%;
  height: 36px;
  padding: 3px 3px 3px 7px;
  border: 0;
  border-bottom: 1px solid #000;
  border-radius: 0;
  background: transparent;
  font-family: var(--font-avenir);
  font-size: 14px;
  color: var(--c-ink);
}
.form__input:focus { outline: 0; border-bottom-color: var(--c-blue); }
.form__textarea {
  display: block;
  width: 100%;
  max-width: 510px;
  height: 92px;
  padding: 10.5px 10px 3px 7px;
  border: 0;
  border-bottom: 1px solid #000;
  background: transparent;
  font-family: var(--font-avenir);
  font-size: 14px;
  /* Live's textarea has no drag grip at any width. */
  resize: none;
}
.form__textarea:focus { outline: 0; border-bottom-color: var(--c-blue); }
.form__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 22px;
}
.form__submit {
  width: 220px;
  height: 46px;
  border-radius: var(--r-pill-sm);
  background: var(--c-blue);
  color: var(--c-offwhite);
  font-family: var(--font-avenir);
  font-size: 17px;
  line-height: 1;
  transition: border-color 0.4s, background-color 0.4s;
}
.form__submit:hover { background: rgb(255, 212, 6); color: rgb(63, 63, 63); }

/* --- Footer: the full-bleed banner, nothing under it ----------------
   The 40 px #3F3F3F strip that used to sit below the banner read as grey dead space at the end of the
   page, so the banner is the last thing on it. The colour stays as the paint behind the image while it
   loads. */
.site-footer { line-height: 0; background: #3f3f3f; }
.site-footer img { width: 100%; height: auto; }

/* --- Skip link -------------------------------------------------------- */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--c-navy);
  color: #fff;
  padding: 10px 16px;
  z-index: 100;
}
.skip:focus { left: 0; }

/* --- Focus visibility ------------------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--c-blue);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ==========================================================================
   Responsive. The reference site serves a fixed 980px layout to non-mobile
   user agents; below are the sensible collapses for narrower viewports.
   ========================================================================== */
@media (max-width: 1330px) {
  .site-header { padding: 0 40px; }
  .site-nav { margin-right: 0; }
  /* The 1440 split is a 616.76 px text column beside the photo, with the heading and body set in measured
     boxes centred on it. Narrower, those boxes are wider than 55% of the window: the 539 px heading alone
     sets the column's min-content width, so at 900 the column holds 568 px and squeezes the photo to 37%
     of the window. Take the column's width (up to the measured box) and let the column shrink, so the
     halves stay 55/45 at every width above the stacked layout. */
  .split__text { flex: 1 1 55%; min-width: 0; padding-left: 40px; }
  /* The photo's basis is its own 1440 px width, so left alone it takes 59% of the window and the text 41%.
     Give both halves a share of the sheet and the 55/45 split holds. */
  .split__media { flex: 1 1 45%; }
  .h-display { width: 100%; max-width: 539px; margin-left: 0; }
  .body-lg { width: 100%; max-width: 502px; margin-left: 0; }
  /* The 1440 button row is a 718.53 px box hung 101.77 px left to centre its button on the 539 px heading.
     Narrower, that offset puts the button off the left edge; the row takes the heading's own box (up to the
     sheet) and the button stays centred under the heading, which is how live has it at every width. */
  .split__cta { width: 539px; max-width: 100%; margin: 60px 0 0; padding: 0 0 60px; justify-content: center; }
  .partners__row { gap: clamp(32px, 6vw, 96px); }
  .news__inner { width: calc(100% - 80px); }
}

/* Two columns, the photo's 478 px box is shorter than the text column once the copy wraps: at 900 the
   column is 525 px, and the stretch leaves that 47 px remainder as a band of the section's own background
   under the photo. Above the stacked layout the photo covers the whole column instead, so the band is gone
   at every width where the two sit side by side. */
@media (min-width: 861px) and (max-width: 1330px) {
  .split__media { min-height: 478px; }
  .split__media img { height: 100%; object-fit: cover; }
}

/* The nav collapses at 1160 rather than 1080: live's six anchors are 715 px of fixed width and the crest
   and name are 224, so the row leaves 17 px at 1081 - not enough for the shop pill that now ends it. The
   pill rides in the menu below this width, where it is a full-width row like the anchors. */
@media (max-width: 1160px) {
  .site-nav { display: none; margin: 0; }
  .site-nav.is-open {
    display: flex;
    position: absolute;
    top: 70px;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--c-bg);
    padding: 8px 24px 24px;
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
    z-index: 40;
  }
  .site-nav.is-open .site-nav__link { width: 100%; line-height: 44px; text-align: left; }
  /* In the menu the pill is a row of its own, not a chip hanging off the last anchor. 44 px tall, so it is
     as easy to hit as the anchors around it. */
  .site-nav.is-open .site-nav__merch {
    width: 100%;
    height: 44px;
    margin: 8px 0 0;
  }
  .site-header { position: sticky; justify-content: space-between; }
  /* A 44x44 target is the smallest a finger hits reliably, so the button keeps that; the glyph inside it is
     a drawn hamburger and had been stretched to the full 44, which read as a slab. The bars are 33 wide -
     three quarters of the target, the usual relationship between a hamburger's drawn width and its hit
     area - and centred in it, so the target stays 44 square while the mark looks like a mark. */
  .site-nav__toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    width: 44px;
    height: 44px;
    margin-left: auto;
    /* The tap target does not give up width to a long name. */
    flex-shrink: 0;
    /* Chromium's own button styles say `align-items: flex-start` and `padding: 1px 6px`. The bars carry
       their own width below, so they draw whatever the user agent's alignment is; `stretch` used to be the
       fix and made them as wide as the button, which is what this change undoes. */
    align-items: center;
    padding: 0;
  }
  .site-nav__toggle span { display: block; width: 33px; height: 2px; background: var(--c-ink); }
}

@media (max-width: 1080px) {
  .battalion-grid { grid-template-columns: repeat(3, 223px); justify-content: center; }
  .battalions__inner,
  .leaderboard__inner { width: calc(100% - 60px); }
  /* The header is one row between the crest and the menu button, and the name can use all of it. 10.2 is
     the wordmark's width per pixel of type; 191 px is everything else in that row (2 x 40 px gutters, the
     47 px crest, its 10 px gap, the 44 px button and the header's own 10 px gap). */
  .site-header__wordmark { font-size: min(21px, calc((100vw - 191px) / 10.2)); }
  .contact__card { width: calc(100% - 40px); padding: 32px 20px; }
  .contact__lede { margin-bottom: 24px; }
}

/* Live's desktop panel is 440 px wide, 155 px down a 1440 px map. Below 980 the map is shorter than the
   panel's 155 px offset plus its own height, so the panel hangs off the image and covers the first figure.
   In flow it is a panel under the map instead, keeping the desktop's proportions to the sheet rather than
   its pixels. The visual's own padding paints the band under it, so the panel's margin cannot collapse.
   This is also the phone layout: one sheet, from 320 px up. */
@media (max-width: 979px) {
  /* The band under the panel is 24 px, and above the map there was none: stacked, the map sat flush under
     the sticky header. The same 24 px now sits above it, so the map has the same room at both ends.
     Two layers, and the first has to be a gradient rather than a bare colour: a colour in that slot is
     not a valid image, and Chromium dropped the whole declaration - which takes #3D3D55 with it and
     leaves the 16 px under the map and the 24 px under the panel painted white. The strip above is the
     map's own first row, rgb(23, 24, 44), so it meets the artwork without a seam. */
  .hero__visual {
    background:
      linear-gradient(rgb(23, 24, 44), rgb(23, 24, 44)) top / 100% 24px no-repeat,
      var(--c-hero);
    padding: 24px 0;
  }
  .hero__glass {
    position: static;
    transform: none;
    width: clamp(280px, 44.9vw, 440px);
    /* A gap under the map, so the panel reads as its own element rather than a continuation of it. */
    margin: 16px auto 0;
  }
  .hero__title { font-size: clamp(24px, 3.9vw, 38px); }
}

@media (max-width: 860px) {
  .stats { flex-wrap: wrap; row-gap: 24px; }
  .stat { width: 50%; }
  .split { flex-direction: column; }
  .split__text { flex-basis: auto; padding: 40px 24px 0; }
  /* Stacked, the heading is full-width, so the row is too and the button centres with it. */
  .split__cta { width: auto; margin: 40px 0 0; padding-bottom: 56px; }
  .h-display { width: 100%; max-width: none; margin-left: 0; font-size: 34px; }
  /* The owner's call, and it holds at every width where the layout is one column: the three blocks that
     are flush left under a centred heading read as broken on a phone. The Why copy, "We're still
     missing: ..." and "The Latest News" centre with the heading and the button instead. This is the
     stacked layout only - the measured desktop boxes keep their own alignment, which is asserted in
     e2e/compact-sections.spec.js. */
  .split__text .body-lg,
  .band--start .band__body,
  .news__head { text-align: center; }
  /* The 502 px measure is the text column's width beside the photo; stacked, the copy runs the width of the
     sheet like every other section, instead of leaving the right half of the row empty. */
  .body-lg { max-width: none; }
  .split__media img { height: 320px; }
  .band__title { font-size: 28px; }
  .band__title--sm { font-size: 26px; }
  .h-section { font-size: 26px; }
  .news__head { font-size: 40px; }
  /* Three logos stacked at 92/106/96 px read as thumbnails in a field of cream: the crest's lettering was
     unreadable. They now sit at close to the size the files were drawn at - 150, 174 and 156 px, none
     upscaled past its own pixels - and the row wraps instead of stacking unconditionally, so a phone puts
     the crest and NAFO side by side and Help99 under them, while a tablet keeps all three in one row. The
     `vw` caps keep the pair on one line down to a 320 px window instead of spilling. */
  /* 24px gutters, like every other band. With none, the two columns - sized to their own logos - came out
     383 wide at 390 and the marks ran 4px from the screen edge. */
  .partners { padding: 24px 24px 28px; }
  .partners__title { font-size: 24px; margin-bottom: 14px; }
  /* Two by two, not a wrap: a wrap packed three logos on the first line and left the fourth alone under
     them at 700, which read as an afterthought. The pair is one 470px lockup centred in the band, with
     equal columns, so the marks keep their size and spacing from a 320px phone to an 860px tablet
     instead of the columns growing with the largest logo and pushing the row edge to edge. */
  .partners__row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: center;
    width: min(100%, 470px);
    margin: 0 auto;
    gap: 22px 24px;
  }
  /* Each mark centred in its own cell. The anchors used to stretch to the column and leave every image
     flush left, so the two columns' right edges never lined up. The 44px floor is for the Help99 lockup,
     which is only 38 tall at 320; its hit area clears the finger minimum even though the art is shorter. */
  .partners__row a {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    min-height: 44px;
  }
  .partners__row a:nth-child(1) img { width: min(165px, 100%); max-width: none; height: auto; }
  .partners__row a:nth-child(2) img { width: min(190px, 100%); max-width: none; height: auto; }
  .partners__row a:nth-child(3) img { width: min(180px, 100%); max-width: none; height: auto; }
  /* Fourth logo: the crest's size, not a postage stamp beside it. Its 400x412 file is 74% circle, so at
     200 the drawn circle is ~148px beside the crest's 165 and the lockup as a whole - circle plus the
     arced wordmark - is taller than the crest. The `vw` cap keeps that on a 320px screen, where it hangs
     ~11px past its cell on each side; at 390 the overhang is ~10px, which is the optical match. */
  .partners__row a:nth-child(4) img { width: min(200px, 46vw); max-width: none; height: auto; }
  .social { padding: 20px 0 24px; }
  .social__row { flex-wrap: wrap; gap: 16px; }
  .social__row img { width: 56px; height: 56px; }
  .social__title { font-size: 18px; margin-bottom: 14px; }
  .contact { padding: 24px 0; }
  .contact__title { width: 100%; font-size: 24px; }
  .contact__lede { font-size: 15px; line-height: 1.55; }
  .form__row { flex-direction: column; gap: 18px; }
  .form__field--email,
  .form__field--full,
  .form__textarea { flex: 1 1 auto; width: 100%; }
  .form__row + .form__field { margin-top: 18px; }
  .form__actions { justify-content: stretch; margin-top: 18px; }
  .form__submit { width: 100%; }
  .battalion-grid { grid-template-columns: repeat(2, 1fr); column-gap: 16px; row-gap: 24px; justify-content: center; }
  .battalion { width: 100%; }
  /* Full width of the 157 px column, live's own phone size; the tighter rows are what make the band
     shorter, not a smaller crest. */
  .battalion__crest { width: 100%; height: auto; }
  .btn--wide { width: 100%; }
  .stat__value { font-size: 40px; }

  /* Touch targets on a phone and a tablet. 44 px is the smallest box a finger hits reliably, so the
     controls that were 40 high grow by four (their labels stay put: they are centred), and the two text
     links that live inside a band or a heading keep their measured box and borrow the height from a
     pseudo-element - nothing on the page moves. Measured at 390: buttons 40, inputs 40, skip link 35,
     "More on YouTube" 17, the social heading 23. */
  .btn { min-height: 44px; }
  .form__input { min-height: 44px; }
  .skip { min-height: 44px; display: inline-flex; align-items: center; }
  .news__more,
  .social__title a { position: relative; }
  .news__more::after,
  .social__title a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 44px;
    transform: translateY(-50%);
  }
}

/* Live's Our Why copy is two text elements, so "where" opens a line; the <br> in the paragraph marks that.
   The break is invisible at some widths but leaves the rest of its line empty at others (the 552 px stacked
   sheet, and the 502 px measure at 1440), and no width can fill that line without dropping the break. The
   copy is left to wrap naturally instead: same paragraph height at 320, 390, 550, 700, 1024 and 1440, and
   one line shorter between 861 and 940 where the forced break was adding a line. */
.split__text .body-lg br { display: none; }

/* At a phone's width the map is only as tall as the sheet is wide, and most of that band is the navy
   around the country. Show the file at a taller 2.2:1 and let `cover` trim the navy at the sides: that
   keeps the middle 71% of the image, and the silhouette sits between 24% and 77% of it, so the country
   gets bigger while staying whole. Wider sheets keep the file's own 3.08:1 - there the map already fills
   the band. */
@media (max-width: 600px) {
  .hero__image img { aspect-ratio: 2.2; object-fit: cover; }
}

/* The wordmark is one line beside a 47 px crest; on the narrowest phones the 40 px gutters left the menu
   button 6 px of its 44. Shrink the gutters to 20 px and re-measure the name for that row: 2 x 20 px
   gutters, the crest, its gap, the button and the header's gap are 151 px. */
@media (max-width: 380px) {
  .site-header { padding: 0 20px; }
  .site-header__wordmark { font-size: min(21px, calc((100vw - 151px) / 10.2)); }
}
