/* ═══════════════════════════════════════════════════════════════════════════
 Dinks & Drinks — shared stylesheet for the pickleball event series.

 Loaded by the series home (index.html), every event page in a dated
 subdirectory, and _template/event.html. It carries the EQ5 tokens and every
 component the series reuses: header, hero, photo strip, the Bea band, the
 team cards, session cards, the registration form, the success screen, the
 Equals 5 ad band and the footer.

 WHY A SHARED FILE IS SAFE HERE: this site is its own Cloudflare Pages project
 (eq5-events), rooted at events/ in the repo, and this file is a sibling of the
 pages that load it. Until 2026-08-13 the series was deployed inside the hub,
 where a shared stylesheet needed an argument — /assets/, /css/ and /js/ sat
 behind the Cloudflare Access catch-all, so a public page referencing them
 rendered unstyled for the public while looking right to whoever built it.
 There is no hub tree above this file any more, so that trap is gone; the rule
 that survives is simpler. Everything this site loads comes from inside
 events/, and nothing here may reference a hub path.

 PATHS: url() in a stylesheet resolves against the stylesheet, not the page.
 Images referenced here are siblings of this file, so they work from any
 depth. An event page setting its own image writes it relative to itself
 (../hero-bg.jpg) via the --hero-photo custom property.

 Companion: event.js — same directory, owns the session cards, the form and
 the success screen so an event page carries none of that markup.
 ═══════════════════════════════════════════════════════════════════════════ */

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

:root {
  /* EQ5 brand — matches hub/css/hub.css and the Brandbook */
  --navy:        #0A1020;
  --surface:     #272f46;
  --surface-2:   #253b62;
  --blue:        #3079E9;
  --cyan:        #00D3D3;
  --gradient:    linear-gradient(-28deg, #3079E9 8%, #00D3D3 88%);
  --muted:       #8a95b1;
  --faint:       #5d6884;
  --border:      rgba(255,255,255,0.10);
  --border-lit:  rgba(0,211,211,0.32);
  --tint:        rgba(0,211,211,0.08);
  --red:         #F87171;
}

html { scroll-behavior: smooth; }
body {
  background: var(--navy);
  color: #fff;
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: 16px;
  line-height: 1.5;
}
h1, h2, h3 { letter-spacing: -0.02em; font-weight: 800; line-height: 1.05; }
::placeholder { color: rgba(255,255,255,0.22) !important; }
input, textarea, button { font-family: inherit; }

.grad-text {
  background: var(--gradient);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* ── Decorative blobs ───────────────────────────────────────────────── */
.deco { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 0; }
.blob {
  position: absolute; border-radius: 50%;
  background: linear-gradient(180deg, #253b62 0, #492040 100%);
  filter: blur(80px); opacity: 0.6;
}

/* ── Header ─────────────────────────────────────────────────────────── */
/* Sticky so the CTA is reachable from anywhere on the page, not just the
   top. Translucent + blurred rather than solid, so the hero photograph still
   reads underneath it. */
.site-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  padding: 14px 40px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 30;
  background: rgba(10,16,32,.82);
  backdrop-filter: saturate(160%) blur(14px);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
}
.header-actions { display: flex; align-items: center; gap: 16px; }
.header-cta {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 24px; border-radius: 8px;
  background: var(--gradient); color: #fff; text-decoration: none;
  font-size: 14.5px; font-weight: 800; white-space: nowrap;
  box-shadow: 0 10px 26px rgba(0,211,211,.22);
  transition: filter .2s, transform .2s;
}
.header-cta:hover { filter: brightness(1.1); transform: translateY(-1px); }
/* The anchor points into the home screen, so the button is meaningless once
   the visitor is on the form or the confirmation. */
.site-header.cta-off .header-cta { display: none; }
@media (max-width: 720px) {
  .site-header { padding: 12px 18px; }
  .header-badge { display: none; }
  .header-cta { height: 40px; padding: 0 18px; font-size: 13.5px; }
}
.logo { display: flex; align-items: center; gap: 12px; }
.logo img { width: 34px; height: 34px; }
.logo-name { font-size: 13px; font-weight: 600; color: var(--muted); letter-spacing: 0.04em; }
.header-badge {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--cyan); background: var(--tint); border: 1px solid var(--border-lit);
  padding: 6px 14px; border-radius: 20px;
}
/* Quiet outlined sibling to .header-cta — the way back to the series home from
   an event page, which must never compete with that event's own CTA. */
.header-link {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 20px; border-radius: 8px;
  background: transparent; border: 1px solid rgba(255,255,255,.24);
  color: #fff; text-decoration: none;
  font-size: 14px; font-weight: 700; white-space: nowrap;
  transition: border-color .2s, background .2s, transform .2s;
}
.header-link:hover { border-color: var(--border-lit); background: var(--tint); transform: translateY(-1px); }
@media (max-width: 720px) {
  .header-link { height: 40px; padding: 0 14px; font-size: 13px; }
}

/* ── Screens ────────────────────────────────────────────────────────── */
.screen { display: none; position: relative; z-index: 1; }
.screen.active { display: block; }

/* ── Hero ───────────────────────────────────────────────────────────── */
/* Photographic backdrop behind the hero, supplied per event. The overlay is
   doing real work — these are bright daylight court shots with open sky across
   the top, and white text over one raw is unreadable. Never lighten the scrim
   without re-checking the headline against the brightest part of the photo.

   Whatever a page points --hero-photo at needs NO EXIF orientation tag: CSS
   background-image honours EXIF less reliably than <img>, so a rotated-with-tag
   photo lands on its side here while looking fine everywhere else.
   hero-bg.jpg has none. */
.pro-band, .home-inner { position: relative; z-index: 1; }
.hero-wrap {
  position: relative; z-index: 1; overflow: hidden;
  border-bottom: 1px solid var(--border);
}
/* The photo is per page, the scrim is not: each event sets --hero-photo (and
   optionally --hero-pos), and the two-stop gradient above it stays here so no
   page can accidentally ship a hero with white text on bare daylight. A page
   that sets nothing gets the flat navy background and still reads.

   url() in this file resolves against the stylesheet, not the page, so an
   event page one directory down writes url('../hero-bg.jpg'). */
.hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background-image:
    linear-gradient(180deg, rgba(10,16,32,.86) 0%, rgba(10,16,32,.72) 45%, rgba(10,16,32,.97) 100%),
    var(--hero-photo, none);
  background-size: cover;
  background-position: var(--hero-pos, center 42%);
  background-repeat: no-repeat;
}
.hero-wrap > .home-inner { position: relative; z-index: 1; }

