/* ==========================================================================
   V2B Montana — v2bmontana.com
   Section 02: Hero

   Sections not yet designed: navigation, Why V2B, What Happens, agenda,
   supporter wall, Who It's For, FAQ, closing CTA, footer.

   ---------------------------------------------------------------------------
   ON THE SCRIM

   Every opacity in this file is derived from a luminance sample of the two
   hero JPEGs, not chosen by eye. The photograph is near-monochrome and splits
   into two very different grounds:

     - the still water, left ~33% of the landscape crop, sits at sRGB 133-170
       and clears 4.5:1 against off-white type at alpha 0.14-0.44
     - the frosted forest, everything right of it, peaks at sRGB 211-254 and
       needs alpha 0.48-0.63 for the same result

   That gap drives both layouts. At 1280px and up the photograph is full bleed
   and type is set over it, so the scrim is shaped to that split: low across
   the water, peaking over the treeline where the headline's tail crosses the
   brightest frost, gone by 70%. Below 1280px the portrait crop interleaves
   water and forest down every horizontal band — no cheap zone anywhere — so
   type moves off the photograph entirely onto solid ink and the only gradient
   left is the dissolve between them.

   The JPEGs are never edited; everything is composited in CSS, so the masters
   stay reusable and re-croppable.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Ground */
  --ink:        #0B0F14;   /* deep charcoal-navy */
  --ink-soft:   #14181D;   /* text on bronze */
  --scrim:        9, 13, 18;

  /* Light */
  --paper:      #F6F4F0;   /* warm off-white */
  --paper-hi:   #FBFAF8;   /* display type */
  --paper-lede: #EFECE6;   /* body over photograph — solid, never translucent */
  --stone:      #E8E1D2;   /* eyebrow and hairlines over photograph */

  /* Accent — used sparingly: button fill and focus ring, nothing else.
     Bronze is deliberately absent from type set over the photograph; at
     #BE9553 it only reaches ~2.5:1 against the scrimmed water. */
  --bronze:      #BE9553;
  --bronze-lift: #CFA662;

  --font: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text",
          "Segoe UI Variable Text", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Motion. Slower out than in: hover settles, press answers. */
  --ease:     cubic-bezier(0.2, 0.7, 0.3, 1);
  --ease-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-in:  cubic-bezier(0.4, 0, 1, 1);

  --gutter: clamp(1.25rem, 5vw, 6rem);
  --media-h: clamp(18rem, 46svh, 28rem);   /* photo band below 1280px */
}

/* --------------------------------------------------------------------------
   Reset — minimal
   -------------------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, p, dl, dd { margin: 0; }
img { display: block; max-width: 100%; }

/* --------------------------------------------------------------------------
   Focus
   -------------------------------------------------------------------------- */

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   Placeholder header — replaced during the navigation pass
   -------------------------------------------------------------------------- */

/* Solid bar below 1280, transparent over the photograph above it.
   Not an aesthetic preference: on the banded layout the photo strip is only
   ~370px tall, and a scrim ramp dense enough to carry header type through its
   top 28% would collide with the dissolve starting at 38%, leaving no clean
   photograph at all. A solid bar costs nothing and gives the whole strip back.
   The navigation pass owns this and is free to change it. */
.site-header {
  position: relative;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(1rem, 2.2vw, 1.75rem) var(--gutter);
  background: var(--ink);
}

.site-header__home {
  display: block;
  line-height: 0;
}

/* Logo.
   The masters are exported on a 1920x960 (2:1) artboard, but the artwork only
   fills the middle of it — measured at 82.5% of the width and 54.5% of the
   height, so 8.8% transparent padding left and right and 22.8% top and bottom.
   Sized naively the element is nearly twice as tall as the ink and inflates
   the header by ~45%.

   So the box is set to the artwork's true 660:218 ratio and the SVG is covered
   into it, which crops most of the dead space away. Artwork height then lands
   at ~0.825 of the box height.

   If the masters are ever re-exported tightly cropped, drop the aspect-ratio
   and object-fit here — with no padding to remove, cover would start eating
   the artwork itself. */
.logo {
  display: block;
  width: auto;
  aspect-ratio: 660 / 218;
  object-fit: cover;
}

