/* ==========================================================================
   UTV Offroad Adventures — site stylesheet

   Self-hosted so the Content-Security-Policy needs no third-party origin.
   Replaces the previous inline <style> block plus Bootstrap and jQuery loaded
   from an external CDN without integrity attributes.

   Only the layout primitives the site actually uses are implemented, which is
   far less code than a full framework and keeps the visual language identical:
   red on black, white content cards, the wordmark's display type.
   ========================================================================== */

/* --- Fonts (self-hosted; woff2 with ttf fallback) ----------------------- */
@font-face {
  font-family: 'Rock Salt';
  src: url('/assets/font/RockSalt-Regular.woff2') format('woff2'),
       url('/assets/font/RockSalt-Regular.ttf') format('truetype');
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: 'Protest Guerrilla';
  src: url('/assets/font/ProtestGuerrilla-Regular.woff2') format('woff2'),
       url('/assets/font/ProtestGuerrilla-Regular.ttf') format('truetype');
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}
/* The closest open face to the wordmark's lettering: squared forms with the
   same chamfered corner cuts, used at its bold italic like the logo's slant. */
@font-face {
  font-family: 'Chakra Petch';
  src: url('/assets/font/ChakraPetch-BoldItalic.woff2') format('woff2'),
       url('/assets/font/ChakraPetch-BoldItalic.ttf') format('truetype');
  font-style: italic;
  font-weight: 700;
  font-display: swap;
}

/* --- Design tokens ------------------------------------------------------ */
:root {
  --red: #e01515;
  --red-bright: #ff2b2b;
  --red-dark: #a90d0d;
  --black: #000;
  --ink: #1c1c1e;
  --ink-soft: #3c3c41;
  /* Darkened from #6a6a70. "Muted" still has to be readable in daylight on a
     phone; this clears 7:1 against white rather than scraping past 4.5:1. */
  --ink-muted: #56565c;
  --white: #fff;
  --paper: #f7f7f8;
  --line: #e2e2e6;
  --grey-900: #141414;
  --grey-800: #1d1d1d;
  --grey-700: #2d2d2d;
  --grey-500: #555;
  --green: #1c7c3d;
  --green-dark: #14602e;
  --amber: #a86612;
  --amber-bg: #fff6e0;
  --amber-line: #e8c37a;
  --info-bg: #eaf3ff;
  --info-line: #9dc4f0;
  --danger-bg: #fdecec;
  --danger-line: #f0a9a9;
  --success-bg: #e8f6ec;
  --success-line: #9fd3af;

  --radius: 12px;
  --radius-sm: 8px;
  --gap-xs: 0.35rem;
  --gap-sm: 0.6rem;
  --gap: 1rem;
  --gap-lg: 2rem;
  --shadow: 0 2px 10px rgba(0, 0, 0, .3);
  --shadow-soft: 0 2px 8px rgba(0, 0, 0, .1);
  --shadow-lift: 0 8px 24px rgba(0, 0, 0, .16);
  --focus: 0 0 0 3px rgba(255, 80, 80, .55);
  --ease: .22s ease;
  --measure: 1200px;

  /* Display face for headings: the wordmark's lettering. Chakra Petch bold
     italic is the closest open face to the logo's squared, chamfered, slanted
     forms. Self-hosted (assets/font), so it loads under the CSP that forbids
     third-party font hosts. */
  --font-display: 'Chakra Petch', 'Arial Narrow', Impact, sans-serif;
}

/* --- Reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--black);
  color: var(--ink);
  /* 19px base. Most of the people who ride with UOA are reading this with
     long sight, often outdoors on a phone, so the body face is set well above
     the 16px web default and the leading is opened up to match. */
  font: 400 1.1875rem/1.7 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
        Ubuntu, Cantarell, 'Helvetica Neue', Arial, sans-serif;
}
img, video, svg { max-width: 100%; height: auto; }
h1, h2, h3, h4, h5, h6 {
  margin: 0 0 .5rem; line-height: 1.2; font-weight: 700;
  font-family: var(--font-display); font-style: italic; letter-spacing: .5px;
}
p { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.4rem; }
hr { margin: var(--gap) 0; border: 0; border-top: 1px solid var(--line); }
/* Links stay underlined and stay red. Colour alone is not enough to mark a
   link for anyone whose colour vision has shifted with age, and a thicker rule
   set slightly off the baseline survives a low-contrast screen outdoors. */
:where(a) {
  color: var(--red-dark); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 2px;
}
:where(a):hover { color: var(--red-bright); }