.home-inner { max-width: 980px; margin: 0 auto; padding: 64px 24px 80px; }
.hero { text-align: center; margin-bottom: 52px; animation: fadeUp 0.7s ease both; }
.hero-title, .hero-sub { text-shadow: 0 2px 24px rgba(10,16,32,.8); }
/* --muted (#8a95b1) is tuned for flat navy and goes soft over the photo's
   bright patches. Lift it inside the hero only; everywhere else keeps the
   brand tone. */
.hero-wrap .hero-sub { color: #cdd6e8; }
.hero-badge {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--tint); border: 1px solid var(--border-lit);
  padding: 8px 18px; border-radius: 30px; margin-bottom: 26px;
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--cyan);
}
.hero-title { font-size: clamp(44px, 8vw, 82px); margin-bottom: 22px; font-weight: 900; }
.hero-sub { font-size: 18px; line-height: 1.65; color: var(--muted); max-width: 560px; margin: 0 auto; }
.hero-sub strong { color: #fff; font-weight: 600; }

/* Date band. The single fact most readers are scanning for, so it gets
   display weight rather than sitting in body copy. Kept in sync by hand with
   the LOCATIONS block below — this is the one place the date is written into
   the markup rather than rendered from config. */
.hero-date {
  margin: 34px auto 0; display: inline-block;
  padding: 18px 34px; border-radius: 18px;
  background: rgba(10,16,32,.42);
  border: 1px solid var(--border-lit);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.hero-date-main {
  font-size: clamp(24px, 4.2vw, 42px); font-weight: 900;
  letter-spacing: -0.02em; line-height: 1.05; color: #fff;
  text-shadow: 0 2px 24px rgba(10,16,32,.8);
}
.hero-date-sub {
  margin-top: 9px; font-size: clamp(13px, 1.7vw, 16px); font-weight: 600;
  letter-spacing: 0.03em; color: var(--cyan);
  text-shadow: 0 2px 18px rgba(10,16,32,.8);
}

/* The Reserve CTA lives in the sticky header, upper right — one button,
   always on screen, rather than a second copy competing with it here. */
.hero-cta-note {
  margin-top: 16px; font-size: 13px; font-weight: 600;
  color: #cdd6e8; letter-spacing: 0.02em;
  text-shadow: 0 2px 18px rgba(10,16,32,.8);
}
/* Post-event: the hero gets a real button rather than a note. The header CTA
   still points at the same place, but the recap is now the only thing to do
   on this page and it should not be reachable only from the top bar. */
/* flex + width:fit-content, not inline-flex: .hero-date above it is an
   inline-block, so an inline button flows onto the same line and lands off to
   its right instead of centred beneath it. */
.hero-cta-btn {
  display: flex; width: fit-content; align-items: center; gap: 9px;
  margin: 24px auto 0;
  height: 54px; padding: 0 34px; border-radius: 8px;
  background: var(--gradient); color: #fff; text-decoration: none;
  font-size: 16px; font-weight: 800; white-space: nowrap;
  box-shadow: 0 14px 38px rgba(0,211,211,.22);
  transition: filter .2s, transform .2s;
}
.hero-cta-btn:hover { filter: brightness(1.1); transform: translateY(-1px); }

/* ── Photo strip ────────────────────────────────────────────────────── */
.photo-strip {
  display: flex; justify-content: center; align-items: center;
  gap: 18px; flex-wrap: wrap; margin-bottom: 48px;
  animation: fadeUp 0.7s 0.15s ease both;
}
.photo { margin: 0; }
.photo img {
  width: 170px; height: 170px; border-radius: 50%;
  object-fit: cover; display: block;
  border: 3px solid var(--cyan);
  box-shadow: 0 16px 44px rgba(0,0,0,.28);
}
/* An empty strip (no photos added yet) must not leave a 48px gap. */
.photo-strip:empty { display: none; margin: 0; }

/* ── Bea feature ────────────────────────────────────────────────────── */
.pro-band {
  background: linear-gradient(180deg, rgba(37,59,98,.35), rgba(10,16,32,0));
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  margin-bottom: 52px;
}
.pro-inner { max-width: 980px; margin: 0 auto; padding: 52px 24px 56px; }
.pro-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 34px; align-items: center; }
@media (max-width: 780px) { .pro-grid { grid-template-columns: 1fr; gap: 26px; } }

.pro-label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: 10px;
}
.pro-name { font-size: 38px; margin-bottom: 6px; }
.pro-role { font-size: 14px; color: var(--faint); margin-bottom: 18px; }
.pro-body { font-size: 16px; color: var(--muted); line-height: 1.7; margin-bottom: 20px; }
.pro-body strong { color: #fff; font-weight: 600; }
.pro-creds { display: flex; gap: 9px; flex-wrap: wrap; }
.cred {
  font-size: 11.5px; font-weight: 600; color: var(--cyan);
  background: var(--tint); border: 1px solid var(--border-lit);
  padding: 6px 13px; border-radius: 20px; letter-spacing: 0.04em;
}

/* The tournament frame carries the argument; the standing portrait says
   "and here she is at one of ours". Landscape + portrait side by side,
   locked to one height so the pair reads as a unit. */
.pro-shots { display: grid; grid-template-columns: 1.55fr 1fr; gap: 12px; }
.pro-shots img {
  width: 100%; height: 300px; display: block; border-radius: 16px;
  object-fit: cover;
  border: 1px solid var(--border);
  box-shadow: 0 18px 50px rgba(0,0,0,.32);
}
@media (max-width: 780px) {
  .pro-shots { grid-template-columns: 1fr; }
  .pro-shots .side { display: none; }  /* one strong image beats two cramped ones */
}

/* ── Equals 5 ad ────────────────────────────────────────────────────
   Built from equals5.com's own vocabulary so it reads as a placement, not
   another section of this page: navy panel, blurred blob accents, one
   gradient headline word, and monospace figures. Two columns — the argument
   on the left, the evidence on the right. */
.ad-band {
  margin-top: 84px;   /* clear air after the registration card */
  margin-bottom: 64px;
  position: relative; overflow: hidden;
  background: var(--navy);
  border: 1px solid var(--border);
  border-radius: 30px;
  padding: 54px 52px 50px;
}
.ad-band::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0;
  height: 4px; background: var(--gradient); z-index: 3;
}
.ad-blob {
  position: absolute; border-radius: 50%; z-index: 0;
  background: linear-gradient(180deg, #253b62 0, #492040 100%);
  filter: blur(80px); opacity: .62; pointer-events: none;
}
.ad-blob.a { width: 420px; height: 420px; top: -170px; right: -110px; }
.ad-blob.b { width: 340px; height: 340px; bottom: -170px; left: -90px; }
.ad-inner { position: relative; z-index: 2; }

.ad-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 34px;
  padding-bottom: 22px; border-bottom: 1px solid var(--border);
}
.ad-brand { display: flex; align-items: center; gap: 13px; }
.ad-logo { width: 44px; height: 44px; flex-shrink: 0; }
.ad-wordmark { font-size: 18px; font-weight: 900; letter-spacing: 0.07em; color: #fff; }
.ad-eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--cyan);
}