.site-header .logo { height: clamp(2.7rem, 3.6vw, 3.3rem); }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0.875rem 1.75rem;
  border: 0;
  border-radius: 0;
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;   /* keeps "RSVP — it's free" on one line */
  cursor: pointer;
}

/* The RSVP control — squared, with one 45-degree corner clipped bottom-right.

   RESERVED FOR THIS CONTROL. The chamfer lives on .btn--cta, not .btn, so it
   cannot spread by accident. One CTA shape is a detail; the same cut repeated
   on cards, the supporter wall or section dividers becomes a tactical motif,
   which the design brief rules out.

   Drawn by two clipped pseudo-elements rather than clip-path on the element,
   because clipping the element clips its focus ring too. This way the ring
   stays intact and the rim follows the chamfer, so the shape carries its own
   WCAG 1.4.11 boundary. It also means shadows must be cast with drop-shadow on
   the rim — box-shadow on a clip-path element is clipped away entirely. */
.btn--cta {
  --cut: 14px;
  position: relative;
  isolation: isolate;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding-inline: 1.875rem;
}
.btn--cta::before,
.btn--cta::after {
  content: "";
  position: absolute;
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--cut)),
                     calc(100% - var(--cut)) 100%, 0 100%);
}
.btn--cta::before { inset: 0;   z-index: -2; }   /* rim    */
.btn--cta::after  { inset: 1px; z-index: -1; }   /* face   */

/* Primary — filled bronze, treated as a machined key.

   Gradient runs 135deg, along the chamfer's own angle, so the implied light
   source and the cut describe the same object. Both overlays lighten from the
   base, never darken below it, so the darkest point of the fill is always the
   base bronze and the label cannot drop under its 6.46:1 in any state.

   background-image is not interpolatable — a gradient swap on hover would snap
   — so the overlays are fixed and background-color animates beneath them.

   It carries a contact shadow at rest: this is the page's one job, and on a
   phone, where hover never fires, the rest state is the only state most
   visitors will ever see. */
.btn--primary {
  color: var(--ink-soft);                        /* 6.46:1 on bronze */
  transition: transform 200ms var(--ease);
}
.btn--primary::before {
  background: rgba(var(--scrim), 0.55);
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.40))
          drop-shadow(0 2px 3px rgba(0, 0, 0, 0.22));
  transition: filter 200ms var(--ease);
}
.btn--primary::after {
  background-color: var(--bronze);
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0 1px, rgba(255, 255, 255, 0) 1px),
    linear-gradient(135deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0) 62%);
  transition: background-color 200ms var(--ease);
}
.btn--primary:hover { transform: translateY(-1px); }
.btn--primary:hover::after { background-color: var(--bronze-lift); }
.btn--primary:hover::before {
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.45))
          drop-shadow(0 5px 10px rgba(0, 0, 0, 0.32));
}
.btn--primary:active {
  transform: translateY(1px);
  transition: transform 90ms var(--ease-in);
}
.btn--primary:active::before {
  filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.5));
  transition: filter 90ms var(--ease-in);
}

/* Outline — the same action at nav weight, so two bronze fills stop competing.

   The interior is opaque ink, and it has to be. Two reasons, both measured:

   1. The face pseudo sits on top of the rim pseudo, so anything translucent
      composites over bronze rather than over the page. At 55% it came out
      rgb(91,74,47) — muddy bronze at 3.09:1, worse than no fill at all.
   2. A genuinely transparent interior fails anyway at 1280px and up, where the
      bar is transparent over the photograph and this button sits top-right.
      Only the header ramp reaches that far, so the frost behind composites to
      roughly sRGB 72 and bronze text on it lands at 3.50:1, under the 4.5:1
      it needs.

   Opaque ink solves both and costs nothing visually: below 1280 it is the same
   colour as the bar, so the button reads as pure bronze rule and bronze label;
   above it, it reads as a dark plate with a bronze edge. Either way the label
   has a fixed 7.09:1 ground that does not depend on the photograph. */
.btn--outline {
  color: var(--bronze);                          /* 7.09:1 on --ink */
  transition: color 160ms var(--ease-out);
}
.btn--outline::before { background: var(--bronze); }
.btn--outline::after {
  background-color: var(--ink);
  transition: background-color 160ms var(--ease-out);
}
.btn--outline:hover { color: var(--ink-soft); }
.btn--outline:hover::before { background: var(--bronze-lift); }
.btn--outline:hover::after { background-color: var(--bronze-lift); }