/* Visible focus everywhere. The old site removed outlines on nav links,
   which left keyboard users with no indication of position. */
:focus-visible { outline: 3px solid var(--red-bright); outline-offset: 2px; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--white); color: var(--ink); padding: .65rem 1rem;
  border-radius: 0 0 var(--radius-sm) 0; font-weight: 600;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* --- Navigation --------------------------------------------------------- */
.site-nav {
  background: linear-gradient(135deg, var(--grey-800) 0%, var(--grey-700) 100%);
  box-shadow: var(--shadow);
  position: sticky; top: 0; z-index: 100;
}
.nav-inner {
  max-width: var(--measure); margin: 0 auto;
  display: flex; align-items: center; gap: var(--gap);
  padding: .5rem var(--gap);
}
.nav-brand { display: inline-flex; flex: 0 0 auto; }
.nav-brand img { width: 155px; height: auto; }

.nav-toggle {
  display: none; margin-left: auto;
  background: transparent; border: 2px solid rgba(255, 255, 255, .4);
  border-radius: var(--radius-sm); padding: .5rem .6rem; cursor: pointer;
}
.nav-toggle-bar { display: block; width: 22px; height: 2px; background: var(--white); margin: 4px 0; }

.nav-menu { margin-left: auto; }
.nav-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: .15rem; flex-wrap: wrap;
}
.nav-list > li { position: relative; }
.nav-list a, .submenu-toggle {
  display: block; padding: .7rem .75rem;
  color: var(--white); text-decoration: none;
  font-size: 1.15rem; font-weight: 600; letter-spacing: .5px;
  background: transparent; border: 0; cursor: pointer; font-family: inherit;
  border-radius: var(--radius-sm); transition: color var(--ease), background var(--ease);
}
.nav-list a:hover, .submenu-toggle:hover,
.nav-list a:focus-visible, .submenu-toggle:focus-visible {
  color: var(--red-bright); background: rgba(255, 255, 255, .07);
}
.caret { display: inline-block; border: .3em solid transparent; border-top-color: currentColor; vertical-align: .1em; margin-left: .2em; }

