/* ===== Design tokens =====
   Shared colors, fonts, and reusable values, referenced throughout this file
   as var(--name). Change a value here to update it site-wide instead of
   hunting down every place it's used. */
:root {
  --red: #cf2e2e;
  --red-dark: #a51f1f;
  --black: #111111;
  --near-black: #1a1a1a;
  --charcoal: #262626;
  --gray: #6b6b6b;
  --light-gray: #f4f4f4;
  --border: #e5e5e5;
  --white: #ffffff;
  --font-body: 'Roboto', sans-serif;
  --font-display: 'Bebas Neue', sans-serif;
  --radius: 4px;
  --shadow: 0 2px 10px rgba(0,0,0,0.08);
  --shadow-lg: 0 10px 30px rgba(0,0,0,0.25);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; } /* smooth-scrolls to in-page anchors, e.g. nav links to #events */

body {
  margin: 0;
  font-family: var(--font-body);
  color: #333;
  background: var(--white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

/* Centered content wrapper used inside every section — caps line width on
   large screens and adds side padding on small ones. */
.container {
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 24px;
}

a { color: inherit; text-decoration: none; }

ul { list-style: none; margin: 0; padding: 0; }

/* ===== Buttons =====
   Base .btn class plus color/size variants (.btn-red, .btn-outline, .btn-sm)
   that get combined on the element, e.g. class="btn btn-red btn-sm". */
.btn {
  display: inline-block;
  padding: 12px 26px;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  border-radius: var(--radius);
  border: 2px solid transparent;
  cursor: pointer;
  transition: all .2s ease;
}
.btn-red { background: var(--red); color: var(--white); }
.btn-red:hover { background: var(--red-dark); }
.btn-outline { background: transparent; border-color: var(--black); color: var(--black); }
.btn-outline:hover { background: var(--black); color: var(--white); }
.btn-sm { padding: 8px 18px; font-size: 12px; }
.btn.disabled { opacity: .5; pointer-events: none; }

.center-cta { text-align: center; margin-top: 34px; }

/* ===== Top utility bar =====
   The thin black strip above the main header (social icons left, note
   center, button right) — three-column grid keeps the center note truly
   centered regardless of how wide the side content is. */
.topbar {
  background: var(--black);
  color: #ccc;
  font-size: 14px;
}
.topbar-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 8px 20px;
  gap: 14px;
}
.topbar-social { display: flex; gap: 14px; }
.topbar-social a { color: #ccc; transition: color .2s; }
.topbar-social a:hover { color: var(--red); }
.topbar-note { letter-spacing: .04em; text-align: center; }
.topbar-inner .btn { justify-self: end; }

/* ===== Header / Nav =====
   The sticky black bar with the Crossroads logo, nav links, and Register
   button. On mobile this collapses into a hamburger menu — see .nav-toggle
   below and the .main-nav overrides in the responsive section at the bottom
   of this file. */
.site-header {
  background: var(--near-black);
  border-bottom: 3px solid var(--red);
  position: sticky; /* stays pinned to the top of the viewport while scrolling */
  top: 0;
  z-index: 100;
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 20px;
}
.brand { display: flex; align-items: center; color: var(--white); }
.brand-logo { height: 58px; width: auto; display: block; }
/* align-items: center here is what keeps the logo, plain nav links, and the
   taller Register button (which has extra padding) all vertically centered
   on the same line instead of stretching to different heights. */
.main-nav { display: flex; align-items: center; gap: 28px; }
.main-nav a {
  color: #ddd;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
  transition: border-color .2s, color .2s;
}
.main-nav a:hover { color: var(--white); border-color: var(--red); }
.main-nav a.nav-register-btn,
.main-nav a.nav-register-btn:hover {
  color: var(--white);
  border-bottom: none;
  padding: 8px 18px;
}
.main-nav a.nav-register-btn:hover { background: var(--red-dark); }
/* Hamburger button — hidden on desktop; toggled visible at the 720px
   breakpoint below. Click handler that toggles .main-nav.open lives in
   script.js. */
.nav-toggle {
  display: none;
  background: none;
  border: none;
  color: var(--white);
  font-size: 22px;
  cursor: pointer;
}

/* ===== Hero =====
   The full-width dark banner at the top of the homepage with the big logo,
   event dates, registration banner, and countdown timer. */
.hero {
  position: relative;
  min-height: 640px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--white);
  background:
    radial-gradient(circle at 30% 20%, rgba(207,46,46,.18), transparent 55%),
    repeating-linear-gradient(60deg, rgba(255,255,255,.035) 0 2px, transparent 2px 34px),
    repeating-linear-gradient(-60deg, rgba(255,255,255,.035) 0 2px, transparent 2px 34px),
    linear-gradient(180deg, #0c0c0c 0%, #1c1c1c 100%);
  overflow: hidden;
}
/* Darkening gradient laid over the hero's textured background so the white
   text/logo stays readable regardless of the background pattern underneath. */
.hero-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.75) 100%);
}
.hero-content { position: relative; padding: 80px 20px; }
.hero-eyebrow {
  letter-spacing: .25em;
  font-size: 13px;
  font-weight: 700;
  color: var(--red);
  margin-bottom: 18px;
}
.hero-title {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
}
.hero-logo {
  height: clamp(90px, 20vw, 220px);
  width: auto;
  display: block;
  filter: drop-shadow(0 4px 14px rgba(0,0,0,.5));
}
.hero-dates {
  font-size: 17px;
  letter-spacing: .08em;
  margin: 16px 0 30px;
  color: #ddd;
}
.hero-banner-note {
  display: inline-block;
  background: rgba(207,46,46,.15);
  border: 1px solid var(--red);
  color: #ffb3b3;
  padding: 8px 18px;
  border-radius: 30px;
  font-size: 12px;
  letter-spacing: .05em;
  margin-bottom: 40px;
}
.hero-banner-note i { margin-right: 6px; }