/* Same control, smaller: the cut scales with it so the angle stays 45 degrees
   and both RSVP buttons read as one shape. */
.btn--sm {
  --cut: 10px;
  min-height: 42px;
  padding: 0.5rem 1.125rem;
  font-size: 0.8125rem;
}

/* --------------------------------------------------------------------------
   HERO — base: photo band on top, type on solid ink below.

   This is the layout everything under 1280px gets, phones included. Most of
   this traffic is a text message opened on a phone, so the phone case is
   written first and the wide case is the override.

   Why a split rather than type over the photo: in the portrait crop the water
   and forest interleave down the entire frame, so every horizontal band
   demands alpha 0.50-0.61. Type over that photograph means burying it under
   58% black at full height. The band keeps the photograph clean where it is
   clean, dissolves it into the type ground, and gives the type a perfect
   surface — 17:1 instead of a fight for 4.5:1.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  isolation: isolate;
  background: var(--ink);
}

.hero__media {
  display: block;
  position: relative;
  height: var(--media-h);
}
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 28% 30%;   /* water, treeline and the road curve in frame */
}

.hero::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: var(--media-h);
  z-index: 1;
  pointer-events: none;
  /* One gradient only: the dissolve into the type ground, so the split doesn't
     read as two stacked boxes. No header ramp needed — the bar above is solid,
     which leaves the top 38% of the strip as untouched photograph. */
  background: linear-gradient(180deg,
    rgba(var(--scrim), 0) 38%,
    rgba(var(--scrim), 0.50) 72%,
    rgba(var(--scrim), 0.90) 92%,
    var(--ink) 100%);
}

.hero__inner {
  position: relative;
  z-index: 2;
  padding: clamp(2rem, 6vw, 3rem) var(--gutter) 0;
}

/* --------------------------------------------------------------------------
   Hero — type
   -------------------------------------------------------------------------- */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 0.875rem;
  margin-bottom: clamp(1.125rem, 2.4vw, 1.625rem);
  color: var(--stone);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.eyebrow__rule {
  display: block;
  width: clamp(2rem, 5vw, 3.5rem);
  height: 1px;
  background: currentColor;
  opacity: 0.55;
}

.hero__title {
  color: var(--paper-hi);
  /* Sized so "Stronger Communities." — the widest line at 10.72em — holds one
     line from 375px up, with ~5% headroom for fallback-font metrics. */
  font-size: clamp(1.8125rem, 7.2vw, 3.25rem);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.028em;
  text-wrap: pretty;
}
.hero__title-line { display: block; }

.hero__lede {
  max-width: 54ch;
  margin-top: clamp(1.125rem, 2.6vw, 1.625rem);
  color: var(--paper-lede);
  font-size: clamp(1.0625rem, 0.5vw + 0.95rem, 1.1875rem);
  line-height: 1.55;
  text-wrap: pretty;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(1rem, 2.4vw, 2rem);
  margin-top: clamp(1.75rem, 3.4vw, 2.5rem);
}

.hero__jump {
  /* Light caps to match the primary, so the pair reads as one system rather
     than a tracked button next to an untreated link. Inline-block padding
     brings the tap target to ~28px — at 13px the bare line box is only ~20px,
     under the 24px WCAG 2.5.8 asks for. */
  display: inline-block;
  padding-block: 0.35rem;
  color: var(--paper-hi);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  text-decoration-color: rgba(251, 250, 248, 0.45);
  transition: text-decoration-color 150ms ease;
}
.hero__jump:hover { text-decoration-color: var(--paper-hi); }
.hero__jump-arrow {
  display: inline-block;
  transition: transform 150ms ease;
}
.hero__jump:hover .hero__jump-arrow { transform: translateY(2px); }

/* --------------------------------------------------------------------------
   Fact rail — date, time, venue, cost. The same four at every width.

   Replaces the floating info card in the concept, which sat off-grid on top of
   the photograph and was the one element reading as a widget rather than a
   designed page. Anchored to the baseline it aligns with the headline, gives
   the frame a foot, and collapses to a clean list on a phone.
   -------------------------------------------------------------------------- */

.factrail {
  position: relative;
  z-index: 2;
  margin-top: clamp(2rem, 5vw, 3rem);
  padding: 0 var(--gutter) clamp(2rem, 5vw, 3rem);
}