.ad-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 46px; align-items: center; }
@media (max-width: 860px) { .ad-grid { grid-template-columns: 1fr; gap: 32px; } }

.ad-head {
  font-size: clamp(32px, 4.6vw, 50px); line-height: 1.02;
  letter-spacing: -0.025em; font-weight: 800; margin-bottom: 20px;
}
.ad-body { font-size: 16.5px; line-height: 1.72; color: var(--muted); margin-bottom: 30px; }
.ad-body strong { color: #fff; font-weight: 600; }

.ad-cta {
  display: inline-flex; align-items: center; gap: 9px;
  height: 54px; padding: 0 38px; border-radius: 8px;
  background: var(--gradient); color: #fff; text-decoration: none;
  font-size: 16px; font-weight: 700;
  box-shadow: 0 14px 38px rgba(0,211,211,.18);
  transition: filter .2s, transform .2s;
}
.ad-cta:hover { filter: brightness(1.1); transform: translateY(-1px); }
.ad-foot { margin-top: 16px; font-size: 12.5px; color: var(--faint); }

/* Evidence panel. Monospace figures in the brand gradient — the site sets
   data in mono, and it separates the numbers from the sales copy. */
.ad-stats {
  background: rgba(255,255,255,.035);
  border: 1px solid var(--border); border-radius: 20px;
  overflow: hidden;
}
.ad-stat {
  display: flex; align-items: baseline; gap: 14px;
  padding: 17px 24px; border-bottom: 1px solid var(--border);
}
.ad-stat:last-child { border-bottom: none; }
.ad-stat-n {
  font-family: Menlo, Consolas, monospace;
  font-size: 25px; font-weight: 700; line-height: 1;
  flex-shrink: 0; min-width: 4.6ch;
}
.ad-stat-l { font-size: 13.5px; color: var(--muted); line-height: 1.4; }

@media (max-width: 620px) {
  .ad-band { padding: 34px 24px 32px; border-radius: 22px; margin-top: 60px; }
  .ad-stat { padding: 15px 18px; }
}

/* Confirmation-screen variant: one column, left-aligned, tighter. */
.ad-compact {
  margin: 44px 0 0; padding: 36px 34px 34px;
  text-align: left; border-radius: 22px;
}
.ad-compact .ad-grid { grid-template-columns: 1fr; gap: 26px; }
.ad-compact .ad-head { font-size: clamp(24px, 3.6vw, 32px); margin-bottom: 14px; }
.ad-compact .ad-body { font-size: 15px; margin-bottom: 24px; }
.ad-compact .ad-top { margin-bottom: 26px; padding-bottom: 18px; }
.ad-compact .ad-logo { width: 38px; height: 38px; }
.ad-compact .ad-wordmark { font-size: 16px; }
.ad-compact .ad-cta { height: 50px; padding: 0 30px; font-size: 15px; }
.ad-compact .ad-blob.a { width: 300px; height: 300px; top: -130px; right: -90px; }
.ad-compact .ad-blob.b { width: 240px; height: 240px; bottom: -130px; left: -80px; }
/* Stats become a 2×2 block so four figures still fit a narrow column. */
.ad-compact .ad-stats {
  display: grid; grid-template-columns: 1fr 1fr;
  background: rgba(255,255,255,.035);
}
.ad-compact .ad-stat {
  display: block; padding: 16px 18px;
  border-bottom: 1px solid var(--border); border-right: 1px solid var(--border);
}
.ad-compact .ad-stat:nth-child(2n) { border-right: none; }
.ad-compact .ad-stat:nth-last-child(-n+2) { border-bottom: none; }
.ad-compact .ad-stat-n { font-size: 22px; display: block; margin-bottom: 4px; min-width: 0; }
.ad-compact .ad-stat-l { font-size: 12.5px; }
@media (max-width: 480px) {
  .ad-compact { padding: 28px 20px 26px; }
  .ad-compact .ad-stats { grid-template-columns: 1fr; }
  .ad-compact .ad-stat { border-right: none; }
  .ad-compact .ad-stat:nth-last-child(-n+2) { border-bottom: 1px solid var(--border); }
  .ad-compact .ad-stat:last-child { border-bottom: none; }
}

/* ── Bottom-of-page backdrop ────────────────────────────────────────────
   The paddle shot, sunk behind the ad and footer. Sits at the very bottom of
   the page under everything, faded to nothing at the top so it emerges
   rather than starting abruptly. */
.foot-bg {
  position: absolute; left: 0; right: 0; bottom: 0; height: 620px;
  z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(180deg, rgba(10,16,32,1) 0%, rgba(10,16,32,.90) 38%, rgba(10,16,32,.82) 100%),
    url('paddles.jpg');
  background-size: cover;
  background-position: center 62%;
  background-repeat: no-repeat;
}

/* ── Hosts ──────────────────────────────────────────────────────────── */
/* Four people, one row. The min track was 268px when there were three, which
   wrapped the fourth card onto a row of its own and left it stranded in the
   left column; 216px fits all four across the 980px column, and the cards
   fall to 2×2 and then 1-up on the way down. */
.hosts-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(216px, 1fr));
  gap: 16px; margin-bottom: 48px;
}
/* Photo-forward cards. The earlier version floated the name over a scrim on
   top of the photograph, which meant fighting bright daylight court shots for
   legibility and washing the pictures out to do it. Here the photo gets its
   own band at full strength, the headshot straddles the seam, and the copy
   sits on solid surface — nothing competes. */
