/* ============================================
   AES Cancer Foundation — Global Stylesheet
   Warm · Editorial · Accessible · Modern
   ============================================ */

/* --- Reset & Base --- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --color-primary: #C0533A;
  --color-primary-dark: #9E3E2A;
  --color-accent: #E8A87C;
  --color-bg: #FDF8F4;
  --color-bg-alt: #F5EDE6;
  --color-text: #3A2E2A;
  --color-text-light: #5E504A;
  --color-white: #FFFFFF;
  --color-border: #E8DDD5;

  --font-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --max-width: 1140px;
  --nav-height: 72px;
  --radius: 12px;
  --radius-lg: 20px;
  --radius-xl: 28px;
  --radius-pill: 999px;
  --shadow-sm: 0 1px 3px rgba(58,46,42,.08);
  --shadow-md: 0 4px 16px rgba(58,46,42,.10);
  --shadow-lg: 0 8px 32px rgba(58,46,42,.12);

  /* --- Motion system (Sep 2026) ---
     One entrance, three spellings (.reveal, .reveal-stagger, .anim-in), one
     set of values. --transition is the interaction step (hover / focus /
     press) and is consumed by ~18 rules across this file, so retuning
     --motion-quick retunes all of them together. --motion-rise drops to 10px
     under 768px (see the mobile block), which is why the old page-local
     mobile .reveal overrides are gone. */
  --motion-quick: 180ms;
  --motion-enter: 520ms;
  --motion-feature: 680ms;
  --motion-stagger: 70ms;
  --motion-rise: 16px;
  --ease-quick: cubic-bezier(.2, 0, .2, 1);
  --ease-enter: cubic-bezier(.22, 1, .36, 1);
  --transition: var(--motion-quick) var(--ease-quick);

  /* Editorial refresh (2026) */
  --color-ink: #3A2E2A;
  --color-ink-deep: #2A211D;
  --color-kicker: #B34A32;
  /* Alias, not a second curve: ~67 uses across the pages' inline <style>
     blocks still name --ease-spring. New code uses --ease-enter. */
  --ease-spring: var(--ease-enter);

  /* --- Golf campaign palette (Sep 2026) ---
     Declared globally so the derivatives are one source of truth, but only
     ever consumed inside `main.golf-campaign` and the two events.html poster
     cards. Measured pairings, all AA or better:
       ivory on green-deep 12.3:1 · ivory on green-ink 14.7:1
       green-mid on ivory 7.6:1  · green-deep on ivory 12.3:1
       lime on green-deep 10.3:1 · lime on green-ink 12.4:1
       charcoal on lime 12.0:1   · charcoal on ivory 14.3:1
       charcoal-soft on ivory 8.2:1
     Lime measures 1.19:1 on ivory, so it is a green-surface colour only;
     --golf-lime-text-on-ivory (5.6:1) is the lime family's ONLY ivory text
     value, and a lime focus ring never appears on ivory. */
  --golf-green-deep: #11331F;
  --golf-green-ink:  #0A2315;
  --golf-green-mid:  #1E5637;
  --golf-green-line: #2C5C3E;
  --golf-ivory:      #F7F2E7;
  --golf-ivory-alt:  #EFE7D8;
  --golf-charcoal:   #22211E;
  --golf-charcoal-soft: #4A4740;
  --golf-lime:       #C2F03C;
  --golf-lime-text-on-ivory: #4E680B;
}

html { scroll-behavior: smooth; font-size: 16px; }

body {
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

/* Carries the html.js gate so it stays ahead of `html.js .anim-in`'s paused
   state, which is now equally specific (0,2,1) and sits later in the file. */
html.js body.is-ready .anim-in {
  animation-play-state: running;
}

img { max-width: 100%; display: block; }
/* Body links use --color-kicker, not --color-primary, for WCAG AA.
   #C0533A measures 4.39:1 on --color-bg and 4.00:1 on --color-bg-alt — both
   under the 4.5:1 bar for body-size text. #B34A32 measures 5.05:1 and 4.60:1
   and passes on every light ground the site uses. Hover keeps
   --color-primary-dark (#9E3E2A, 6.27:1 / 5.71:1). Anchors on dark grounds
   all set their own colour (see .footer-links a, .ev-link, .btn-*); don't
   let one inherit from here. */
a { color: var(--color-kicker); text-decoration: none; transition: color var(--transition); }
a:hover { color: var(--color-primary-dark); }
/* Inline links inside prose carry an underline so they are never signalled by
   colour alone. `:not([class])` excludes every styled link class (.btn,
   .deeper-read, .ev-link, .footer-links a, .cta-quiet a and so on), which all
   own their own affordance; only bare prose anchors are matched. */
main :is(p, li, dd) > a:not([class]) {
  text-decoration: underline;
  text-underline-offset: .16em;
  text-decoration-thickness: 1px;
}

h1, h2, h3, h4 { line-height: 1.2; color: var(--color-text); }
h1, h2 {
  font-family: var(--font-heading);
  font-weight: 800;
  letter-spacing: -.02em;
  text-wrap: balance;
}
h3, h4 {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: -.015em;
}
h1 { font-size: clamp(2rem, 5vw, 3.25rem); }
h2 { font-size: clamp(1.6rem, 4vw, 2.5rem); }
h3 { font-size: clamp(1.2rem, 3vw, 1.5rem); }

.utility-heading-xl {
  font-family: var(--font-body);
  /* Shipped without a font-size, so both closing-band h2s fell through to the
     base h2 clamp (2.5rem cap) and were the quietest heading on their page.
     This lands them at the top of the section-head step without outranking
     an interior h1 (.display-xl, 3.9rem). */
  font-size: clamp(1.9rem, 3.6vw, 2.8rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
}

.utility-heading-lg {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.2;
}

body.utility-page .hero-content h1,
body.utility-page .section-header h2,
body.utility-page .cta-banner h2 {
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
}


.container { width: 90%; max-width: var(--max-width); margin: 0 auto; }

/* --- Utility --- */
/* `.prose` is defined once, in the EDITORIAL REFRESH SYSTEM block below. */
.text-center { text-align: center; }

/* --- Buttons ---
   One chassis, exactly four variants (two for light grounds, two for dark)
   plus .btn-block. Navigation is an <a class="btn">, submissions and controls
   are a <button class="btn">.

   Fills use --color-kicker (#B34A32), not --color-primary (#C0533A): white on
   #C0533A measures 4.36:1 and misses the 4.5:1 bar at this text size, while
   white on #B34A32 measures 5.3:1. Same terracotta family, passes AA.
   --color-primary is still right for large display type and plain fills. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;             /* clears the 44px touch target at every size */
  padding: 12px 28px;
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .02em;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  /* Every variant carries the border, transparent where it is not drawn, so a
     filled and an outlined button are the same height. Only .btn-outline used
     to declare one, which made it 58px against the filled button's 54px. */
  border: 2px solid transparent;
  /* An explicit property list, never the `all` keyword, which would
     animate layout properties too. */
  transition: background-color var(--transition), color var(--transition),
              border-color var(--transition), box-shadow var(--transition),
              transform var(--transition);
}

/* Light grounds */
.btn-primary {
  background: var(--color-kicker);
  color: var(--color-white);
}
.btn-outline {
  background: transparent;
  color: var(--color-kicker);
  border-color: var(--color-kicker);
}
/* Dark grounds (hero, founder feature, closing band, event cards) */
.btn-white {
  background: var(--color-white);
  color: var(--color-kicker);
}
.btn-outline-white {
  background: transparent;
  color: var(--color-white);
  border-color: rgba(255,255,255,.72);
}
/* Full-width variant: the thank-you pages' payment button. */
.btn-block { width: 100% }
/* The one campaign variant. Green surfaces only (hero shelf, green bands, the
   green poster card): charcoal on lime measures 12.0:1, but lime on ivory is
   1.19:1, so this must never sit on an ivory ground. */
.btn-lime {
  background: var(--golf-lime);
  color: var(--golf-charcoal);
  border-color: transparent;
}

/* Shared arrow slot. `.btn-arrow` holds a 16x16 inline SVG and is the only
   sanctioned arrow glyph on a button: no typed → characters. It belongs on
   outlined navigation buttons whose label opens with See / Read / Explore /
   Get help / Other ways, and never on a filled button, a submit control, a
   "Back to …" button or an external payment link. */
.btn-arrow {
  display: inline-flex;
  width: 16px;
  height: 16px;
  flex: none;
  transition: transform var(--transition);
}
.btn-arrow svg { display: block; width: 100%; height: 100% }

/* No sticky hover on touch: every button, arrow, card and image hover state
   on this site sits behind (hover: hover). Nothing moves more than 1px. */
@media (hover: hover) {
  .btn:hover { transform: translateY(-1px) }
  .btn-primary:hover {
    background: var(--color-primary-dark);
    color: var(--color-white);
    box-shadow: var(--shadow-sm);
  }
  .btn-outline:hover {
    background: rgba(179,74,50,.08);
    color: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
  }
  .btn-white:hover {
    background: var(--color-bg);
    color: var(--color-primary-dark);
    box-shadow: var(--shadow-sm);
  }
  .btn-outline-white:hover {
    background: rgba(255,255,255,.10);
    color: var(--color-white);
    border-color: #fff;
  }
  .btn-lime:hover {
    background: #B2E22C;
    color: var(--golf-charcoal);
    box-shadow: var(--shadow-sm);
  }
  .btn:hover .btn-arrow { transform: translateX(3px) }
}
/* Press returns to rest rather than scaling: declared after the hover block
   so it wins at equal specificity. */
.btn:active { transform: translateY(0) }

@media (prefers-reduced-motion: reduce) {
  /* Colour is not motion, so the colour transitions stay; the transforms go.
     index.html's `body .btn { transition: none !important }` block is deleted
     in favour of this. */
  .btn {
    transition: background-color var(--transition), color var(--transition),
                border-color var(--transition), box-shadow var(--transition);
  }
  .btn:hover,
  .btn:active { transform: none }
  .btn-arrow { transition: none }
  .btn:hover .btn-arrow { transform: none }
}

/* --- Navigation --- */
.navbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--nav-height);
  background: rgba(253,248,244,.95);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--color-border);
  z-index: 1000;
  transition: box-shadow var(--transition);
}
.navbar.scrolled { box-shadow: var(--shadow-sm); }

.navbar .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
}

.nav-logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.nav-logo-img {
  height: 40px;
  width: auto;
  display: block;
  object-fit: contain;
}
@media (max-width: 480px) {
  .nav-logo-img { height: 34px; }
}

/* The menu is centred in the bar while the logo stays left. It is taken out of
   the container's flex row and absolutely positioned against .navbar itself —
   .navbar is position:fixed, so it is already the containing block, and using
   it (rather than making .container relative) keeps the mobile dropdown
   full-bleed instead of snapping to the 90% container. Centring on .navbar and
   centring on .container are the same point, since .container is margin:auto. */
