:root {
  --navy: #0a2342; --blue: #1565c0; --sky: #2196f3;
  --light-blue: #e3f2fd; --ice: #f0f7ff;
  --white: #ffffff; --gold: #c9a84c;
  --text: #0d1b2a; --muted: #5a6a7e;
  /* Heading font — overridable per-tenant via /admin/site-design. The admin
     can choose from a curated list of Google Fonts; the public _site-design
     partial injects a <style>:root override to swap this variable. */
  --heading-font: var(--heading-font);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body { font-family: 'DM Sans', sans-serif; color: var(--text); background: var(--white); overflow-x: hidden; }
img { max-width: 100%; }

/* ── WYSIWYG list rendering (Quill output) ───────────────────────────────────
   Quill 2.x (see _wysiwyg-init.ejs) always serializes BOTH bullet and
   numbered lists as an <ol>, distinguishing them only via a
   data-list="bullet" / "ordered" attribute on each <li> — native <ul> is
   never used. The admin's own editor renders these correctly because it
   loads quill.snow.css, but every public page just drops the saved HTML
   straight through via renderRichBody() with no Quill CSS, so plain
   browser <ol> numbering was showing up even for lists the admin picked
   as bullets. Unscoped (keyed off the data-list attribute rather than any
   one section's class) so it fixes every WYSIWYG list on the public site
   — hero/about copy on the homepage, Sub Event hero + Event Details, and
   any future rich-body field — in this one place. */
ol { counter-reset: rich-list; }
li[data-list] { list-style-type: none; }
li[data-list="ordered"] { counter-increment: rich-list; }
li[data-list="ordered"]::before { content: counter(rich-list) '. '; }
li[data-list="bullet"]::before { content: '\2022  '; }
li[data-list="checked"]::before { content: '\2611  '; }
li[data-list="unchecked"]::before { content: '\2610  '; }

/* ── NAV ── */
/*
  Top-bar uses --nav-bg-top (a translucent fill so content shows softly
  through). Mobile drawer uses --nav-bg-drawer (fully opaque). Both
  variables are overridable per-tenant via views/public/_site-design.ejs.
  Defaults reproduce the original MILK appearance:
    top bar = rgba(10,35,66,0.96)  (--navy at 96% opacity)
    drawer  = var(--navy)          (whatever --navy resolves to)
*/
:root {
  --nav-bg-top:    rgba(10,35,66,0.96);
  --nav-bg-drawer: var(--navy);
}
nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 48px; height: 72px;
  background: var(--nav-bg-top); backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.nav-logo img { height: 38px; filter: brightness(0) invert(1); }
.nav-logo a, .nav-drawer-header a { display: flex; align-items: center; }
.nav-links { display: flex; align-items: center; gap: 32px; list-style: none; }
.nav-links a { color: rgba(255,255,255,0.75); text-decoration: none; font-size: 13px;
  font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; transition: color 0.2s; }
.nav-links a:hover { color: var(--white); }
.nav-cta { background: var(--button-bg); color: var(--button-text) !important; padding: 10px 22px;
  border-radius: 4px; font-weight: 700 !important; transition: background 0.2s, transform 0.15s !important; }
.nav-cta:hover { background: var(--button-bg-hover) !important; transform: translateY(-1px); }

/* ── HAMBURGER BUTTON ── */
.nav-hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 44px; height: 44px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  border-radius: 6px;
  transition: background 0.2s;
  flex-shrink: 0;
}
.nav-hamburger:hover { background: rgba(255,255,255,0.08); }
.nav-hamburger span {
  display: block;
  width: 22px; height: 2px;
  background: rgba(255,255,255,0.85);
  border-radius: 2px;
  transition: transform 0.32s cubic-bezier(0.4,0,0.2,1),
              opacity  0.2s ease,
              width    0.2s ease;
  transform-origin: center;
}
/* Hamburger → X animation when nav-open */
body.nav-open .nav-hamburger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.nav-open .nav-hamburger span:nth-child(2) { opacity: 0; width: 0; }
body.nav-open .nav-hamburger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ── MOBILE NAV OVERLAY ── */
.nav-overlay {
  position: fixed; inset: 0;
  background: rgba(4,14,27,0.65);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
body.nav-open .nav-overlay { opacity: 1; pointer-events: all; }

/* ── MOBILE NAV DRAWER ── */
.nav-drawer {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: min(320px, 85vw);
  background: var(--nav-bg-drawer);
  z-index: 300;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 0.35s cubic-bezier(0.4,0,0.2,1);
  overflow-y: auto;
  box-shadow: -8px 0 40px rgba(0,0,0,0.45);
}
body.nav-open .nav-drawer { transform: translateX(0); }

/* Prevent body scroll when drawer is open */
body.nav-open { overflow: hidden; }

.nav-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 24px;
  border-bottom: 1px solid rgba(255,255,255,0.1);
  flex-shrink: 0;
}
.nav-drawer-header img { height: 30px; filter: brightness(0) invert(1); }
.nav-drawer-close {
  width: 40px; height: 40px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 8px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: rgba(255,255,255,0.7);
  transition: background 0.2s, color 0.2s;
  flex-shrink: 0;
}
.nav-drawer-close:hover { background: rgba(255,255,255,0.14); color: var(--white); }

/* ── DRAWER LINKS ── */
.nav-drawer-links {
  list-style: none;
  padding: 16px 0 32px;
  flex: 1;
}
.nav-drawer-links li { border-bottom: 1px solid rgba(255,255,255,0.06); }
.nav-drawer-links a {
  display: block;
  padding: 15px 28px;
  color: rgba(255,255,255,0.75);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color 0.2s, background 0.2s, padding-left 0.25s;
}
.nav-drawer-links a:hover {
  color: var(--white);
  background: rgba(255,255,255,0.05);
  padding-left: 36px;
}
.nav-drawer-cta-item {
  border-bottom: none !important;
  padding: 24px 28px 0;
}
.nav-drawer-cta {
  display: block !important;
  background: var(--button-bg) !important;
  color: var(--button-text) !important;
  text-align: center;
  padding: 16px 24px !important;
  border-radius: 4px;
  font-weight: 700 !important;
  letter-spacing: 0.08em;
  transition: background 0.2s, transform 0.15s !important;
}
.nav-drawer-cta:hover {
  background: var(--button-bg-hover) !important;
  padding-left: 24px !important;
  transform: translateY(-1px);
}

/* ── HERO ── */
/*
  Hero overlay is a 3-stop gradient layered on top of the hero background
  image. Each stop is exposed as its own CSS variable so the per-tenant
  Site Design Settings can override them via views/public/_site-design.ejs.
  Defaults below reproduce the original MILK navy → blue → navy overlay
  (with 88% / 75% / 92% opacity, which the admin page does NOT expose —
  admins pick a hex color, opacity stays fixed).
*/
:root {
  --hero-overlay-stop-1: rgba(10,35,66,0.88);   /* top-left corner   */
  --hero-overlay-stop-2: rgba(21,101,192,0.75); /* middle highlight  */
  --hero-overlay-stop-3: rgba(10,35,66,0.92);   /* bottom-right edge */
}
.hero {
  min-height: 100vh;
  /* Split into longhand so background-image can be overridden by the
     inline style="background-image: <gradient>, url(X)" in index.ejs
     WITHOUT dropping the position/size/repeat qualifiers. Solid
     background-color falls back to tenant navy when the admin hasn't
     set a hero image — previously this CSS carried a hardcoded MILK
     Swoogo image URL as the fallback, which meant clearing the
     admin-side image still rendered that legacy MILK photo on the
     public site. Now: no admin image → gradient overlay over solid
     navy, no leftover branding from other tenants. */
  background-image: linear-gradient(165deg,
                      var(--hero-overlay-stop-1) 0%,
                      var(--hero-overlay-stop-2) 60%,
                      var(--hero-overlay-stop-3) 100%);
  background-color: var(--navy);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  display: flex; flex-direction: column; justify-content: center;
  /* 140px top padding matches the agenda/speakers/exhibitors/sponsors/
     activities hero spacing — single shared "space above the hero text"
     value across every page. Bottom padding stays at the original 80px
     since the home hero is full-viewport (min-height: 100vh) and the
     content centers vertically inside the available space. */
  padding: 140px 48px 80px; position: relative; overflow: hidden;
}
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 60% at 70% 50%, rgba(33,150,243,0.18) 0%, transparent 70%);
  pointer-events: none;
}
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--gold); font-size: 12px; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase; margin-bottom: 24px;
}
.hero-eyebrow::before { content: ''; display: block; width: 32px; height: 2px; background: var(--gold); }
.hero-logo { width: 340px; max-width: 90%; margin-bottom: 36px; }
/* Unified hero h1 typography — see the shared rule near the speakers
   header below. Home hero just adds its own max-width constraint
   because it spans the full viewport (100vw) and the headline would
   otherwise stretch end-to-end. */
.hero h1 { max-width: 800px; }
.hero-emphasis {
  /* color set directly by scroll JS — starts at emphasis_color_before, lerps to emphasis_color_after */
  /* initial value overridden immediately on DOMContentLoaded; fallback is the before color */
  color: #1a0e00;
  display: inline;
}
.hero-sub { font-size: 20px; font-weight: 300; color: rgba(255,255,255,0.85);
  max-width: 520px; line-height: 1.6; margin-bottom: 48px; }
/* WYSIWYG-rendered body is now wrapped in a <div>; reset default <p> margins
   inside it so the visual matches the previous single-<p> rendering. */