.host-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 18px; padding: 0; overflow: hidden;
  box-shadow: 0 12px 40px rgba(0,0,0,.18);
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  transition: transform .25s, box-shadow .25s, border-color .25s;
}
.host-card:hover {
  transform: translateY(-4px); border-color: var(--border-lit);
  box-shadow: 0 24px 60px rgba(0,0,0,.34);
}
.host-media { position: relative; width: 100%; height: 132px; overflow: hidden; }
.host-bg {
  position: absolute; inset: 0;
  background-size: cover; background-position: center 32%;  /* per-card override inline */
  transition: transform .5s ease;
}
/* Only enough of a fade to seat the headshot and blend into the card. */
.host-media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(39,47,70,0) 45%, rgba(39,47,70,.88) 100%);
}
.host-card:hover .host-bg { transform: scale(1.06); }

.host-photo {
  width: 92px; height: 92px; border-radius: 50%;
  object-fit: cover; flex-shrink: 0;
  margin-top: -50px; position: relative; z-index: 1;
  border: 3px solid var(--surface);
  box-shadow: 0 10px 26px rgba(0,0,0,.5);
}
.host-body { padding: 14px 22px 24px; }
.host-name { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 5px; }
.host-title { font-size: 13px; color: var(--muted); line-height: 1.5; }
.host-note {
  font-size: 12.5px; color: var(--cyan); line-height: 1.5;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
}
/* LinkedIn mark is inlined as SVG rather than a file: this site is
   self-contained, and it keeps the icon working without another request. */