.submenu {
  list-style: none; margin: 0; padding: .4rem;
  position: absolute; top: 100%; left: 0; min-width: 17rem;
  background: #3a3a3f; border-radius: var(--radius);
  box-shadow: 0 8px 18px rgba(0, 0, 0, .35);
  display: none; z-index: 110;
}
.has-submenu:hover > .submenu,
.has-submenu:focus-within > .submenu,
.submenu[data-open="true"] { display: block; }
.submenu a { padding: .45rem .6rem; letter-spacing: .5px; }
.submenu a:hover { background: #4a4a50; }

/* --- Layout ------------------------------------------------------------- */
.container { flex: 1; width: 100%; max-width: var(--measure); margin: 0 auto; padding: var(--gap); }
.grid { display: grid; gap: var(--gap); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr)); }
.split { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.split-even { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
/* The mirrored split: narrow column first, wide second — used where the
   picture sits left of the form. */
.split-flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
@media (max-width: 62rem) { .split, .split-even { grid-template-columns: 1fr; } }

/* A form that reads better narrow than full-bleed. Long lines of input labels
   are hard to track back to the start on a wide screen. */
.form-column { max-width: 46rem; margin: 0 auto; }

/* --- Contact page people ------------------------------------------------
   Kyle and Debbie are two separate people and the page has to say so. Each
   sits in its own bordered card with its own name as a heading, so nobody
   e-mails one address expecting the other to answer. The markup comes from
   the editable page content, which uses .contact-person per block.          */
.contact-people {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.contact-person {
  border: 2px solid var(--line); border-left: 6px solid var(--red);
  border-radius: var(--radius-sm); padding: var(--gap); background: var(--paper);
}
.contact-person > :last-child { margin-bottom: 0; }
.contact-person-name {
  font-family: var(--font-display); font-style: italic; font-size: 1.4rem; letter-spacing: .5px;
  margin: 0 0 .15rem;
}
.contact-person-role {
  color: var(--ink-muted); font-weight: 600; margin: 0 0 .75rem;
}
/* Label and value on one line, the label in a fixed column so the addresses
   underneath each other line up and can be scanned down. */
.contact-person dl { display: grid; grid-template-columns: auto 1fr; gap: .3rem .6rem; margin: 0; }
.contact-person dt { font-weight: 700; color: var(--ink-soft); }
.contact-person dd { margin: 0; overflow-wrap: anywhere; }

/* Affiliate cards: logo on the left, copy on the right, stacking on narrow
   screens. Every listing is built to the same shape so the page can be scanned
   down a column rather than read through. */
.affiliate-media { display: flex; gap: var(--gap); align-items: flex-start; }
.affiliate-logo { flex: 0 0 auto; }
/* A fixed box, contained rather than stretched: vendor logos arrive at every
   size and aspect going, and letting them set their own width was most of what
   made one listing look nothing like the next. */
.affiliate-logo img {
  width: 180px; max-width: 40vw; height: 120px; object-fit: contain;
  background: var(--white); border-radius: var(--radius-sm); padding: var(--gap-sm);
}
.affiliate-body { flex: 1 1 0; min-width: 0; }
.affiliate-action { margin-top: var(--gap); }
/* Write-ups arrived with the vendor's tagline as an <h2>. The vendor name is
   already the card's heading, so the tagline is demoted rather than left to
   shout over it. */
.affiliate-body .prose h2,
.affiliate-body .prose h3 { font-size: 1.15rem; margin-top: 0; }
.affiliate-body .prose > :first-child { margin-top: 0; }
/* The legacy two-column rule must not apply here: an affiliate's logo has its
   own field and its own column already. */
.affiliate-body .prose .row { display: block; }

/* The discount itself. This is what the page is for, so it sits directly under
   the vendor name and looks identical on every listing. */
.discount-block {
  border: 2px dashed var(--green); border-radius: var(--radius-sm);
  background: var(--success-bg); padding: var(--gap-sm) var(--gap);
  margin: 0 0 var(--gap);
}
.discount-terms { font-weight: 700; color: var(--green-dark); margin: 0; }
.discount-code-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem; margin: .4rem 0 0;
}
.discount-label { font-weight: 600; color: var(--ink-soft); }
/* Monospaced with wide tracking, because this gets copied by hand off a phone
   screen and 0/O and 1/I have to be told apart. */
.discount-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.25rem; font-weight: 700; letter-spacing: .12em;
  background: var(--white); color: var(--ink);
  border: 2px solid var(--green); border-radius: var(--radius-sm);
  padding: .15rem .6rem; user-select: all;
}
.discount-terms + .discount-code-line { margin-top: .5rem; }
.affiliate-body > :last-child { margin-bottom: 0; }
@media (max-width: 40rem) {
  .affiliate-media { flex-direction: column; }
  .affiliate-logo img { width: 220px; max-width: 100%; }
}

.card {
  background: var(--white); color: var(--ink);
  border-radius: var(--radius); padding: var(--gap);
  margin-bottom: var(--gap); overflow-wrap: break-word;
}
.card > :last-child { margin-bottom: 0; }
.card-flush { padding: 0; overflow: hidden; }

.card-header {
  margin: calc(var(--gap) * -1) calc(var(--gap) * -1) var(--gap);
  padding: .7rem var(--gap);
  background: linear-gradient(to right, rgba(0, 0, 0, .06), #c8c8c8 18%, #c8c8c8 82%, rgba(0, 0, 0, .06));
  border-radius: var(--radius) var(--radius) 0 0;
  /* Tracking was 4px, which pulls the letters far enough apart that the word
     stops reading as a word. 1.5px keeps the poster look and stays legible. */
  font-size: 1.5rem; font-weight: 700; letter-spacing: 1.5px;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, .28);
  color: var(--ink);
}
.card-flush .card-header { margin: 0 0 var(--gap); }
/* Padded region inside a flush card, below its full-bleed header. Exists as a
   class because the Content-Security-Policy refuses inline style attributes. */
.card-body { padding: 0 var(--gap) var(--gap); }
.card-body > :last-child { margin-bottom: 0; }

/* Heading classes for elements that need a heading's size without its level —
   an <h1> inside a status banner, or an <h2> that should look smaller. */
.h1 { font-size: 1.8rem; font-weight: 700; line-height: 1.25; font-family: var(--font-display); font-style: italic; }
.h2 { font-size: 1.5rem; font-weight: 700; line-height: 1.25; font-family: var(--font-display); font-style: italic; }
.h3 { font-size: 1.25rem; font-weight: 700; line-height: 1.3; font-family: var(--font-display); font-style: italic; }
.h4 { font-size: 1.1rem; font-weight: 700; line-height: 1.3; font-family: var(--font-display); font-style: italic; }

/* A registration reference, quoted back to us over the phone. */
.reference-code {
  font-size: 1.15rem; letter-spacing: .06em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.prose { line-height: 1.75; }
.prose img { border-radius: var(--radius-sm); }
/* News as a grid of cards, like the past-events grid: three per line on a
   wide screen, two on a middling one, one only on a phone. */
.news-grid { display: grid; gap: var(--gap); grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 64rem) { .news-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 34rem) { .news-grid { grid-template-columns: 1fr; } }
.news-grid > .card { margin-bottom: 0; }
.news-grid .news-image img, .news-grid .news-video { max-width: 100%; }

.news-image { margin: 0 0 var(--gap); }
.news-image img { max-width: 340px; border-radius: var(--radius-sm); }
/* A news video sits in the same column as the copy, so it is held to the width
   a single player wants rather than filling a wide card. */
.news-video { margin: 0 0 var(--gap); max-width: 560px; }
.prose h2, .prose h3 { margin-top: 1.5rem; }

/* Two-column content blocks inside stored copy.
   Several pages came across from the old site carrying its Bootstrap grid —
   Quick Draw Poker is a picture beside a list of rules — and with nothing
   answering to .row the picture stacked above the text at full width, which is
   why it looked enormous on a desktop. These rules give that markup the layout
   it was written for without dragging a grid framework back in: the columns
   size themselves and fold to one on a narrow screen. Content authored from
   now on can use the same class names. */
.prose .row {
  display: grid; gap: var(--gap); align-items: center;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}
.prose .row > * { min-width: 0; }
.prose .row > :last-child { margin-bottom: 0; }
/* Half a 1200px page is still a big picture; hold it to something that sits
   comfortably beside its text rather than dwarfing it. */
.prose .row img { max-width: 420px; margin: 0 auto; display: block; }
.prose table { width: 100%; border-collapse: collapse; margin-bottom: 1rem; }
.prose th, .prose td { border: 1px solid var(--line); padding: .5rem .6rem; text-align: left; }
.prose th { background: var(--paper); }
/* Stored content can contain wide tables; keep them from breaking the page. */
.prose { overflow-x: auto; }

.section-title {
  color: var(--white); font-family: var(--font-display); font-style: italic;
  font-size: 2rem; letter-spacing: 1px;
  margin: var(--gap-lg) 0 var(--gap); text-shadow: 2px 2px 5px rgba(0, 0, 0, .7);
}

.text-center { text-align: center; }
.text-muted { color: var(--ink-muted); }
/* Not below 1rem anywhere. "Small print" that cannot be read is not small
   print, it is missing print. */
.text-small { font-size: 1rem; }
.text-danger { color: var(--red-dark); }
.text-success { color: var(--green-dark); }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: .5rem; } .mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; }
.nowrap { white-space: nowrap; }