/* Days/Hours/Minutes/Seconds countdown boxes. The actual numbers (#cd-days,
   #cd-hours, #cd-mins, #cd-secs) are written into .cd-num elements by
   updateCountdown() in script.js, once per second. */
.countdown { display: flex; justify-content: center; gap: 18px; flex-wrap: wrap; }
.countdown-box {
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.15);
  border-radius: var(--radius);
  padding: 16px 22px;
  min-width: 90px;
}
.cd-num {
  display: block;
  font-family: var(--font-display);
  font-size: 40px;
  color: var(--red);
  line-height: 1;
}
.cd-label {
  display: block;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin-top: 6px;
  color: #ccc;
}

/* ===== Sections =====
   Generic layout classes reused by every content section on the page
   (About, Events, Gallery, Sponsors, Contact, etc). */
.section { padding: 80px 0; }
.section-title {
  font-family: var(--font-display);
  font-size: 38px;
  letter-spacing: .04em;
  text-align: center;
  margin: 0 0 10px;
  position: relative;
  padding-bottom: 18px;
}
/* The short red underline beneath every section heading — a generated
   element rather than a border, so it can be centered independently of the
   heading text's own width. */
.section-title::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 60px;
  height: 3px;
  background: var(--red);
}
.section-title.light { color: var(--white); }
.section-intro {
  max-width: 760px;
  margin: 0 auto 40px;
  text-align: center;
  color: var(--gray);
}

/* ===== News grid =====
   Card layout for the "Latest News" cards (Facebook, hotel booking, key
   dates, etc) near the top of the homepage. */
.news-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 28px;
  margin-top: 46px;
}
.news-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform .2s, box-shadow .2s;
  flex: 1 1 320px;
  max-width: 380px;
}
.news-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.news-card-head {
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  color: var(--white);
}
/* Icon-header background color per news card type — pick the matching class
   for whatever kind of card you're adding (e.g. head-hotel for a booking
   card, head-dates for a schedule card). */