.nav-links {
  display: flex;
  align-items: center;
  gap: 20px;
  list-style: none;
  flex-wrap: nowrap;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.nav-links a {
  color: var(--color-text);
  font-weight: 700;
  font-size: .875rem;
  letter-spacing: .01em;
  position: relative;
  font-family: var(--font-body);
  white-space: nowrap;
}
.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -4px; left: 0;
  width: 0; height: 2px;
  background: var(--color-primary);
  transition: width var(--transition);
}
.nav-links a.active::after { width: 100%; }
/* The `.nav-dropdown*` / `.nav-submenu` motion rules that sat here went at
   zero consumers; the nav is a flat 7-item list. */
@media (hover: hover) {
  .nav-links a:hover::after { width: 100%; }
  .nav-links a:hover { color: var(--color-primary); }
}

/* Not a .btn (it is a nav item that happens to be a pill), but it carries the
   button system's fill and hover. The block padding lands the 44px touch
   target: this is an INLINE box, so its content area comes from the font's em
   metrics (~17px at .875rem Inter), not from line-height, and 14px each side
   measures 45px. 11px would have measured 39px. The width is unchanged on
   purpose, because the 960px hamburger breakpoint is a width measurement
   against the logo. Its two !importants stay: `.nav-links a` and the
   `::after` underline both need beating. */