/* --- Hero video --------------------------------------------------------- */
.hero {
  position: relative; height: min(52vh, 30rem); min-height: 18rem;
  background: var(--black); overflow: hidden; border-radius: var(--radius);
  margin-bottom: var(--gap);
}
.hero video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.hero-overlay {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, .35), rgba(0, 0, 0, .1) 45%, rgba(0, 0, 0, .55));
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  padding: var(--gap); text-align: center;
}
.hero-overlay h1 {
  color: var(--white); font-family: var(--font-display); letter-spacing: 1px;
  font-size: clamp(1.6rem, 5.5vw, 3.2rem); text-shadow: 3px 3px 8px rgba(0, 0, 0, .85);
}

/* --- Buttons ------------------------------------------------------------ */
.btn {
  /* min-height, not just padding: a 44px target is the size a finger can hit
     reliably, and every button on the site clears it. */
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 2.75rem; padding: .6rem 1.2rem;
  border: 0; border-radius: var(--radius-sm); cursor: pointer;
  font: 700 1.0625rem/1.3 inherit; text-align: center; text-decoration: none;
  transition: background var(--ease), transform var(--ease), box-shadow var(--ease);
}
.btn:hover { transform: translateY(-1px); box-shadow: var(--shadow-soft); text-decoration: none; }
.btn:active { transform: translateY(0); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .55; cursor: not-allowed; transform: none; }
.btn-primary { background: var(--green); color: var(--white); }
.btn-primary:hover { background: var(--green-dark); color: var(--white); }
.btn-register { background: var(--red); color: var(--white); }
.btn-register:hover { background: var(--red-dark); color: var(--white); }
.btn-secondary { background: var(--grey-700); color: var(--white); }
.btn-secondary:hover { background: var(--grey-900); color: var(--white); }
.btn-outline { background: transparent; color: var(--ink); border: 2px solid var(--line); }
.btn-outline:hover { border-color: var(--ink-muted); color: var(--ink); }
.btn-block { display: block; width: 100%; }
.btn-lg { min-height: 3.25rem; padding: .9rem 1.6rem; font-size: 1.2rem; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--gap-sm); }
.btn-row-center { justify-content: center; }