.head-facebook { background: #3b5998; }
.head-hotel { background: var(--red); }
.head-dates { background: var(--black); }
.head-dark { background: var(--charcoal); }
.head-app { background: #1d7a8c; }
.news-card-body { padding: 22px 24px 26px; }
.news-card-body h3 { font-size: 18px; margin: 0 0 8px; }
.news-meta {
  font-size: 12px;
  color: var(--gray);
  margin: 0 0 12px;
  letter-spacing: .03em;
}
.news-meta i { margin-right: 5px; color: var(--red); }
.news-card-body p:not(.news-meta) { color: #555; font-size: 14px; margin: 0 0 18px; }
.news-card-actions { display: flex; flex-wrap: wrap; gap: 10px; }
.news-card-actions .btn { padding: 8px 14px; }
.news-card-actions .btn i { margin-right: 5px; }

/* ===== Promo strip =====
   The thin solid-red bar of quick highlights (dates, location, etc) directly
   under the news cards. */
.promo-strip { background: var(--red); color: var(--white); }
.promo-inner {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 40px;
  padding: 18px 20px;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: .04em;
}
.promo-inner i { margin-right: 8px; }

/* ===== About =====
   Two-column "About Crossroads" section: descriptive copy on one side,
   icon + stat rows (years running, players, etc) on the other. */
.about-section { background: var(--light-gray); }
.about-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 60px;
  margin-top: 46px;
  align-items: start;
}
.about-kicker {
  font-family: var(--font-display);
  color: var(--red);
  font-size: 20px;
  letter-spacing: .08em;
  margin-top: 0;
}
.about-copy p { color: #444; }
.about-stats { display: flex; flex-direction: column; gap: 30px; }
.about-stat { display: flex; gap: 18px; }
.about-stat i { font-size: 26px; color: var(--red); margin-top: 4px; }
.about-stat h4 { margin: 0 0 6px; font-size: 15px; letter-spacing: .04em; text-transform: uppercase; }
.about-stat p { margin: 0; color: #555; font-size: 14px; }

/* ===== Associated GTs =====
   Cards linking out to other, non-Crossroads grand tournaments the site
   promotes (dark diagonal-striped background to visually separate this
   section from the plain white ones around it). */
.associated-section {
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.04) 0 2px, transparent 2px 30px),
    linear-gradient(120deg, #1a1a1a, #333);
}
.associated-section .section-intro { color: #ccc; }
.associated-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
  margin-top: 46px;
}
.associated-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 26px 24px;
  flex: 1 1 260px;
  max-width: 300px;
  display: flex;
  flex-direction: column;
  transition: transform .2s, box-shadow .2s;
}
.associated-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.associated-card h4 { margin: 0 0 8px; font-size: 17px; }
.associated-card-meta { font-size: 12px; color: var(--gray); margin: 0 0 12px; }
.associated-card-meta i { margin-right: 5px; color: var(--red); }
.associated-card p:not(.associated-card-meta) { font-size: 13px; color: #555; margin: 0 0 16px; }
.associated-card .btn { margin-top: auto; align-self: flex-start; }

/* ===== Events =====
   The clickable event cards (Kings of War, BattleTech, etc) on the
   homepage. Clicking one opens the event modal below via
   openEventModal() in script.js — see EVENT_INFO there for each event's
   content. */
.events-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 28px;
  margin-top: 46px;
}
.event-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  flex: 1 1 300px;
  max-width: 400px;
  transition: transform .2s, box-shadow .2s;
  cursor: pointer;
}
.event-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.event-card:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.event-card-img {
  width: 100%;
  height: 150px;
  display: block;
  object-fit: cover;
  background: var(--charcoal);
}
.event-card-body { padding: 22px 24px 26px; }
.event-card-body h3 { margin: 0 0 8px; font-size: 18px; }
.event-card-body p { font-size: 13px; color: #555; margin: 0 0 18px; }

/* ===== Event modal =====
   The popup shown when an event card, hotel link, or photo-gallery trigger
   is clicked. All of these modals share this same overlay/box/close-button
   structure (see .hotel-modal / .photo-modal size variants below); the
   open/close logic and content live in script.js (openEventModal(),
   closeEventModal(), setupSimpleModal()). */
/* Added to <body> while any modal is open, to stop the page behind it from
   scrolling. */
body.modal-open { overflow: hidden; }
.event-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.75);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transition: opacity .25s ease; /* fades in/out; visibility avoids the invisible overlay blocking clicks when closed */
}
.event-modal-overlay.open { opacity: 1; visibility: visible; }
.event-modal {
  background: var(--white);
  border-radius: var(--radius);
  width: 100%;
  max-width: 640px;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
  position: relative;
  transform: scale(.94) translateY(10px);
  transition: transform .25s ease;
}
.event-modal-overlay.open .event-modal { transform: scale(1) translateY(0); }
/* Size variants: the hotel-info popup is narrower (no hero image), the photo
   gallery popups are wider (need room for a photo grid). Both skip the hero
   image so their body gets extra top padding to clear the floating close
   button instead. */