.factrail__label {
  color: rgba(246, 244, 240, 0.62);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.factrail__value {
  margin-top: 0.3rem;
  color: var(--paper);
  font-size: 1.0625rem;
  font-weight: 500;
  line-height: 1.3;
}

.factrail__sub {
  display: block;
  margin-top: 0.2rem;
  color: rgba(246, 244, 240, 0.62);
  font-size: 0.875rem;
  font-weight: 400;
}

/* Below 600px the rail reads fastest as label/value rows. A 2x2 grid at 375px
   forces "Black Rifle Coffee Company" into a three-line wrap. */
@media (max-width: 599px) {
  .factrail__item {
    display: grid;
    grid-template-columns: 4.5rem 1fr;
    align-items: baseline;
    column-gap: 1rem;
    padding: 0.8125rem 0;
    border-top: 1px solid rgba(246, 244, 240, 0.14);
  }
  .factrail__item:first-child { border-top: 0; }
  .factrail__label { padding-top: 0.2rem; }
  .factrail__value { margin-top: 0; }
}

@media (min-width: 600px) {
  .factrail {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(1.25rem, 3vw, 2rem) clamp(1.5rem, 4vw, 3rem);
  }
}

/* Four across as soon as there is room. A 2x2 at tablet width leaves the right
   half of the rail empty and the band stops reading as a band. */
@media (min-width: 860px) {
  .factrail {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    align-items: start;
    gap: clamp(1.5rem, 2.5vw, 2.5rem);
  }
  /* Hairline separators drawn only where a column begins — restrained
     dividers, not boxes. */
  .factrail__item + .factrail__item {
    padding-left: clamp(1.5rem, 2.5vw, 2.5rem);
    margin-left: calc(clamp(1.5rem, 2.5vw, 2.5rem) * -1);
    border-left: 1px solid rgba(246, 244, 240, 0.16);
  }
}

/* --------------------------------------------------------------------------
   HERO — 1280px and up: full-bleed photograph, type over the water.

   Type column runs to 46% of the hero width — wide enough that "Stronger
   Businesses. / Stronger Communities." holds two lines and the matched pair
   stays a pair.

   That width is what the scrim costs. Measured per element, the requirement
   to clear 4.5:1 is cheap almost everywhere and expensive in exactly one
   place — the last stretch of the headline:

     eyebrow   x  5-25%   alpha 0.34
     actions   x  5-35%   alpha 0.22
     lede      x  5-39%   alpha 0.53
     headline  x 38-45%   alpha 0.56   <- p99.5 sRGB 247, near-white frost

   So the ramp is not a left-dark wash. It is low and even across the water,
   which needs almost nothing, and peaks over the treeline at 30-47% where the
   headline's tail crosses the brightest frost in the file. Two layers, because
   a monotonic gradient strong enough for the treeline would have to be at
   least that strong across all the water to its left, and that is what turns
   the water to mud.
   -------------------------------------------------------------------------- */

@media (min-width: 1280px) {

  .site-header {
    position: absolute;
    inset: 0 0 auto 0;
    background: none;
  }

  .hero {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Capped short of the viewport so the next section is visibly cut off at
       the fold. A hero that exactly fills the screen reads as a template and
       gives no scroll cue. Never 100vh. */
    min-height: 42rem;
    min-height: clamp(42rem, 86svh, 52rem);
    padding-top: clamp(6.5rem, 13vh, 9.5rem);
  }

  .hero__media {
    position: absolute;
    inset: 0;
    z-index: -2;
    height: 100%;
  }
  /* Left-aligned, not centred. On tall viewports cover crops horizontally, and
     centring throws away the left edge — the water drops from 33% of the frame
     to 27% and the treeline slides under the headline. Left-aligned keeps the
     whole water column at every aspect ratio. */
  .hero__media img { object-position: left center; }

  .hero::before {
    inset: 0;
    height: auto;
    z-index: -1;
    background:
      /* header ramp — the top of this crop is bright frost (p99.5 ~213) */
      linear-gradient(180deg,
        rgba(var(--scrim), 0.72) 0%,
        rgba(var(--scrim), 0.68) 8%,
        rgba(var(--scrim), 0.46) 13%,
        rgba(var(--scrim), 0.14) 19%,
        rgba(var(--scrim), 0) 26%),
      /* treeline knockdown — carries the headline's tail across the frost */
      linear-gradient(90deg,
        rgba(var(--scrim), 0) 12%,
        rgba(var(--scrim), 0.12) 24%,
        rgba(var(--scrim), 0.34) 30%,
        rgba(var(--scrim), 0.44) 36%,
        rgba(var(--scrim), 0.50) 42%,
        rgba(var(--scrim), 0.50) 47%,
        rgba(var(--scrim), 0.24) 58%,
        rgba(var(--scrim), 0) 70%),
      /* bed — low and even, so the water keeps its tonal range */
      linear-gradient(90deg,
        rgba(var(--scrim), 0.32) 0%,
        rgba(var(--scrim), 0.32) 20%,
        rgba(var(--scrim), 0.26) 40%,
        rgba(var(--scrim), 0.14) 55%,
        rgba(var(--scrim), 0) 70%);
  }

  .hero__inner {
    /* Type must not cross 46%. Column and scrim are both percentages of the
       same element, so they stay locked together at every viewport. */
    max-width: min(46%, 46rem);
    padding: 0 1rem 0 var(--gutter);
  }

  .hero__title {
    /* Sized so "Stronger Communities." — 10.72em, the binding line — holds one
       line across the range with ~6% headroom for fallback-font metrics. */
    font-size: clamp(2.75rem, calc(3.6vw - 1.6px), 3.375rem);
    line-height: 1.04;
  }

  .hero__lede {
    max-width: 46ch;
    margin-top: clamp(1rem, 2vw, 1.5rem);
  }

  .hero__actions { margin-top: clamp(1.5rem, 2.6vw, 2rem); }

  /* Rail pinned to the base; type stays at the top of the frame. */
  .hero .factrail {
    margin-top: auto;
    padding-top: clamp(1.5rem, 2.4vw, 2rem);
    padding-bottom: clamp(1.5rem, 2.4vw, 2rem);
    /* Small type crosses the full width here, including the brightest frost in
       the file (sRGB 254), so the rail gets its own ground rather than trusting
       the scrim. Solid, with the transition band above the text — not a
       gradient running through it. */
    background: rgba(var(--scrim), 0.94);
  }
  .hero .factrail::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    height: clamp(4rem, 9vw, 7rem);
    pointer-events: none;
    background: linear-gradient(180deg,
      rgba(var(--scrim), 0) 0%,
      rgba(var(--scrim), 0.55) 62%,
      rgba(var(--scrim), 0.94) 100%);
  }
}