.nav-donate {
  background: var(--color-kicker);
  color: var(--color-white) !important;
  padding: 14px 22px;
  border-radius: var(--radius-pill);
  font-weight: 700;
  transition: background-color var(--transition), transform var(--transition);
}
.nav-donate::after { display: none !important; }
@media (hover: hover) {
  .nav-donate:hover {
    background: var(--color-primary-dark);
    color: var(--color-white) !important;
    transform: translateY(-1px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .nav-donate:hover { transform: none }
}

/* Mobile hamburger */
.nav-toggle {
  display: none;
  background: none; border: none; cursor: pointer;
  width: 44px; height: 44px; position: relative;
  align-items: center; justify-content: center;
  margin-right: -10px;
  flex-shrink: 0;
  align-self: center;
}
.nav-toggle span {
  display: block;
  width: 26px; height: 2px;
  background: var(--color-text);
  position: absolute;
  left: 50%; transform: translateX(-50%);
}
/* Center the 3 lines (20px total span) inside the 44px button */
.nav-toggle span:nth-child(1) { top: 12px; }
.nav-toggle span:nth-child(2) { top: 21px; }
.nav-toggle span:nth-child(3) { top: 30px; }

/* --- Hero Sections --- */
.hero {
  padding: calc(var(--nav-height) + 80px) 0 80px;
  position: relative;
  overflow: hidden;
}
.hero-home {
  background: linear-gradient(135deg, var(--color-bg) 0%, var(--color-bg-alt) 50%, #F0E0D0 100%);
  min-height: 85vh;
  display: flex;
  align-items: center;
  padding-top: var(--nav-height);
}
.hero-content { max-width: 640px; }
.hero-content > .section-label + h1,
.hero-content > .section-label + h2 {
  margin-top: 10px;
}
.hero-content p {
  font-size: 1.15rem;
  color: var(--color-text-light);
  margin: 30px 0 36px;
  line-height: 1.8;
}

/* --- Action rows ---
   Buttons sit outside paragraphs, in a row. `.hero-actions` is the row;
   `.row-actions` is the sibling modifier for a row that follows a paragraph
   inside an editorial row, card or entry (`class="hero-actions row-actions"`).
   `.registration-form .hero-actions` replaces the inline
   `style="margin-top: 20px"` that contact and volunteer-checkout carried and
   help.html's page-local `#apply .hero-actions` rule. */
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.row-actions { margin-top: 24px; }
.registration-form .hero-actions { margin-top: 20px; }

/* --- Shared Motion ---
   Every initial-hidden state below is gated behind `html.js`, the class
   site.js adds as its first statement. Without JavaScript nothing here
   applies, so the page renders statically instead of blank. Anything that
   must beat a gated hidden state needs the gate too (html.js is 0,1,1, so an
   ungated `.reveal.visible` at 0,2,0 would silently lose to `html.js .reveal`
   at 0,2,1) — that is why the .visible rules and the reduced-motion block
   below carry it as well. New reveal-style patterns must follow the gate. */
/* Load-triggered spelling: paused until site.js sets body.is-ready. */
html.js .anim-in {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  animation: fadeSlideUp var(--motion-enter) var(--ease-enter) forwards;
  animation-play-state: paused;
}

/* Gated too, and deliberately: `html.js .anim-in` sets the `animation`
   shorthand, which resets animation-delay to 0. Ungated at 0,1,0 these would
   now lose to it and the whole hero cascade would fire at once. The ladder
   caps at 240ms: -3 and -4 are the same step on purpose. */
html.js .anim-delay-1 { animation-delay: 80ms; }
html.js .anim-delay-2 { animation-delay: 160ms; }
html.js .anim-delay-3 { animation-delay: 240ms; }
html.js .anim-delay-4 { animation-delay: 240ms; }

@keyframes fadeSlideUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Scroll-triggered spelling. Same values as .anim-in. */
html.js .reveal {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-enter) var(--ease-enter),
              transform var(--motion-enter) var(--ease-enter);
}

/* Gated so it stays above `html.js .reveal` (0,2,1); ungated at 0,2,0 it
   would lose and nothing would ever reveal. */
html.js .reveal.visible {
  opacity: 1;
  transform: translateY(0);
}

/* The old soft-travel and delayed `.reveal` modifier classes are deleted:
   the single set of values above replaces them, and the mobile travel is now
   the --motion-rise token rather than a second block of overrides. */

/* --- Sections --- */
section { padding: 80px 0; }

/* NOTE: the old `section:nth-child(even)` zebra rule and its `.section-alt`
   opt-in replacement are both gone. Sections that want the tonal band use
   `.editorial-section--alt`; do not reintroduce a positional background. */

.section-header {
  text-align: center;
  max-width: 780px;
  margin: 0 auto 56px;
}
.section-header > .section-label + h1,
.section-header > .section-label + h2 {
  margin-top: 10px;
}
.section-header p {
  color: var(--color-text-light);
  margin-top: 28px;
  font-size: 1.05rem;
  line-height: 1.65;
  max-width: 66ch;
  margin-left: auto;
  margin-right: auto;
  text-wrap: pretty;
}
.section-header p a,
.prose p a,
.credibility-note p a {
  white-space: nowrap;
}

.registration-intro > .section-label + h2,
.interest-intro > .section-label + h2 {
  margin-top: 10px;
}
.registration-intro p,
.interest-intro p {
  margin-top: 22px;
}

.cta-banner h2 {
  margin-inline: auto;
}
/* Measure, not nowrap. A `@media (min-width: 900px)` block used to set
   `max-width: none; white-space: nowrap` here. With .utility-heading-xl now
   carrying a real font-size that forced the closing-band heading onto one
   line and overflowed index's 720px banner container; 26ch lets both live
   headings set as two balanced lines, which is the intended behaviour. */
.cta-heading {
  text-wrap: balance;
  max-width: 26ch;
  line-height: 1.08;
  margin-inline: auto;
}
.section-label {
  display: inline-block;
  font-size: .8rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: 12px;
}
.mission-section-header h2 {
  font-family: var(--font-body);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.15;
}

.form-field input[readonly] {
  background: #F7EFE8;
  color: var(--color-text);
  cursor: default;
}

.registration-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(320px, .9fr);
  gap: 28px;
  align-items: start;
}

.registration-card,
.registration-sidebar {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.registration-card {
  padding: 34px 32px;
}

/* Form-page measure. help.html and contact.html run this card outside
   `.registration-layout`; both used to set 760px/820px inline. Left aligned
   on purpose (no auto margins) so the card shares the `.page-opener` h1 axis. */
.registration-card--page {
  max-width: 760px;
  margin-top: 32px;
}

.registration-sidebar {
  padding: 28px 26px;
}

.registration-intro {
  margin-bottom: 32px;
}

.registration-intro p {
  color: var(--color-text-light);
}

.registration-form {
  display: grid;
  gap: 18px;
  /* The in-flight dim below fades rather than snapping. */
  transition: opacity var(--transition);
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}

.form-field {
  display: grid;
  gap: 8px;
}

.form-field-full {
  grid-column: 1 / -1;
}

.form-field label {
  font-size: .92rem;
  font-weight: 600;
  color: var(--color-text);
}

.form-field input,
.form-field textarea {
  width: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: #FFFCFA;
  color: var(--color-text);
  padding: 14px 16px;
  font: inherit;
  transition: border-color var(--transition), box-shadow var(--transition), background var(--transition);
}

.form-field input:focus,
.form-field textarea:focus {
  outline: none;
  border-color: rgba(192,83,58,.55);
  box-shadow: 0 0 0 4px rgba(192,83,58,.12);
  background: var(--color-white);
}

.form-field textarea {
  min-height: 120px;
  resize: vertical;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: #FFFCFA;
  position: relative;
}

.checkbox-row input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.checkbox-row label {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  font-size: .95rem;
  line-height: 1.55;
  cursor: pointer;
}

.checkbox-row label::before {
  content: '';
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  border: 1.5px solid rgba(192,83,58,.35);
  background: var(--color-white);
  box-shadow: inset 0 0 0 0 var(--color-primary);
  transition: border-color var(--transition), background var(--transition), box-shadow var(--transition), transform var(--transition);
}

.checkbox-row input:checked + label::before {
  border-color: var(--color-primary);
  background: var(--color-primary);
  box-shadow: inset 0 0 0 5px var(--color-primary);
  background-image: linear-gradient(45deg, transparent 44%, #fff 44%, #fff 56%, transparent 56%), linear-gradient(-45deg, transparent 47%, #fff 47%, #fff 59%, transparent 59%);
  background-size: 65% 65%, 42% 42%;
  background-position: 58% 58%, 30% 72%;
  background-repeat: no-repeat;
}

.checkbox-row input:focus-visible + label::before {
  outline: none;
  box-shadow: 0 0 0 4px rgba(192,83,58,.12);
}

@media (hover: hover) {
  .checkbox-row:hover {
    border-color: rgba(192,83,58,.28);
    background: #FFF9F5;
  }
}

.form-note {
  color: var(--color-text-light);
  font-size: .92rem;
}

.form-status {
  margin-top: 18px;
  padding: 14px 16px;
  border-radius: var(--radius);
  font-size: .95rem;
}

.form-status[hidden] {
  display: none;
}

.form-status.is-success {
  background: #F3F8F2;
  border: 1px solid #D5E5D2;
  color: #2F5B39;
}

.form-status.is-error {
  background: #FFF5F2;
  border: 1px solid #F0D3C8;
  color: #8C3D2C;
}

.registration-form.is-submitting {
  opacity: .78;
}

.registration-sidebar h3 {
  margin-bottom: 10px;
}

.registration-sidebar p,
.registration-sidebar li {
  color: var(--color-text-light);
}

.registration-sidebar ul {
  margin: 16px 0 0;
  padding-left: 18px;
}

.registration-sidebar li + li {
  margin-top: 10px;
}

.post-submit-panel {
  margin-top: 28px;
  padding: 22px 24px;
  border-radius: var(--radius);
  border: 1px solid rgba(192,83,58,.2);
  background: linear-gradient(135deg, #FFF9F5 0%, #F6EEE7 100%);
}

.post-submit-panel[hidden] {
  display: none;
}

/* A state change gets a fade, not a snap. Opacity only, and a keyframe rather
   than a transition because the panel arrives by un-hiding a `display: none`
   element, which no transition can catch. */
.post-submit-panel:not([hidden]) {
  animation: stateFadeIn 200ms var(--ease-quick) both;
}

@keyframes stateFadeIn {
  from { opacity: 0 }
  to   { opacity: 1 }
}

@media (prefers-reduced-motion: reduce) {
  .post-submit-panel:not([hidden]) { animation: none }
}

.post-submit-panel h3 {
  margin-bottom: 10px;
}

/* What-happens-next list inside a post-submit panel (help + contact). */
.panel-list {
  list-style: none;
  margin: 14px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.panel-list li {
  position: relative;
  padding-left: 16px;
  font-size: .92rem;
  line-height: 1.65;
  color: var(--color-text-light);
}

.panel-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-primary);
}

.post-submit-panel p,
.post-submit-panel li {
  color: var(--color-text-light);
}

.post-submit-panel ol {
  margin: 16px 0 0;
  padding-left: 20px;
}

.post-submit-panel li + li {
  margin-top: 10px;
}

.post-submit-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 18px;
}

.hero-actions[hidden],
.registration-layout[hidden] {
  display: none;
}

.interest-layout {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(300px, .95fr);
  gap: 28px;
  align-items: start;
}

.interest-card,
.interest-sidebar {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.interest-card {
  padding: 34px 32px;
}

.interest-sidebar {
  padding: 28px 26px;
}

.interest-intro {
  margin-bottom: 32px;
}

.interest-intro p {
  color: var(--color-text-light);
}

/* `.interest-form` is deleted: golf-volunteer-checkout's form is plain
   `.registration-form` now, which already declares the identical
   `display: grid; gap: 18px`. `.interest-intro`, `.interest-checklist` and
   `.interest-layout` are still in use and stay. */

.interest-checklist {
  margin: 16px 0 0;
  padding-left: 18px;
}

.interest-checklist li {
  color: var(--color-text-light);
}

.interest-checklist li + li {
  margin-top: 10px;
}

body.golf-sponsorship-page .hero-content h1 {
  max-width: none;
  font-size: clamp(2rem, 4vw, 3rem);
}

body.golf-volunteer-page .interest-layout {
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

body.golf-volunteer-page .interest-card {
  padding: 30px 28px;
}

body.golf-volunteer-page .interest-sidebar {
  padding: 30px 28px;
}

body.golf-volunteer-page .section-header p {
  max-width: 42ch;
  margin-inline: auto;
}

/* The two-up split above is more specific than the shared mobile collapse in
   the 768px block, so it has to be restated here. Without this the sidebar
   stays in a second column on phones and hangs off the right edge. */
@media (max-width: 768px) {
  body.golf-volunteer-page .interest-layout { grid-template-columns: 1fr; }
}


/* --- Credibility Blocks --- */
.credibility-note {
  max-width: 760px;
  margin: 32px auto 0;
  padding: 28px 32px;
  background: linear-gradient(135deg, #FFF9F5 0%, #F6EEE7 100%);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.credibility-note strong {
  display: block;
  margin-bottom: 8px;
  color: var(--color-text);
  font-family: var(--font-heading);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -.015em;
}
.credibility-note p {
  color: var(--color-text-light);
  font-size: .95rem;
  margin-bottom: 10px;
  line-height: 1.6;
  text-wrap: pretty;
}
.credibility-note p:last-child { margin-bottom: 0; }

/* --- CTA Banner --- */
/* The terracotta gradient that used to sit here was declared `!important` and
   then always overridden by `.cta-banner.ink-section`, so it rendered on zero
   pages. Folded to the ink value both live banners actually show. The
   `.cta-banner.ink-section` pairing further down the file is still required:
   `.ink-section` is declared later and would otherwise win at equal
   specificity and repaint both bands --color-ink. */
.cta-banner {
  background: var(--color-ink-deep);
  color: var(--color-white);
  text-align: center;
  /* Promoted from index's page-local override so the two closing bands
     (index, impact) are the same component at the same height. */
  padding: clamp(80px, 9vw, 116px) 0;
}
/* The band is centred, so its action row has to be too: `.hero-actions` is
   left-aligned by default and impact's two-button row rendered flush left
   inside a centred band. Same treatment `.hero-home .hero-actions` gets. */
.cta-banner .hero-actions { justify-content: center; }
.cta-banner h2 { color: var(--color-white); margin-bottom: 16px; }
.cta-banner p { color: rgba(255,255,255,.85); max-width: 540px; margin: 0 auto 32px; font-size: 1.1rem; }
/* Quiet second route out of the closing band (promoted from impact.html's
   inline <style> so index's band can use it too). */
.cta-banner p.cta-quiet { margin: 22px auto 0; font-size: .9rem; }
.cta-banner p.cta-quiet a {
  color: rgba(255,255,255,.75);
  text-decoration: underline;
  text-underline-offset: 3px;
  /* 45.5px hit area. These are inline boxes inside a sentence, so block
     padding costs no layout at all (an inline box contributes nothing to line
     height) and no negative margin is needed to claw it back. 14px, not 10px:
     an inline box's content area comes from the font's em metrics, which is
     17.5px at .9rem Inter, not from the 1.7 line-height. */
  padding-block: 14px;
}
.cta-banner p.cta-quiet a:hover { color: #fff; }
/* The white focus ring for this band now comes from the one shared on-dark
   rule at the end of this file, which names every dark surface on the site
   (hero, founder feature, closing band, ink bands, event cards). */

/* --- Footer --- */
.footer {
  background: var(--color-text);
  color: rgba(255,255,255,.7);
  padding: 64px 0 32px;
}
.footer-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 48px;
  margin-bottom: 48px;
}
.footer h3 {
  color: var(--color-white);
  font-size: 1rem;
  margin-bottom: 20px;
}
.footer p { font-size: .9rem; line-height: 1.7; }
.footer-links { list-style: none; }
.footer-links li { margin-bottom: 10px; }
.footer-links a { color: rgba(255,255,255,.88); font-size: .9rem; }
.footer-links a:hover { color: var(--color-white); }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.1);
  padding-top: 24px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 26px;
  font-size: .85rem;
}
/* Copyright and Privacy sit together on the left; the domain stays right. */
.footer-bottom > a:last-child { margin-left: auto; }
.footer-bottom a { color: rgba(255,255,255,.5); }

/* --- Responsive --- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Gated to match the hidden states these have to beat: ungated at 0,1,0
     they would now lose to `html.js .reveal` at 0,2,1 and reduced-motion
     users would get a blank page. Without JS the hidden states never apply,
     so there is nothing here left to undo. */
  html.js .anim-in,
  html.js .reveal,
  html.js .reveal.visible {
    opacity: 1;
    transform: none;
    animation: none;
    transition: none;
    animation-delay: 0s;
    transition-delay: 0s;
  }
}

/* The navbar collapses earlier than the rest of the mobile layout, which still
   switches at 768px below. The seven desktop items measure ~650px at weight
   700, and the menu is centred in the bar rather than sitting flush right, so
   the binding constraint is clearance beside the ~70px logo: at 961px, the
   first pixel above this breakpoint, there is ~37px. Below that it tightens
   fast, hence 960px. */
@media (max-width: 960px) {
  .nav-links {
    display: none;
    position: absolute;
    top: var(--nav-height);
    left: 0; right: 0;
    /* undo the desktop centring transform so the panel is full-bleed */
    transform: none;
    background: var(--color-bg);
    flex-direction: column;
    padding: 24px;
    gap: 20px;
    border-bottom: 1px solid var(--color-border);
    box-shadow: var(--shadow-md);
  }
  /* Fades in rather than snapping. A keyframe, not a transition, because the
     panel arrives by toggling `display`. Opacity only: no movement. */
  .nav-links.open {
    display: flex;
    animation: navPanelIn var(--motion-quick) var(--ease-quick) both;
  }
  .nav-toggle { display: flex; }
  .nav-links li { width: 100%; }
}
@keyframes navPanelIn {
  from { opacity: 0 }
  to   { opacity: 1 }
}
@media (prefers-reduced-motion: reduce) {
  .nav-links.open { animation: none }
}

@media (max-width: 768px) {
  /* Shorter travel on phones, once, as a token. This replaces the separate
     mobile `.reveal` override block that used to sit further down the file
     and had to be ordered against the reduced-motion block. */
  :root { --motion-rise: 10px; }

  .hero-home { min-height: auto; padding: calc(var(--nav-height) + 48px) 0 48px; }

  section { padding: 56px 0; }
  .section-header { margin-bottom: 40px; }

  .footer-grid { grid-template-columns: 1fr; gap: 32px; }
  .footer-bottom { flex-direction: column; gap: 12px; text-align: center; }
  /* Button groups: stack vertically, stay content-width (no full-viewport stretch) */
  .hero-actions {
    flex-direction: column;
    align-items: flex-start;
  }
  .hero-home .hero-actions,
  .cta-banner .hero-actions {
    align-items: center;   /* the hero and the closing band are center-aligned */
  }
  .registration-layout,
  .interest-layout,
  .form-grid {
    grid-template-columns: 1fr;
  }
  .registration-card,
  .registration-sidebar,
  .interest-card,
  .interest-sidebar {
    padding: 28px 24px;
  }
}

/* ── Golf tournament page nav strip ───────────────────────────── */
.golf-tab-strip {
  background: var(--color-bg-alt);
  border-bottom: 1px solid var(--color-border);
}
.golf-tab-strip-inner {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 12px 0;
}
.golf-tab-strip-label {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-light);
  margin-right: 12px;
  flex-shrink: 0;
}
.golf-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;      /* touch target; the strip grows, the pills do not */
  padding: 7px 16px;
  border-radius: 999px;
  font-size: .82rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--color-text-light);
  transition: background var(--transition), color var(--transition);
  white-space: nowrap;
}
@media (hover: hover) {
  .golf-tab:hover {
    background: var(--color-border);
    color: var(--color-text);
  }
}
.golf-tab.active {
  background: var(--color-primary);
  color: #fff;
}
@media (max-width: 600px) {
  .golf-tab-strip-label { display: none; }
  .golf-tab-strip-inner { gap: 6px; flex-wrap: wrap; }
  .golf-tab { font-size: .78rem; padding: 6px 13px; }
}