.event-modal.hotel-modal { max-width: 480px; }
.event-modal.hotel-modal .event-modal-body { padding-top: 40px; }
.event-modal.photo-modal { max-width: 820px; }
.event-modal.photo-modal .event-modal-body { padding-top: 40px; }
.event-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,.55);
  color: var(--white);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .2s;
  z-index: 1;
}
.event-modal-close:hover { background: var(--red); }
.event-modal-img { width: 100%; height: 300px; object-fit: cover; display: block; background: var(--charcoal); }
.event-modal-body { padding: 32px; }
.event-modal-body h3 { font-family: var(--font-display); font-size: 30px; letter-spacing: .03em; margin: 0 0 16px; }
.event-modal-body p { color: #444; font-size: 15px; line-height: 1.7; margin: 0; }
.event-modal-body p.event-modal-event-desc { margin-top: 14px; }
.event-modal-facts {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
}
.event-modal-facts li { font-size: 14px; color: #444; line-height: 1.7; }
.event-modal-facts strong { color: var(--charcoal); }
/* "X of Y slots remaining" line. !important overrides the generic
   .event-modal-body p rule above it, since this is a <p> too but needs its
   own smaller/bolder styling. Text content and the .slots-low class (applied
   once 25% or fewer slots remain) are set by script.js. */
.event-modal-slots {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 20px !important;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-weight: 700;
  font-size: 13px !important;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--charcoal) !important;
}
.event-modal-slots i { color: var(--red); }
.event-modal-slots .slots-low { color: var(--red); }
.event-modal-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 20px; }
/* Container for the expandable participant list — toggled visible/hidden
   via the [hidden] attribute by the "Participants" button's click handler
   in script.js, not by a CSS class. */
.event-modal-participants {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
}
.event-modal-participants-status { color: #777 !important; font-size: 14px !important; font-style: italic; }
.event-modal-participants-status a { color: var(--red); }
.event-modal-participants-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 280px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.event-modal-participants-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  font-size: 14px;
  color: var(--charcoal);
  border-bottom: 1px solid var(--border);
}
.event-modal-participants-list li:last-child { border-bottom: none; }
.event-modal-participants-list li:not(.participants-header):nth-child(even) { background: var(--light-gray); }
/* Each row is a flex line of #, Name, (Team,) Status spans, rendered by
   renderParticipantsListHtml() in script.js. Name gets the flexible
   remaining space; # and Status are fixed-width. On narrow screens the
   mobile override further down (in the Responsive section) reorders these
   so Team drops to its own line instead of squeezing Name. */