/* ==========================================================================
   SECTIONS — Why V2B, What Happens, Who It's For, RSVP, Closing

   Two grounds only: --ink (dark) and --paper (light). Alternating them is the
   section transition; there are no borders, cards or boxes doing that work.
   Every section shares one editorial split — a lead column that holds the
   eyebrow and the headline, and a body column beside it — so the page keeps a
   single rhythm instead of inventing a layout per section.
   ========================================================================== */

.section {
  padding-block: clamp(4rem, 10vw, 8.5rem);
  background: var(--ink);
  color: var(--paper);
}
.section--light {
  background: var(--paper);
  color: var(--ink);
}

.section__inner {
  max-width: 78rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.section__inner + .section__inner { margin-top: clamp(3rem, 6vw, 5rem); }

.section__title {
  margin: 0;
  font-size: clamp(1.875rem, 3.6vw, 2.875rem);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.022em;
  text-wrap: balance;
}
.section__lede {
  margin-top: clamp(1rem, 2vw, 1.5rem);
  max-width: 46ch;
  font-size: 1.0625rem;
  line-height: 1.6;
}
.section__body p { max-width: 54ch; font-size: 1.0625rem; line-height: 1.65; }
.section__body p + p { margin-top: 1.125rem; }
.section--light .section__body p { color: #35404B; }
.section:not(.section--light) .section__body p { color: var(--paper-lede); }

/* Eyebrow on a light ground needs its own colour — the stone tone is tuned
   for type over the photograph and is far too pale here. */
.eyebrow--dark { color: #6B5836; }
.eyebrow--dark .eyebrow__rule { opacity: 0.45; }

@media (min-width: 900px) {
  .section__inner--split {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 5rem);
    align-items: start;
  }
}
.section__body { margin-top: clamp(1.5rem, 3vw, 0rem); }
@media (min-width: 900px) { .section__body { margin-top: 0.5rem; } }

.section__inner--center {
  max-width: 46rem;
  text-align: center;
}
.section__inner--center .section__lede { margin-inline: auto; }

/* --------------------------------------------------------------------------
   Stats — two, deliberately. Displaying fewer at larger size beats padding
   the row; the same principle as the supporter wall. Source and year are on
   the page, not only in /docs/statistics.md.
   -------------------------------------------------------------------------- */

.stats {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  margin: 0;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid rgba(11, 15, 20, 0.16);
}
@media (min-width: 760px) { .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.stats__value {
  font-size: clamp(2.75rem, 6vw, 4.25rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.stats__label {
  margin: 0.625rem 0 0;
  max-width: 30ch;
  font-size: 1rem;
  line-height: 1.5;
  color: #35404B;
}
.stats__source {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  max-width: 74ch;
  font-size: 0.8125rem;
  line-height: 1.6;
  color: #5C6976;
}

/* --------------------------------------------------------------------------
   01–05 — numbered, no icons. Value propositions, not a schedule.
   -------------------------------------------------------------------------- */

.steps {
  display: grid;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
  border-top: 1px solid rgba(246, 244, 240, 0.16);
}
.steps__item {
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid rgba(246, 244, 240, 0.16);
}
.steps__num {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  color: var(--bronze);
  font-variant-numeric: tabular-nums;
}
.steps__title {
  margin: 0.5rem 0 0;
  font-size: clamp(1.25rem, 2vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -0.012em;
}
.steps__body {
  margin: 0.5rem 0 0;
  max-width: 52ch;
  color: var(--paper-lede);
  line-height: 1.6;
}

/* Above 900px each step becomes a row: number, title, body — a table of
   contents rather than five stacked blocks. */
@media (min-width: 900px) {
  .steps__item {
    display: grid;
    grid-template-columns: 5rem minmax(0, 12rem) minmax(0, 1fr);
    gap: clamp(1.5rem, 3vw, 3rem);
    align-items: baseline;
  }
  .steps__num, .steps__title, .steps__body { margin: 0; }
}

/* --------------------------------------------------------------------------
   Who it's for — editorial list, no cards, no icons
   -------------------------------------------------------------------------- */

.groups {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem) clamp(2rem, 5vw, 4rem);
  margin: 0;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid rgba(11, 15, 20, 0.16);
}
@media (min-width: 760px) { .groups { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.groups__title {
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.groups__body {
  margin: 0.4375rem 0 0;
  max-width: 42ch;
  color: #35404B;
  line-height: 1.6;
}

/* --------------------------------------------------------------------------
   RSVP form
   -------------------------------------------------------------------------- */

.section--rsvp { background: #10151B; }

.factrail--inline {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  margin-top: clamp(1.75rem, 3vw, 2.5rem);
  padding: 0;
  background: none;
}
.factrail--inline .factrail__item { padding: 0; margin: 0; border: 0; }
.factrail--inline .factrail__value { margin-top: 0.2rem; }

.form { margin-top: clamp(1.5rem, 3vw, 0.5rem); }

.field { margin-bottom: 1.375rem; border: 0; padding: 0; }
.field__label {
  display: block;
  margin-bottom: 0.4375rem;
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--paper);
}
.field__optional {
  font-weight: 400;
  color: rgba(246, 244, 240, 0.55);
}
.field__input {
  display: block;
  width: 100%;
  min-height: 52px;                   /* comfortable tap target */
  padding: 0.75rem 0.9375rem;
  border: 1px solid rgba(246, 244, 240, 0.28);
  border-radius: 0;
  background: rgba(255, 255, 255, 0.04);
  color: var(--paper-hi);
  font: inherit;
  font-size: 1rem;                    /* 16px — stops iOS zooming on focus */
  transition: border-color 160ms var(--ease-out), background-color 160ms var(--ease-out);
}
.field__input:hover { border-color: rgba(246, 244, 240, 0.44); }
.field__input:focus {
  outline: none;
  border-color: var(--bronze-lift);
  background: rgba(255, 255, 255, 0.07);
}
.field__input:focus-visible {
  outline: 2px solid var(--bronze-lift);
  outline-offset: 2px;
}
.field__input[aria-invalid="true"] { border-color: #E2A08A; }

.field__error {
  margin: 0.4375rem 0 0;
  font-size: 0.8125rem;
  color: #E2A08A;                     /* 6.6:1 on --ink */
}

.field--choice legend { padding: 0; }

.choice {
  display: flex;
  align-items: flex-start;
  gap: 0.6875rem;
  padding-block: 0.4375rem;
  cursor: pointer;
}
.choice__input {
  flex: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.1875rem;
  accent-color: var(--bronze);
}
.choice__text { font-size: 0.9375rem; line-height: 1.5; color: var(--paper-lede); }
.choice--optin {
  margin-block: 0.5rem 1.5rem;
  padding-top: 1.125rem;
  border-top: 1px solid rgba(246, 244, 240, 0.16);
}

/* Honeypot: off-screen rather than display:none, which some bots skip. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__submit { width: 100%; }
@media (min-width: 480px) { .form__submit { width: auto; } }
.form__submit[disabled] { opacity: 0.6; cursor: progress; }

.form__status:empty { display: none; }
.form__status {
  margin: 0 0 1.125rem;
  font-size: 0.9375rem;
  color: var(--paper-lede);
}

/* Confirmation — replaces the form in place, restating date, time and address */
.confirm { max-width: 34rem; }
.confirm:focus { outline: none; }
.confirm__title {
  margin: 0;
  font-size: clamp(1.375rem, 2.4vw, 1.75rem);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--paper-hi);
}
.confirm__note {
  margin: 0.625rem 0 0;
  color: var(--paper-lede);
  line-height: 1.6;
}
.factrail--confirm {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding: clamp(1.25rem, 3vw, 1.75rem) 0 0;
  border-top: 1px solid rgba(246, 244, 240, 0.16);
  background: none;
  gap: 1.125rem clamp(1.5rem, 4vw, 3rem);
}
.factrail--confirm .factrail__item { padding: 0; margin: 0; border: 0; }

.section--confirm { min-height: 70svh; display: flex; align-items: center; }
.confirm__back { margin-top: clamp(1.75rem, 4vw, 2.5rem); }

/* --------------------------------------------------------------------------
   Closing CTA
   -------------------------------------------------------------------------- */

.section--closing { background: var(--ink); }
.closing__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.closing__note {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  font-size: 0.875rem;
  color: rgba(246, 244, 240, 0.62);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.site-footer {
  padding: clamp(2.5rem, 6vw, 4rem) var(--gutter) clamp(2rem, 5vw, 3rem);
  border-top: 1px solid rgba(246, 244, 240, 0.12);
  background: var(--ink);
}
.site-footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3rem);
}
.site-footer__home { display: block; line-height: 0; }
.site-footer__logo { height: clamp(2.5rem, 3.2vw, 3rem); }

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 2.5vw, 2rem);
}
.site-footer__nav a {
  display: inline-block;
  padding-block: 0.35rem;             /* ~28px target, over the 24px minimum */
  color: var(--paper-lede);
  font-size: 0.9375rem;
  text-decoration: none;
  transition: color 160ms var(--ease-out);
}
.site-footer__nav a:hover { color: var(--paper-hi); text-decoration: underline;
  text-underline-offset: 5px; }

.site-footer__meta {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.5rem, 3vw, 2rem);
  border-top: 1px solid rgba(246, 244, 240, 0.12);
  display: flex;
  flex-wrap: wrap;
  gap: 1rem clamp(2rem, 5vw, 4rem);
  justify-content: space-between;
}
.site-footer__event {
  margin: 0;
  font-size: 0.875rem;
  color: var(--paper-lede);
}
.site-footer__contact {
  margin: 0;
  font-size: 0.875rem;
  color: rgba(246, 244, 240, 0.62);
}
.site-footer__contact a {
  display: inline-block;
  padding-block: 0.25rem;             /* 17px line box was under the 24px minimum */
  color: var(--bronze-lift);
}

.site-footer__credits {
  color: rgba(246, 244, 240, 0.62);   /* 7.08:1 on --ink */
  font-size: 0.8125rem;
  line-height: 1.6;
  text-wrap: pretty;
}
.site-footer__credits p + p { margin-top: 0.35rem; }

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@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;
  }
  .hero__jump:hover .hero__jump-arrow { transform: none; }
  .btn--primary:hover,
  .btn--primary:active { transform: none; }
}