.hero-sub p { margin: 0 0 12px 0; }
.hero-sub p:last-child { margin-bottom: 0; }
.hero-sub a { color: var(--gold); text-decoration: underline; }
.hero-sub strong { color: #fff; font-weight: 600; }
/* About body content (WYSIWYG-rendered or legacy plain-text-converted-to-<p>).
   Scoped to .about-body wrapper so it does NOT bleed into the buttons that
   sit elsewhere inside .about-content. */
.about-body > p:first-of-type { margin-top: 24px; }
.about-body p { font-size: 17px; line-height: 1.8; color: var(--muted); margin-top: 24px; }
.about-body p:first-child { margin-top: 0; }
.about-body ul, .about-body ol { margin: 16px 0 16px 24px; padding: 0; font-size: 17px; line-height: 1.8; color: var(--muted); }
.about-body a { color: var(--blue); text-decoration: underline; }
.about-body strong { color: var(--text); }
.hero-meta { display: flex; flex-wrap: wrap; gap: 24px; margin-bottom: 48px; }
.hero-meta-item { display: flex; align-items: center; gap: 10px;
  color: rgba(255,255,255,0.9); font-size: 15px; font-weight: 500; }
.hero-meta-item svg { opacity: 0.6; flex-shrink: 0; }
.hero-actions { display: flex; gap: 16px; flex-wrap: wrap; }

/* ── HERO 2-COLUMN LAYOUT (with countdown) ──
   When a countdown is rendered, the hero becomes a 2-column flex row on
   desktop (>=1024px): content on the left, countdown on the right. On
   smaller viewports it falls back to the original single-column stack,
   with the countdown landing AFTER .hero-content (i.e. after the
   Register button) per the design spec.
   .hero-content wraps the existing eyebrow → logo → headline → sub →
   meta → actions block. .hero-scroll is absolutely positioned at the
   bottom so it sits outside this row layout. */
.hero-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 1 1 auto;
  min-width: 0;
}
@media (min-width: 1024px) {
  .hero { flex-direction: row; align-items: center; gap: 64px; }
}

/* ── HERO COUNTDOWN TIMER ──
   Four SVG-ring units showing days / hours / minutes / seconds until the
   admin-configured countdown_target. Numbers in DM Sans Bold, labels in
   the same letter-spaced uppercase style as .hero-eyebrow. Transparent
   background — sits on top of the hero gradient overlay.
   Ring math: r=46 in a 100x100 viewBox → circumference ≈ 289. The JS
   updates strokeDashoffset on each tick to animate progress around each
   ring. SVG itself is rotated -90deg so the arc starts at 12 o'clock.

   Sizing strategy: CSS custom properties (--ring-size, --value-font,
   etc.) defined on .hero-countdown. The mobile defaults stay close to
   the original sizes; the desktop media query (>=1024px) bumps them up
   significantly (~2x at the max) and uses `vw` in the middle of the
   clamp() so the rings smoothly scale down as the browser narrows —
   right up until the mobile breakpoint, where the layout switches to
   stacked-below-the-buttons and the smaller mobile sizes kick in. */
.hero-countdown {
  /* Default (mobile / <1024px) sizing. Overridden in the desktop media
     query below. Keeping these as variables means each downstream rule
     references one source of truth per breakpoint. */
  --ring-size:    clamp(75px, 12vw, 110px);
  --value-font:   clamp(24px, 3.2vw, 34px);
  --label-font:   11px;
  --label-margin: 14px;

  display: grid;
  grid-template-columns: repeat(4, minmax(60px, 1fr));
  gap: 20px;
  flex: 0 0 auto;
  justify-items: center;
  align-items: start;
}
.hero-countdown[hidden] { display: none; }
.countdown-unit {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.countdown-ring {
  width:  var(--ring-size);
  height: var(--ring-size);
  /* rotate(-90deg) puts the SVG circle's path origin (which is at the
     3 o'clock position by spec) up at the 12 o'clock position.
     scaleX(-1) mirrors horizontally so the path direction reverses
     from CW to CCW — meaning the arc now grows counter-clockwise from
     12, and as time decreases the trailing edge retreats clockwise
     instead of counter-clockwise (the visual "drain direction"). */
  transform: scaleX(-1) rotate(-90deg);
}
.countdown-ring-bg {
  fill: none;
  stroke: rgba(255,255,255,0.18);
  stroke-width: 3;
}
.countdown-ring-fg {
  fill: none;
  stroke: rgba(255,255,255,0.95);
  stroke-width: 3;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.5s ease;
}
.countdown-value {
  position: absolute;
  /* Vertically center over the SVG ring (which is the first child).
     Half the ring height places the value's center on the ring's center. */
  top: calc(var(--ring-size) / 2);
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: 'DM Sans', sans-serif;
  font-weight: 700;
  font-size: var(--value-font);
  color: #fff;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  pointer-events: none;
}
.countdown-label {
  margin-top: var(--label-margin);
  font-family: 'DM Sans', sans-serif;
  font-size: var(--label-font);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.7);
}

/* Desktop (>=1024px): bigger rings than mobile but scaled back ~30%
   from the initial 2x bump after the first design pass felt too
   bulky on narrow/mid desktops. `vw` in the middle of the clamp
   keeps the smooth shrink as the window narrows. At 1024px the vw
   value resolves to ~102px; at very wide screens (2200px+) the
   ceiling at 220px kicks in, preserving the original "big" feel
   for ultrawide displays. Common laptop/desktop widths (1280-1700)
   land in the 128-170px range. */
@media (min-width: 1024px) {
  .hero-countdown {
    --ring-size:    clamp(100px, 10vw,  220px);
    --value-font:   clamp(32px,  3.7vw, 68px);
    --label-font:   11px;
    --label-margin: 16px;
    gap: 18px;
  }
}

/* Mobile (<1024px): countdown drops below the Register button (handled
   by .hero flex-direction: column at this breakpoint). Add margin so it
   doesn't sit right against the button, center it within the hero
   padding, and cap its width so on tablet it doesn't span the full
   hero. */
@media (max-width: 1023px) {
  .hero-countdown {
    margin-top: 40px;
    justify-content: center;
    width: 100%;
    max-width: 460px;
  }
}

/* Very narrow phones: 4-across is cramped. Drop to a 2x2 grid. */
@media (max-width: 480px) {
  .hero-countdown {
    grid-template-columns: repeat(2, 1fr);
    gap: 24px;
    max-width: 320px;
  }
}

.hero-scroll {
  position: absolute; bottom: 36px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  color: rgba(255,255,255,0.5); font-size: 11px; letter-spacing: 0.15em; text-transform: uppercase;
  animation: scrollBob 2s ease-in-out infinite;
}
@keyframes scrollBob {
  0%,100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(6px); }
}

/* ── BUTTONS ── */
/*
  Primary CTA buttons (Register Now, .btn-primary / .btn-gold / .nav-cta /
  .nav-drawer-cta) all share one pair of CSS variables so the per-tenant
  Site Design Settings can override their color + hover color in one place.
  Defaults reproduce the original MILK gold-with-lighter-gold-on-hover look.
  The hover var is decoupled (not auto-derived from the base) so admins
  picking a non-gold base can specify a coherent hover shade.
*/
:root {
  --button-bg:       var(--gold);
  --button-bg-hover: #e0bc6a;
  /* Label color on the four primary CTA buttons. Defaults to the tenant's
     dark color (var(--navy)) so legacy MILK keeps its dark-text-on-gold
     look; per-tenant Site Design Settings can override this when the
     button background is light and a different label color is needed. */
  --button-text:     var(--navy);
}

/*
  Decorative monoline accent icons. Currently used in the Hotel section
  (location pin, dollar sign, check) and reserved for any future themed
  icon decoration. Opt-in via class="icon-themed" on the <svg>; the SVG's
  inline stroke="..." attribute stays as a graceful fallback for when the
  stylesheet hasn't loaded yet, but the class wins via CSS specificity.
  Default tracks --gold (= accent_color) so an admin who only changes
  accent_color sees the icons + their soft backing tint follow along.
*/
:root {
  --icon-color: var(--gold);
}
.icon-themed { stroke: var(--icon-color); }
.btn-primary {
  display: inline-block; background: var(--button-bg); color: var(--button-text);
  padding: 16px 36px; border-radius: 4px; font-weight: 700; font-size: 14px;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  transition: background 0.2s, transform 0.15s, box-shadow 0.2s;
}
.btn-primary:hover { background: var(--button-bg-hover); transform: translateY(-2px); box-shadow: 0 8px 32px rgba(201,168,76,0.4); }
.btn-outline {
  display: inline-block; border: 1.5px solid rgba(255,255,255,0.45); color: var(--white);
  padding: 15px 32px; border-radius: 4px; font-weight: 500; font-size: 14px;
  letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none;
  transition: border-color 0.2s, background 0.2s;
}
.btn-outline:hover { border-color: var(--white); background: rgba(255,255,255,0.08); }
/*
  .btn-blue was originally the "secondary CTA" family — solid-fill blue
  for buttons like "View Agenda" / "Inquire About Sponsoring". Folded
  into the unified Primary Button variables in the Site Design pass so
  the entire site has a single user-controllable button color. Keeps its
  own dimensions (padding/font-size) — only the colors merged. The class
  name is left intact rather than refactored to .btn-primary to avoid a
  churn-heavy markup pass; both classes now resolve to identical color
  treatment via the shared variables.
*/
.btn-blue {
  display: inline-block; background: var(--button-bg); color: var(--button-text);
  padding: 14px 32px; border-radius: 4px; font-weight: 600; font-size: 13px;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  transition: background 0.2s, transform 0.15s;
}
.btn-blue:hover { background: var(--button-bg-hover); transform: translateY(-1px); }
.btn-outline-blue {
  display: inline-block; border: 1.5px solid var(--blue); color: var(--blue);
  padding: 13px 28px; border-radius: 4px; font-weight: 600; font-size: 13px;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  transition: background 0.2s;
}
.btn-outline-blue:hover { background: var(--light-blue); }
.btn-gold {
  display: inline-block; background: var(--button-bg); color: var(--button-text);
  padding: 14px 32px; border-radius: 4px; font-weight: 700; font-size: 13px;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  margin-top: 32px; transition: background 0.2s, transform 0.15s;
}
.btn-gold:hover { background: var(--button-bg-hover); transform: translateY(-1px); }