.event-modal-participants-list .participant-num {
  flex: 0 0 24px;
  color: #999;
  font-size: 12px;
  font-weight: 700;
}
.event-modal-participants-list .participant-name { flex: 1 1 auto; font-weight: 600; }
.event-modal-participants-list .participant-team { flex: 0 0 auto; color: #777; font-size: 13px; }
.event-modal-participants-list .participant-paid {
  flex: 0 0 64px;
  text-align: right;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}
.event-modal-participants-list .is-paid { color: #1c8a4c; }
.event-modal-participants-list .is-pending { color: #b8860b; }
/* Column-label row ("# Name Team Status") — sticky so it stays visible at
   the top while the list scrolls inside its max-height container. */
.event-modal-participants-list li.participants-header {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--light-gray);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: #888;
}
.event-modal-participants-list li.participants-header .participant-name,
.event-modal-participants-list li.participants-header .participant-num { font-weight: 700; color: #888; }

/* ===== Stats banner =====
   The dark "Players / Events / Hotel" strip with big count-up numbers.
   Numbers start at 0 and animate up to each element's data-count value the
   first time it scrolls into view (see the IntersectionObserver in
   script.js). On phones this collapses to a tighter 3-column layout — see
   the 720px breakpoint in the Responsive section below. */
.stats-banner {
  position: relative;
  background:
    repeating-linear-gradient(60deg, rgba(255,255,255,.04) 0 2px, transparent 2px 34px),
    linear-gradient(180deg, #111 0%, #222 100%);
  color: var(--white);
  padding: 70px 0;
}
.stats-inner {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  text-align: center;
  gap: 20px;
}
.stat-num {
  display: block;
  font-family: var(--font-display);
  font-size: 52px;
  color: var(--red);
  line-height: 1;
}
.stat-label {
  display: block;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  margin-top: 8px;
  color: #ccc;
}

/* ===== Split section (rules / featured events) =====
   The dark call-out box(es) linking to rules packs / featured events.
   .split-box-solo is used when there's just one box to show full-width
   (larger heading/list text) instead of the normal side-by-side pair. */
.split-section { background: var(--light-gray); }
.split-grid {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}
.split-box {
  background: var(--black);
  color: var(--white);
  padding: 40px;
  border-radius: var(--radius);
}
.split-box h3 {
  font-family: var(--font-display);
  font-size: 26px;
  letter-spacing: .04em;
  margin: 0 0 18px;
  color: var(--red);
}
.split-quote { font-style: italic; color: #ddd; margin-bottom: 16px; }
.split-box p { color: #ccc; font-size: 14px; }
.split-box-solo {
  width: 100%;
  max-width: 1040px;
  padding: 72px 84px;
}
.split-box-solo h3 { font-size: 44px; margin-bottom: 32px; }
.featured-list li {
  padding: 0;
  border-bottom: 1px solid rgba(255,255,255,.1);
  font-size: 14px;
  color: #ddd;
}
.featured-list li:last-child { border-bottom: none; }
.featured-list i { color: var(--red); width: 22px; }
.featured-list a {
  display: block;
  padding: 10px 0;
  color: inherit;
  text-decoration: none;
  transition: color .2s;
}
.featured-list a:hover { color: var(--red); }
.split-box-solo .featured-list li { font-size: 21px; }
.split-box-solo .featured-list a { padding: 20px 0; }
.split-box-solo .featured-list i { font-size: 22px; width: 34px; }

/* ===== Gallery =====
   The homepage's single large "Photo Gallery" showcase tile — a plain photo
   tile (.gallery-photo), sized up via .gallery-showcase below instead of
   sitting in a multi-tile grid. Opens the combined photos modal (see
   #photosModalOverlay in index.html) when clicked. */
.gallery-tile {
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--white);
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-align: center;
  padding: 10px;
  font-weight: 700;
  position: relative;
  overflow: hidden;
  text-decoration: none;
  cursor: pointer;
  transition: transform .2s, box-shadow .2s;
}
.gallery-tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.gallery-tile::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0,0,0,.15);
}

.gallery-photo { padding: 0; }
.gallery-photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .3s;
}
.gallery-photo:hover img { transform: scale(1.06); }

/* Overrides .gallery-tile's default square aspect-ratio with a wide, fixed-
   height showcase block, capped and centered so it doesn't stretch edge to
   edge on very wide screens. */
.gallery-showcase {
  aspect-ratio: auto;
  height: 420px;
  max-width: 900px;
  margin: 40px auto 0;
}

/* ===== Photo lightbox modal =====
   The photo grid(s) shown inside the combined #photosModalOverlay. Clicking
   any image here opens it full-size in the separate "Image viewer" overlay
   defined further down (handled by the delegated click listener on
   .photo-lightbox-grid img in script.js). */
.photo-lightbox-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
}
.photo-lightbox-grid img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  cursor: zoom-in;
  transition: transform .2s;
}
.photo-lightbox-grid img:hover { transform: scale(1.03); }