/* ── Scroll cue (index's hero) ──
   The infinite bobbing keyframe loop is deleted: continuous decorative
   motion is banned. The cue now enters with the hero cascade (240ms, the .anim-in
   ladder's last step) and fades out once scrolling starts.

   It is spelled as a transition driven by body.is-ready rather than with
   .anim-in, because a `forwards` keyframe fill sits above normal author
   declarations in the cascade and would outrank the .is-hidden fade-out.
   Centred with insets instead of translateX so nothing here fights a
   transform. Ungated, no-JS renders it visible and static. */
.hero-scroll-cue {
  position: absolute;
  bottom: 22px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  color: rgba(255,255,255,.6);
  pointer-events: none;
  z-index: 3;
}
html.js .hero-scroll-cue {
  opacity: 0;
  transition: opacity var(--motion-enter) var(--ease-enter) 240ms;
}
html.js body.is-ready .hero-scroll-cue { opacity: 1; }
/* 0,4,2, so it beats the is-ready rule above (0,3,2). Class toggle from
   index.html's inline script; never an inline style.opacity write. */
html.js body.is-ready .hero-scroll-cue.is-hidden {
  opacity: 0;
  transition: opacity var(--transition);
}
@media (prefers-reduced-motion: reduce) {
  /* Opacity is not motion, so the scroll fade-out stays; only the timing
     goes. */
  html.js .hero-scroll-cue,
  html.js body.is-ready .hero-scroll-cue { opacity: 1; transition: none; }
  html.js body.is-ready .hero-scroll-cue.is-hidden { opacity: 0; transition: none; }
}

/* ============================================
   EDITORIAL REFRESH SYSTEM (2026)
   High-contrast · photography-forward · deliberate motion
   ============================================ */

/* Kicker — strong, branded section label (used deliberately, not everywhere) */
.section-kicker {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--color-kicker);
  margin-bottom: 18px;
}
.section-kicker::before {
  content: "";
  width: 30px;
  height: 2px;
  background: currentColor;
}
.ink-section .section-kicker { color: var(--color-accent); }
/* Kicker over a photograph (get-involved's hero), replacing a hand-rolled
   page-local rule. Keeps the shared 30px rule and tracking; colour only. */
.section-kicker--on-dark { color: rgba(255,255,255,.86); }

/* Editorial display heading */
.display-xl {
  font-size: clamp(2.3rem, 5.2vw, 3.9rem);
  font-weight: 800;
  line-height: 1.0;
  letter-spacing: -.035em;
  font-optical-sizing: auto;
  text-wrap: balance;
}

/* Display face on all major headings (Inter, optical-sized) */
h1, h2,
.display-xl,
.utility-heading-xl,
.utility-heading-lg,
.cta-heading {
  font-family: var(--font-display);
}

/* Ink editorial band */
.ink-section { background: var(--color-ink); color: #fff; }
.cta-banner.ink-section { background: var(--color-ink-deep); }
.ink-section h1, .ink-section h2, .ink-section h3, .ink-section h4 { color: #fff; }
.ink-section p { color: rgba(255,255,255,.82); }

/* Newsletter signup */
.newsletter-form {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 18px;
  max-width: 460px;
}
.newsletter-form input[type="email"] {
  flex: 1 1 220px;
  padding: 14px 18px;
  border-radius: var(--radius-pill);
  border: 1px solid rgba(255,255,255,.22);
  background: rgba(255,255,255,.08);
  color: #fff;
  font: inherit;
}
.newsletter-form input[type="email"]::placeholder { color: rgba(255,255,255,.55); }
.newsletter-form input[type="email"]:disabled,
.newsletter-form button:disabled { opacity: .6; cursor: default; }
/* Inline confirmation / error, injected by site.js on submit. */
.newsletter-status {
  flex: 1 1 100%;
  margin: 0;
  font-size: .92rem;
  line-height: 1.6;
  color: #fff;
}
.newsletter-status:empty { display: none; }
/* Fades in when site.js puts text in it. Keyed on :not(:empty) rather than on
   the element, because `:empty` keeps it `display: none` until then and the
   animation has to start at the moment it begins rendering. */
.newsletter-status:not(:empty) {
  animation: stateFadeIn 200ms var(--ease-quick) both;
}
.newsletter-status.is-error { color: #F4C4B4; }
@media (prefers-reduced-motion: reduce) {
  .newsletter-status:not(:empty) { animation: none }
}
.footer-newsletter {
  display: flex;
  flex-wrap: wrap;
  gap: 28px 48px;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 44px;
  margin-bottom: 44px;
  border-bottom: 1px solid rgba(255,255,255,.14);
}
.footer-newsletter h2 { color: #fff; margin: 0; }
.footer-newsletter p { margin-top: 10px; }
.footer-newsletter .newsletter-form { margin-top: 0; }
@media (max-width: 640px) {
  .footer-newsletter { flex-direction: column; align-items: flex-start; }
}

/* Staggered grid reveal (container observed; children stagger in).
   Same values as .reveal and .anim-in; only the per-child delay differs, and
   it caps at 210ms (3 x --motion-stagger) however many children there are. */
html.js .reveal-stagger > * {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-enter) var(--ease-enter),
              transform var(--motion-enter) var(--ease-enter);
}
/* Gated: at 0,2,0 this would lose to the 0,2,1 hidden state above. */
html.js .reveal-stagger.visible > * { opacity: 1; transform: translateY(0); }
html.js .reveal-stagger.visible > *:nth-child(2) { transition-delay: var(--motion-stagger); }
html.js .reveal-stagger.visible > *:nth-child(3) { transition-delay: calc(var(--motion-stagger) * 2); }
html.js .reveal-stagger.visible > *:nth-child(n+4) { transition-delay: calc(var(--motion-stagger) * 3); }

@media (prefers-reduced-motion: reduce) {
  /* The nth-child delay rules above are 0,4,1. The override that used to sit
     here was 0,2,1 and silently lost every transition-delay, so reduced-motion
     users still got the stagger. `:nth-child(n)` matches every child and
     raises this to 0,4,1, and it is later in source order, so it wins. */
  html.js .reveal-stagger > *,
  html.js .reveal-stagger.visible > *:nth-child(n) {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

/* ============================================
   INTERIOR PAGE SYSTEM (2026)
   Extends the editorial refresh to non-home pages.
   ============================================ */

/* --- Page opener: the quiet interior alternative to a color hero --- */
.page-opener {
  background: var(--color-bg);
  padding: clamp(96px, 12vw, 160px) 0 clamp(40px, 6vw, 68px);
  text-align: left;
}
.page-opener .container { max-width: var(--max-width); }
.page-opener h1 {
  color: var(--color-ink);
  margin: 0;
}
.page-opener .page-standfirst {
  margin-top: clamp(18px, 2.4vw, 26px);
  max-width: 44ch;
  font-size: clamp(1.08rem, 1.5vw, 1.28rem);
  line-height: 1.6;
  color: var(--color-text-light);
}
.page-opener .page-opener-actions {
  margin-top: clamp(26px, 3.2vw, 38px);
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}

/* --- Editorial section scaffolding (left-aligned by default) --- */
.editorial-section { padding: clamp(56px, 7vw, 96px) 0; }
.editorial-section--alt { background: var(--color-bg-alt); }
/* Band rhythm modifiers, replacing `style="padding-top:…"` attributes three
   pages were hand-writing against the shared scale. */
.editorial-section--flush { padding-top: 0; }
.editorial-section--lead { padding-top: clamp(96px, 12vw, 160px); }
/* No max-width here. A 42ch cap (~440px) used to sit on this block, which
   forced every section h2 — set as large as 2.7rem — to wrap after three or
   four words on desktop, and `text-wrap: balance` made the early break read as
   deliberate. Measure is controlled where it belongs: the standfirst `p` below
   caps itself at 60ch. */
.editorial-head { margin-bottom: clamp(32px, 4vw, 52px); }
.editorial-head h2 {
  font-size: clamp(1.85rem, 3.4vw, 2.7rem);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -.03em;
  color: var(--color-ink);
  margin: 0;
  text-wrap: balance;
}
.editorial-head p {
  margin-top: 16px;
  max-width: 60ch;
  color: var(--color-text-light);
  line-height: 1.7;
}
/* Form-page head: the same measure as `.registration-card--page` beneath it,
   left aligned so both sit on the `.page-opener` h1's axis. */
.editorial-head--page { max-width: 760px; }
/* Reading measure. Single source of truth: a duplicate `.prose` block used to
   sit in the Utility section above, and the two interleaved (66ch won the
   width, 1.82 lost the leading). Values below are the ones that were actually
   rendering. `margin: 0 auto` centers it inside a full-width container and is
   inert inside a narrower grid column. */
.prose { max-width: 66ch; margin: 0 auto; }
.prose p {
  font-size: 1.05rem;
  line-height: 1.75;
  margin-bottom: 1.15em;
  color: var(--color-text-light);
  text-wrap: pretty;
}
.prose p:last-child { margin-bottom: 0; }
.prose strong { color: var(--color-text); font-weight: 600; }

/* --- Numbered editorial list: rules, not cards --- */
.rule-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--color-border); }
.rule-list > li {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: clamp(16px, 3vw, 40px);
  padding: clamp(22px, 3vw, 32px) 0;
  border-bottom: 1px solid var(--color-border);
  align-items: start;
}
.rule-list .rule-num {
  font-size: .82rem;
  font-weight: 800;
  letter-spacing: .12em;
  color: var(--color-kicker);
  padding-top: .35em;
  font-variant-numeric: tabular-nums;
}
.rule-list h3 {
  font-size: clamp(1.12rem, 1.7vw, 1.32rem);
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 8px;
}
.rule-list p { margin: 0; color: var(--color-text-light); line-height: 1.65; max-width: 62ch; }
@media (max-width: 560px) {
  .rule-list > li { grid-template-columns: 1fr; gap: 6px; }
  .rule-list .rule-num { padding-top: 0; }
}

/* --- Typographic columns (de-carded feature rows) --- */
.point-columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(28px, 4vw, 56px);
}
.point-columns > div > h3 {
  font-size: 1.08rem;
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 10px;
  padding-top: 18px;
  border-top: 2px solid var(--color-ink);
}
.point-columns > div > p { margin: 0; color: var(--color-text-light); line-height: 1.65; }

/* --- Page ledger: slim utility row, content starts immediately.
       Full-width variant (events) and column-width variant (about). --- */
/* Top padding is the same expression .page-opener and .editorial-section--lead
   use, so every interior page clears the fixed navbar by the same amount. */
.page-ledger {
  padding: clamp(96px, 12vw, 160px) 0 clamp(14px, 1.8vw, 20px);
  border-bottom: 1px solid var(--color-border);
}
.ledger-label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--color-ink);
}
.ledger-label svg { flex: none; width: 16px; height: 16px; }
/* Column-width variant: the rule spans only its grid column. */
.page-ledger--inline {
  padding: 0 0 clamp(14px, 1.8vw, 20px);
  margin-bottom: clamp(22px, 3vw, 32px);
}