.host-li {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 14px; padding: 7px 14px; border-radius: 20px;
  background: rgba(255,255,255,.06); border: 1px solid var(--border);
  color: var(--muted); text-decoration: none;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.02em;
  transition: color .2s, border-color .2s, background .2s;
}
.host-li:hover {
  color: #fff; background: #0A66C2; border-color: #0A66C2;
}
.host-li svg { flex-shrink: 0; }

@media (prefers-reduced-motion: reduce) {
  .host-card:hover { transform: none; }
  .host-card:hover .host-bg { transform: none; }
}

/* ── What to expect ─────────────────────────────────────────────────── */
.expect-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px; margin-bottom: 52px;
  animation: fadeUp 0.7s 0.2s ease both;
}
/* These four answer the questions that actually stop people signing up —
   do I need a paddle, am I good enough, what do I wear. They were the
   flattest block on the page; now they carry brand weight. */
.expect-card {
  position: relative; overflow: hidden;
  background: linear-gradient(165deg, rgba(0,211,211,.09), rgba(255,255,255,.03) 60%);
  border: 1px solid var(--border-lit);
  border-radius: 16px; padding: 26px 24px 24px;
  transition: transform .2s, box-shadow .2s, border-color .2s;
}
.expect-card::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0;
  height: 3px; background: var(--gradient);
}
.expect-card:hover {
  transform: translateY(-3px); border-color: var(--cyan);
  box-shadow: 0 18px 44px rgba(0,211,211,.14);
}
/* Icon gets a plate so it reads as a badge rather than loose emoji. */
.expect-icon {
  width: 46px; height: 46px; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--tint); border: 1px solid var(--border-lit);
  font-size: 23px; margin-bottom: 16px;
}
.expect-title {
  font-size: 16.5px; font-weight: 800; margin-bottom: 7px;
  letter-spacing: -0.015em; color: #fff;
}
.expect-body { font-size: 13.5px; color: var(--muted); line-height: 1.6; }
@media (prefers-reduced-motion: reduce) { .expect-card:hover { transform: none; } }