/* --- Event cards --------------------------------------------------------
   Cards in a grid are made the same height and their contents centred, so a
   row reads as a row. Two things did the damage before: event logos arrive at
   whatever size and aspect the designer gave them, so a tall one pushed its
   card far past its neighbours; and the buttons sat directly under copy of
   varying length, so they landed at a different height in every card.

   The picture gets a fixed 16:9 box and is contained inside it — never
   cropped, never stretched, and the same height whatever it started as. The
   button row is pushed to the bottom with margin-top:auto, so the buttons line
   up across the row no matter how much text is above them.               */
.event-card { display: flex; flex-direction: column; height: 100%; }
.event-media {
  position: relative; display: block; border-radius: var(--radius-sm); overflow: hidden;
  /* The fixed ratio letterboxes a logo that is not 16:9, so the box needs a
     colour of its own — before it had one, the card's white simply showed
     through. White is what that was, and what the logos are drawn against. */
  aspect-ratio: 16 / 9; background: var(--white);
}
.event-media img { width: 100%; height: 100%; display: block; object-fit: contain; }
.event-media.is-sold-out img { filter: grayscale(65%) brightness(.72); }
/* The buttons are the last thing in the card, so this is what aligns them. */
.event-card .btn-row { margin-top: auto; }
/* Anything after the buttons — a closed reason, a waiting-list line — must not
   re-introduce the gap that margin-top:auto just removed. */
.event-card .btn-row ~ * { margin-top: .5rem; }
.sold-out-banner {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-12deg);
  background: rgba(190, 0, 0, .82); color: var(--white);
  font-weight: 800; font-size: clamp(1.2rem, 4.5vw, 2.4rem); letter-spacing: .08em;
  padding: .1em .35em; border: 4px solid var(--white);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .45);
  text-transform: uppercase; white-space: nowrap; pointer-events: none;
}
/* Sold out, shown across the Register button rather than the logo. The button
   stays in the card so the layout keeps its shape, but it is inert. */
.btn-sold-out-wrap { position: relative; display: inline-flex; }
.btn-sold-out-wrap .btn.is-disabled { opacity: .55; pointer-events: none; }
.sold-out-banner.sold-out-on-button {
  font-size: 1.05rem; border-width: 2px; padding: .05em .4em;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .4);
}
.event-meta { margin: var(--gap-sm) 0; }
.event-meta dt { font-weight: 600; color: var(--ink-soft); float: left; margin-right: .4rem; }
.event-meta dd { margin: 0 0 .25rem; }
.event-name { font-size: 1.2rem; margin-bottom: .35rem; }
.spaces-left { font-size: .875rem; color: var(--amber); font-weight: 600; }

/* Centred variant, used by every event card on the home and events pages. The
   meta list floats its labels by default, so centring needs the label back in
   flow with a line break after each value. */
.event-centered { text-align: center; }
.event-centered .event-meta dt { float: none; display: inline; margin-right: .3rem; }
.event-centered .event-meta dd { display: inline; margin: 0; }
.event-centered .event-meta dd::after { content: "\A"; white-space: pre; }
.event-centered .btn-row { justify-content: center; }

/* The grid rows stretch so every card fills the tallest cell in its row; a
   past-events grid of three is narrower, so its pictures get less height. */
.grid-2 > .event-card, .grid-3 > .event-card { align-self: stretch; }
.grid-3 .event-media { aspect-ratio: 4 / 3; }