/* --- Bio split: ledger + name + prose + quiet links beside one portrait --- */
.bio-split {
  display: grid;
  /* Text column leads. The portrait track is narrower so the 4:5 photo
     renders near its natural height instead of towering over the prose. */
  grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  column-gap: clamp(36px, 5vw, 80px);
  align-items: start;
}
/* The whole left column is ONE grid item, so its contents flow normally.
   Nothing here can be stretched or distributed by the photo beside it. */
.bio-col { min-width: 0; }
.bio-body { margin-top: clamp(28px, 3.4vw, 36px); }
.bio-photo {
  margin: 0;
  align-self: start;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-bg-alt);
}
.bio-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 5;
  max-height: 760px;
  object-fit: cover;
  object-position: center top;
}
.bio-name {
  /* The .display-xl clamp. about.html and privacy.html were the only interior
     pages whose h1 sat off that step. */
  font-size: clamp(2.3rem, 5.2vw, 3.9rem);
  font-weight: 800;
  line-height: 1.04;
  letter-spacing: -.035em;
  color: var(--color-ink);
  margin: 0;
}
.bio-body p {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--color-text-light);
  margin: 0 0 1.15em;
  max-width: 60ch;
}
.bio-links {
  list-style: none;
  margin: clamp(26px, 3vw, 34px) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.bio-links a {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: .92rem;
  color: var(--color-text-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color var(--transition);
  /* 44px hit area, no layout shift: the padding grows the box and the
     negative margin gives the space back, so the flex gap still separates
     the same margin boxes it did before. Adjacent targets overlap by 8px,
     which is the accepted trade for a thumb-sized row. */
  padding-block: 10px;
  margin-block: -10px;
}
.bio-links a:hover { color: var(--color-primary); }
.bio-links svg { flex: none; width: 15px; height: 15px; }
.bio-cta { margin-top: clamp(28px, 3.4vw, 38px); }

@media (max-width: 860px) {
  .bio-split { grid-template-columns: 1fr; row-gap: clamp(24px, 4vw, 34px); }
  /* Unwrap the left column so head / photo / body can interleave:
     ledger + name, then the portrait, then the prose. */
  .bio-col { display: contents; }
  .bio-head { order: 1; }
  .bio-photo { order: 2; max-width: 460px; }
  .bio-body { order: 3; margin-top: 0; }
}

/* --- Two-column editorial list (Other ways to give) --- */
.split-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 0 clamp(32px, 5vw, 72px);
  border-top: 1px solid var(--color-border);
}
.split-list > div {
  padding: clamp(22px, 2.6vw, 30px) 0;
  border-bottom: 1px solid var(--color-border);
}
.split-list h3 {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 8px;
}
.split-list p { margin: 0; color: var(--color-text-light); line-height: 1.65; }

/* --- FAQ: native disclosure, keyboard-accessible, no JS --- */
.faq-set { border-top: 1px solid var(--color-border); max-width: 74ch; }
.faq-set details { border-bottom: 1px solid var(--color-border); }
.faq-set summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(18px, 2.4vw, 24px) 0;
  font-size: clamp(1.02rem, 1.5vw, 1.15rem);
  font-weight: 600;
  color: var(--color-ink);
}
.faq-set summary::-webkit-details-marker { display: none; }
.faq-set summary::after {
  content: "+";
  flex: none;
  font-size: 1.3rem;
  font-weight: 500;
  line-height: 1;
  color: var(--color-primary);
  transition: transform var(--transition);
}
.faq-set details[open] summary::after { transform: rotate(45deg); }
.faq-set summary:hover { color: var(--color-primary); }
.faq-set summary:focus-visible { outline: 3px solid var(--color-primary); outline-offset: 3px; border-radius: 6px; }
.faq-set .faq-body { padding: 0 0 clamp(20px, 2.6vw, 26px); }
.faq-set .faq-body p { margin: 0; max-width: 64ch; color: var(--color-text-light); line-height: 1.7; }
@media (prefers-reduced-motion: reduce) {
  .faq-set summary::after { transition: none; }
}

/* --- Event facts: stated once, read as a record --- */
.fact-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--color-border); max-width: 62ch; }
.fact-list > li {
  display: grid;
  grid-template-columns: minmax(90px, 7.5rem) 1fr;
  gap: clamp(14px, 2.5vw, 32px);
  padding: 16px 0;
  border-bottom: 1px solid var(--color-border);
}
.fact-list dt, .fact-list .fact-key {
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-kicker);
  padding-top: .28em;
}
.fact-list .fact-val { margin: 0; color: var(--color-text); line-height: 1.6; }
@media (max-width: 520px) {
  .fact-list > li { grid-template-columns: 1fr; gap: 4px; }
  .fact-list dt, .fact-list .fact-key { padding-top: 0; }
}

/* --- Entry list: dated editorial rows (Updates) --- */
.entry-list { border-top: 1px solid var(--color-border); }
.entry-list article {
  display: grid;
  grid-template-columns: minmax(150px, 12rem) 1fr;
  gap: clamp(18px, 3.5vw, 48px);
  padding: clamp(26px, 3.4vw, 40px) 0;
  border-bottom: 1px solid var(--color-border);
}
.entry-list .entry-meta {
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-kicker);
  padding-top: .5em;
}
.entry-list h2, .entry-list h3 {
  font-size: clamp(1.25rem, 2.1vw, 1.6rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.02em;
  color: var(--color-ink);
  margin: 0 0 12px;
}
.entry-list p { margin: 0 0 16px; color: var(--color-text-light); line-height: 1.7; max-width: 64ch; }
@media (max-width: 640px) {
  .entry-list article { grid-template-columns: 1fr; gap: 10px; }
  .entry-list .entry-meta { padding-top: 0; }
}

/* --- Form-page intro heading (system typography) --- */
.registration-intro h2,
.interest-intro h2 {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -.03em;
  color: var(--color-ink);
  margin: 0;
}
.registration-sidebar .tier-amount { margin-bottom: 10px; }
.registration-sidebar .tier-includes { margin-bottom: 18px; }

/* --- Thank-you payment heading (system typography) --- */
.payment-heading {
  font-size: clamp(1.5rem, 2.8vw, 2.05rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.03em;
  color: var(--color-ink);
  margin: 0 0 10px;
}
.payment-tier {
  font-size: .74rem;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--color-kicker);
  margin: 0 0 18px;
}

/* --- Tier cards: comparable siblings, no badges, no icons --- */
.tier-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: clamp(18px, 2.4vw, 28px);
}
.tier-card {
  background: var(--color-white);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 2.8vw, 32px);
  display: flex;
  flex-direction: column;
}
.tier-card h2,
.tier-card h3 {
  font-size: 1.18rem;
  font-weight: 700;
  color: var(--color-ink);
  margin: 0 0 4px;
}
.tier-amount {
  font-size: clamp(1.6rem, 2.6vw, 2rem);
  font-weight: 800;
  letter-spacing: -.03em;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
  margin-bottom: 14px;
}
.tier-card > p { margin: 0 0 18px; color: var(--color-text-light); line-height: 1.6; }
.tier-includes { list-style: none; margin: 0 0 26px; padding: 0; }
.tier-includes li {
  padding: 9px 0;
  border-top: 1px solid var(--color-border);
  color: var(--color-text-light);
  line-height: 1.5;
  font-size: .94rem;
}
.tier-card .btn { align-self: flex-start; margin-top: auto; }

/* --- Quiet trust line (facts once, near the action) --- */
.trust-line {
  margin-top: 20px;
  font-size: .86rem;
  line-height: 1.7;
  color: var(--color-text-light);
}

/* --- Deeper-read link: quiet inline pointer ---
   Still a text link, not a button: reserved for incidental wayfinding
   ("Back to events"). Anything that is a real next step is a .btn now. */
.deeper-read {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-weight: 600;
  /* --color-kicker, not --color-primary: this is body-size link text, and
     #C0533A measures 4.39:1 / 4.00:1 on the two grounds it sits on, both
     under AA. Same fix the global `a` rule already carries. */
  color: var(--color-kicker);
  /* The underline was a `border-bottom` plus `padding-bottom: 2px`. It is a
     real text-decoration now, so the block padding below is free to carry the
     44px hit area without dragging the rule 11px away from the text. Matches
     `.bio-links a`, which already underlines this way. */
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  /* 45px hit area, no layout shift (padding out, margin back). 11px, not
     10px: at .86rem inside a `.trust-line` the line box is 23.4px, and 10px
     would land at 43.4px. */
  padding-block: 11px;
  margin-block: -11px;
}
.deeper-read:hover { color: var(--color-primary-dark); }

/* ============================================
   FOUNDER FEATURE (promoted from index.html)
   Light top, ink band below; portrait overlaps the split.
   Reveal: photo rises + unveils bottom-up; text cascades up.
   ============================================ */
.founder-feature {
  position: relative;
  overflow: hidden;
  /* No !important: these only had to beat `section { padding: 80px 0 }` at
     0,0,0,1, which a class already outranks. The band now sits on the
     interior rhythm scale instead of opting out of it. */
  padding-top: clamp(64px, 7vw, 96px);
  padding-bottom: clamp(72px, 8vw, 104px);
  background: linear-gradient(180deg,
    var(--color-bg) 0%, var(--color-bg) 50%,
    var(--color-ink) 50%, var(--color-ink) 100%) !important;
}
.founder-head { margin-bottom: clamp(32px, 4vw, 52px); }
.founder-head .section-kicker { color: var(--color-kicker); margin-bottom: 18px; }
.founder-title {
  font-family: var(--font-display);
  /* Capped so the ladder reads hero > founder > section h2 > closing CTA.
     At 6rem this outranked the homepage hero h1. */
  font-size: clamp(2.6rem, 6vw, 4rem);
  font-weight: 800;
  line-height: .92;
  letter-spacing: -.045em;
  color: var(--color-ink);
}
.founder-sub {
  margin-top: 16px;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--color-primary);
}
.founder-grid {
  display: grid;
  /* Second track constrained so the field of ink to the right of the 46ch
     paragraph reads as deliberate margin rather than dead space. */
  grid-template-columns: minmax(260px, 380px) minmax(0, 660px);
  justify-content: start;
  gap: clamp(32px, 5vw, 72px);
  align-items: end;
}
.founder-photo {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 30px 70px rgba(0,0,0,.42);
  aspect-ratio: 4 / 5;
}
.founder-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.founder-body { padding-bottom: clamp(8px, 2vw, 26px); }
.founder-body p {
  color: rgba(253, 248, 244, .88);
  font-size: clamp(1.05rem, 1.4vw, 1.22rem);
  line-height: 1.7;
  max-width: 46ch;
  margin-bottom: 30px;
}
/* The founder feature's page-local CTA class is deleted: the CTA is a
   `btn btn-white` from the shared system, and the white focus ring now comes from the one shared on-dark rule
   at the end of this file. */