/* ── Locations ──────────────────────────────────────────────────────── */
.section-title { font-size: 34px; margin-bottom: 8px; }
.section-sub { color: var(--faint); margin-bottom: 26px; font-size: 14px; }
.section-intro {
  font-size: 15.5px; line-height: 1.7; color: var(--muted);
  max-width: 70ch; margin: -14px 0 28px;
  padding-left: 16px; border-left: 2px solid var(--border-lit);
}
.section-intro strong { color: #fff; font-weight: 600; }
.intro-link {
  color: var(--cyan); text-decoration: none; font-weight: 600;
  white-space: nowrap; border-bottom: 1px solid rgba(0,211,211,.35);
}
.intro-link:hover { border-bottom-color: var(--cyan); }
.locations-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); gap: 20px; }
/* One session shouldn't stretch a card the full width of the page. */
.locations-grid.single { grid-template-columns: minmax(0, 520px); }
.location-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 18px;
  padding: 0; overflow: hidden; cursor: pointer;
  transition: border-color .2s, transform .2s, box-shadow .2s;
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
  animation: fadeUp 0.6s ease both;
  text-align: left; width: 100%; color: inherit; font: inherit;
}
.card-body { padding: 22px 24px 26px; }
/* Venue banner. Fades into the card so the photo doesn't fight the text
   under it, and sits above a gradient rule for a clean seam. */
.card-banner { position: relative; line-height: 0; }
.card-banner img { width: 100%; height: 132px; object-fit: cover; display: block; }
.card-banner::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(39,47,70,0) 40%, rgba(39,47,70,.92) 100%);
}
/* Paddle shot inset on the venue banner: what the place looks like and what
   you'll be handed, in one block. Sits above the banner's gradient overlay,
   and removes only itself if the file is missing.

   The selector must out-specify `.card-banner img` above, which sets
   width:100% and height:132px — a bare `.card-inset` ties on specificity and
   loses to source order, leaving the inset filling the whole banner. */
.card-banner img.card-inset {
  position: absolute; right: 16px; bottom: 14px; z-index: 2;
  width: 84px; height: 84px; border-radius: 14px;
  object-fit: cover; display: block;
  border: 2px solid rgba(255,255,255,.85);
  box-shadow: 0 10px 26px rgba(0,0,0,.45);
}
.venue-line { display: inline-flex; align-items: center; gap: 8px; }
/* The venue's own mark on a dark card — a white plate keeps it legible
   whatever it ships as, and it removes itself if the file is absent. */
.venue-logo {
  height: 22px; width: auto; max-width: 96px; object-fit: contain;
  background: #fff; border-radius: 4px; padding: 3px 5px;
}
.location-card:hover:not(:disabled) {
  border-color: var(--cyan); transform: translateY(-3px);
  box-shadow: 0 20px 56px rgba(0,211,211,0.14);
}
.location-card:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }
.location-card:disabled { opacity: 0.5; cursor: not-allowed; }
.location-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 16px; }
.location-name { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; }
.spot-badge { font-size: 11px; font-weight: 700; padding: 4px 10px; border-radius: 12px; white-space: nowrap; }
.spot-badge.ok  { color: var(--cyan); background: var(--tint); }
.spot-badge.low { color: var(--red);  background: rgba(248,113,113,0.12); }
.location-meta { font-size: 13.5px; color: var(--muted); line-height: 1.8; }
.location-meta .tbd { color: var(--cyan); font-weight: 600; }

/* The when-block. Deliberately the loudest thing inside the card after the
   city name — a reader scanning for "when is this" should not have to read
   a paragraph of meta at uniform weight to find it. */
.card-when {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin: 4px 0 16px; padding: 14px 16px;
  background: var(--tint); border: 1px solid var(--border-lit);
  border-radius: 12px;
}
.card-when-date {
  font-size: clamp(17px, 2.1vw, 21px); font-weight: 800;
  letter-spacing: -0.02em; color: #fff; line-height: 1.15;
}
.card-when-date .tbd { color: var(--cyan); font-weight: 700; }
.card-when-time {
  font-size: 15px; font-weight: 700; color: var(--cyan);
  letter-spacing: 0.02em; white-space: nowrap;
}
.card-when-time::before { content: '·'; margin-right: 12px; opacity: .5; }
/* Narrow cards wrap the time onto its own line, which would leave the
   separator dot stranded at the start of it. Stack instead and drop the dot. */