/* ===== Image viewer (click-to-enlarge) =====
   Full-screen dark overlay showing one enlarged gallery photo at a time.
   Sits above the regular event modal (z-index 1100 vs 1000) so it can be
   opened on top of a photo-lightbox modal that's already open. Opened by
   openImageViewer() in script.js. */
.image-viewer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 50px;
  z-index: 1100;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease;
}
.image-viewer-overlay.open { opacity: 1; visibility: visible; }
.image-viewer-overlay img {
  max-width: 100%;
  max-height: 100%;
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}
.image-viewer-overlay .event-modal-close { position: fixed; top: 20px; right: 24px; }

/* ===== Sponsors =====
   Row of sponsor logo badges near the bottom of the homepage. */
.sponsors-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  margin-top: 40px;
}
.sponsor-badge {
  background: var(--near-black);
  border: 1px solid #2c2c2c;
  border-radius: var(--radius);
  padding: 26px 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 210px;
  height: 110px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color .2s, transform .2s;
}
.sponsor-badge:hover { border-color: var(--red); transform: translateY(-4px); }
.sponsor-badge img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* ===== Contact =====
   The contact form at the bottom of the homepage. Submits via Netlify Forms
   — see the JS comment block above contactForm in script.js for how that
   works and why it won't succeed outside of an actual Netlify deploy. */