/* ── SECTION BASE ── */
section { padding: 96px 48px; }
.section-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--blue); font-size: 11px; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 16px;
}
.section-eyebrow::before { content: ''; display: block; width: 24px; height: 2px; background: var(--blue); }
h2 { font-family: var(--heading-font); font-size: clamp(32px, 4vw, 52px);
  font-weight: 700; line-height: 1.15; color: var(--navy); }

/* ── STATS ── */
.stats { background: var(--navy); padding: 56px 48px; display: flex; justify-content: center; }
.stats-inner { display: flex; flex-wrap: wrap; gap: 0; max-width: 1200px; width: 100%; }
.stat-item { flex: 1 1 200px; text-align: center; padding: 24px 32px;
  border-right: 1px solid rgba(255,255,255,0.1); }
.stat-item:last-child { border-right: none; }
.stat-num { font-family: var(--heading-font); font-size: 48px; font-weight: 700;
  color: var(--gold); line-height: 1; margin-bottom: 8px; }
.stat-label { font-size: 12px; font-weight: 600; color: rgba(255,255,255,0.55);
  letter-spacing: 0.14em; text-transform: uppercase; }

/* ── ABOUT ── */
.about { background: var(--ice); position: relative; overflow: hidden; }
.about::after {
  content: ''; position: absolute; right: -120px; top: -80px;
  width: 600px; height: 600px; border-radius: 50%;
  background: radial-gradient(circle, rgba(33,150,243,0.07) 0%, transparent 70%);
  pointer-events: none;
}
.about-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 80px;
  align-items: center; max-width: 1200px; margin: 0 auto; }
.about-content p { font-size: 17px; line-height: 1.8; color: var(--muted); margin-top: 24px; }
.about-img { border-radius: 12px; overflow: hidden; position: relative;
  box-shadow: 0 40px 80px rgba(10,35,66,0.18); }
.about-img > img { width: 100%; display: block; aspect-ratio: 4/3; object-fit: cover; }
.about-img::before {
  content: ''; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(135deg, rgba(21,101,192,0.15), transparent);
}

/* About photo slider: up to 5 images stack absolutely; the .active one
   fades to opacity 1, the rest stay at 0. The container itself reserves
   the same 4/3 aspect ratio as a single image so the surrounding layout
   doesn't jump as slides switch. The decorative .about-img::before
   gradient sits at z-index: 2, above the slides (z-index: 0/1) so it
   keeps its overlay effect regardless of which slide is active. */
.about-slider {
  position: relative;
  width: 100%;
  aspect-ratio: 4/3;
}
.about-slide {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.7s ease;
  z-index: 0;
}
.about-slide.active {
  opacity: 1;
  z-index: 1;
}