/* Gated: this section is driven by .js-inview, so without JS it never gains
   .visible and the whole Angela's Story block stayed invisible. The .visible
   rules below are 0,3,0 and still out-rank these gated 0,2,1 states, so they
   need no gate of their own.

   The clip-path wipe is gone from BOTH states, deliberately and completely:
   it was the only reveal on the site that animated a clipping geometry, and
   its `round var(--radius-lg)` term was a standing hazard (dropping `round`
   squared the portrait's corners, which shipped once). Opacity plus rise now,
   at the feature duration. */
html.js .founder-photo {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-feature) var(--ease-enter),
              transform var(--motion-feature) var(--ease-enter);
}
.founder-feature.visible .founder-photo {
  opacity: 1;
  transform: none;
}
/* Head and body enter as TWO GROUPS, not per child. The old
   .12/.22/.32/.44/.56 per-child ladder ran to 560ms before the last line of
   the paragraph block had moved; the kicker, title and subtitle are one
   thought and arrive together. */
html.js .founder-head,
html.js .founder-body {
  opacity: 0;
  transform: translateY(var(--motion-rise));
  transition: opacity var(--motion-enter) var(--ease-enter),
              transform var(--motion-enter) var(--ease-enter);
}
.founder-feature.visible .founder-head,
.founder-feature.visible .founder-body { opacity: 1; transform: none; }
.founder-feature.visible .founder-body { transition-delay: 80ms; }

@media (max-width: 900px) {
  .founder-feature {
    background: linear-gradient(180deg,
      var(--color-bg) 0%, var(--color-bg) 32%,
      var(--color-ink) 32%, var(--color-ink) 100%) !important;
  }
  .founder-grid { grid-template-columns: 1fr; align-items: stretch; }
  .founder-photo { max-height: 460px; }
}
@media (prefers-reduced-motion: reduce) {
  /* Written at the specificity of the rules it has to beat
     (`.founder-feature.visible .founder-body` is 0,3,0) and placed after
     them, so the three !importants this block used to need are gone. */
  html.js .founder-photo,
  html.js .founder-head,
  html.js .founder-body,
  .founder-feature.visible .founder-photo,
  .founder-feature.visible .founder-head,
  .founder-feature.visible .founder-body {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}

/* Post-payment "what happens next" list (golf thank-you pages).
   These items are prose containing inline links, so the li must stay a normal
   block. It previously carried `display: flex; gap: 12px` (a leftover from an
   icon layout that no longer exists), which promoted every inline <a> to its
   own flex item and broke sentences apart mid-line. */
.next-steps-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.next-steps-list li {
  font-size: .9rem;
  color: var(--color-text-light);
  line-height: 1.65;
}

/* ============================================
   TWO-STEP CHECKOUT INDICATOR
   Shared by the golf details pages (step 1, `--lead` variant) and their
   matching thank-you pages (step 2). This block used to be duplicated
   inline in all six thank-you pages. payment-complete.html is deliberately
   left self-contained, since it is reachable only from Square.
   ============================================ */
.checkout-steps {
  display: flex;
  align-items: center;
  margin-bottom: 52px;
}
/* Lead-in variant: the details pages sit above a full-width form layout,
   so cap the measure instead of letting the connector stretch to 1140px. */
.checkout-steps--lead {
  max-width: 520px;
  margin-bottom: clamp(28px, 3.5vw, 44px);
}
.checkout-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.checkout-step-circle {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .9rem;
  font-weight: 700;
}
.checkout-step--done   .checkout-step-circle { background: #22c55e; color: #fff; }
.checkout-step--active .checkout-step-circle { background: var(--color-primary); color: #fff; }
/* Upcoming step: present but clearly not yet reached. */
.checkout-step--todo   .checkout-step-circle {
  background: var(--color-bg-alt);
  color: var(--color-text-light);
  border: 1px solid var(--color-border);
}
.checkout-step-label {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-text-light);
  white-space: nowrap;
}
.checkout-step--active .checkout-step-label { color: var(--color-primary); }
.checkout-step--todo   .checkout-step-label { opacity: .75; }
/* "Step 1 of 2" and its name sit on one line, joined by a middot. On narrow
   screens they stack instead, so the separator never dangles at a line end. */
/* Non-breaking spaces: the two spans are adjacent in the markup, so ordinary
   whitespace in generated content collapses away at the element boundary. */
.checkout-step-label .step-of::after { content: "\00A0\00B7\00A0"; }
.checkout-step-connector {
  flex: 1;
  height: 2px;
  background: var(--color-border);
  margin: 0 16px 24px;
}
/* Narrow screens: the labels are too long to sit on one line each, so let
   them wrap and share the row evenly. */
@media (max-width: 560px) {
  .checkout-steps { margin-bottom: 36px; }
  .checkout-step { flex: 1 1 0; min-width: 0; }
  .checkout-step-label {
    white-space: normal;
    text-align: center;
    font-size: .64rem;
    letter-spacing: .04em;
  }
  .checkout-step-label .step-of,
  .checkout-step-label .step-name { display: block; }
  .checkout-step-label .step-of::after { content: none; }
  .checkout-step-connector { margin: 0 8px 24px; }
}

/* --- Skip-to-content link (site-wide accessibility) --- */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  background: var(--color-primary);
  color: #fff;
  padding: 12px 20px;
  border-radius: 8px;
  font-weight: 600;
  transition: top var(--transition);
}
.skip-link:focus {
  top: 16px;
  outline: 3px solid #fff;
  outline-offset: 2px;
}

/* --- Global focus-visible for keyboard nav (site-wide a11y) --- */
body a:focus-visible,
body button:focus-visible,
body .btn:focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 3px;
  border-radius: 6px;
}
/* Pills keep their own radius. The 6px above is for bare links and controls;
   on a `.btn` it squares off the ring of a focused pill. `.nav-donate` is
   deliberately not a `.btn` (see its block), so it is named here too. Both
   selectors are 0,2,1 and sit after the 0,2,1 rule above, so they win on
   source order. */
body .btn:focus-visible,
body .nav-donate:focus-visible {
  border-radius: var(--radius-pill);
}
/* One shared on-dark ring for every dark surface on the site. The global
   terracotta outline all but disappears on a dark ground: #C0533A on
   --color-ink (#3A2E2A) measures 2.19:1, under the 3:1 bar a focus indicator
   has to clear, while #fff measures 12.7:1.
   `:is()` takes the specificity of its most specific argument, so this is
   0,3,0 and clears both rules above without an !important. Page-local copies
   of this on index.html and impact.html are deleted.
   `.footer` is in the list because it is dark on all 29 pages and carries
   real controls (the Pages / Connect columns, the newsletter Subscribe
   button, the Privacy Policy link). `.event-card` is events.html's October
   card on --color-ink-deep; `.letter-hero` is dear-angela's terracotta
   gradient. */
:is(.hero-home, .founder-feature, .cta-banner, .ink-section, .ev-card,
    .event-card, .letter-hero, .footer,
    .golf-hero, .golf-shelf, .golf-band, .golf-card--poster)
  :is(a, .btn):focus-visible {
  outline-color: #fff;
}

/* ============================================
   GOLF CAMPAIGN (Sep 2026)
   One identity for the tournament: deep forest green, warm ivory, charcoal,
   one restrained lime accent, 900-weight display type, prominent photography.
   Principles borrowed from thelifechurch.com; none of its branding, colours
   or assets are.

   Scope is `main.golf-campaign`, a class on <main> and NEVER on <body>, so the
   navbar and footer keep the site brand on every campaign page. events.html is
   a site page and does not take the class: its two poster cards carry the
   campaign through `.golf-card` selectors instead.
   ============================================ */

/* --- Theme remap -------------------------------------------------------
   Every shared component (registration card, checkout steps, form fields,
   tier cards, panel lists, buttons, .trust-line, .section-kicker,
   .ledger-label) rethemes through these eight tokens, with no new selectors.
   The overrides that follow exist only for shared rules that hardcode a
   terracotta literal instead of reading a token. */
main.golf-campaign {
  --color-bg: var(--golf-ivory);
  --color-bg-alt: var(--golf-ivory-alt);
  --color-text: var(--golf-charcoal);
  --color-text-light: var(--golf-charcoal-soft);
  --color-ink: var(--golf-green-deep);
  --color-ink-deep: var(--golf-green-ink);
  --color-kicker: var(--golf-green-mid);
  --color-primary: var(--golf-green-deep);
  --color-primary-dark: var(--golf-green-ink);
  /* Warm hairline derived from the ivory pair, not the terracotta border. */
  --color-border: #DDD3C0;
  /* The peach accent only ever appears on ink grounds here
     (`.ink-section .section-kicker`), where lime is the campaign's answer. */
  --color-accent: var(--golf-lime);
  background: var(--color-bg);
  color: var(--color-text);
}

/* Hardcoded-terracotta overrides. Each of these shared rules bakes in a
   literal rather than reading a token, so the remap alone cannot reach them. */
@media (hover: hover) {
  main.golf-campaign .btn-outline:hover { background: rgba(30,86,55,.08); }
  main.golf-campaign .checkbox-row:hover {
    border-color: rgba(30,86,55,.30);
    background: #FBF8F0;
  }
}
main.golf-campaign .btn-outline-white {
  color: var(--golf-ivory);
  border-color: rgba(247,242,231,.72);
}
@media (hover: hover) {
  main.golf-campaign .btn-outline-white:hover {
    background: rgba(247,242,231,.10);
    color: var(--golf-ivory);
    border-color: var(--golf-ivory);
  }
}
main.golf-campaign .form-field input,
main.golf-campaign .form-field textarea { background: var(--color-white); }
main.golf-campaign .form-field input:focus,
main.golf-campaign .form-field textarea:focus {
  border-color: rgba(30,86,55,.55);
  box-shadow: 0 0 0 4px rgba(30,86,55,.14);
}
main.golf-campaign .form-field input[readonly] { background: var(--golf-ivory-alt); }
main.golf-campaign .checkbox-row { background: var(--color-white); }
main.golf-campaign .checkbox-row label::before { border-color: rgba(30,86,55,.38); }
main.golf-campaign .checkbox-row input:focus-visible + label::before {
  box-shadow: 0 0 0 4px rgba(30,86,55,.14);
}
main.golf-campaign .post-submit-panel {
  border-color: rgba(30,86,55,.22);
  background: var(--golf-ivory-alt);
}
main.golf-campaign .credibility-note { background: var(--golf-ivory-alt); }
/* Active tab is green-mid, a step lighter than the green-deep the remap gives
   --color-primary, so the pill reads as selected rather than as a dark slab. */