.contact-section { background: var(--near-black); color: var(--white); }
.contact-form { max-width: 700px; margin: 40px auto 0; }
.form-row { display: flex; gap: 16px; margin-bottom: 16px; }
.form-field { flex: 1; }
.form-row input, .form-row textarea, .form-row select {
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--radius);
  border: 1px solid #444;
  background: #222;
  color: var(--white);
  font-family: var(--font-body);
  font-size: 14px;
}
.form-row input::placeholder, .form-row textarea::placeholder { color: #999; }
.form-row input:focus, .form-row textarea:focus, .form-row select:focus { outline: none; border-color: var(--red); }
/* appearance: none removes the browser's native dropdown arrow so this
   custom SVG chevron (a small inline data-URI image, avoiding an extra
   asset file) can be drawn in its place, matching the dark theme. */
.form-row select { appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='%23999'%3E%3Cpath d='M5.5 7.5l4.5 5 4.5-5h-9z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 18px;
  padding-right: 40px;
}
.form-row select option { background: #222; color: var(--white); }
/* Visually hides an element while keeping it readable to screen readers —
   standard "screen-reader only" pattern (used for the honeypot field's
   label; see .hidden-field below). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* Hides the Netlify Forms spam-bot honeypot field (name="bot-field" in
   index.html) — real visitors never see or fill it in, but simple spam bots
   that auto-fill every field will, letting Netlify silently discard the
   submission. */
.hidden-field { display: none; }
.form-note { margin-top: 14px; color: #7fd88f; font-size: 13px; min-height: 18px; }
.form-note.form-error { color: #ff8a8a; }
.contact-social { display: flex; justify-content: center; gap: 20px; margin-top: 40px; }
.contact-social a {
  width: 40px; height: 40px;
  border: 1px solid #444;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #ccc;
  transition: all .2s;
}
.contact-social a:hover { background: var(--red); border-color: var(--red); color: var(--white); }

/* ===== Footer =====
   The plain black copyright bar at the very bottom of every page. The
   year text is filled in by script.js so it never needs a manual yearly update. */
.site-footer {
  background: var(--black);
  color: #999;
  text-align: center;
  padding: 22px 0;
  font-size: 12px;
  letter-spacing: .03em;
}

/* ===== Rules document page =====
   Styling shared by the four standalone rules-pack pages (battletech-rules.
   html, firelock-rules.html, kings-of-war-rules.html, mordheim-rules.html).
   .rules-content in particular styles the #rulesDocContent block whose
   headings/paragraphs get replaced with live content pulled from the
   organizer's Google Doc — see rules-page.js and
   netlify/functions/rules-doc.js. */
.page-hero {
  position: relative;
  color: var(--white);
  text-align: center;
  padding: 70px 20px 56px;
  background:
    repeating-linear-gradient(60deg, rgba(255,255,255,.035) 0 2px, transparent 2px 34px),
    repeating-linear-gradient(-60deg, rgba(255,255,255,.035) 0 2px, transparent 2px 34px),
    linear-gradient(180deg, #0c0c0c 0%, #1c1c1c 100%);
}
.page-hero .back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: #ccc;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  text-decoration: none;
  margin-bottom: 22px;
  transition: color .2s;
}
.page-hero .back-link:hover { color: var(--white); }
.page-hero-title {
  font-family: var(--font-display);
  font-size: clamp(34px, 6vw, 60px);
  letter-spacing: .02em;
  margin: 6px 0 8px;
}
.page-hero-title span { color: var(--red); }
.page-hero-sub {
  color: #bbb;
  font-size: 14px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.rules-content { max-width: 820px; margin: 0 auto; }
.rules-toolbar { display: flex; justify-content: flex-end; margin-bottom: 24px; }
.rules-toolbar .btn i { margin-right: 6px; }
.rules-content h2 {
  font-family: var(--font-display);
  font-size: 28px;
  letter-spacing: .03em;
  margin: 48px 0 18px;
  padding-bottom: 10px;
  border-bottom: 2px solid var(--red);
}
.rules-content h2:first-child { margin-top: 0; }
.rules-content h3 {
  font-family: var(--font-display);
  font-size: 19px;
  letter-spacing: .03em;
  margin: 26px 0 10px;
  color: var(--charcoal);
}
.rules-content p { color: #444; font-size: 15px; line-height: 1.75; margin: 0 0 16px; }
.rules-content ul, .rules-content ol { color: #444; font-size: 15px; line-height: 1.75; margin: 0 0 16px; padding-left: 22px; }
.rules-content li { margin-bottom: 6px; }
.rules-content a { color: var(--red); text-decoration: underline; }
.rules-content a.btn { text-decoration: none; }
.rules-content a.btn-red { color: var(--white); }
.rules-content a.btn-outline { color: var(--black); }

.rules-facts { list-style: none; padding: 20px 24px; margin: 0 0 16px; background: var(--light-gray); border-radius: var(--radius); }
.rules-facts li { font-size: 15px; color: #333; margin-bottom: 8px; }
.rules-facts li:last-child { margin-bottom: 0; }
.rules-facts strong { color: var(--black); }

.rules-schedule { width: 100%; border-collapse: collapse; margin: 0 0 24px; font-size: 14px; }
.rules-schedule td { padding: 10px 14px; border-bottom: 1px solid var(--border); color: #444; }
.rules-schedule tr:last-child td { border-bottom: none; }
.rules-schedule td:first-child { white-space: nowrap; font-weight: 700; color: var(--black); width: 190px; }

.rules-example {
  background: var(--light-gray);
  border-left: 4px solid var(--red);
  border-radius: var(--radius);
  padding: 22px 26px;
  margin: 0 0 24px;
}
.rules-example h4 { font-family: var(--font-display); font-size: 16px; letter-spacing: .03em; margin: 0 0 12px; }
.rules-example ol, .rules-example ul { margin-bottom: 0; }

.back-to-top-cta { text-align: center; margin-top: 60px; }

/* ===== Responsive =====
   Overrides applied at two breakpoints, tablet (960px) and phone (720px).
   Keep new mobile-only tweaks in whichever of these two blocks already
   matches the width they need to kick in at, rather than adding new
   @media blocks, so all responsive behavior stays in one place. */
@media (max-width: 960px) {
  .about-grid { grid-template-columns: 1fr; }
  .gallery-showcase { height: 340px; }
  .stats-inner { grid-template-columns: repeat(2, 1fr); row-gap: 34px; }
  .split-box-solo { padding: 40px; }
  .split-box-solo h3 { font-size: 28px; }
}

@media (max-width: 720px) {
  /* Collapses the horizontal nav into a slide-down hamburger menu; opened by
     toggling .open via the #navToggle click handler in script.js. */
  .main-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--near-black);
    flex-direction: column;
    gap: 0;
    max-height: 0;
    overflow: hidden;
    transition: max-height .3s ease;
  }
  .main-nav.open { max-height: 460px; border-top: 1px solid #333; }
  .main-nav a { padding: 14px 20px; border-bottom: 1px solid #262626; width: 100%; }
  .main-nav a.nav-register-btn { padding: 14px 20px; text-align: center; }
  .nav-toggle { display: block; }
  .gallery-showcase { height: 260px; }
  .sponsor-badge { width: 160px; height: 90px; padding: 18px 20px; }
  .form-row { flex-direction: column; }
  .hero { min-height: 520px; }
  /* Shrinks the "SEPTEMBER 18TH – 20TH, 2026 • ELMIRA, NY" line enough to
     stay on one line even on narrow phones (tested down to 320px width),
     instead of wrapping "ELMIRA, NY" onto its own second line. */
  .hero-dates { font-size: 12px; letter-spacing: .03em; }

  /* Countdown boxes: shrink padding/font and disable wrapping so all four
     (Days/Hours/Minutes/Seconds) fit on one line instead of wrapping to a
     3-then-1 layout on narrow phones. */
  .countdown { flex-wrap: nowrap; gap: 8px; }
  .countdown-box { padding: 10px 4px; min-width: 0; flex: 1 1 0; }
  .cd-num { font-size: 26px; }
  .cd-label { font-size: 9px; margin-top: 4px; letter-spacing: .05em; }

  /* Stats banner: keep all 3 numbers on one row (overrides the 2-column
     tablet layout from the 960px breakpoint above, which left an awkward
     2-then-1 layout for this 3-item stat group on phones). */
  .stats-inner { grid-template-columns: repeat(3, 1fr); gap: 10px; row-gap: 0; }
  .stat-num { font-size: 34px; }
  .stat-label { font-size: 10px; margin-top: 4px; }

  /* Participants list: on the desktop layout, Team sits inline next to Name
     with a fixed width, which squeezed and wrapped long names on narrow
     screens. Here each row is allowed to wrap, and the `order` values push
     Team onto its own second line below Name/Status instead of fighting it
     for horizontal space. */
  .event-modal-participants-list li:not(.participants-header) {
    flex-wrap: wrap;
    row-gap: 2px;
  }
  .event-modal-participants-list li:not(.participants-header) .participant-num { order: 1; }
  .event-modal-participants-list li:not(.participants-header) .participant-name { order: 2; }
  .event-modal-participants-list li:not(.participants-header) .participant-paid { order: 3; }
  .event-modal-participants-list li:not(.participants-header) .participant-team {
    order: 4;
    flex: 1 1 100%; /* forces this element onto its own full-width line */
    padding-left: 34px; /* lines up under the name, past the # column */
    font-size: 12px;
  }
}

/* ===== PRINT =====
   Used when a visitor prints a rules page directly (e.g. Firelock's "Print"
   button, which has no external doc to link to). Strips chrome that doesn't
   belong on paper so only the rules content itself prints. */
@media print {
  .site-header, .rules-toolbar, .back-to-top-cta, .site-footer, .page-hero .back-link {
    display: none !important;
  }
}