/* ── REGISTRATION ── */
.registration { max-width: 1200px; margin: 0 auto; }
.reg-header { margin-bottom: 56px; }
.reg-header p { font-size: 17px; color: var(--muted); margin-top: 16px; max-width: 560px; line-height: 1.7; }
.reg-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px; margin-bottom: 40px; }
.reg-card {
  border: 1.5px solid #e2ecf7; border-radius: 12px; padding: 36px 32px;
  background: var(--white); transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
  position: relative; overflow: hidden;
}
.reg-card:hover { border-color: var(--sky); box-shadow: 0 16px 48px rgba(21,101,192,0.1); transform: translateY(-4px); }
.reg-card.featured { border-color: var(--blue); background: linear-gradient(135deg, #f0f7ff, #e3f2fd); }
/* The "EARLY BIRD" pill in the top-right is a separate class so it can be
   applied per-tier — only when that tier actually has an early_bird_price
   configured. .featured (background + border) is independent and is applied
   to every tier during the early-bird window. */
.reg-card.eb-pill::after {
  content: 'EARLY BIRD'; position: absolute; top: 16px; right: 16px;
  background: var(--gold); color: var(--navy); font-size: 10px; font-weight: 700;
  letter-spacing: 0.1em; padding: 4px 10px; border-radius: 20px;
}
.reg-type { font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--blue); margin-bottom: 12px; }
.reg-title { font-family: var(--heading-font); font-size: 22px; font-weight: 700;
  color: var(--navy); margin-bottom: 20px; }
.reg-prices { display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.reg-price-pair { display: inline-flex; align-items: baseline; gap: 6px; }
.reg-price-early { font-size: 38px; font-weight: 700; color: var(--navy);
  font-family: var(--heading-font); }
.reg-price-std { font-size: 18px; color: var(--muted); text-decoration: line-through; }
/* "(early bird)" / "(standard)" labels next to each price. Match .reg-title
   typography (Playfair Display serif, 22px, 700 navy). Sits inside
   .reg-price-pair so it stays glued to its price; text-decoration:none stops
   the strikethrough from .reg-price-std bleeding onto the adjacent label. */
.reg-price-label {
  font-family: var(--heading-font);
  font-size: 22px; font-weight: 700;
  color: var(--navy);
  text-decoration: none;
}
.reg-note { font-size: 13px; color: var(--muted); line-height: 1.6;
  border-top: 1px solid #e2ecf7; padding-top: 16px; margin-top: 16px; }
.reg-deadline {
  display: inline-flex; align-items: center; gap: 10px;
  background: #fff8e5; border: 1px solid #f0d87e; border-radius: 8px;
  padding: 14px 20px; font-size: 14px; font-weight: 600; color: #7a5800;
}

/* ── HOTEL ── */
.hotel { background: var(--navy); position: relative; overflow: hidden; padding: 96px 48px; }
.hotel::before {
  content: ''; position: absolute; inset: 0;
  /* Screened-back background image, sourced from --hotel-bg-image which
     the public index.ejs sets inline on the .hotel section from
     hotel.image. When the admin changes the foreground photo in
     /admin/hotel, this 12%-opacity backdrop follows automatically.
     When the admin CLEARS the hotel image, --hotel-bg-image is unset
     and this falls back to `none` — the backdrop renders as nothing
     rather than the legacy MILK Swoogo URL that used to live here. */
  background-image: var(--hotel-bg-image, none);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0.12;
}
.hotel-inner { max-width: 1200px; margin: 0 auto; display: grid;
  grid-template-columns: 1fr 1fr; gap: 80px; align-items: center; position: relative; z-index: 1; }
/* When the admin hasn't set a hotel image, the .hotel section carries
   a --no-image modifier class (added in views/public/index.ejs) and
   the foreground <img> wrapper is skipped in markup. Collapse the grid
   to a single centered text column instead of leaving the right side
   empty at 2-col width. */
.hotel--no-image .hotel-inner { grid-template-columns: 1fr; max-width: 800px; }
.hotel .section-eyebrow::before { background: var(--gold); }
.hotel .section-eyebrow { color: var(--gold); }
.hotel h2 { color: var(--white); }
.hotel-detail { display: flex; align-items: flex-start; gap: 16px; margin-top: 28px;
  padding: 24px; border-radius: 10px; background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.1); }
.hotel-detail-icon { width: 40px; height: 40px; border-radius: 8px;
  /* Soft tinted circle behind the monoline icon. color-mix derives a 20%
     opacity version of --icon-color so the backing follows whatever color
     the admin picks (or whatever accent_color it falls back to). The
     rgba(201,168,76,0.2) fallback covers the case where color-mix isn't
     supported (Chrome <111, Safari <16.2, Firefox <113 — all from 2023). */
  background: rgba(201,168,76,0.2);
  background: color-mix(in srgb, var(--icon-color) 20%, transparent);
  display: flex; align-items: center;
  justify-content: center; flex-shrink: 0; }
.hotel-detail-text h4 { color: var(--white); font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.hotel-detail-text p { color: rgba(255,255,255,0.6); font-size: 14px; line-height: 1.6; }
.hotel-img-wrap { border-radius: 12px; overflow: hidden; box-shadow: 0 40px 80px rgba(0,0,0,0.5); }
.hotel-img-wrap img { width: 100%; display: block; aspect-ratio: 4/3; object-fit: cover; }

/* ── FLIGHT STRIP ── */
.flight-strip { background: linear-gradient(135deg, var(--blue), var(--navy));
  padding: 56px 48px; text-align: center; }
.flight-strip h3 { font-family: var(--heading-font); font-size: 28px;
  color: var(--white); margin-bottom: 12px; }
.flight-strip p { color: rgba(255,255,255,0.7); font-size: 15px; margin-bottom: 28px; }

/* ── AWARDS ── */
.awards-section { background: var(--ice); padding: 96px 48px; }
.awards-inner { max-width: 1200px; margin: 0 auto; }
.awards-header { margin-bottom: 56px; }
.awards-header p { font-size: 16px; color: var(--muted); margin-top: 16px; }
.awards-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.award-card { background: var(--white); border-radius: 12px; overflow: hidden;
  border: 1.5px solid #e2ecf7; transition: transform 0.2s, box-shadow 0.2s;
  display: flex; flex-direction: column; }
.award-card:hover { transform: translateY(-6px); box-shadow: 0 20px 60px rgba(21,101,192,0.12); }
/* Main award image — width is admin-controllable per card via the
   Image Size slider (inline style="width: N%" on the img). The
   width: 100% here is a fallback for legacy records that pre-date
   the slider; height: auto preserves the uploaded image's aspect
   ratio. margin: 0 auto centers the image horizontally when the
   slider drops it below 100% of the card width. Scoped to the
   direct child so it doesn't cascade to the badge logo below. */
.award-card-image > img {
  width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
}

/* Badge block sits BELOW the award image as a sibling, right-aligned.
   margin-top: -20px slides its top edge modestly up into the bottom
   of the image — badge peeks into the lower edge without dominating.
   z-index keeps it above the image so the overlap renders correctly.
   Layout: vertical stack, right-aligned children, small gap between
   caption and logo. Either child can render independently — both,
   just the caption, or just the logo all lay out correctly. */
.award-card-badge {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  padding: 0 14px 0 14px;
  margin-top: -20px;
  position: relative;
  z-index: 2;
  pointer-events: none;
}

/* Caption text — small uppercase label. Uses a semi-transparent
   white scrim so it stays legible whether it's floating over the
   image's bottom pixels or sitting on the card's white background
   below the image. text-overflow:ellipsis is the last-line defense
   if the admin's maxlength=24 guard is ever bypassed. */
.award-card-badge-caption {
  font-family: var(--heading-font);
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--navy);
  background: rgba(255, 255, 255, 0.9);
  padding: 2px 7px;
  border-radius: 3px;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Sponsor-logo image — width is admin-controllable per card via the
   Badge Image Size slider (inline style="width: N%" on the img,
   where N is the percent of the card column width). height: auto
   scales proportionally so aspect ratio is preserved for whatever
   the admin uploads. The 50% default sizes most logos to roughly
   the same visual footprint as the previous height-driven 110px
   design. Parent .award-card has overflow: hidden so an unusually
   wide logo clips at the card edge rather than pushing layout
   around. Transparent PNGs recommended. */
.award-card-badge-logo {
  display: block;
  height: auto;
}

/* Per-card title shown above the image (only rendered when populated).
   Needs its own padding because the image below bleeds edge-to-edge. */
.award-card-title {
  font-family: var(--heading-font);
  font-size: 20px; font-weight: 700;
  color: var(--navy);
  margin: 0;
  padding: 20px 24px 12px;
  line-height: 1.25;
}

/* Body + button area below the image (only rendered when populated) */
.award-card-content { padding: 20px 24px 24px; display: flex; flex-direction: column;
  gap: 16px; flex: 1; }
.award-card-body { font-size: 14px; line-height: 1.55; color: #4b5563; }
.award-card-body p { margin: 0 0 10px 0; }
.award-card-body p:last-child { margin-bottom: 0; }
.award-card-body a { color: var(--blue); text-decoration: underline; }
.award-card-body a:hover { opacity: 0.85; }
.award-card-body ul,
.award-card-body ol { margin: 0 0 10px 20px; padding: 0; }
.award-card-body strong { color: #1f2937; }

.award-card-button { display: inline-block; align-self: flex-start; margin-top: auto;
  padding: 10px 18px; background: var(--button-bg); color: var(--button-text); text-decoration: none;
  border-radius: 6px; font-weight: 600; font-size: 14px; transition: background 0.15s; }
.award-card-button:hover { background: var(--button-bg-hover); }

/* "All Awards Information" — full-width block below the three-card grid.
   Each piece (headline + body) renders only when populated. */
.awards-info {
  margin-top: 48px;
  padding: 32px 36px;
  background: var(--white);
  border-radius: 12px;
  border: 1.5px solid #e2ecf7;
}
.awards-info-headline {
  font-family: var(--heading-font);
  font-size: 22px; font-weight: 700;
  color: var(--navy);
  margin: 0 0 16px 0;
  line-height: 1.3;
}
.awards-info-body { font-size: 16px; line-height: 1.7; color: #4b5563; }
.awards-info-body p { margin: 0 0 12px 0; }
.awards-info-body p:last-child { margin-bottom: 0; }
.awards-info-body a { color: var(--blue); text-decoration: underline; }
.awards-info-body a:hover { opacity: 0.85; }
.awards-info-body ul, .awards-info-body ol { margin: 0 0 12px 22px; padding: 0; }
.awards-info-body strong { color: #1f2937; }

/* ── SPONSORS ── */
#sponsors { padding: 96px 48px; }
.sponsor-section { max-width: 1200px; margin: 0 auto; }
.sponsor-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: center; }
.sponsor-content p { font-size: 17px; color: var(--muted); line-height: 1.8; margin-top: 20px; }
.sponsor-actions { display: flex; gap: 16px; margin-top: 32px; flex-wrap: wrap; }
.sponsor-visual { background: linear-gradient(135deg, var(--light-blue), #dbeeff);
  border-radius: 16px; padding: 56px; text-align: center; }
.sponsor-visual p { font-family: var(--heading-font); font-size: 22px;
  color: var(--navy); line-height: 1.4; margin-bottom: 8px; }
.sponsor-visual span { font-size: 14px; color: var(--muted); }
/* When the admin uploads a visual image, drop the gradient/padding so the
   image fills the column edge-to-edge with rounded corners. */
.sponsor-visual--image { background: none; padding: 0; }
.sponsor-visual--image img {
  width: 100%; height: auto; display: block;
  border-radius: 16px;
}
/* When no image is set, collapse the right column so the sponsor content
   isn't stranded next to an empty gap. */
.sponsor-grid--single { grid-template-columns: 1fr; }

/* ── CTA BAND ── */
.cta-band { background: var(--navy); padding: 96px 48px; text-align: center;
  position: relative; overflow: hidden; }
.cta-band::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 70% 60% at 50% 50%, rgba(33,150,243,0.15) 0%, transparent 70%);
}
.cta-band h2 { color: var(--white); margin-bottom: 16px; position: relative; }
.cta-band p { color: rgba(255,255,255,0.65); font-size: 17px; margin-bottom: 36px; position: relative; }

/* ── FOOTER ── */
footer { background: #040e1b; padding: 56px 48px 32px; }
.footer-top { display: flex; justify-content: space-between; align-items: flex-start;
  flex-wrap: wrap; gap: 32px; padding-bottom: 40px;
  border-bottom: 1px solid rgba(255,255,255,0.08); margin-bottom: 32px; }
.footer-logo img { height: 32px; filter: brightness(0) invert(1); opacity: 0.7; }
.footer-links { display: flex; gap: 24px; flex-wrap: wrap; list-style: none; }
.footer-links a { color: rgba(255,255,255,0.45); font-size: 12px; text-decoration: none; transition: color 0.2s; }
.footer-links a:hover { color: rgba(255,255,255,0.8); }
.social-links { display: flex; gap: 12px; }
.social-btn { width: 36px; height: 36px; border-radius: 50%;
  background: rgba(255,255,255,0.07); display: flex; align-items: center;
  justify-content: center; transition: background 0.2s; }
.social-btn:hover { background: rgba(255,255,255,0.15); }
.social-btn img { width: 16px; height: 16px; filter: brightness(0) invert(1); opacity: 0.6; }
.footer-bottom { display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 12px; }
.footer-copy { color: rgba(255,255,255,0.3); font-size: 12px; }

/* ── ANIMATIONS ── */
@keyframes fadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: translateY(0); } }
.hero-eyebrow { animation: fadeUp 0.7s ease both; }
.hero-logo     { animation: fadeUp 0.7s 0.1s ease both; }
.hero h1       { animation: fadeUp 0.7s 0.2s ease both; }
.hero-sub      { animation: fadeUp 0.7s 0.3s ease both; }
.hero-meta     { animation: fadeUp 0.7s 0.4s ease both; }
.hero-actions  { animation: fadeUp 0.7s 0.5s ease both; }

/* ── REDUCED MOTION ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.1ms !important; }
}

/* ── RESPONSIVE ── */
@media (max-width: 900px) {
  /* Show hamburger, hide desktop nav links */
  .nav-links { display: none; }
  .nav-hamburger { display: flex; }

  nav { padding: 0 24px; }
  section, .hotel, .awards-section, #sponsors { padding: 72px 24px; }
  .hero { padding: 120px 24px 72px; }  /* mobile padding-top matches the agenda's mobile (.speakers-header below) so above-text spacing is consistent on narrow viewports too */
  .about-grid, .hotel-inner, .sponsor-grid { grid-template-columns: 1fr; gap: 40px; }
  .awards-grid { grid-template-columns: 1fr; }
  .stats { padding: 40px 24px; }
  .stat-item { border-right: none; border-bottom: 1px solid rgba(255,255,255,0.1); padding: 20px; }
  .stat-item:last-child { border-bottom: none; }
  .flight-strip { padding: 40px 24px; }
  footer { padding: 40px 24px 24px; }
  .sponsor-visual { padding: 36px 28px; }
  .reg-cards { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .hero-logo { width: 240px; }
  /* Home hero h1 mobile sizing removed — covered by the unified
     hero-h1 rule's clamp(36px, 5vw, 64px), which already scales
     down nicely on narrow viewports. */
  .hero-scroll { display: none; }
  .nav-drawer { width: 100vw; }
}

/* ── NAV ACTIVE STATE ── */
.nav-active { color: var(--white) !important; border-bottom: 2px solid var(--gold); padding-bottom: 2px; }

/* ── SPEAKERS PAGE HEADER ── */
.speakers-header {
  background: var(--navy);
  padding: 140px 48px 72px;
  position: relative;
  overflow: hidden;
}
/* When a background image is set via inline style, disable the default radial glow */
.speakers-header--img::before { display: none; }
.speakers-header::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 60% at 70% 50%, rgba(33,150,243,0.14) 0%, transparent 70%);
  pointer-events: none;
}
/* Background image support — image is set as inline style by EJS */
.speakers-header--img {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.speakers-header-inner { max-width: 1200px; margin: 0 auto; position: relative; }
/* Conference logo at the top of a page hero (agenda/speakers/etc.).
   Sized smaller than the homepage .hero-logo (340px) since these sub-page
   heroes are shorter strips, not full-viewport heroes. max-width keeps the
   logo from overflowing on narrow viewports; the auto-height preserves the
   logo's natural aspect ratio. */
.page-header-logo {
  display: block;
  width: 220px;
  max-width: 60%;
  height: auto;
  margin-bottom: 24px;
}

/* ── Hero photo slider 2-column layout ──
   When the agenda or exhibitors hero has photos to show (the .has-hero-slider
   modifier class is set by the EJS), the inner container becomes a 2-column
   grid: text on the left, slider on the right. With no photos, no slider
   renders and the text takes the full inner width as before.
   On viewports under 900px the columns stack with the slider beneath the
   text, since the slider's natural width would crowd the text otherwise. */
.has-hero-slider .speakers-header-inner,
.has-hero-slider .exhibitors-hero-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: center;
}
.has-hero-slider .hero-text-col { min-width: 0; }
@media (max-width: 900px) {
  .has-hero-slider .speakers-header-inner,
  .has-hero-slider .exhibitors-hero-inner {
    grid-template-columns: 1fr;
    gap: 32px;
  }
}
/* Border + shadow treatment on hero-context sliders so they read as a
   distinct visual element against the navy hero background. The
   homepage About slider already gets a similar treatment via .about-img
   wrapping it, so this rule scopes to the hero context only. */
.has-hero-slider .about-slider {
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 30px 60px rgba(0,0,0,0.35);
}
/* Unified hero h1 typography — applies to every page hero so headlines
   are visually consistent regardless of which sub-page a visitor is on.
   The home hero adds a max-width constraint above; everything else
   inherits its container width via the .*-header-inner wrappers. */
.hero h1,
.speakers-header h1,
.exhibitors-hero h1,
.sponsors-header h1,
.activities-header h1,
.subevent-hero h1 {
  font-family: var(--heading-font);
  font-size: clamp(36px, 5vw, 64px);
  font-weight: 900;
  color: var(--white);
  line-height: 1.1;
  margin-bottom: 16px;
}
.speakers-header p { font-size: 18px; color: rgba(255,255,255,0.7); max-width: 560px; line-height: 1.6; }
.speakers-synced {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 20px; font-size: 12px; color: rgba(255,255,255,0.35);
  letter-spacing: 0.04em;
}

/* ── SPEAKERS SECTION + GRID ── */
.speakers-section { padding: 72px 48px; background: var(--ice); min-height: 400px; }
.speakers-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 28px;
  max-width: 1200px;
  margin: 0 auto;
}

/* ── SPEAKER CARD ── */
.speaker-card {
  background: var(--white);
  border: 1.5px solid #e2ecf7;
  border-radius: 14px;
  padding: 32px 28px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
}
.speaker-card:hover {
  border-color: var(--sky);
  box-shadow: 0 16px 48px rgba(21,101,192,0.1);
  transform: translateY(-4px);
}

/* ── SPEAKER PHOTO ── */
.speaker-photo-wrap { margin-bottom: 20px; }
.speaker-photo, .speaker-initials {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  object-fit: cover;
  object-position: top;
  display: block;
}
.speaker-photo { border: 3px solid var(--light-blue); }
.speaker-initials {
  background: linear-gradient(135deg, var(--navy), var(--blue));
  display: flex; align-items: center; justify-content: center;
  font-family: var(--heading-font);
  font-size: 64px; font-weight: 700;
  color: var(--white); letter-spacing: 0.04em;
  border: 3px solid rgba(33,150,243,0.2);
}

/* ── SPEAKER INFO ── */
.speaker-info { flex: 1; display: flex; flex-direction: column; width: 100%; }
.speaker-name {
  font-family: var(--heading-font);
  font-size: 20px; font-weight: 700;
  color: var(--navy); margin-bottom: 4px;
  line-height: 1.2;
}
.speaker-name a { color: inherit; text-decoration: none; transition: color 0.2s; }
.speaker-name a:hover { color: var(--blue); }
.speaker-title { font-size: 13px; font-weight: 600; color: var(--gold); margin-bottom: 2px; letter-spacing: 0.02em; }
.speaker-company { font-size: 13px; color: var(--muted); margin-bottom: 14px; }
.speaker-bio {
  font-size: 14px; color: var(--muted); line-height: 1.65;
  margin-bottom: 16px;
}

/* ── SESSION TAGS ── */
.speaker-sessions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 14px; }
.session-tag {
  background: var(--light-blue); color: var(--blue);
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  padding: 4px 10px; border-radius: 20px; line-height: 1.4;
}

/* ── TWITTER LINK ── */
.speaker-twitter {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--muted); text-decoration: none;
  margin-top: 10px; transition: color 0.2s;
}
.speaker-twitter:hover { color: var(--navy); }