@media (max-width: 520px) {
  .card-when { flex-direction: column; align-items: flex-start; gap: 5px; }
  .card-when-time::before { content: none; margin: 0; }
}
.location-meta strong { color: #fff; font-weight: 600; }
.location-meta .addr { color: var(--faint); font-size: 12.5px; }
.progress-wrap { margin-top: 18px; }
.progress-labels { display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 11px; color: var(--faint); }
.progress-bar { height: 4px; background: rgba(255,255,255,0.07); border-radius: 4px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--gradient); border-radius: 4px; transition: width 1s ease; }
/* The card is the conversion point, so its CTA reads as a button rather than
   a caption. The card itself is the <button>; this is its visual affordance. */
.location-cta {
  margin-top: 20px; height: 52px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; gap: 9px;
  background: var(--gradient); color: #fff;
  font-size: 17px; font-weight: 800; letter-spacing: 0.01em;
  box-shadow: 0 12px 32px rgba(0,211,211,.22);
  transition: filter .2s;
}
.location-card:hover:not(:disabled) .location-cta { filter: brightness(1.1); }
.location-cta.off {
  background: rgba(255,255,255,.06); color: var(--faint);
  box-shadow: none; font-weight: 700;
}

/* ── Form ───────────────────────────────────────────────────────────── */
.form-inner { max-width: 700px; margin: 0 auto; padding: 48px 24px 80px; animation: fadeUp 0.5s ease both; }
.back-btn, .restart-btn {
  background: transparent; border: 1px solid var(--border); color: var(--muted);
  padding: 9px 18px; border-radius: 10px; cursor: pointer; font-size: 13px;
  display: inline-flex; align-items: center; gap: 6px; transition: background .2s, border-color .2s;
}
.back-btn { margin-bottom: 32px; }
.back-btn:hover, .restart-btn:hover { background: rgba(255,255,255,0.06); border-color: var(--border-lit); }

.session-summary {
  background: var(--tint); border: 1px solid var(--border-lit);
  border-radius: 16px; padding: 18px 22px; margin-bottom: 30px;
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
}
.session-summary h3 { font-size: 20px; margin-bottom: 4px; }
.session-summary p { font-size: 13px; color: var(--muted); }