main.golf-campaign .golf-tab.active { background: var(--golf-green-mid); }
/* Step 2 (active) is green-deep from the remap; step 1 (done) was a generic
   #22c55e that fights the forest palette. Green-mid keeps the two steps
   distinguishable by depth, as the label colours already distinguish them. */
main.golf-campaign .checkout-step--done .checkout-step-circle {
  background: var(--golf-green-mid);
}

/* Focus rings. On ivory the ring is --color-primary, which the remap makes
   green-deep (12.3:1). On the four green surfaces it is lime (10.3:1); the
   shared on-dark rule above would otherwise leave them white, which is
   correct site-wide but off-brand here. Never a lime ring on ivory. */
main.golf-campaign :is(.golf-hero, .golf-shelf, .golf-band, .golf-card--poster)
  :is(a, .btn):focus-visible {
  outline-color: var(--golf-lime);
}

/* --- Type register -----------------------------------------------------
   Inter at 900 for display, 400 for body. Everything is sentence case except
   the hero and card titles, which are uppercase. */
main.golf-campaign { font-size: 1rem; }
main.golf-campaign p,
main.golf-campaign li,
main.golf-campaign dd { font-size: 1.05rem; line-height: 1.6; }

.golf-label {
  /* `flex`, not `inline-flex`: this is a <p> (or <dt>) and must start its own
     line. As inline-flex it flowed onto the preceding `.golf-back` link's line
     in every hero. `fit-content` keeps it shrink-wrapped to its own content. */
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px;
  font-size: .8rem;
  font-weight: 900;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--golf-green-mid);
}
/* The .section-kicker geometry, reused rather than reinvented. */
.golf-label::before {
  content: "";
  width: 30px;
  height: 2px;
  background: currentColor;
  flex: none;
}
/* On every green surface the label is lime. */
:is(.golf-hero, .golf-shelf, .golf-band, .golf-card--poster) .golf-label {
  color: var(--golf-lime);
}

.golf-hero-title {
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 7.2vw, 6.4rem);
  font-weight: 900;
  text-transform: uppercase;
  line-height: .92;
  letter-spacing: -.02em;
  max-width: 14ch;
  text-wrap: balance;
  font-optical-sizing: auto;
  margin: 0;
}
.golf-h2 {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 3.2rem);
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: -.02em;
  margin: 0;
}
.golf-card-title {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 2.75rem);
  font-weight: 900;
  text-transform: uppercase;
  line-height: .95;
  letter-spacing: -.02em;
  margin: 0;
}
.golf-lede {
  font-size: 1.15rem;
  line-height: 1.6;
  max-width: 48ch;
  margin: 16px 0 0;
}
main.golf-campaign .golf-lede { font-size: 1.15rem; }
.golf-section { padding: clamp(72px, 8vw, 112px) 0; }
main.golf-campaign .editorial-section.golf-section { padding: clamp(72px, 8vw, 112px) 0; }
.golf-section .golf-h2 + * { margin-top: 16px; }

/* --- .golf-hero --------------------------------------------------------- */
.golf-hero {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(520px, 62vh, 720px);
  background: var(--golf-green-ink);
  color: var(--golf-ivory);
  overflow: hidden;
}
.golf-hero-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* The golfer sits right of centre, so the type gets the darker left. */
  object-position: 60% 40%;
}
.golf-hero-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* MEASURED, not eyeballed: composited over golf-hero.jpg's real pixels under
     every glyph box at 1440 / 1024 / 375, with each element's true colour
     (lime label, ivory title and lede, ivory-82% back link and meta).
     The binding case is 375: the hero is only ~610px tall there while the
     content nearly fills it, so the back link and label sit at 86% and 77% of
     the way up, over bright sky. At the drafted .94 / .62@48% / .18 they
     measured 2.0 and 2.35:1. Raising the mid ALPHA alone could not fix it
     without flooding the whole frame, so the mid STOP moved up to 75%: the
     text band is covered and the top quarter stays photographic.
     Worst glyph pixel at 1440 / 1024 / 375 -
       back link 7.29 / 8.46 / 5.03:1 (bar 4.5)
       label     10.99 / 10.33 / 6.92:1 (bar 4.5)
       title      9.31 / 10.06 / 8.97:1 (bar 3)
       lede      12.08 / 11.42 / 10.80:1 (bar 4.5)
       meta       8.57 / 8.46 / 8.63:1 (bar 4.5)
     Re-measure if the photo, the hero min-height or the type sizes change. */
  background: linear-gradient(to top,
    rgba(10,35,21,.94) 0%,
    rgba(10,35,21,.82) 75%,
    rgba(10,35,21,.10) 100%);
}
.golf-hero-inner {
  position: relative;
  z-index: 2;
  padding: clamp(40px, 6vw, 72px) 0;
}
.golf-hero-title { color: var(--golf-ivory); }
.golf-hero .golf-lede { color: var(--golf-ivory); }
.golf-hero-meta {
  margin: 20px 0 0;
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .01em;
  color: rgba(247,242,231,.82);
}
/* `.golf-hero--photo` carries no rules on purpose: the photo variant IS the
   base `.golf-hero` plus its `.golf-hero-media` / `.golf-hero-scrim` children.
   The class stays in the markup as a readable marker beside `--type` and
   `--compact`; don't "fix" it by inventing declarations for it. */

/* Type-only variant: sponsorship and volunteer overviews, which have no
   usable photograph. */
.golf-hero--type {
  background: var(--golf-green-deep);
  min-height: clamp(380px, 46vh, 520px);
  border-bottom: 1px solid var(--golf-green-line);
}
/* Compact variant: checkout, tier detail and thank-you pages. */
.golf-hero--compact {
  background: var(--golf-green-ink);
  min-height: 0;
  padding: clamp(48px, 6vw, 80px) 0 clamp(40px, 5vw, 56px);
}
.golf-hero--compact .golf-hero-inner { padding: 0; }
.golf-hero--compact .golf-hero-title { font-size: clamp(2.2rem, 4.6vw, 3.6rem); }
.golf-price { margin: clamp(22px, 2.6vw, 30px) 0 0; }
.golf-price .golf-label { margin-bottom: 8px; }
.golf-price-value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.2rem);
  font-weight: 900;
  letter-spacing: -.02em;
  line-height: 1;
  color: var(--golf-lime);
  font-variant-numeric: tabular-nums;
}
/* Back route: the first line of every hero. */
.golf-back {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 10px;
  margin: 0 0 clamp(20px, 2.6vw, 28px);
  font-size: .8rem;
  font-weight: 900;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(247,242,231,.82);
  text-decoration: none;
  /* 44px hit area, no layout shift. */
  padding-block: 12px;
  margin-block: -12px clamp(8px, 1.4vw, 16px);
}
.golf-back:hover { color: var(--golf-ivory); }
/* The shared arrow SVG, turned around to point back. */
.golf-back .btn-arrow { transform: rotate(180deg); }
@media (hover: hover) {
  .golf-back:hover .btn-arrow { transform: rotate(180deg) translateX(3px); }
}

/* --- .golf-shelf (dark action shelf directly under a hero) --------------- */
.golf-shelf {
  background: var(--golf-green-ink);
  color: var(--golf-ivory);
  border-top: 1px solid var(--golf-green-line);
  padding: 28px 0;
}
.golf-shelf-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 32px;
}
.golf-shelf .hero-actions { margin: 0; }
.golf-shelf-note {
  margin: 0;
  font-size: .95rem;
  color: rgba(247,242,231,.82);
  max-width: 46ch;
}

/* --- .golf-facts (When / Where / Cost) ---------------------------------- */
.golf-facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 40px;
  margin: 0;
}
.golf-facts > div {
  /* The site's .point-columns device: a 2px ink rule over each column. */
  border-top: 2px solid var(--golf-green-deep);
  padding-top: 18px;
  min-width: 0;
}
.golf-facts dt.golf-label { margin-bottom: 12px; }
.golf-facts dd {
  margin: 0;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--golf-charcoal);
}
.golf-facts dd strong {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 900;
  letter-spacing: -.02em;
  color: var(--golf-green-deep);
}
.golf-directions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-weight: 600;
  color: var(--golf-green-mid);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  /* 44px hit area, no layout shift. */
  padding-block: 11px;
  margin-block: -1px -11px;
}
.golf-directions:hover { color: var(--golf-green-ink); }

/* --- .golf-band (green highlight section) and .golf-close --------------- */
.golf-band {
  background: var(--golf-green-deep);
  color: var(--golf-ivory);
  padding: clamp(72px, 8vw, 112px) 0;
}
.golf-band .golf-h2 { color: var(--golf-ivory); }
.golf-band p { color: var(--golf-ivory); }
.golf-band p.trust-line,
.golf-band .golf-band-quiet { color: rgba(247,242,231,.82); }
.golf-band hr,
.golf-band .golf-rule {
  border: 0;
  border-top: 1px solid var(--golf-green-line);
  margin: clamp(24px, 3vw, 34px) 0;
}
.golf-band .point-columns > div > h3 {
  color: var(--golf-ivory);
  border-top-color: var(--golf-green-line);
}
.golf-band .point-columns > div > p { color: rgba(247,242,231,.82); }
.golf-band a:not(.btn) { color: var(--golf-lime); }
/* Paired statements inside a green band ("Player names" / "How it works").
   Same 2px-rule-over-column device as .golf-facts and .point-columns, in the
   band's hairline colour. */
.golf-band-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 40px;
}
.golf-band-grid > * {
  border-top: 2px solid var(--golf-green-line);
  padding-top: 18px;
  min-width: 0;
}
.golf-band-grid p { color: var(--golf-ivory); margin: 0; }
@media (max-width: 768px) {
  .golf-band-grid { grid-template-columns: 1fr; gap: 28px; }
}

.golf-close .hero-actions { margin-top: clamp(26px, 3vw, 34px); }
.golf-close .trust-line { color: rgba(247,242,231,.82); }
.golf-close .trust-line a { color: var(--golf-lime); }