/* ── EXPAND BUTTON ── */
.speaker-expand-btn {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 12px;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: 'DM Sans', sans-serif;
  font-size: 13px; font-weight: 600;
  color: var(--blue); letter-spacing: 0.02em;
  transition: color 0.2s, gap 0.2s;
}
.speaker-expand-btn:hover { color: var(--navy); gap: 8px; }

/* ── SPEAKER MODAL ── */
.speaker-modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(10,35,66,0.72);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  opacity: 0; pointer-events: none;
  transition: opacity 0.25s ease;
}
.speaker-modal-overlay[aria-hidden="false"] {
  opacity: 1; pointer-events: all;
}
body.modal-open { overflow: hidden; }

.speaker-modal {
  background: #fff;
  border-radius: 16px;
  box-shadow: 0 24px 80px rgba(10,35,66,0.3);
  max-width: 760px; width: 100%;
  max-height: 90vh; overflow-y: auto;
  position: relative;
  transform: translateY(16px);
  transition: transform 0.25s ease;
}
.speaker-modal-overlay[aria-hidden="false"] .speaker-modal {
  transform: translateY(0);
}

.speaker-modal-close {
  position: absolute; top: 16px; right: 16px; z-index: 10;
  background: rgba(10,35,66,0.08); border: none;
  width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--navy);
  transition: background 0.2s;
}
.speaker-modal-close:hover { background: rgba(10,35,66,0.16); }

.speaker-modal-inner {
  display: flex; gap: 36px; padding: 48px;
  align-items: flex-start;
}

/* Photo column */
.speaker-modal-photo-wrap { flex-shrink: 0; }
.speaker-modal-photo {
  width: 180px; height: 180px;
  border-radius: 50%; object-fit: cover; object-position: top;
  border: 4px solid var(--light-blue); display: block;
}
.speaker-modal-initials {
  width: 180px; height: 180px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--navy), var(--blue));
  display: flex; align-items: center; justify-content: center;
  font-family: var(--heading-font);
  font-size: 56px; font-weight: 700;
  color: #fff; letter-spacing: 0.04em;
}

/* Text column */
.speaker-modal-body { flex: 1; min-width: 0; }
.speaker-modal-name {
  font-family: var(--heading-font);
  font-size: 26px; font-weight: 700;
  color: var(--navy); margin-bottom: 6px; line-height: 1.2;
}
.speaker-modal-title {
  font-size: 13px; font-weight: 600; color: var(--gold);
  letter-spacing: 0.04em; margin-bottom: 2px;
}
.speaker-modal-company {
  font-size: 13px; color: var(--muted); margin-bottom: 20px;
}
.speaker-modal-bio {
  font-size: 15px; color: #374151; line-height: 1.75;
  margin-bottom: 20px;
}
.speaker-modal-sessions {
  display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px;
}
.speaker-modal-links {
  display: flex; flex-wrap: wrap; gap: 12px; margin-top: 4px;
}
.speaker-modal-link {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 13px; font-weight: 600; color: var(--blue);
  text-decoration: none; transition: color 0.2s;
}
.speaker-modal-link:hover { color: var(--navy); }

/* Modal responsive */
@media (max-width: 600px) {
  .speaker-modal-inner { flex-direction: column; align-items: center; padding: 36px 24px; gap: 24px; }
  .speaker-modal-body { text-align: center; }
  .speaker-modal-sessions, .speaker-modal-links { justify-content: center; }
}