/* --- Alerts ------------------------------------------------------------- */
.alert { padding: .8rem 1rem; border-radius: var(--radius-sm); border: 1px solid; margin-bottom: var(--gap); }
.alert > :last-child { margin-bottom: 0; }
.alert-info { background: var(--info-bg); border-color: var(--info-line); color: #143a63; }
.alert-warning { background: var(--amber-bg); border-color: var(--amber-line); color: #6b4106; }
.alert-danger { background: var(--danger-bg); border-color: var(--danger-line); color: #7d1616; }
.alert-success { background: var(--success-bg); border-color: var(--success-line); color: #13512a; }
.alert-urgent {
  background: var(--danger-bg); border: 2px solid var(--red); color: #7d1616; font-weight: 600;
}

/* --- Forms -------------------------------------------------------------- */
.form-section { border: 1px solid var(--line); border-radius: var(--radius); padding: var(--gap); margin-bottom: var(--gap); }
.form-section > legend, .form-section > h3 {
  font-size: 1.1rem; font-weight: 700; padding: 0; margin-bottom: .5rem;
}
/* A legend normally sits ON the fieldset's border line, half above the box —
   on a .card fieldset that puts the top half of the heading outside the white
   background, where it is clipped against the page. Floating a legend opts it
   out of that special placement and lays it out as an ordinary heading inside
   the card; the width and the clear keep the following content below it. */
.form-section > legend { float: left; width: 100%; }
.form-section > legend + * { clear: both; }
.field { margin-bottom: var(--gap); }
.field label, .field-label { display: block; font-weight: 600; margin-bottom: .3rem; color: var(--ink-soft); }
.required-marker { color: var(--red); }

input[type="text"], input[type="email"], input[type="tel"], input[type="number"],
input[type="password"], input[type="search"], input[type="date"], input[type="url"],
select, textarea {
  width: 100%; padding: .7rem .75rem; min-height: 3rem;
  border: 2px solid #8d8d96; border-radius: var(--radius-sm);
  font: inherit; color: var(--ink); background: var(--white);
}
textarea { min-height: 8rem; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--red); box-shadow: var(--focus); outline: none; }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] {
  border-color: var(--red); background: #fffafa;
}
.field-error { display: block; color: var(--red-dark); font-size: 1rem; font-weight: 600; margin-top: .25rem; }
.field-hint { display: block; color: var(--ink-muted); font-size: 1rem; margin-top: .25rem; }

/* Card-number field: the brand badge sits inside the input's right edge once
   site.js has a complete, checksum-valid number. Drawn with CSS text rather
   than image files, so there is no artwork to host and it prints in any
   theme; the empty span costs nothing while hidden. */
.card-number-wrap { position: relative; display: block; }
.card-number-wrap input { padding-right: 6.5rem; }
.card-brand {
  position: absolute; right: .55rem; top: 50%; transform: translateY(-50%);
  font-weight: 800; font-size: .8rem; letter-spacing: .05em; line-height: 1;
  padding: .3rem .5rem; border-radius: 4px; color: var(--white);
  pointer-events: none; white-space: nowrap;
}
.card-brand-visa       { background: #1434cb; }
.card-brand-visa::after       { content: 'VISA'; }
.card-brand-mastercard { background: #eb001b; }
.card-brand-mastercard::after { content: 'MASTERCARD'; }
.card-brand-amex       { background: #2e77bc; }
.card-brand-amex::after       { content: 'AMEX'; }
.card-brand-discover   { background: #e55c20; }
.card-brand-discover::after   { content: 'DISCOVER'; }

.check-row { display: flex; align-items: flex-start; gap: .6rem; margin-bottom: .6rem; }
/* Bigger than the browser default. A small checkbox is a small target, and the
   people filling in these forms are often doing it one-handed on a trail. */
.check-row input[type="checkbox"], .check-row input[type="radio"] {
  width: 1.4rem; height: 1.4rem; margin: .15rem 0 0; flex: 0 0 auto; accent-color: var(--red);
}
.check-row label { font-weight: 400; margin: 0; color: var(--ink); }

.radio-cards { display: grid; gap: var(--gap-sm); }
.radio-card {
  display: flex; gap: .6rem; align-items: flex-start;
  border: 2px solid var(--line); border-radius: var(--radius-sm); padding: .8rem; cursor: pointer;
}
.radio-card:hover { border-color: var(--ink-muted); }
.radio-card input:checked ~ .radio-card-body { color: var(--ink); }
.radio-card:has(input:checked) { border-color: var(--green); background: var(--success-bg); }
.radio-card-title { font-weight: 700; display: block; }

/* The honeypot field: present in the DOM, never shown, never reachable by
   keyboard. A bot that fills every input gets caught; a screen reader user
   never encounters it. */
.hp-field {
  position: absolute !important; left: -9999px !important;
  width: 1px; height: 1px; overflow: hidden;
}

/* --- Order summary ------------------------------------------------------ */
.summary-table { width: 100%; border-collapse: collapse; }
.summary-table td { padding: .5rem .3rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.summary-table .amount { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.summary-table .credit .amount { color: var(--green-dark); }
.summary-detail { display: block; font-size: .85rem; color: var(--ink-muted); }
.summary-total td { border-top: 2px solid var(--ink); border-bottom: 0; font-size: 1.2rem; font-weight: 700; padding-top: .8rem; }
.summary-note { background: var(--amber-bg); border: 1px solid var(--amber-line); border-radius: var(--radius-sm); padding: .7rem; margin-top: var(--gap); }

/* --- Tables ------------------------------------------------------------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table { width: 100%; border-collapse: collapse; font-size: .95rem; }
.table th, .table td { padding: .55rem .6rem; text-align: left; border-bottom: 1px solid var(--line); }
.table th { background: var(--paper); font-weight: 700; white-space: nowrap; }
.table tbody tr:hover { background: #fafafb; }
.table .amount { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* --- Sponsors ----------------------------------------------------------- */
/* No white panel behind a tier. These logos were drawn to sit on black — most
   of them are white artwork with no background of their own — so a white card
   under them either washed them out or boxed each one in its own dark chip on
   a light field. The tier now sits straight on the page's black, and the chips
   disappear into it. */
.sponsor-tier { margin-bottom: var(--gap-lg); }
.sponsor-tier-header {
  color: var(--white); font-family: var(--font-display);
  font-size: 1.5rem; letter-spacing: 1.5px;
  margin: 0 0 var(--gap); padding-bottom: .4rem;
  border-bottom: 2px solid var(--red);
  text-shadow: 2px 2px 5px rgba(0, 0, 0, .7);
}
.sponsor-grid { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: center; justify-content: center; }
.sponsor-item {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--black); border-radius: var(--radius-sm); padding: var(--gap-sm);
}
.sponsor-item:hover { box-shadow: var(--shadow-soft); }
/* One fixed box for every logo, whatever its tier. The tiers used to step the
   sizes down (200px → 125px), which read less as a hierarchy and more as a
   page that could not make up its mind; the tier headings already carry the
   ranking. Contained, never cropped or stretched. */
.sponsor-item img { width: 180px; height: 100px; object-fit: contain; }

/* --- Gallery ------------------------------------------------------------ */
.photo-grid { display: grid; gap: .5rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr)); }
.photo-grid a { display: block; border-radius: var(--radius-sm); overflow: hidden; line-height: 0; }
.photo-grid img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform var(--ease), filter var(--ease); }
.photo-grid a:hover img { transform: scale(1.04); filter: brightness(1.08); }

/* Lightbox, ~30 lines of self-hosted CSS+JS instead of a CDN library. */
.lightbox {
  position: fixed; inset: 0; z-index: 500;
  background: rgba(0, 0, 0, .92);
  display: none; align-items: center; justify-content: center; padding: 1rem;
}
.lightbox[data-open="true"] { display: flex; }
.lightbox img { max-width: 96vw; max-height: 88vh; object-fit: contain; border-radius: var(--radius-sm); }
.lightbox-close, .lightbox-prev, .lightbox-next {
  position: absolute; background: rgba(255, 255, 255, .12); color: var(--white);
  border: 0; border-radius: 50%; width: 3rem; height: 3rem;
  font-size: 1.5rem; cursor: pointer; line-height: 1;
}
.lightbox-close { top: 1rem; right: 1rem; }
.lightbox-prev { left: 1rem; top: 50%; transform: translateY(-50%); }
.lightbox-next { right: 1rem; top: 50%; transform: translateY(-50%); }
.lightbox-close:hover, .lightbox-prev:hover, .lightbox-next:hover { background: rgba(255, 255, 255, .28); }
.lightbox-caption { position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); color: #ddd; font-size: .9rem; }

/* --- Video embeds ------------------------------------------------------- */
.video-grid { display: grid; gap: var(--gap); grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.video-frame { position: relative; aspect-ratio: 16 / 9; background: var(--black); border-radius: var(--radius-sm); overflow: hidden; }
.video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Click-to-load: no third-party frame until the visitor asks for it, so an
   embed cannot track someone who never pressed play. */
.video-facade { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; padding: 0; cursor: pointer; background: var(--black); }
.video-facade img { width: 100%; height: 100%; object-fit: cover; }
.video-facade::after {
  content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 4.5rem; height: 4.5rem; border-radius: 50%;
  background: rgba(224, 21, 21, .92) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E") center/2rem no-repeat;
}
.video-facade:hover::after { background-color: var(--red-bright); }

/* --- Image maps --------------------------------------------------------- */
.image-map-wrap { position: relative; display: block; }
.image-map-wrap img { display: block; width: 100%; }
/* Overlay anchors positioned in percentages, so the hot-spots scale with the
   image. A classic <map>/<area> uses fixed pixels and misaligns on mobile. */
.image-map-area {
  position: absolute; display: block; text-decoration: none;
  border: 2px solid transparent; border-radius: 4px;
  transition: background var(--ease), border-color var(--ease);
}
.image-map-area:hover, .image-map-area:focus-visible {
  background: rgba(224, 21, 21, .22); border-color: var(--red-bright);
}
.image-map-area .visually-hidden { color: transparent; }

/* --- Social links ------------------------------------------------------- */
.social-row { display: flex; flex-wrap: wrap; gap: var(--gap-sm); justify-content: center; }
.social-row a { display: inline-flex; transition: transform var(--ease); border-radius: 50%; }
.social-row a:hover { transform: translateY(-4px); }
.social-row svg { width: 56px; height: 56px; }

/* --- Story index -------------------------------------------------------- */
.story-index { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1rem 1.2rem; margin-bottom: 1.5rem; }
.story-index ul { margin: 0; padding-left: 1.2rem; }
.story-index li { padding: .15rem 0; }
.back-to-top { font-size: .875rem; }

/* --- Steps indicator ---------------------------------------------------- */
.steps { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; margin: 0 0 var(--gap); padding: 0; }
.steps li {
  flex: 1 1 8rem; padding: .5rem .7rem; border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .1); color: rgba(255, 255, 255, .7);
  font-size: .875rem; font-weight: 600; text-align: center;
}
.steps li[aria-current="step"] { background: var(--red); color: var(--white); }
.steps li.is-done { background: rgba(28, 124, 61, .85); color: var(--white); }

/* --- Loading overlay ---------------------------------------------------- */
.loading-overlay {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(0, 0, 0, .55);
  display: none; align-items: center; justify-content: center;
}
.loading-overlay[data-open="true"] { display: flex; }
.loading-box { background: var(--white); border-radius: var(--radius); padding: 1.5rem 2rem; text-align: center; box-shadow: var(--shadow-lift); }
.spinner {
  width: 2.5rem; height: 2.5rem; margin: 0 auto .7rem;
  border: 4px solid var(--line); border-top-color: var(--red);
  border-radius: 50%; animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto; }
  .spinner { animation: none; border-top-color: var(--line); }
}

/* --- Code checker feedback --------------------------------------------- */
.code-row { display: flex; gap: var(--gap-sm); align-items: flex-start; }
.code-row input { flex: 1 1 auto; }
.code-row .btn { flex: 0 0 auto; }
.code-feedback { display: block; margin-top: .35rem; font-size: .9rem; font-weight: 600; }
.code-feedback.is-ok { color: var(--green-dark); }
.code-feedback.is-error { color: var(--red-dark); }

/* --- Footer ------------------------------------------------------------- */
.site-footer {
  background: linear-gradient(135deg, var(--black) 0%, var(--grey-700) 100%);
  color: #cfcfd4; margin-top: auto; padding: var(--gap-lg) var(--gap);
}
.footer-inner { max-width: var(--measure); margin: 0 auto; text-align: center; font-size: .85rem; }
.footer-legal a { color: #f0b6b6; }
.footer-legal a:hover { color: var(--red-bright); }
.footer-legal { color: #8f8f96; line-height: 1.6; max-width: 60rem; margin: var(--gap) auto 0; }

/* --- Responsive nav ----------------------------------------------------- */
@media (max-width: 78rem) {
  .nav-toggle { display: block; }
  .nav-menu { display: none; flex-basis: 100%; margin-left: 0; }
  .nav-menu[data-open="true"] { display: block; }
  .nav-inner { flex-wrap: wrap; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; padding-top: var(--gap-sm); }
  .nav-list > li { border-top: 1px solid rgba(255, 255, 255, .1); }
  .nav-list a, .submenu-toggle { padding: .75rem .6rem; width: 100%; text-align: left; }
  .submenu { position: static; min-width: 0; box-shadow: none; background: rgba(0, 0, 0, .25); margin: 0 0 .4rem; }
  .has-submenu:hover > .submenu { display: none; }
  .submenu[data-open="true"] { display: block; }
}

/* --- Print (check-in lists and receipts) ------------------------------- */
@media print {
  body { background: var(--white); color: #000; }
  .site-nav, .site-footer, .btn, .nav-toggle, .skip-link { display: none !important; }
  .card { box-shadow: none; border: 1px solid #ccc; page-break-inside: avoid; }
  a { color: #000; text-decoration: none; }
}