/* --- .golf-photo (full-bleed photo band) -------------------------------- */
.golf-photo { padding: 0; }
.golf-photo img {
  display: block;
  width: 100%;
  /* `height: auto` is load-bearing: the <img height> attribute is a
     presentational hint that outranks `aspect-ratio`, so without it the course
     band rendered 1024x787 and the volunteer strip 1024x470 instead of the
     ratios below. */
  height: auto;
  aspect-ratio: 21 / 9;
  object-fit: cover;
}
.golf-photo--strip img { aspect-ratio: 3 / 1; }

/* Two-item variant: the volunteer overview's facts row is When / Where with
   no Cost column, and must not leave a third column empty. */
.golf-facts--two { grid-template-columns: repeat(2, 1fr); }

/* --- .point-columns and .tier-card inside the campaign ------------------ */
main.golf-campaign .point-columns > div > h3 {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 900;
  letter-spacing: -.02em;
}
/* `.prose` centres itself with `margin: 0 auto`. Every other campaign block is
   left-aligned on the container's axis, so an ivory prose block sat visibly
   inboard of the label and heading above it. Measure is unchanged. */
main.golf-campaign .prose { margin-inline: 0; }
main.golf-campaign .tier-amount {
  font-family: var(--font-display);
  font-size: clamp(2rem, 3vw, 2.6rem);
  font-weight: 900;
  color: var(--golf-green-deep);
  border-top: 2px solid var(--golf-green-mid);
  padding-top: 14px;
  margin-top: 4px;
}

/* --- Promoted from the golf pages' 182-line inline core -----------------
   These were duplicated in all 11 sign-up pages. They already read tokens, so
   they retheme through the remap with no campaign-specific values. */
.signup-section { padding-top: clamp(36px, 5vw, 60px); }
.form-group { border: 0; margin: 0; padding: 0; min-width: 0; }
.form-group + .form-group { margin-top: clamp(10px, 1.6vw, 18px); }
.form-group-legend {
  display: block;
  width: 100%;
  margin-bottom: 18px;
  padding: 0 0 12px;
  border-bottom: 1px solid var(--color-border);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--color-ink);
}
.req { color: var(--color-primary); }
.form-total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  margin-top: clamp(18px, 2.4vw, 26px);
  padding: 18px 20px;
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}
.form-total-label {
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-kicker);
}
.form-total-value {
  font-size: clamp(1.2rem, 2vw, 1.45rem);
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--color-ink);
  font-variant-numeric: tabular-nums;
}
/* The 5 sponsor detail pages only. */
.form-logo-note {
  background: var(--color-bg-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: 14px 16px;
  font-size: .82rem;
  color: var(--color-text-light);
  line-height: 1.65;
  margin: 4px 0 0;
}

/* --- Events poster cards ------------------------------------------------
   These live on events.html, which does NOT carry the theme remap, so every
   colour here is named from the golf palette directly. */
.golf-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* 46px at 1440, 33px at 1024: 24px read as too tight between two posters
     this heavy (owner, Sep 2026). The stacked layout below 900px keeps 24px,
     where the gap is vertical and a wider one just pushes card 2 off screen. */
  gap: clamp(32px, 3.2vw, 48px);
  align-items: stretch;
}
.golf-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 560px;
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
}
.golf-card--poster {
  background: var(--golf-green-ink);
  color: var(--golf-ivory);
  scroll-margin-top: calc(var(--nav-height) + 16px);
}
.golf-card--ivory {
  background: var(--golf-ivory-alt);
  color: var(--golf-charcoal);
}
.golf-card-media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--transition);
}
.golf-card--poster .golf-card-media {
  position: absolute;
  inset: 0;
  object-position: 62% 38%;
  /* Painted with the scrim BELOW the in-flow body (see .golf-card-body), and
     clipped to the card by its `isolation: isolate`. */
  z-index: -1;
}
.golf-card-scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* MEASURED, not eyeballed: the scrim was composited over golf-hero.jpg's
     real pixels under every glyph box at 1440 / 1024 / 375.
     At the drafted .94 / .66@50% / .22 the 375 card is only 520px tall, so its
     title and meta sat high in the ramp over bright sky and measured 2.63:1
     (bar 3) and 3.45:1 (bar 4.5). Raising the mid alpha everywhere would have
     worked but muddied the photo, so the mid STOP moved up instead: the dark
     band now covers the text, and the top is lighter than the draft (.14, not
     .22), so more sky survives.
     Worst glyph pixel now: title 7.16 / 6.95 / 3.70:1 (bar 3) and body copy
     6.71 / 6.62 / 5.27:1 (bar 4.5) at 1440 / 1024 / 375.
     Re-measure if the photo, the card's min-height or the type sizes change. */
  background: linear-gradient(to top,
    rgba(10,35,21,.94) 0%,
    rgba(10,35,21,.74) 62%,
    rgba(10,35,21,.14) 100%);
  z-index: -1;
}
/* NOT positioned, deliberately. It used to carry `position: relative;
   z-index: 1` to sit above the scrim, but that made it the containing block
   for `.golf-card-action::after`, so the whole-card overlay covered only the
   body and a click on the photo hit nothing. The media and scrim are now at
   z-index -1 instead, and CSS paint order puts in-flow block content above
   negative-z-index children anyway, so the body still renders over the scrim
   while `.golf-card` stays the overlay's containing block. */
.golf-card-body {
  padding: clamp(28px, 3.5vw, 44px);
}
.golf-card--poster .golf-card-body { margin-top: auto; }
.golf-card--poster .golf-card-title { color: var(--golf-ivory); }
.golf-card--ivory .golf-card-title {
  color: var(--golf-green-deep);
  /* A step down from the poster card's title: the ivory card's text column is
     only ~321px inside at 1440, and at the shared clamp "TOURNAMENT" set wider
     than the column and ran under the photo. No hyphenation and no
     `overflow-wrap: anywhere` needed at this step. */
  font-size: clamp(1.6rem, 2.4vw, 2.2rem);
}
/* Grid and flex items floor at min-content by default, which let the long
   title push the column wider than its track. */
.golf-card--ivory .golf-card-body { min-width: 0; }
/* The volunteer route is its own line: as a middot-joined clause it wrapped
   and left a stray separator hanging at the end of the line above. */
.golf-card-facts--alt { margin-top: 8px; }
.golf-card-meta {
  margin: 14px 0 0;
  font-size: .95rem;
  font-weight: 600;
  color: rgba(247,242,231,.82);
}
.golf-card-desc {
  margin: 14px 0 0;
  font-size: 1.02rem;
  line-height: 1.6;
  max-width: 44ch;
}
.golf-card--poster .golf-card-desc { color: rgba(247,242,231,.86); }
.golf-card--ivory .golf-card-desc { color: var(--golf-charcoal-soft); }
.golf-card-facts {
  margin: 16px 0 0;
  font-size: .92rem;
  line-height: 1.6;
}
.golf-card--poster .golf-card-facts { color: rgba(247,242,231,.82); }
.golf-card--ivory .golf-card-facts { color: var(--golf-charcoal-soft); }
/* Sits ABOVE the whole-card overlay so it stays independently clickable. */
.golf-card-link {
  position: relative;
  z-index: 1;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  /* 46px hit area. 14px, not 11px: these are inline boxes at .92rem, whose
     content area comes from the font's em metrics (~17.9px), not line-height. */
  padding-block: 14px;
  margin-block: -14px;
}
.golf-card--poster .golf-card-link { color: var(--golf-ivory); }
.golf-card--poster .golf-card-link:hover { color: var(--golf-lime); }
.golf-card--ivory .golf-card-link { color: var(--golf-green-mid); }
.golf-card--ivory .golf-card-link:hover { color: var(--golf-green-ink); }
.golf-card .hero-actions { margin-top: clamp(22px, 2.6vw, 30px); }
/* Whole-card click, honestly: the card's ONE action stretches to fill it, so
   the doorway is the real link rather than a JS click handler. The two
   in-body links above raise themselves out of its way. */
.golf-card-action::after {
  content: "";
  position: absolute;
  inset: 0;
}
/* events.html carries no `main.golf-campaign` remap, so a shared `.btn-*`
   inside these cards would read the SITE's terracotta tokens. Card 2's action
   is repainted from the golf palette here; card 1's is `.btn-lime`, which is
   already palette-native. */
.golf-card--ivory .btn-primary { background: var(--golf-green-mid); }
@media (hover: hover) {
  .golf-card--ivory .btn-primary:hover { background: var(--golf-green-ink); }
}

/* Keyboard users see the whole doorway, not just the button. */
.golf-card:focus-within {
  outline: 3px solid var(--golf-green-deep);
  outline-offset: 3px;
}
.golf-card--poster:focus-within { outline-color: var(--golf-lime); }
@media (hover: hover) {
  .golf-card:hover .golf-card-media { transform: scale(1.02); }
}
/* Card 2: text left, photo filling the right column at full card height. */
@media (min-width: 901px) {
  .golf-card--ivory {
    display: grid;
    /* minmax(0, …): a bare `fr` floors at the track's min-content width, and
       the text column's long words squeezed the photo to 138px. */
    grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
    align-items: stretch;
  }
  .golf-card--ivory .golf-card-media {
    height: 100%;
    object-position: 52% 62%;
  }
}
/* Between the split's breakpoint and ~1100px the text column is only ~258px,
   and at the shared clamp(28px, 3.5vw, 44px) padding its content box measured
   186.4px against the action's 191.7px max-content, so "See the levels"
   wrapped to two lines and the button rendered 64.5px. The spec's 1.15/.85
   ratio is kept and the 5.3px is bought back from the padding instead, which
   leaves 18px of headroom without narrowing the photo column. */
@media (min-width: 901px) and (max-width: 1100px) {
  .golf-card--ivory .golf-card-body { padding: 28px 24px; }
}
@media (max-width: 900px) {
  .golf-grid { grid-template-columns: 1fr; gap: 24px; }
  .golf-card { min-height: 0; }
  .golf-card--poster { min-height: 520px; }
  /* Photo becomes a 16:9 band above the text. */
  .golf-card--ivory { flex-direction: column-reverse; }
  .golf-card--ivory .golf-card-media { aspect-ratio: 16 / 9; height: auto; }
}

/* --- Campaign responsive ------------------------------------------------ */
@media (max-width: 768px) {
  .golf-hero { min-height: clamp(460px, 70vh, 640px); }
  .golf-shelf-inner { align-items: flex-start; }
  .golf-facts { grid-template-columns: 1fr; gap: 28px; }
  .golf-photo img { aspect-ratio: 16 / 10; }
}

@media (prefers-reduced-motion: reduce) {
  .golf-card-media,
  .golf-back .btn-arrow { transition: none; }
  .golf-card:hover .golf-card-media { transform: none; }
  .golf-back:hover .btn-arrow { transform: rotate(180deg); }
}