/* ── EMPTY STATE ── */
.speakers-empty {
  max-width: 480px; margin: 64px auto; text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.speakers-empty h3 { font-family: var(--heading-font); font-size: 24px; color: var(--navy); }
.speakers-empty p { font-size: 15px; color: var(--muted); line-height: 1.6; }
.speakers-empty code { background: #eef2f7; padding: 2px 6px; border-radius: 4px; font-size: 13px; }

/* ── RESPONSIVE: speakers ── */
@media (max-width: 900px) {
  .speakers-header { padding: 120px 24px 56px; }
  .speakers-section { padding: 48px 24px; }
  .speakers-grid { grid-template-columns: 1fr 1fr; gap: 20px; }
}
@media (max-width: 600px) {
  .speakers-grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   AGENDA PAGE
   ═══════════════════════════════════════════════════════════════════════════════ */

.agenda-header { padding-bottom: 32px; }

/* ── Track filter pills ── */
.agenda-filters {
  display: flex; flex-wrap: wrap; gap: 8px;
  max-width: 900px; margin: 0 auto 28px;
  padding: 0 32px;
}
.agenda-filter-btn {
  padding: 7px 16px; border-radius: 20px; border: 2px solid transparent;
  font-family: 'DM Sans', sans-serif; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.18s ease;
  background: #eef2f7; color: var(--muted);
}
.agenda-filter-btn:hover { background: var(--light-blue); color: var(--blue); }
.agenda-filter-btn.active { background: var(--navy); color: #fff; border-color: var(--navy); }
.agenda-filter-btn[data-track]:not([data-track="all"]).active {
  background: var(--track-color, var(--blue));
  border-color: var(--track-color, var(--blue));
  color: #fff;
}

/* ── Day tabs ── */
.agenda-tabs {
  display: flex; gap: 0;
  max-width: 900px; margin: 0 auto 36px;
  padding: 0 32px;
  border-bottom: 2px solid #e2e8f0;
}
.agenda-tab {
  padding: 12px 24px; border: none; background: none;
  font-family: 'DM Sans', sans-serif; font-size: 14px; font-weight: 600;
  color: var(--muted); cursor: pointer;
  border-bottom: 3px solid transparent; margin-bottom: -2px;
  transition: color 0.18s, border-color 0.18s;
}
.agenda-tab:hover { color: var(--navy); }
.agenda-tab.active { color: var(--navy); border-bottom-color: var(--gold); }

/* ── Day panel ── */
.agenda-days { max-width: 900px; margin: 0 auto; padding: 0 32px 64px; }
.agenda-day { display: none; }
.agenda-day.active { display: block; }
.agenda-day-label {
  font-family: var(--heading-font);
  font-size: 22px; font-weight: 700; color: var(--navy);
  margin-bottom: 28px; padding-bottom: 12px;
  border-bottom: 2px solid var(--light-blue);
}

/* ── Session list ── */
.agenda-session-list { display: flex; flex-direction: column; gap: 12px; }

/* ── Session card ── */
.agenda-card {
  display: flex; gap: 0;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(10,35,66,0.07);
  overflow: hidden;
  transition: box-shadow 0.2s, transform 0.2s;
}
.agenda-card:hover {
  box-shadow: 0 6px 24px rgba(10,35,66,0.12);
  transform: translateY(-1px);
}

/* Time column */
.agenda-card-time {
  flex-shrink: 0; width: 140px;
  padding: 20px 20px;
  background: var(--navy);
  color: rgba(255,255,255,0.9);
  font-size: 13px; font-weight: 600;
  display: flex; flex-direction: column;
  align-items: flex-start; justify-content: center;
  line-height: 1.5;
  letter-spacing: 0.01em;
}
.agenda-time-sep { display: block; color: rgba(255,255,255,0.4); font-size: 11px; margin: 2px 0; }

/* Body column */
.agenda-card-body {
  flex: 1; padding: 20px 24px;
  display: flex; flex-direction: column; gap: 8px;
}
.agenda-session-name {
  font-family: var(--heading-font);
  font-size: 17px; font-weight: 700;
  color: var(--navy); line-height: 1.3; margin: 0;
}

/* Meta row (track + location) */
.agenda-card-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
}
.agenda-track-pill {
  display: inline-block;
  padding: 3px 10px; border-radius: 20px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.06em;
  color: #fff; text-transform: uppercase;
}
.agenda-location {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--muted); font-weight: 500;
}

/* Speakers row — icon + a stacked list so name/title/company read
   cleanly for both single- and multi-speaker sessions */
.agenda-speakers {
  display: flex; align-items: flex-start; gap: 6px;
  font-size: 13px; color: #374151; font-weight: 500;
}
.agenda-speakers svg { flex-shrink: 0; color: var(--muted); margin-top: 2px; }
.agenda-speaker-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.agenda-speaker-list li { line-height: 1.4; }
/* Clickable — opens the speaker-bio modal (shared with /speakers, see
   views/public/_speaker-modal.ejs). Reset button chrome so it reads as
   inline text, same as before it became clickable. */
.agenda-speaker-name {
  font: inherit; font-weight: 600; color: #374151;
  background: none; border: none; margin: 0; padding: 0;
  cursor: pointer; text-align: left;
}
.agenda-speaker-name:hover,
.agenda-speaker-name:focus-visible {
  color: var(--blue);
  text-decoration: underline;
}
.agenda-speaker-role { font-weight: 400; color: var(--muted); }

/* Session description (raw HTML from Swoogo WYSIWYG; only shown when non-empty) */
.agenda-session-description {
  margin-top: 4px;
  font-size: 14px; line-height: 1.55; color: #4b5563;
}
.agenda-session-description p { margin: 0 0 8px 0; }
.agenda-session-description p:last-child { margin-bottom: 0; }
.agenda-session-description a { color: var(--blue); text-decoration: underline; }
.agenda-session-description a:hover { opacity: 0.85; }
.agenda-session-description ul,
.agenda-session-description ol { margin: 0 0 8px 20px; padding: 0; }
.agenda-session-description img { max-width: 100%; height: auto; border-radius: 6px; margin: 4px 0; }
.agenda-session-description strong { color: #1f2937; }

/* ── Responsive ── */
@media (max-width: 700px) {
  .agenda-filters, .agenda-tabs, .agenda-days { padding: 0 16px; }
  .agenda-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .agenda-tab { padding: 12px 16px; white-space: nowrap; }
  .agenda-card { flex-direction: column; }
  .agenda-card-time {
    width: 100%; flex-direction: row; gap: 6px;
    padding: 10px 16px; align-items: center;
  }
  .agenda-time-sep { display: inline; margin: 0 4px; }
  .agenda-card-body { padding: 16px; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   FAQ SECTION
   ───────────────────────────────────────────────────────────────────────────── */
.faq-section { background: var(--ice); padding: 80px 48px; }
.faq-inner { max-width: 760px; margin: 0 auto; }
.faq-inner h2 {
  font-family: var(--heading-font);
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  color: var(--navy);
  margin-top: 16px;
  margin-bottom: 40px;
}

.faq-list { display: flex; flex-direction: column; gap: 0; }

.faq-item {
  border-top: 1px solid #d1dce8;
}
.faq-item:last-child { border-bottom: 1px solid #d1dce8; }

.faq-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 0;
  font-size: 17px;
  font-weight: 600;
  color: var(--navy);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
/* Remove default marker in all browsers */
.faq-question::-webkit-details-marker { display: none; }
.faq-question::marker { display: none; }

.faq-chevron {
  flex-shrink: 0;
  color: var(--blue);
  transition: transform 0.25s ease;
}
.faq-item[open] .faq-chevron { transform: rotate(180deg); }

.faq-answer {
  padding: 0 0 20px;
  animation: faqFadeIn 0.2s ease;
}
.faq-answer p {
  font-size: 16px;
  color: var(--muted);
  line-height: 1.8;
  margin: 0;
}

@keyframes faqFadeIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .faq-chevron { transition: none; }
  .faq-answer  { animation: none; }
}

@media (max-width: 700px) {
  .faq-section  { padding: 56px 24px; }
  .faq-question { font-size: 15px; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   SPONSORS PAGE
   ───────────────────────────────────────────────────────────────────────────── */
.sponsors-page { min-height: 100vh; background: var(--white); }

/* Page header — left-justified to match the agenda hero. Top padding
   bumped from 80px to 140px so above-text spacing matches every other
   page hero. */
.sponsors-header {
  background: var(--navy);
  padding: 140px 48px 64px;
  text-align: left;
}
.sponsors-header-inner { max-width: 1200px; margin: 0 auto; }
.sponsors-header .section-eyebrow { color: var(--gold); }
.sponsors-header .section-eyebrow::before { background: var(--gold); }
/* Typography for .sponsors-header h1 lives in the unified hero-h1
   rule above. Top margin removed; the eyebrow's own margin-bottom
   creates the spacing between eyebrow and headline. */
.sponsors-header p {
  color: rgba(255,255,255,0.65);
  font-size: 17px;
  max-width: 560px;
  margin: 16px 0 0;
  line-height: 1.7;
}

/* Tier sections */
.sponsors-body { max-width: 1200px; margin: 0 auto; padding: 64px 48px 80px; }

.sp-tier { margin-bottom: 64px; }
.sp-tier:last-of-type { margin-bottom: 0; }

.sp-tier-header {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 32px;
}
.sp-tier-label {
  font-family: var(--heading-font);
  font-size: clamp(1.3rem, 2.5vw, 1.75rem);
  color: var(--navy);
  font-weight: 700;
}
.sp-tier-line {
  flex: 1; height: 1px; background: var(--light-blue);
}
.sp-tier-count {
  font-size: 0.78rem; color: var(--muted);
  background: var(--light-blue); padding: 3px 10px; border-radius: 10px;
  font-weight: 600; white-space: nowrap;
}

/* Logo grids — three size tiers */
.sp-grid {
  display: grid;
  gap: 20px;
}
.sp-grid-large  { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
.sp-grid-medium { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.sp-grid-small  { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }

/* Individual sponsor card */
.sp-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--white);
  border: 1.5px solid var(--border, #e2e8f0);
  border-radius: 10px;
  padding: 16px;
  text-decoration: none;
  color: var(--text);
  transition: box-shadow 0.2s, border-color 0.2s, transform 0.2s;
}
.sp-card:hover {
  box-shadow: 0 6px 24px rgba(0,0,0,0.1);
  border-color: var(--blue);
  transform: translateY(-2px);
}
.sp-card-inner { display: flex; flex-direction: column; align-items: center; width: 100%; }

/* 1.5:1 logo box (width:height = 3:2) */
.sp-logo-box {
  width: 100%;
  aspect-ratio: 3 / 2;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #f8fafc;
  border-radius: 6px;
  padding: 12px;
}
.sp-logo-box img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

/* Company name below logo box — always shown */
.sp-sponsor-name {
  font-size: 0.78rem;
  font-weight: 500;
  text-align: center;
  color: var(--text);
  margin-top: 10px;
  line-height: 1.3;
  word-break: break-word;
}

/* "Become a Sponsor" CTA at page bottom */
.sponsors-cta {
  background: var(--ice);
  border-top: 1px solid var(--light-blue);
  padding: 64px 48px;
  text-align: center;
}
.sponsors-cta h2 {
  font-family: var(--heading-font);
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  color: var(--navy);
  margin-bottom: 12px;
}
.sponsors-cta p {
  color: var(--muted);
  font-size: 16px;
  max-width: 520px;
  margin: 0 auto 28px;
  line-height: 1.7;
}
.sponsors-cta-actions { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }

/* Empty state */
.sponsors-empty {
  text-align: center;
  padding: 80px 48px;
  color: var(--muted);
}
.sponsors-empty p { font-size: 16px; margin-top: 8px; }

/* Responsive */
@media (max-width: 900px) {
  .sponsors-header { padding: 120px 24px 48px; }  /* mobile top padding aligned to agenda's 120px */
  .sponsors-body   { padding: 48px 24px 64px; }
  .sponsors-cta    { padding: 48px 24px; }
}
@media (max-width: 600px) {
  .sp-grid-large, .sp-grid-medium { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .sp-grid-small  { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); }
}

/* ─── ACTIVITIES PAGE ────────────────────────────────────────────────────── */
.activities-header {
  background: var(--navy);
  /* Top padding bumped from 80px to 140px so above-text spacing matches
     every other page hero. Left-justified to match the agenda hero. */
  padding: 140px 48px 64px;
  text-align: left;
}
.activities-header-inner { max-width: 1200px; margin: 0 auto; }
.activities-header .section-eyebrow { color: var(--gold); }
.activities-header .section-eyebrow::before { background: var(--gold); }

/* ── EXHIBITORS PAGE ────────────────────────────────────────────────────────
   Free-form recruitment surface: hero strip on top of the standard nav-aware
   page padding, then a body region with an admin-managed sequence of
   WYSIWYG blocks and a smart-distributed button grid below them.

   NOTE: do NOT add a `.exhibitors-page section { padding: 0 }` reset here —
   it would clobber the body section's vertical padding via element-selector
   specificity. Explicit per-element padding below is the right way.
*/
.exhibitors-hero {
  background: var(--navy);
  color: #fff;
  padding: 140px 48px 80px;
  /* Left-justified to match the agenda hero. Was text-align: center
     during the initial build; the wider site treatment leans
     left-aligned across sub-page heroes for consistency. */
  text-align: left;
}
.exhibitors-hero-inner { max-width: 1200px; margin: 0 auto; }
/* Typography for .exhibitors-hero h1 lives in the unified hero-h1
   rule above. Page-specific top margin removed; the shared rule
   uses margin-bottom: 16px and inherits zero top margin. */
.exhibitors-hero-subhead {
  font-family: var(--heading-font);
  font-size: clamp(22px, 3vw, 32px);
  font-weight: 600;
  color: rgba(255,255,255,0.88);
  margin: 0;
}

/* Body section gets deliberately more vertical padding than other site
   sections (120px vs. the global 96px default) so the page reads as a
   focused recruitment surface with clear breathing room above the
   headline and below the button stack. */
.exhibitors-body { padding: 120px 48px; background: var(--bg, #f4f6f9); }
.exhibitors-body-inner { max-width: 920px; margin: 0 auto; }
.exhibitors-body-headline {
  font-family: var(--heading-font);
  font-size: clamp(28px, 4vw, 38px);
  color: var(--navy);
  font-weight: 700;
  text-align: center;
  margin: 0 0 32px;
}
.exhibitors-body-block {
  font-size: 16px;
  line-height: 1.7;
  color: #1a1a2e;
  margin-bottom: 24px;
}
.exhibitors-body-block:last-child { margin-bottom: 32px; }
.exhibitors-body-block p { margin-bottom: 12px; }
.exhibitors-body-block p:last-child { margin-bottom: 0; }
.exhibitors-body-block ul,
.exhibitors-body-block ol { margin: 0 0 16px 24px; }
.exhibitors-body-block li { margin-bottom: 6px; }
.exhibitors-body-block a { color: var(--blue); text-decoration: underline; }
.exhibitors-body-block strong { color: var(--navy); }

/* Smart-distributed button grid.
   Each row is an independent flex container with `flex: 1 1 0` children, so
   N children share the row's width equally — N comes from data-cols set
   server-side by the distribution algorithm. */
.exhibitors-button-stack {
  display: flex; flex-direction: column;
  gap: 16px; margin-top: 28px;
}
.exhibitors-button-row { display: flex; gap: 16px; flex-wrap: nowrap; }
.exhibitors-button-row .btn-primary {
  flex: 1 1 0; min-width: 0; text-align: center;
  padding: 16px 18px; box-sizing: border-box;
}
/* On narrow viewports the multi-column rows would crowd; stack to 1-per-row. */
@media (max-width: 640px) {
  .exhibitors-button-row { flex-wrap: wrap; }
  .exhibitors-button-row .btn-primary { flex: 1 1 100%; }
}
/* Typography for .activities-header h1 lives in the unified hero-h1
   rule above. Top margin removed; the eyebrow's own margin-bottom
   creates the spacing between eyebrow and headline. */
.activities-header p {
  color: rgba(255,255,255,0.65);
  font-size: 17px;
  max-width: 640px;
  /* Was `16px auto 0` (centered via auto horizontal); switched to
     left-aligned to match the agenda hero. */
  margin: 16px 0 0;
  line-height: 1.7;
}

.activities-body {
  max-width: 1200px;
  margin: 0 auto;
  padding: 64px 48px 40px;
}

.act-group { margin-bottom: 64px; }
.act-group:last-of-type { margin-bottom: 0; }

.act-group-header {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 28px;
}
.act-group-label {
  font-family: var(--heading-font);
  font-size: clamp(1.4rem, 2.4vw, 1.85rem);
  color: var(--navy);
  margin: 0;
  flex-shrink: 0;
}
.act-group-line {
  flex: 1;
  height: 1px;
  background: var(--border, #e5e7eb);
}
.act-group-count {
  font-size: 0.85rem;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.act-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 18px;
}

.act-card {
  background: #fff;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 10px;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}
.act-card:hover {
  border-color: var(--gold, #c9a84c);
  box-shadow: 0 6px 20px rgba(0,0,0,0.04);
  transform: translateY(-2px);
}

.act-card-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 6px;
}
.act-name {
  font-family: var(--heading-font);
  font-size: 1.2rem;
  color: var(--navy);
  margin: 0;
  line-height: 1.25;
}
.act-cost {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--gold, #c9a84c);
  white-space: nowrap;
  flex-shrink: 0;
}
.act-category {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 12px;
}
.act-description {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text, #1a1a1a);
  margin: 0 0 14px;
  flex: 1;
}
.act-description a { color: var(--blue); text-decoration: none; }
.act-description a:hover { text-decoration: underline; }
.act-notes {
  font-size: 0.85rem;
  color: var(--muted);
  border-top: 1px solid #f1f1f1;
  padding-top: 10px;
  line-height: 1.5;
  word-break: break-word;
}
.act-notes a { color: var(--blue); text-decoration: none; }
.act-notes a:hover { text-decoration: underline; }

.activities-footer-note {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 48px 64px;
  font-size: 0.85rem;
  color: var(--muted);
  text-align: center;
  line-height: 1.6;
}

.activities-empty {
  text-align: center;
  padding: 80px 48px;
  color: var(--muted);
}
.activities-empty p { font-size: 16px; margin-top: 8px; }

@media (max-width: 900px) {
  .activities-header { padding: 120px 24px 48px; }  /* mobile top padding aligned to agenda's 120px */
  .activities-body   { padding: 48px 24px 32px; }
  .activities-footer-note { padding: 0 24px 48px; }
}
@media (max-width: 600px) {
  .act-grid { grid-template-columns: 1fr; }
  .act-card-top { flex-direction: column; gap: 4px; }
  .act-cost { align-self: flex-start; }
}

/* ── SUB EVENT PAGES (admin-created standalone pages) ────────────────────────
   Hero styled like .speakers-header (compact navy strip + optional bg image,
   not the full-viewport homepage .hero). Event Details styled like .hotel
   (dark navy, two-column: text left, optional photo right). Sponsors keeps
   its own light section reusing .sp-grid / .sp-card / .sp-card-inner /
   .sp-logo-box from the /sponsors page (same clickable-logo-tile pattern). */

/* Hero — see views/public/sub-event.ejs. Mirrors .speakers-header exactly
   (background, padding, radial glow, optional bg-image handling); h1 joins
   the unified hero-h1 rule below so headline typography stays consistent
   with every other page hero. */
.subevent-hero {
  background: var(--navy); padding: 140px 48px 72px;
  position: relative; overflow: hidden;
}
.subevent-hero--img::before { display: none; }
.subevent-hero::before {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 80% 60% at 70% 50%, rgba(33,150,243,0.14) 0%, transparent 70%);
  pointer-events: none;
}
.subevent-hero--img {
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
.subevent-hero-inner { max-width: 1200px; margin: 0 auto; position: relative; }
.subevent-hero-body { font-size: 18px; color: rgba(255,255,255,0.7); max-width: 640px; line-height: 1.6; margin-top: 4px; }
.subevent-hero-body p { margin: 0 0 12px; }
.subevent-hero-body p:last-child { margin-bottom: 0; }
.subevent-hero-body ul, .subevent-hero-body ol { margin: 0 0 12px 24px; padding: 0; }
.subevent-hero-body li { margin-bottom: 4px; }
.subevent-hero-body a { color: var(--gold); text-decoration: underline; }
.subevent-hero-body strong { color: #fff; font-weight: 600; }
/* Defensive: see the matching comment on .subevent-details-body below —
   pasted WYSIWYG content can carry inline colors that fight this section's
   theme. New saves are sanitized server-side; this covers content saved
   before that existed (or via any path that skips it). */
.subevent-hero-body, .subevent-hero-body * { color: inherit !important; }
.subevent-hero-body { color: rgba(255,255,255,0.7) !important; }
.subevent-hero-body a { color: var(--gold) !important; }
.subevent-hero-body strong { color: #fff !important; }

/* Event Details — mirrors .hotel exactly, including the screened-back
   backdrop image trick: --subevent-details-bg-image is set inline by the
   EJS from event_details.image (same field feeds the foreground photo in
   .subevent-details-img-wrap). No image → --subevent-details-bg-image is
   unset, ::before falls back to `none`, and .subevent-details--no-image
   collapses the grid to a single centered text column. */
.subevent-details { background: var(--navy); position: relative; overflow: hidden; padding: 96px 48px; }
.subevent-details::before {
  content: ''; position: absolute; inset: 0;
  background-image: var(--subevent-details-bg-image, none);
  background-position: center; background-size: cover; background-repeat: no-repeat;
  opacity: 0.12;
}
.subevent-details-inner {
  max-width: 1200px; margin: 0 auto; display: grid;
  grid-template-columns: 1fr 1fr; gap: 80px; align-items: center;
  position: relative; z-index: 1;
}
.subevent-details--no-image .subevent-details-inner { grid-template-columns: 1fr; max-width: 800px; }
.subevent-details h2 { color: var(--white); }
/* Body copy sits inside a bordered/tinted card so the section reads with
   the same "visual interest" as the homepage Accommodations section's
   .hotel-detail boxes, instead of floating text directly on the navy
   background. */
.subevent-detail-card {
  margin-top: 28px; padding: 24px; border-radius: 10px;
  background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1);
}
.subevent-details-body { color: rgba(255,255,255,0.7); font-size: 17px; line-height: 1.8; }
.subevent-details-body p { margin: 0 0 16px; }
.subevent-details-body p:last-child { margin-bottom: 0; }
.subevent-details-body ul, .subevent-details-body ol { margin: 0 0 16px 24px; padding: 0; }
.subevent-details-body li { margin-bottom: 6px; }
.subevent-details-body a { color: var(--gold); text-decoration: underline; }
.subevent-details-body strong { color: var(--white); }
/* Defensive: WYSIWYG paste (Word/Google Docs) commonly carries inline
   `style="color: rgb(...)"` on every <span> it produces. Because that
   style sits directly on the element, it beats any external rule short of
   !important — which is exactly why real content pasted from Word showed
   up as near-illegible dark text on this dark section. New saves are
   sanitized server-side (stripForcedTextColors in lib/sub-events.js), but
   this keeps already-saved content readable too. */
.subevent-details-body, .subevent-details-body * { color: inherit !important; }
.subevent-details-body { color: rgba(255,255,255,0.7) !important; }
.subevent-details-body a { color: var(--gold) !important; }
.subevent-details-body strong { color: var(--white) !important; }
.subevent-details-img-wrap { border-radius: 12px; overflow: hidden; box-shadow: 0 40px 80px rgba(0,0,0,0.5); position: relative; z-index: 1; }
.subevent-details-img-wrap img { width: 100%; display: block; aspect-ratio: 4/3; object-fit: cover; }

/* Sponsors — now sit in the hero, above the headline. "Sponsored by" label
   plus a row of logo tiles (reusing the .sp-card/.sp-logo-box structure from
   the /sponsors page for the card look + hover + link behavior), scoped
   down to a fixed, compact size appropriate for sharing space with the
   hero headline: 200px logo box, logo itself capped at 170px on its
   longer side. */
.subevent-hero-sponsors { margin-top: 24px; }
/* Tapered divider between the sponsor row and the body paragraphs below it
   (only rendered when there are any to separate from — see sub-event.ejs).
   Capped at the same max-width as the paragraph column so it reads as part
   of that text block rather than spanning the full hero width. */
.subevent-hero-sponsors-divider {
  border: none; height: 1px; max-width: 640px; margin: 24px 0 4px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.22), transparent);
}
.subevent-hero-sponsors-label {
  color: rgba(255,255,255,0.55); font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 14px;
}
.subevent-hero-sponsors-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px; }
/* .sp-card/.sp-card-inner were built for a fixed-width grid cell (see
   .sp-grid elsewhere) where align-items:stretch + width:100% just fill
   that cell. Here each card should instead shrink-to-fit its own logo box,
   so pin both to hug their content directly rather than stretch/percentage
   against a width this row doesn't set. */
.subevent-hero-sponsors-row .sp-card { padding: 15px; align-items: center; }
.subevent-hero-sponsors-row .sp-card-inner { width: auto; }
/* The box hugs its own logo's aspect ratio instead of forcing every logo
   into a fixed square: width/height are auto (sized to the logo once it's
   been scaled down to fit), with max-width/max-height as the only caps. A
   wide logo yields a wide, short box; a tall logo yields a narrow, taller
   box — each still bounded by the same 200px box / 170px logo limits as
   before. */
.subevent-hero-sponsors-row .sp-logo-box {
  display: inline-flex; width: auto; height: auto;
  max-width: 200px; max-height: 200px;
  aspect-ratio: unset; padding: 15px;
}
.subevent-hero-sponsors-row .sp-logo-box img {
  width: auto; height: auto; max-width: 170px; max-height: 170px;
}

@media (max-width: 900px) {
  .subevent-hero            { padding: 120px 24px 56px; }
  .subevent-details         { padding: 64px 24px; }
  .subevent-details-inner   { grid-template-columns: 1fr; gap: 40px; }
  .subevent-hero-sponsors-row .sp-logo-box { max-width: 130px; max-height: 130px; }
  .subevent-hero-sponsors-row .sp-logo-box img { max-width: 110px; max-height: 110px; }
}

/* ── BUYERS (homepage rotating logo grid) ──────────────────────────────────
   Column count lives in --buyers-cols so views/public/_buyers.ejs's script
   can read it and paginate cols × 2 logos per set:
   6 desktop (≥1024px) · 4 tablet (640–1023px) · 3 mobile (<640px).
   Without JS the grid simply shows every logo. */
.buyers-section { background: var(--white); padding: 96px 48px; border-bottom: 1px solid #e2ecf7; }
.buyers-inner { max-width: 1200px; margin: 0 auto; }
.buyers-header { margin-bottom: 48px; }
.buyers-header p { font-size: 16px; color: var(--muted); margin-top: 16px; max-width: 720px; }
.buyers-grid {
  --buyers-cols: 6;
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(var(--buyers-cols), minmax(0, 1fr)); gap: 16px;
  transition: opacity 0.35s ease;
}
.buyers-grid.is-fading { opacity: 0; }
.buyer-logo {
  background: var(--white); border: 1.5px solid #e2ecf7; border-radius: 12px;
  aspect-ratio: 3 / 2; display: flex; align-items: center; justify-content: center;
  padding: 12%; overflow: hidden;
  transition: transform 0.2s, box-shadow 0.2s;
}
.buyer-logo:hover { transform: translateY(-3px); box-shadow: 0 12px 32px rgba(21,101,192,0.10); }
.buyer-logo a { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.buyer-logo img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; display: block; }
.buyers-dots { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.buyers-dot {
  width: 9px; height: 9px; border-radius: 50%; border: none; padding: 0; cursor: pointer;
  background: #cfdcec; transition: background 0.2s, transform 0.2s;
}
.buyers-dot.is-active { background: var(--blue); transform: scale(1.25); }
.buyers-dot:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }
@media (max-width: 1023px) {
  .buyers-grid { --buyers-cols: 4; }
}
@media (max-width: 900px) {
  .buyers-section { padding: 72px 24px; }
}
@media (max-width: 639px) {
  .buyers-grid { --buyers-cols: 3; gap: 10px; }
  .buyer-logo { border-radius: 8px; padding: 10%; }
}
@media (prefers-reduced-motion: reduce) {
  .buyers-grid, .buyer-logo { transition: none; }
}