.form-title { font-size: 38px; margin-bottom: 8px; }
.form-note { color: var(--faint); font-size: 14px; margin-bottom: 30px; }
.form-stack { display: flex; flex-direction: column; gap: 18px; }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 6px; }
.field-label { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.field input, .field textarea {
  background: rgba(255,255,255,0.05); border: 1px solid var(--border);
  border-radius: 10px; padding: 12px 16px; color: #fff; font-size: 15px;
  outline: none; transition: border-color .2s; width: 100%;
}
.field input:focus, .field textarea:focus { border-color: var(--cyan); }
.field.has-error input, .field.has-error textarea { border-color: var(--red); }
.field-error { font-size: 11.5px; color: var(--red); }

.skill-row { display: flex; gap: 10px; flex-wrap: wrap; }
.skill-btn {
  cursor: pointer; font-size: 13px; font-weight: 600;
  padding: 9px 18px; border-radius: 30px; border: 1px solid var(--border);
  background: transparent; color: var(--faint); transition: all .2s;
}
.skill-btn:hover { border-color: var(--border-lit); color: var(--muted); }
.skill-btn.selected { border-color: var(--cyan); background: var(--tint); color: var(--cyan); }
.skill-btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.submit-btn {
  width: 100%; background: var(--gradient); color: #fff; border: none;
  height: 52px; border-radius: 8px; font-size: 16px; font-weight: 700;
  cursor: pointer; letter-spacing: 0.01em; margin-top: 6px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  transition: filter .2s, transform .2s;
}
.submit-btn:hover:not(:disabled) { filter: brightness(1.1); transform: translateY(-1px); }
.submit-btn:disabled { opacity: 0.7; cursor: not-allowed; }
.spinner {
  width: 17px; height: 17px; border: 2px solid #fff; border-top-color: transparent;
  border-radius: 50%; animation: spin .7s linear infinite; display: inline-block;
}
.form-legal { font-size: 12px; color: var(--faint); text-align: center; line-height: 1.6; margin-top: 10px; }
.error-banner {
  background: rgba(248,113,113,0.10); border: 1px solid rgba(248,113,113,0.30);
  border-radius: 10px; padding: 14px 18px; font-size: 14px; color: var(--red); display: none;
}
.error-banner a { color: var(--red); text-decoration: underline; }

/* ── Success ────────────────────────────────────────────────────────── */
.success-inner { max-width: 620px; margin: 0 auto; padding: 76px 24px; text-align: center; animation: fadeUp .6s ease both; }
.success-icon {
  width: 88px; height: 88px; background: var(--tint); border: 1px solid var(--border-lit);
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 38px; margin: 0 auto 30px;
}
.success-title { font-size: 48px; margin-bottom: 14px; }
.success-sub { font-size: 18px; color: var(--muted); line-height: 1.65; margin-bottom: 8px; }
.success-sub strong { color: #fff; font-weight: 600; }
.success-sub2 { font-size: 15px; color: var(--faint); line-height: 1.7; margin-bottom: 32px; }
.success-sub2 span { color: var(--cyan); }
.success-details {
  background: var(--tint); border: 1px solid var(--border-lit);
  border-radius: 16px; padding: 20px 26px; margin-bottom: 30px; text-align: left;
}
.success-details-title {
  font-size: 12px; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--cyan); margin-bottom: 12px;
}
.success-details-body { font-size: 14px; color: var(--muted); line-height: 2; }

.site-footer {
  text-align: center; padding: 30px 24px; color: var(--faint); font-size: 13px;
  border-top: 1px solid var(--border); position: relative; z-index: 1;
}
.site-footer a { color: var(--muted); text-decoration: none; }
.site-footer a:hover { color: var(--cyan); }
/* Hub timestamp rule — every page in this series carries one of these. */
.stamp { display: block; margin-top: 8px; font-size: 12px; color: var(--faint); }

/* ── Series home: the event archive ──────────────────────────────────────
   One card per event, upcoming first. Deliberately not .location-card: that
   card is a *registration control* with live counts and a capacity bar, and
   this one is a directory entry with two or three links out. Reusing it would
   have meant a button element wrapping anchors, which is invalid and
   unnavigable by keyboard. */
.evt-list { display: grid; gap: 18px; margin-bottom: 12px; }
.evt {
  display: grid; grid-template-columns: 260px 1fr;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 18px; overflow: hidden;
  box-shadow: 0 12px 40px rgba(0,0,0,.16);
  transition: border-color .2s, transform .2s, box-shadow .2s;
  animation: fadeUp .6s ease both;
}
.evt:hover { border-color: var(--border-lit); transform: translateY(-2px); box-shadow: 0 18px 52px rgba(0,0,0,.24); }
@media (hover: none) { .evt:hover { transform: none; } }
.evt-media { position: relative; min-height: 190px; background: var(--surface-2); }
.evt-media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* No photo yet (an announced event) — the panel carries a paddle instead of a
   grey hole, so an upcoming card never looks broken. */
.evt-media.empty::after {
  content: '🏓'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 46px; opacity: .5;
}
.evt-body { padding: 22px 26px 24px; }
.evt-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.evt-name { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; }
.evt-tag {
  font-size: 10.5px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 20px; white-space: nowrap;
}
.evt-tag.open  { color: var(--cyan); background: var(--tint); border: 1px solid var(--border-lit); }
.evt-tag.tbd   { color: #F5C86B; background: rgba(245,200,107,.10); border: 1px solid rgba(245,200,107,.34); }
.evt-tag.done  { color: var(--muted); background: rgba(255,255,255,.05); border: 1px solid var(--border); }
.evt-when { font-size: 15px; font-weight: 700; color: #fff; margin-bottom: 3px; }
.evt-when .tbd { color: #F5C86B; font-weight: 700; }
.evt-where { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin-bottom: 14px; }
.evt-note { font-size: 13.5px; color: var(--muted); line-height: 1.6; margin-bottom: 16px; }
.evt-links { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* Primary is the thing a visitor most likely wants: highlights for a past
   event, registration for an open one. */
.evt-btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 44px; padding: 0 22px; border-radius: 8px;
  background: var(--gradient); color: #fff; text-decoration: none;
  font-size: 14.5px; font-weight: 800; white-space: nowrap;
  box-shadow: 0 10px 26px rgba(0,211,211,.18);
  transition: filter .2s, transform .2s;
}
.evt-btn:hover { filter: brightness(1.1); transform: translateY(-1px); }
.evt-btn.ghost {
  background: transparent; border: 1px solid rgba(255,255,255,.24);
  box-shadow: none; font-weight: 700;
}
.evt-btn.ghost:hover { border-color: var(--border-lit); background: var(--tint); }
@media (max-width: 720px) {
  .evt { grid-template-columns: 1fr; }
  .evt-media { min-height: 168px; }
  .evt-links { gap: 8px; }
  .evt-btn { height: 42px; padding: 0 16px; font-size: 13.5px; }
}

@keyframes fadeUp { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: translateY(0); } }
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
@media (max-width: 620px) {
  .site-header { padding: 14px 20px; }
  .home-inner { padding: 44px 20px 60px; }
  .form-grid { grid-template-columns: 1fr; }
  .photo img { width: 140px; height: 140px; }
}
