/* ============================================================
   BRAND USA TRAVEL WEEK — U.K. & EUROPE 2026
   Global design system for the standalone site.
   Direction: "Wayfinder" — dark navy→ink theme, mint accent only,
   Oswald (light display headlines, single color) + Montserrat body.
   The nav + footer are injected by assets/js/site.js; edit shared
   shell markup there and shared styling here in ONE place.
   ============================================================ */

/* ---------- Design tokens ---------- */
:root {
  --navy:        #101F36;   /* primary background */
  --navy-2:      #17263f;   /* raised surface */
  --navy-3:      #0e1c31;   /* alternate section band */
  --ink:         #0c1728;   /* deepest panel (hero, get-involved) */
  --footer:      #0a1526;   /* footer base */
  /* RGB components of --navy / --ink, for translucent overlays (nav bar,
     hero scrim). Per-event themes override these alongside the hex tokens so
     overlays stay in-palette instead of bleeding navy over another color. */
  --navy-rgb:    16, 31, 54;
  --ink-rgb:     12, 23, 40;
  --mint:        #D3E798;   /* accent ONLY — never a background fill behind copy */
  --mint-rgb:    211, 231, 152;  /* RGB of --mint, for accent tints/glows/underlines (override per event) */
  --dblue:       #4C5768;
  --bgray:       #808A97;
  --warm-1:      #D1BD8B;
  --warm-3:      #E7DDC4;

  --white:       #ffffff;
  --text:        #e8edf2;   /* body copy */
  /* Brightened from #a2b0bf on 2026-08-12: design review (Mimi Jung) found the
     old value blending into the grey-blue surfaces. This is the value already
     used under Venue on the Europe home page, which she signed off on. */
  --text-muted:  #d6dee6;
  --text-faint:  #8fa0b0;
  --hairline:    rgba(255, 255, 255, 0.10);
  --hairline-2:  rgba(255, 255, 255, 0.06);
  --surface:     rgba(255, 255, 255, 0.03);
  --surface-2:   rgba(255, 255, 255, 0.055);

  --font-display: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body:    'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --maxw:        1240px;
  --pad-x:       clamp(20px, 4vw, 32px);
  --radius:      8px;
  --nav-h:       96px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 400;
  color: var(--text);
  background: var(--navy);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
a { color: var(--mint); text-decoration: none; }
address { font-style: normal; }

/* ---------- Layout helpers ---------- */
.container, .wrap {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad-x);
  width: 100%;
}
.section { padding: 100px 0; }
/* NO section's content butts against the top of the page. A section
   that follows the hero gets a reduced top padding rather than the
   full 100px — and never zero, which is what eleven pages were doing
   with an inline `padding-top:0` (Kat 2026-09-08: "that should be a
   templated thing ... no content for a section should butt up to the
   very top"). It is a rule here rather than a per-page style so every
   event and every page gets it, including ones built later. */
.page-hero + .section { padding-top: 56px; }
.section--tint { background: var(--navy-3); border-top: 1px solid var(--hairline-2); }
.section--narrow { max-width: 760px; }
@media (max-width: 768px) { .section { padding: 64px 0; } }

/* ---------- Typography ----------
   Wayfinder: display headlines are Oswald LIGHT, single color, mixed case.
   Small labels (eyebrows, buttons, day/slot labels) stay uppercase + tracked. */
h1, h2, h3, h4, .osw {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--white);
  margin: 0;
  line-height: 1.1;
  letter-spacing: .01em;
}
p { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

.eyebrow {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .3em;
  font-size: 14px;
  font-weight: 400;
  color: var(--mint);
  margin: 0 0 16px;
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.eyebrow--line::before { content: ""; width: 44px; height: 1px; background: var(--mint); flex-shrink: 0; }

.h-xl { font-size: clamp(36px, 5.6vw, 66px); font-weight: 300; }
.h-lg { font-size: clamp(30px, 4.4vw, 50px); font-weight: 300; }
.h-md { font-size: clamp(24px, 3vw, 36px); font-weight: 300; }
.h-sm { font-size: clamp(19px, 2.2vw, 25px); font-weight: 400; color: var(--mint); }

.subtitle-accent {
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .16em;
  font-weight: 400;
  color: var(--mint);
  font-size: 15px;
}

.lead { font-size: 17px; color: var(--text-muted); max-width: 640px; }
.muted { color: var(--text-muted); }
.center { text-align: center; }
.mx-auto { margin-inline: auto; }

/* Untitled intro statement — a centered lead paragraph with a small accent
   rule, so an event overview reads as a deliberate statement (no heading). */
.intro-statement { max-width: 800px; margin: 0 auto; text-align: center; }
.intro-statement .rule { width: 52px; height: 2px; background: var(--mint); margin: 0 auto 30px; }
.intro-statement p { font-size: clamp(20px, 2.4vw, 28px); font-weight: 300; line-height: 1.5; color: var(--white); }
.intro-statement p + p { font-size: 16px; font-weight: 400; color: var(--text-muted); line-height: 1.7; margin-top: 20px; }

/* Centered section head (used by home + interior) */
.center-head { text-align: center; max-width: 720px; margin: 0 auto 44px; }
.center-head .eyebrow { display: block; margin-bottom: 12px; }
.center-head h2 { font-size: clamp(30px, 4.4vw, 50px); font-weight: 300; }

/* Section head with index marker */
.shead { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; margin-bottom: 48px; border-bottom: 1px solid var(--hairline); padding-bottom: 20px; }
.shead h2 { font-size: clamp(30px, 4.4vw, 50px); font-weight: 300; }
.shead .idx { font-family: var(--font-display); color: var(--mint); letter-spacing: .2em; font-size: 15px; white-space: nowrap; text-transform: uppercase; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 15px 34px;
  border-radius: 2px;
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .14em;
  cursor: pointer;
  border: 1px solid var(--mint);
  transition: transform .2s ease, box-shadow .2s ease, background-color .2s ease, color .2s ease;
  white-space: nowrap;
}
.btn svg { width: 14px; height: 14px; flex-shrink: 0; }
/* Primary = the single intentional mint fill (approved). */
.btn--primary { background: var(--mint); color: var(--navy); }
.btn--primary:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(var(--mint-rgb),.22); }
.btn--ghost { background: transparent; color: var(--white); border-color: rgba(255,255,255,.35); }
.btn--ghost:hover { border-color: var(--mint); color: var(--mint); }
.btn--solid { background: var(--navy-2); color: var(--white); border-color: var(--hairline); }
.btn--solid:hover { background: var(--mint); color: var(--navy); border-color: var(--mint); }
.btn[disabled], .btn.is-disabled { opacity: .55; cursor: default; pointer-events: none; }

/* ---------- Cards & grids ---------- */
.grid { display: grid; gap: 24px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; } }

.card {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: 28px;
}
.card h3 { color: var(--white); font-weight: 400; font-size: 1.5rem; margin-bottom: 14px; }
.card p { color: var(--text-muted); font-size: 14px; }
.card--pad-lg { padding: 36px; }

/* Stat figure inside a .card — a big accent number over the card's label + copy.
   For market/impact stats (e.g. India's Market Landscape). Additive + opt-in:
   only affects a .card that contains a .statnum, so every event is unchanged. */
.card .statnum { display: block; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(36px, 4.4vw, 54px); line-height: 1; color: var(--mint); margin-bottom: 12px; }
.card .statnum ~ h3 { font-size: 1.2rem; }

/* Icon/label list */
.feature { display: flex; gap: 14px; align-items: flex-start; }
.feature__icon { flex-shrink: 0; width: 22px; height: 22px; color: var(--mint); margin-top: 2px; }
.feature__title { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.05rem; letter-spacing: .02em; margin-bottom: 4px; }
.feature p { color: var(--text-muted); font-size: 14px; margin: 0; }

/* ---------- Page hero (interior pages) ---------- */
/* Top offset scales with the viewport (2026-08-12 design review): the flat
   72px pushed the first CTA below the fold on mobile. */
.page-hero { padding: calc(var(--nav-h) + clamp(24px, 4.5vw, 56px)) 0 clamp(38px, 4.5vw, 60px); position: relative; background: var(--ink); border-bottom: 1px solid var(--hairline-2); }
/* SITE-WIDE, phones only. The hero pads by the nav height on top of the space
   the nav already occupies, so every page opened with ~110px of nothing before
   its eyebrow. On the Sessions page that helped push the first session 827px
   down the screen (Kat 2026-09-09). Desktop is untouched. */
@media (max-width: 620px) {
  .page-hero { padding-top: clamp(28px, 7vw, 44px); padding-bottom: 30px; }
  .page-hero__title { font-size: 34px; margin-bottom: 14px; }
  .page-hero__sub { font-size: 15px; }
  .page-hero + .section { padding-top: 30px; }
  .ag-controls { margin-bottom: 24px; }
  .ag-find { margin-bottom: 26px; }
}
.page-hero__title { font-size: clamp(38px, 6vw, 68px); font-weight: 300; color: var(--white); margin-bottom: 20px; }
.page-hero__sub { color: var(--text-muted); font-size: 16px; max-width: 680px; }
.page-hero__sub strong { color: var(--mint); font-weight: 600; }

/* Qualifier note that belongs to the page header (e.g. Leadership Track's
   "Add-on track" line). It lives INSIDE .page-hero: as its own section it fell
   into a sliver of body background between the hero and the next tinted band,
   which read as a broken strip (2026-08-12, Kat). Shared so every event's
   equivalent note renders identically. */
.page-hero__note {
  margin-top: 34px; max-width: 760px; font-size: 14px;
  border-left: 2px solid var(--mint); padding-left: 16px;
}
.page-hero__note strong { color: var(--white); }

/* ---------- Pricing table ---------- */
.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
@media (max-width: 900px) { .price-grid { grid-template-columns: 1fr; } }
.price-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 30px; }
.price-card__label { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.4rem; letter-spacing: .02em; }
.price-card__amount { font-family: var(--font-display); font-weight: 500; color: var(--mint); font-size: 2.4rem; margin: 8px 0; }
.price-card__note { color: var(--text-muted); font-size: 13px; }

/* Badge */
.badge {
  display: inline-block; font-family: var(--font-body); font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 1px; color: var(--navy);
  background: var(--mint); border-radius: 20px; padding: 4px 12px;
}

/* ---------- Timeline ---------- */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline li {
  display: grid; grid-template-columns: 160px 1fr; gap: 20px;
  padding: 16px 0; border-bottom: 1px solid var(--hairline); align-items: baseline;
}
.timeline li:last-child { border-bottom: none; }
.timeline .t-date { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.05rem; }
.timeline .t-label { color: var(--text); font-size: 15px; }
.timeline li.is-active { background: linear-gradient(90deg, rgba(var(--mint-rgb),.08), transparent); border-radius: 4px; }
.timeline li.is-active .t-date { color: var(--mint); }
.timeline li.is-active .t-label { color: var(--white); }
@media (max-width: 560px) { .timeline li { grid-template-columns: 1fr; gap: 4px; } }

/* Agenda — schedule-of-the-day module. A CENTERED vertical rail: time on the
   left (right-aligned), node dots on the center line, activity on the right
   (left-aligned). Deliberately distinct from the .timeline / .dcols dated
   lists. Rows with no set time leave the time side empty (no placeholder). */
.agenda { list-style: none; margin: 0 auto; padding: 0; position: relative; width: 100%; max-width: 820px; }
.agenda::before {   /* center rail line */
  content: ""; position: absolute; left: 50%; top: 16px; bottom: 16px;
  width: 2px; transform: translateX(-50%); background: var(--hairline);
}
/* Two real columns (time | activity); the rail + node dot are absolutely
   positioned on the center seam, so both sides get a full half of the width. */
.agenda__item {
  display: grid; grid-template-columns: 1fr 1fr; align-items: center;
  padding: 14px 0; position: relative;
}
.agenda__item::before {   /* node dot on the rail */
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 12px; height: 12px; border-radius: 50%; background: var(--navy);
  border: 2px solid var(--mint); z-index: 1;
}
.agenda__time { text-align: right; padding-right: 30px; font-family: var(--font-display); font-weight: 500; color: var(--mint); font-size: 1.02rem; letter-spacing: .01em; }
.agenda__act  { text-align: left;  padding-left: 30px;  color: var(--white); font-size: 15px; line-height: 1.45; }
@media (max-width: 600px) {
  .agenda { max-width: none; }
  .agenda::before { left: 9px; }
  .agenda__item { grid-template-columns: 1fr; gap: 2px; padding: 12px 0 12px 32px; }
  .agenda__item::before { left: 9px; }
  .agenda__time { text-align: left; padding-right: 0; }
  .agenda__act  { padding-left: 0; }
}

/* ---------- FAQ accordion ---------- */
.faq { border-top: 1px solid var(--hairline); }
.faq__item { border-bottom: 1px solid var(--hairline); }
.faq__q {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  color: var(--white); font-family: var(--font-body); font-weight: 600; font-size: 15px;
  padding: 20px 40px 20px 0; position: relative; display: block;
}
.faq__q::after {
  content: "+"; position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  color: var(--mint); font-size: 22px; font-weight: 400; transition: transform .25s ease;
}
.faq__item.is-open .faq__q::after { transform: translateY(-50%) rotate(45deg); }
.faq__a { max-height: 0; overflow: hidden; transition: max-height .3s ease; }
.faq__a-inner { padding: 0 40px 22px 0; color: var(--text-muted); font-size: 14px; }
.faq__item.is-open .faq__a { max-height: 800px; }

/* ---------- Registration state visibility ---------- */
[data-state] { display: none; }
.reg--pre-open   [data-state~="pre-open"],
.reg--open       [data-state~="open"],
.reg--closed     [data-state~="closed"],
.reg--post-notify[data-state~="post-notify"] { display: revert; }

/* ============================================================
   NAVIGATION (full IA, dropdowns + mobile panel)
   ============================================================ */
header.site {
  position: sticky; top: 0; z-index: 90;
  backdrop-filter: blur(12px);
  background: rgba(var(--navy-rgb),.82);
  border-bottom: 1px solid var(--hairline-2);
}
.nav { display: flex; align-items: center; justify-content: space-between; height: var(--nav-h); gap: 20px; }
.nav .logo { flex: 0 0 auto; }
.nav .logo img { height: 34px; display: block; width: auto; }
/* margin-left:auto pins the menu to the right of the header on every market.
   .nav is space-between, which puts the menu hard right while its only other
   desktop child is the logo - true on Europe, Canada and India. Latin America
   added a third child, the language switcher, and space-between then parked
   the menu in the middle of the row. Kat 2026-09-18: "the menu aligned to the
   right like all the other Travel Weeks... this one looks like it's centered."
   No-op on the markets with no switcher: the menu was already at the edge. */
.menu { display: flex; align-items: center; gap: 4px; list-style: none; margin: 0 0 0 auto; padding: 0; }
.menu > li { position: relative; }
.menu > li > a, .menu > li > span {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 14px;
  color: #c3cdd8; padding: 12px; cursor: pointer; transition: color .2s;
  /* A two-word item ("Brand USA", "Travel Agents") broke onto two lines once
     the log-in button joined the row and took its width. Keep every item on
     one line; the padding step below is what buys the space back. */
  white-space: nowrap;
}

.menu > li > a:hover, .menu > li:hover > span, .menu > li.is-current > a { color: var(--mint); }
.menu .caret { width: 7px; height: 7px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); margin-top: -3px; opacity: .7; }
.submenu {
  position: absolute; top: 100%; left: 0; min-width: 210px;
  background: var(--navy-3); border: 1px solid var(--hairline); border-radius: 6px; padding: 8px;
  opacity: 0; visibility: hidden; transform: translateY(6px); transition: .2s;
  box-shadow: 0 20px 40px rgba(0,0,0,.35); list-style: none; margin: 0;
}
.menu > li:hover .submenu, .menu > li:focus-within .submenu { opacity: 1; visibility: visible; transform: translateY(0); }
.submenu a { display: block; padding: 10px 14px; border-radius: 4px; font-size: 14.5px; color: #c3cdd8; transition: .15s; }
.submenu a:hover { background: var(--navy-2); color: var(--mint); }
.nav .evbtn {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 13px;
  border: 1px solid var(--mint); color: var(--mint); padding: 11px 20px; border-radius: 2px;
  transition: .2s; white-space: nowrap; display: inline-flex; align-items: center; gap: 8px;
}
.nav .evbtn svg { width: 13px; height: 13px; }
.nav .evbtn:hover { background: var(--mint); color: var(--navy); }
/* Event app log-in: a filled primary button at the end of the nav row, with
   the web fallback as a small line under it. The pair is 54px tall, so it sits
   inside the 76px nav without changing its height. */
.navlogin { display: flex; flex-direction: column; align-items: stretch; gap: 3px; flex: 0 0 auto; }
.navlogin-btn {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 13px;
  background: var(--mint); color: var(--navy); border: 1px solid var(--mint);
  padding: 11px 20px; border-radius: 2px; white-space: nowrap; text-align: center;
  transition: .2s;
}
.navlogin-btn:hover { background: transparent; color: var(--mint); }
.navlogin-web { font-size: 11.5px; letter-spacing: .04em; color: #97a4b2; text-align: center; white-space: nowrap; transition: color .2s; }
.navlogin-web:hover { color: var(--mint); }
@media (max-width: 1240px) {
  .menu > li > a, .menu > li > span { padding: 12px 6px; }
}
.navtrigger { display: none; }
@media (max-width: 1120px) {
  .menu, .nav .evbtn, .navlogin { display: none; }
  .navtrigger {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 13px;
    color: #fff; background: none; border: 1px solid rgba(255,255,255,.25); padding: 10px 16px; border-radius: 2px; cursor: pointer;
  }
  .navtrigger svg { width: 20px; height: 14px; }
}
/* Pinned under the sticky header so it opens at the current scroll position
   (not at the top of the document) — otherwise the panel renders at its DOM
   spot up top and you'd have to scroll back up to see it. */
.mobile-panel { display: none; position: fixed; top: var(--nav-h); left: 0; right: 0; z-index: 89;
  max-height: calc(100dvh - var(--nav-h)); overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--navy-3); border-bottom: 1px solid var(--hairline); }
.mobile-panel a { display: block; padding: 14px 32px; border-top: 1px solid var(--hairline-2); font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 14px; color: #c3cdd8; }
.mobile-panel a:hover { color: var(--mint); }
.mobile-panel .mp-login { color: var(--mint); }
.mobile-panel .mp-login-web { text-transform: none; letter-spacing: .02em; font-size: 13px; padding-top: 10px; padding-bottom: 16px; border-top: 0; color: #97a4b2; }
.mobile-panel.open { display: block; }
@media (min-width: 1121px) { .mobile-panel { display: none !important; } }

/* ============================================================
   HERO (home) — real logo lockup + wave + left→right scrim
   ============================================================ */
.hero { position: relative; overflow: hidden; background: var(--ink); }
.hero::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(90deg, rgba(var(--ink-rgb),.95) 0%, rgba(var(--ink-rgb),.74) 36%, rgba(var(--ink-rgb),.22) 64%, rgba(var(--ink-rgb),0) 100%);
}
.hero .wave { position: absolute; inset: 0; background-image: url('../img/wave.png'); background-size: cover; background-position: center; pointer-events: none; }
.hero-inner { position: relative; z-index: 2; padding: 92px 0 100px; }
.hero .hero-lockup { margin: 0; line-height: 0; }
.hero .logo-lockup { height: clamp(64px, 9vw, 116px); display: block; width: auto; }
.hero .eyebrow { display: inline-flex; gap: 12px; align-items: center; margin: 38px 0 20px; }
.hero .eyebrow::before { content: ""; width: 44px; height: 1px; background: var(--mint); }
.hero .hero-headline { font-family: var(--font-display); font-weight: 300; font-size: clamp(34px, 5.2vw, 64px); line-height: 1; color: var(--white); margin: 0; }
.hero .hero-headline b { display: block; font-weight: 500; margin-top: 8px; font-size: .6em; letter-spacing: .02em; }
/* Mimi Jung, 2026-08-18: on mobile the year fell to a second line. The flat 34px
   floor above was the cause — the longest date line we run ("September 28–October 1,
   2026") needs 374px and only ~350px is available at 390px wide. Below 414px, where
   34px stops fitting, the size tracks the viewport instead so the date stays on one
   line down to a 320px phone. Above 414px nothing changes. */
@media (max-width: 414px) { .hero .hero-headline { font-size: 7.9vw; } }
.hero .sub { max-width: 540px; margin-top: 24px; color: #b0bdc9; font-size: 17px; }
.hero .actions { margin-top: 34px; display: flex; gap: 14px; flex-wrap: wrap; }

/* ============================================================
   GET INVOLVED (home) — audience cards, full-width band
   ============================================================ */
.aud { background: var(--navy); border-top: 1px solid var(--hairline-2); border-bottom: 1px solid var(--hairline-2); }
/* Alternate band shade for an .aud that lands next to a .bg-a section, so the
   home page keeps alternating instead of running two navy bands together
   (Europe: the Onsite Resources callout sits above Program). Kat, 2026-08-26. */
.aud--alt { background: var(--navy-3); }
.aud-head { display: flex; justify-content: space-between; align-items: baseline; padding: 40px 0 20px; }
.aud-head .eyebrow { color: var(--mint); }
.aud-title { font-family: var(--font-display); font-size: clamp(28px, 3.6vw, 44px); font-weight: 300; color: var(--white); margin-top: 8px; line-height: 1.05; }

/* Get Involved — SPLIT PANEL: headline/urgency copy on the left, big audience
   buttons stacked on the right. All buttons share one outline style; a
   .big-btn--wide button spans the full grid width (e.g. Sponsors as a bottom bar). */
.aud .split { display: grid; grid-template-columns: 1fr 1fr; gap: 60px; align-items: center; padding: 88px 0; }
.reg-btns { display: grid; grid-template-columns: 1fr; gap: 16px; }
/* 4+ audiences (e.g. Europe) split into two columns so the stack isn't so tall;
   3 or fewer (e.g. Canada) stay a single column. */
.reg-btns:has(> :nth-child(4)) { grid-template-columns: 1fr 1fr; }
.big-btn { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 23px 30px; min-width: 0;
  border: 1px solid var(--mint); border-radius: 3px; font-family: var(--font-display); text-transform: uppercase;
  letter-spacing: .1em; font-size: 19px; color: var(--white); transition: background-color .25s, color .25s, transform .2s; }
.big-btn i { color: var(--mint); font-size: 22px; font-style: normal; transition: color .25s, transform .2s; }
.big-btn:hover { background: var(--mint); color: var(--navy); }
.big-btn:hover i { color: var(--navy); transform: translateX(4px); }
/* A full-width button spans the whole button grid (e.g. the bottom-bar button). */
.reg-btns .big-btn--wide { grid-column: 1 / -1; }
@media (max-width: 820px) { .aud .split { grid-template-columns: 1fr; gap: 32px; padding: 60px 0; } }
/* On phones, force the audience buttons to a single column (the 4+ two-column
   rule above overflows the viewport at ~19px uppercase + 30px side padding). */
@media (max-width: 560px) {
  .reg-btns, .reg-btns:has(> :nth-child(4)) { grid-template-columns: 1fr; }
  .big-btn { padding: 18px 22px; font-size: 16px; gap: 14px; }
}
.aud-grid { display: grid; grid-template-columns: repeat(5, 1fr); padding-bottom: 44px; }
.aud-grid a { padding: 34px 26px 30px; border-right: 1px solid var(--hairline); transition: background-color .25s; }
.aud-grid a:last-child { border-right: none; }
.aud-grid a:hover { background: var(--navy-2); }
.aud-grid .num { font-family: var(--font-display); font-size: 14px; color: var(--mint); letter-spacing: .2em; }
.aud-grid h3 { font-size: 25px; font-weight: 400; color: var(--white); margin: 14px 0 4px; }
.aud-grid .arw { color: var(--mint); margin-top: 16px; font-size: 20px; transition: transform .25s; display: inline-block; }
.aud-grid a:hover .arw { transform: translateX(6px); }
/* CTA label under each card. Registration links get the prominent accent tag
   (.cta--reg) so a click-to-register is obvious; info links use the quiet default. */
.aud-grid .cta { display: inline-flex; align-items: center; gap: 7px; margin-top: 18px;
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .12em;
  font-size: 14px; color: var(--text-muted); transition: gap .25s, color .25s, background-color .25s; }
.aud-grid a:hover .cta { gap: 13px; color: var(--mint); }
/* Registration CTA reads as a real action button (fills on hover) so it's an
   unmistakable action point, not a quiet text link. */
.aud-grid .cta--reg { color: var(--mint); font-weight: 500; border: 1px solid var(--mint);
  border-radius: 2px; padding: 11px 22px; letter-spacing: .14em; }
.aud-grid a:hover .cta--reg { background: var(--mint); color: var(--navy); }
@media (max-width: 900px) { .aud-grid { grid-template-columns: 1fr 1fr; } .aud-grid a { border-right: none; border-bottom: 1px solid var(--hairline); padding-left: 0; } }

/* ============================================================
   TICKER (home) — continuous seamless loop
   ============================================================ */
.ticker { overflow: hidden; background: var(--navy); display: flex; white-space: nowrap; }
.ticker .t { flex: 0 0 auto; display: flex; align-items: center; gap: 46px; padding: 16px 0; margin-right: 46px; font-family: var(--font-display); text-transform: uppercase; letter-spacing: .18em; font-size: 15px; color: #9fb0bf; animation: tw-scroll 42s linear infinite; }
.ticker .t .m { color: var(--mint); }
/* Separator star. Was the glyph ✦ (U+2726, a FOUR pointed star) inline in the
   markup; Mimi Jung, 2026-08-20: the Travel Week brand uses a 5-point star
   everywhere, "in both large and small scale". So it is now design's real vector,
   lifted from TravelWeek2026_Design_Elements_Native.svg, masked so it still takes
   its colour from the surrounding rule per event. One asset, one rule, and no
   glyph to drift across 106 inline spots or render differently per platform. */
.ticker .t .m, .savedate .t .m {
  display: inline-block; width: .8em; height: .8em; flex: 0 0 auto;
  background-color: currentColor;
  -webkit-mask: url('../img/star.svg') center / contain no-repeat;
          mask: url('../img/star.svg') center / contain no-repeat;
}
/* Seamless loop: each copy shifts by its own width PLUS the 46px inter-copy
   margin, so the next identical copy lands exactly where this one started (no
   visible end/stutter). Needs enough copies in the markup to keep the viewport
   filled during the shift — see the ticker markup (repeated item sets). */
@keyframes tw-scroll { from { transform: translateX(0); } to { transform: translateX(calc(-100% - 46px)); } }

/* ============================================================
   PROGRAMME (home) — big numbered rows
   ============================================================ */
.bg-a { background: var(--navy); border-top: 1px solid var(--hairline-2); padding: 100px 0; }
.bg-b { background: var(--navy-3); border-top: 1px solid var(--hairline-2); padding: 100px 0; }
.bg-deep { background: var(--ink); border-top: 1px solid var(--hairline-2); padding: 100px 0; }
@media (max-width: 768px) { .bg-a, .bg-b, .bg-deep { padding: 64px 0; } }
.prow { display: grid; grid-template-columns: 96px 1fr; gap: 34px; padding: 38px 0; border-bottom: 1px solid var(--hairline); align-items: start; transition: padding .2s, background-color .2s; }
.prow:hover { background: linear-gradient(90deg, rgba(var(--mint-rgb),.05), transparent); padding-left: 12px; }
/* Numbers read as the FULL accent — no opacity. Design review 8/12 item 9, made
   global 2026-08-18 (Kat): the .55 washed them out, and the rule applies to
   every event, not just Canada where it was first spotted. */
.prow .k { font-family: var(--font-display); font-weight: 600; font-size: 54px; line-height: .9; color: var(--mint); }
.prow h3 { font-size: 30px; font-weight: 400; color: var(--white); }
.prow p { color: var(--text-muted); font-size: 15px; margin-top: 10px; max-width: 820px; }
.prow p a { color: var(--mint); border-bottom: 1px solid rgba(var(--mint-rgb),.4); }
@media (max-width: 700px) { .prow { grid-template-columns: 1fr; gap: 8px; } .prow .k { font-size: 38px; } }

/* ============================================================
   VENUE split (home) — text + Beurs photo
   ============================================================ */
.venue { display: grid; grid-template-columns: 1.05fr .95fr; border-radius: 8px; overflow: hidden; border: 1px solid var(--hairline); }
.venue .txt { background: linear-gradient(160deg, var(--navy-2), var(--ink)); padding: 56px 48px; display: flex; flex-direction: column; justify-content: center; }
.venue .txt h3 { font-size: 36px; font-weight: 300; color: var(--white); }
.venue .txt .loc { color: var(--mint); font-family: var(--font-display); letter-spacing: .16em; text-transform: uppercase; font-size: 13px; margin-top: 8px; }
.venue .txt p { color: var(--text-muted); margin: 22px 0; }
.venue dl { display: grid; gap: 14px; border-top: 1px solid var(--hairline); padding-top: 20px; margin: 0; }
.venue dt { color: var(--bgray); font-family: var(--font-display); letter-spacing: .1em; text-transform: uppercase; font-size: 11px; }
.venue dd { color: #d6dee6; font-size: 14px; margin: 0; }
/* A row of buttons. Same treatment as the hero's `.actions` (line ~397) rather
   than a one-off, so every button row in the site spaces the same way. It had
   only a margin-top, so two buttons in one row sat flush against each other -
   Kat, 2026-09-10: "there's two buttons for, like, hotel and venue that are,
   like, right up next to each other." A row with a single button renders
   identically to before (a lone inline-flex child in a flex container). */
.btnrow { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.venue .btnrow { margin-top: 26px; }
.venue .img { min-height: 520px; }
.venue .img img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 820px) { .venue { grid-template-columns: 1fr; } .venue .img { min-height: 280px; order: -1; } }

/* ============================================================
   VENUE band (venue.html full-bleed photo variant)
   ============================================================ */
.venue-band { position: relative; min-height: 560px; display: flex; overflow: hidden; }
.venue-band__photo { position: absolute; inset: 0; z-index: 1; background: var(--navy-2); }
.venue-band__photo img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%; }
.venue-band__overlay { position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to right, var(--navy) 0%, var(--navy) 30%, rgba(var(--navy-rgb),.9) 44%, rgba(var(--navy-rgb),.6) 58%, rgba(var(--navy-rgb),.15) 82%, transparent 100%); }
.venue-band__content { position: relative; z-index: 3; padding: 80px var(--pad-x); max-width: var(--maxw); width: 100%; margin: 0 auto; display: flex; flex-direction: column; justify-content: center; }
.venue-band__desc { color: var(--text-muted); max-width: 460px; margin: 22px 0 28px; }
.venue-band__details { display: flex; flex-direction: column; gap: 16px; }
.venue-band__accent { position: absolute; bottom: 0; left: 0; right: 0; height: 2px; z-index: 4;
  background: linear-gradient(to right, var(--mint) 0%, var(--mint) 30%, transparent 100%); }
@media (max-width: 900px) {
  .venue-band { flex-direction: column; min-height: auto; }
  .venue-band__photo { position: relative; height: 280px; }
  .venue-band__overlay { display: none; }
  .venue-band__content { background: var(--navy); }
  .venue-band__desc { max-width: 100%; }
}

/* ============================================================
   KEY DATES (home) — two columns, emphasized event row in-list
   ============================================================ */
.tint { background: linear-gradient(180deg, var(--navy-3), var(--navy)); }
.dcols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 48px; }
.tl .row { display: grid; grid-template-columns: 130px 1fr; gap: 20px; padding: 16px 0; border-bottom: 1px solid var(--hairline); align-items: baseline; }
.tl .row:hover .d { color: var(--mint); }
.tl .d { font-family: var(--font-display); font-size: 17px; color: var(--white); transition: color .2s; }
.tl .t { color: var(--text); font-size: 15px; }
.tl .row.event { background: linear-gradient(90deg, rgba(var(--mint-rgb),.10), transparent); border-bottom: none; padding-left: 14px; margin-left: -14px; }
.tl .row.event .d { color: var(--mint); font-weight: 500; }
.tl .row.event .t { color: var(--mint); }
@media (max-width: 760px) { .dcols { grid-template-columns: 1fr; } }

/* Key dates head column (interior/home shared) */
.kd-head { margin-bottom: 8px; }

/* ============================================================
   SCHEDULE — track tabs (home "at a glance") + session list (API page)
   ============================================================ */
.trk-tabs { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-bottom: 36px; }
.trk-tab { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em; font-size: 13px; color: #c3cdd8; background: transparent; border: 1px solid rgba(255,255,255,.18); padding: 12px 28px; border-radius: 2px; cursor: pointer; transition: .2s; }
.trk-tab:hover { border-color: var(--mint); color: var(--white); }
.trk-tab.active { background: var(--mint); color: var(--navy); border-color: var(--mint); }
.trk-panel { display: none; }
.trk-panel.active { display: block; }
.trk-days { display: grid; gap: 16px; }
.trk-days.d4 { grid-template-columns: repeat(4, 1fr); }
/* Five program days (Latin America runs Sunday arrival through an optional
   Thursday). Five equal columns make each card too narrow for the copy the
   events team writes, so d5 wraps 3 + 2 instead. */
.trk-days.d5 { grid-template-columns: repeat(3, 1fr); }
.trk-days.d3 { grid-template-columns: repeat(3, 1fr); }
.trk-days.d2 { grid-template-columns: repeat(2, 1fr); max-width: 640px; margin: 0 auto; }
.trk-days.d1 { grid-template-columns: 1fr; max-width: 420px; margin: 0 auto; }
.day-card { background: linear-gradient(160deg, var(--navy-2), var(--navy)); border: 1px solid var(--hairline); border-radius: 8px; padding: 26px 24px; }
.day-card .day { font-family: var(--font-display); font-size: 22px; color: var(--white); }
.day-card .date { font-family: var(--font-display); letter-spacing: .12em; text-transform: uppercase; font-size: 13px; color: var(--mint); margin: 2px 0 16px; }
.day-card .slot { padding: 14px 0; border-top: 1px solid var(--hairline); }
.day-card .slot .lbl { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em; font-size: 12px; color: var(--bgray); margin-bottom: 5px; }
.day-card .slot .val { font-size: 14px; color: #d0d9e2; }
.day-card .slot.eve .val { color: var(--mint); }
.sched-note { color: var(--text-faint); margin-top: 28px; font-size: 14px; text-align: center; }
.sched-note a { color: var(--mint); border-bottom: 1px solid rgba(var(--mint-rgb),.4); }
@media (max-width: 900px) { .trk-days.d5, .trk-days.d4, .trk-days.d3, .trk-days.d2 { grid-template-columns: 1fr 1fr; max-width: none; } }

/* Schedule — DETAIL layout. Same track tabs as the summary cards above; each
   day becomes a timeline of every published slot instead of two broad strokes.
   Chosen per event by `schedule.layout` in event-config; build.js renders one
   or the other from the same data.

   ONE flat treatment for every row, with ONE exception (Kat, 2026-09-01). The
   first version faded meals and check-in and put a green dot on programming,
   which is a code the page never explains: "why is some stuff written in green,
   some faded text... what's... why?" Nothing in the events team's sheet ranks
   those against each other, so the page does not either.

   The exception is the evening event, which has been in the accent colour on
   the live site since launch and stays that way here: "you have all of the
   evening events in that green color, so you can continue to do that". Text
   only. The dots stay identical, because a second signal for the same thing is
   what made the first version unreadable. Add no further per-row styling. */
.sched-day { background: linear-gradient(160deg, var(--navy-2), var(--navy)); border: 1px solid var(--hairline); border-radius: 8px; padding: 32px 32px 28px; }
.sched-day__hd { border-bottom: 1px solid var(--hairline); padding-bottom: 16px; }
.sched-day__hd .day { font-family: var(--font-display); font-size: 27px; color: var(--white); }
.sched-day__hd .date { font-family: var(--font-display); letter-spacing: .12em; text-transform: uppercase; font-size: 14px; color: var(--mint); margin-top: 3px; }
.sched-rows { list-style: none; margin: 0; padding: 16px 0 0 26px; position: relative; }
.sched-rows::before { content: ""; position: absolute; left: 5px; top: 26px; bottom: 24px; width: 1px; background: var(--hairline); }
/* Wide two-up columns, so the time sits beside its item instead of above it. */
.sched-row { position: relative; display: grid; grid-template-columns: 155px 1fr; gap: 20px; align-items: baseline; padding: 15px 0; }
.sched-row::before { content: ""; position: absolute; left: -26px; top: 21px; width: 11px; height: 11px; border-radius: 50%; background: var(--navy-2); border: 1px solid var(--bgray); box-sizing: border-box; }
.sched-row .t { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 14px; color: var(--bgray); }
.sched-row .e { font-size: 17px; line-height: 1.45; color: #d0d9e2; }
.sched-row .loc { display: block; color: var(--text-faint); font-size: 13px; margin-top: 4px; }
.sched-row.is-eve .e { color: var(--mint); }

/* Two across at every desktop width, one on a phone. */
.trk-days--detail { gap: 20px; }
.trk-days--detail.d2, .trk-days--detail.d3, .trk-days--detail.d4, .trk-days--detail.d5 { grid-template-columns: repeat(2, 1fr); max-width: none; }

@media (max-width: 560px) { .trk-days.d5, .trk-days.d4, .trk-days.d3, .trk-days.d2 { grid-template-columns: 1fr; } }
@media (max-width: 900px) { .trk-days--detail.d2, .trk-days--detail.d3, .trk-days--detail.d4, .trk-days--detail.d5 { grid-template-columns: 1fr; } }
@media (max-width: 600px) { .sched-row { grid-template-columns: 1fr; gap: 5px; } .sched-day { padding: 26px 24px 22px; } }

/* ============================================================
   Data-driven pages: exhibitor list, speakers, schedule
   ============================================================ */
.state-msg { color: var(--text-muted); padding: 24px 0; }
.state-msg--error { color: #ffb4b4; }

.toolbar { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin-bottom: 32px; }
.toolbar input[type="search"] {
  flex: 1 1 260px; min-width: 0; background: var(--surface); border: 1px solid var(--hairline);
  color: #fff; border-radius: 2px; padding: 12px 20px; font-family: var(--font-body); font-size: 15px;
}
.toolbar input[type="search"]::placeholder { color: var(--text-faint); }
.toolbar input[type="search"]:focus { outline: none; border-color: var(--mint); }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-muted); background: transparent; border: 1px solid rgba(255,255,255,.18);
  border-radius: 2px; padding: 9px 18px; cursor: pointer; transition: .2s;
}
.chip:hover { border-color: var(--mint); color: var(--white); }
.chip.is-active { background: var(--mint); color: var(--navy); border-color: var(--mint); }

/* ---- A dropdown the site draws itself ----------------------
   For the session-type filter Kat asked to have back on
   2026-09-09. A native <select> was tried on 9/8 and rejected
   because the open list is drawn by the DEVICE and matches
   nothing else here, so this is a button and a panel using the
   site's own type, hairlines and mint. Sits at the right end of
   the shared search toolbar. */
.filt { position: relative; flex: 0 0 auto; }
.filt__btn {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-muted); background: transparent; border: 1px solid var(--hairline);
  border-radius: 2px; padding: 12px 18px; transition: .2s;
}
.filt__btn:hover { border-color: var(--mint); color: var(--white); }
.filt__btn svg { transition: transform .2s; }
.filt.is-open .filt__btn { border-color: var(--mint); color: var(--white); }
.filt.is-open .filt__btn svg { transform: rotate(180deg); }
/* Set, not just open: the control says what it is doing without being read. */
.filt.is-set .filt__btn { background: var(--mint); color: var(--navy); border-color: var(--mint); }
/* `display: flex` in a class rule BEATS the browser's own [hidden] rule, so
   without this line the panel is open on every page load - which is exactly
   what it did until a phone screenshot caught it 2026-09-09. */
.filt__menu[hidden] { display: none; }
.filt__menu {
  position: absolute; z-index: 20; top: calc(100% + 6px); right: 0; min-width: 100%;
  display: flex; flex-direction: column; padding: 6px;
  background: var(--navy-3, var(--surface)); border: 1px solid var(--hairline);
  border-radius: 4px; box-shadow: 0 18px 40px rgba(0,0,0,.45);
}
.filt__opt {
  text-align: left; white-space: nowrap; cursor: pointer;
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .1em;
  color: var(--text-muted); background: transparent; border: 0; border-radius: 2px;
  padding: 11px 16px; transition: .15s;
}
.filt__opt:hover { background: rgba(255,255,255,.06); color: var(--white); }
.filt__opt.is-on { color: var(--mint); }

/* Exhibitor cards */
.ex-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 26px; }
.ex-card {
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius);
  display: flex; flex-direction: column; overflow: hidden; cursor: pointer;
  transition: border-color .2s, transform .2s, box-shadow .2s;
}
.ex-card:hover, .ex-card:focus-visible {
  border-color: rgba(var(--mint-rgb),.45); transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(0,0,0,.28); outline: none;
}
.ex-card__logo {
  position: relative; height: 180px; background: #fff;
  display: flex; align-items: center; justify-content: center; padding: 16px 20px;
}
.ex-card__logo img { max-height: 100%; max-width: 100%; width: auto; height: auto; object-fit: contain; }
/* No-logo placeholder: translucent light-blue glass with a ghosted white TWE
   lockup, letting the dark card show through like frosted glass. */
.ex-card__logo--ph {
  background: linear-gradient(150deg, rgba(150,192,228,.12) 0%, rgba(120,160,205,.05) 100%);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.ex-card__logo--ph::before {
  content: ""; position: absolute; inset: 0;
  background: url(../img/logo-white-horizontal.svg) center / 64% auto no-repeat;
  opacity: .13;
}
.ex-card__badge {
  position: absolute; top: 12px; right: 12px; display: inline-flex; align-items: center; gap: 5px;
  background: var(--mint); color: var(--navy); font-family: var(--font-display); font-weight: 500;
  font-size: 11px; text-transform: uppercase; letter-spacing: .12em; padding: 4px 10px; border-radius: 20px;
}
.ex-card__badge svg { width: 12px; height: 12px; }
.ex-card__body { padding: 20px 22px 22px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.ex-card__cat { font-family: var(--font-display); font-size: 13px; text-transform: uppercase; letter-spacing: .16em; color: var(--mint); }
/* An exhibitor can hold more than one category (Canada: 18 are Trade AND Media).
   Each renders as its own eyebrow, separated by a hairline rule rather than a
   word, so "TRADE | MEDIA" reads as two tags and never as one run-on string.
   With a single category the divider never renders and nothing changes. */
.ex-card__cats { display: flex; align-items: center; flex-wrap: wrap; row-gap: 4px; }
.ex-card__cats .ex-card__cat + .ex-card__cat { margin-left: 10px; }
.ex-card__cats .ex-card__cat + .ex-card__cat::before {
  content: ""; display: inline-block; width: 1px; height: 11px; margin-right: 11px;
  background: currentColor; opacity: .45; vertical-align: -1px;
}
.ex-card__name { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.2rem; letter-spacing: .02em; line-height: 1.2; }
.ex-card__desc {
  color: var(--text-muted); font-size: 13.5px; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ex-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 6px; }
.ex-card__links { display: flex; gap: 12px; }
.ex-card__links a { color: var(--text-muted); display: inline-flex; }
.ex-card__links a:hover { color: var(--mint); }
.ex-card__links svg { width: 18px; height: 18px; }
.ex-card__more { font-family: var(--font-display); font-size: 11px; text-transform: uppercase; letter-spacing: .14em; color: var(--text-faint); }
.ex-card:hover .ex-card__more { color: var(--mint); }

/* Exhibitor profile modal */
.ex-modal { position: fixed; inset: 0; z-index: 1000; display: none; align-items: center; justify-content: center; padding: 24px; }
.ex-modal.is-open { display: flex; }
.ex-modal__backdrop { position: absolute; inset: 0; background: rgba(6,12,22,.72); backdrop-filter: blur(3px); }
.ex-modal__panel {
  position: relative; z-index: 1; width: min(640px, 100%); max-height: 88vh; overflow-y: auto;
  background: var(--navy-2); border: 1px solid var(--hairline); border-radius: 14px;
  box-shadow: 0 30px 70px rgba(0,0,0,.5);
}
.ex-modal__close {
  position: absolute; top: 14px; right: 14px; z-index: 2; width: 38px; height: 38px; border-radius: 50%;
  background: rgba(var(--navy-rgb),.7); border: 1px solid var(--hairline); color: var(--white);
  display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background .2s, color .2s;
}
.ex-modal__close:hover { background: var(--mint); color: var(--navy); border-color: var(--mint); }
.ex-modal__logo { position: relative; height: 220px; background: #fff; display: flex; align-items: center; justify-content: center; padding: 24px 32px; }
.ex-modal__logo img { max-height: 100%; max-width: 100%; object-fit: contain; }
.ex-modal__logo--ph {
  background: linear-gradient(150deg, rgba(150,192,228,.12) 0%, rgba(120,160,205,.05) 100%);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.ex-modal__logo--ph::before {
  content: ""; position: absolute; inset: 0;
  background: url(../img/logo-white-horizontal.svg) center / 52% auto no-repeat;
  opacity: .14;
}
.ex-modal__body { padding: 26px 30px 32px; }
.ex-modal__tags { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ex-modal__cat { font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .16em; color: var(--mint); }
/* Same hairline divider as the card, riding the .ex-modal__tags gap. */
.ex-modal__cat + .ex-modal__cat::before {
  content: ""; display: inline-block; width: 1px; height: 10px; margin-right: 10px;
  background: currentColor; opacity: .45; vertical-align: -1px;
}
.ex-modal__name { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.7rem; letter-spacing: .01em; line-height: 1.15; }
.ex-modal__loc { color: var(--text-faint); font-size: 13px; margin-top: 6px; display: flex; align-items: center; gap: 6px; }
.ex-modal__loc svg { width: 14px; height: 14px; color: var(--mint); }
.ex-modal__desc { color: var(--text-muted); font-size: 14.5px; line-height: 1.7; margin: 20px 0; white-space: pre-line; }
.ex-modal__links { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding-top: 20px; border-top: 1px solid var(--hairline); }
.ex-modal__links a.social { color: var(--text-muted); display: inline-flex; }
.ex-modal__links a.social:hover { color: var(--mint); }
.ex-modal__links a.social svg { width: 20px; height: 20px; }

/* Speaker cards */
/* The circular-portrait treatment was REPLACED by the card grid at
   the bottom of this file (Kat 2026-09-08). Nothing renders
   .spk-card__photo any more; the rules are gone rather than left
   to fight the card ones from higher up the cascade. */
.spk-card__bio { color: var(--text-muted); font-size: 13px; margin-top: 10px; }

/* Session list (detailed / API driven) */
.session { display: grid; grid-template-columns: 150px 1fr; gap: 20px; padding: 22px 0; border-bottom: 1px solid var(--hairline); }
.session__time { font-family: var(--font-display); font-weight: 500; color: var(--mint); font-size: 1rem; }
.session__room { color: var(--text-faint); font-size: 12px; text-transform: uppercase; letter-spacing: .1em; margin-top: 4px; }
.session__title { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.3rem; margin-bottom: 8px; }
.session__desc { color: var(--text-muted); font-size: 14px; }
.session__speakers { color: var(--text-faint); font-size: 13px; margin-top: 8px; }
@media (max-width: 560px) { .session { grid-template-columns: 1fr; gap: 6px; } }

/* Cross-link cards */
.crosslinks { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
@media (max-width: 640px) { .crosslinks { grid-template-columns: 1fr; } }
.crosslink { display: flex; justify-content: space-between; align-items: center; gap: 16px; background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 26px; transition: border-color .2s; }
/* THE arrow rule. Every inline arrow on every page of every event uses the
   14x14 viewBox, so it is pinned here by attribute rather than per component:
   as a flex item it was shrinking wherever the neighbouring text ran long,
   which is why Leadership Track's arrow rendered smaller than Buyer
   Information's (2026-08-12 design review). One rule = they cannot drift apart
   again, including on pages built later. Size is deliberately NOT set here:
   buttons use 14px (.btn svg) and the crosslink cards 18px, both correct. */
svg[viewBox="0 0 14 14"] { flex: 0 0 auto; }
.crosslink h3 { color: var(--white); font-weight: 400; font-size: 1.4rem; }
.crosslink p { color: var(--text-muted); font-size: 13px; margin: 6px 0 0; }
.crosslink:hover { border-color: rgba(var(--mint-rgb),.4); }

/* CTA band (interior pages) */
/* Padding scales down on small screens (2026-08-12 design review — the flat
   90px read as excessive above and below the sponsor CTA). */
.cta-band { text-align: center; padding: clamp(48px, 6vw, 82px) var(--pad-x); background: var(--navy-3); border-top: 1px solid var(--hairline-2); }
.cta-band h2 { margin-bottom: 16px; font-weight: 300; }
.cta-band p { color: var(--text-muted); max-width: 560px; margin: 0 auto 28px; }

/* Utility */
.stack > * + * { margin-top: 16px; }
.mt-0 { margin-top: 0; }
.mb-lg { margin-bottom: 40px; }
.hide { display: none !important; }

/* ============================================================
   HOME — hero band fallback (kept for compatibility) & bands below
   ============================================================ */
/* BECOME A SPONSOR — clean full-width band, no box, no wave */
.sponsor-band { background: var(--ink); border-top: 1px solid var(--hairline-2); }
/* Vertical padding scales instead of sitting at a flat 100px. Design review
   8/12 item 2: Mimi flagged "excessive padding above and below" on the Become a
   Sponsor block, worst where the copy is short. The 8/12 pass clamped .cta-band
   (the sponsors PAGE bottom CTA) by mistake — a different block — so this one
   was still flat until 2026-08-18. Same clamp as .cta-band so the two read as
   one component. */
.sponsor-in { max-width: 660px; margin: 0 auto; text-align: center; padding: clamp(48px, 6vw, 82px) 24px; }
.sponsor-in .rule { width: 52px; height: 2px; background: var(--mint); margin: 0 auto 24px; }
.sponsor-in .eyebrow { display: block; margin-bottom: 14px; }
.sponsor-in h2 { font-size: clamp(28px, 4vw, 46px); font-weight: 300; color: var(--white); }
.sponsor-in p { color: var(--text-muted); margin: 16px auto 32px; max-width: 560px; }
.sponsor-in p a { color: var(--mint); border-bottom: 1px solid rgba(var(--mint-rgb),.4); }

/* ============================================================
   SAVE THE DATE strip (shared footer) — the NEXT cycle's dates
   ============================================================ */
/* Design's call 2026-08-12: the ticker's treatment standing still, in GREEN
   TYPE, not a green banner, on the bar right before the solid navy starts.
   Deliberately shares .ticker's type spec (Oswald, uppercase, .18em, 15px) and
   its ✦ separator — it should read as the same device, just not moving. Mimi
   ruled out the top: it clashes with the 2026 logos and the mobile nav
   collapses there. */
/* Bumped to 14px to match the sponsor heading + bold (Mimi Jung, 2026-08-18 —
   was missing it at 12px). Was deliberately kept under the sponsor heading's
   14px (see 2026-08-17 history in git blame) so the two didn't read as peers;
   the bold weight is the new differentiator instead of the size gap. */
.savedate { background: var(--navy); border-top: 1px solid var(--hairline-2); overflow: hidden; }
.savedate .t {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 10px 30px; padding: 22px 24px; text-align: center;
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em;
  font-size: 14px; font-weight: 700; color: var(--mint);
}
.savedate .t .m { opacity: .65; }
@media (max-width: 700px) { .savedate .t { font-size: 13px; letter-spacing: .12em; gap: 8px 18px; } }

/* ============================================================
   SPONSOR LOGO BAND (shared footer) — white tiles on dark
   ============================================================ */
/* Rebuilt 2026-08-12 from design's individual SVGs. Their calls: full colour on
   a light ground, ONE row, no stacking at any width, every sponsor sized
   evenly. So the row never wraps; the logos scale down together instead, which
   Mimi accepted as small-but-readable on mobile.
   FULL BLEED, picked 2026-08-13/14 in Slack: the white row runs edge to edge
   with no floating panel and no bottom padding under it, so it reads as the
   base of the page. It was version 2 of the five mocked up — Mimi's vote
   ("the logos appear maximized in size on mobile view when width is reduced"),
   Thanh's first choice, Savannah's first choice. The other four are gone. */
.sponsors-logos { background: var(--navy-3); border-top: 1px solid var(--hairline-2); padding: clamp(34px, 4vw, 54px) 0 0; }
/* The heading must sit CLOSER to the logos than the save-the-date strip below
   them does, or it stops reading as their label (Kat, 2026-08-17). It was 74px
   above vs 47px below: .eyebrow carries its own 16px bottom margin, which
   stacked on top of this one and the panel's padding. Zero it here only, the
   global .eyebrow is used all over the site. */
.sl-head { text-align: center; margin-bottom: clamp(8px, 1vw, 14px); }
/* "Thank You to Our Sponsors" is WHITE, not the accent (Kat, 2026-08-18 —
   settles the question left open on 8/17). Global on purpose: every event that
   adds a sponsor band later inherits white without another decision. */
.sl-head .eyebrow { margin-bottom: 0; color: var(--white); }
/* Breaks out of .wrap to the full viewport width — square corners, no side
   padding of its own; the grid inside re-establishes the content column. */
.sl-panel {
  background: #fff; border-radius: 0;
  padding: clamp(18px, 2.4vw, 30px) 0;
  width: 100vw; margin-left: calc(50% - 50vw);
}
/* Each tile takes a SHARE of the row (flex-grow, set per logo by EC.sponsors.w)
   rather than sizing from a px height. Two things fall out of that: every logo
   lands at the same height, and the row always fits on one line at any width
   because the shares always sum to the row. Verified by rendering at 1200 and
   390 before shipping. */
.sl-grid { display: flex; flex-wrap: nowrap; justify-content: center; align-items: center; gap: clamp(8px, 1.6vw, 28px);
  max-width: 1160px; margin: 0 auto; padding: 0 clamp(16px, 3vw, 40px); }
.sl-tile { flex-grow: 4; flex-shrink: 1; flex-basis: 0; min-width: 0; display: flex; align-items: center; justify-content: center; }
.sl-tile img { width: 100%; height: auto; max-height: clamp(26px, 4.3vw, 52px); object-fit: contain; }
.sl-note { text-align: center; color: #7d8c9b; font-size: 12.5px; margin-top: 26px; font-style: italic; }
/* Supplied lockup variant — design's finished single-row artwork, used exactly
   as delivered. Its type is dark navy, so it needs a light ground; the band
   itself stays dark and the artwork sits on a contained white panel so it reads
   as a framed plate rather than a full-bleed white stripe. Nothing is redrawn. */
.sponsors-logos--supplied { background: var(--navy-3); padding: 72px 0; }
.sponsors-logos--supplied .sl-panel {
  background: #ffffff; border-radius: var(--radius);
  padding: 40px clamp(24px, 4vw, 56px); max-width: 1000px; margin-inline: auto;
  width: auto;   /* opt out of the full-bleed panel above */
}
.sponsors-logos--supplied .sl-lockup { width: 100%; height: auto; display: block; }
@media (max-width: 700px) {
  .sponsors-logos--supplied { padding: 48px 0; }
  .sponsors-logos--supplied .sl-panel { padding: 28px 22px; }
}
/* NO wrap breakpoints. Design's rule is one row with every sponsor the same
   size (Mimi, 2026-08-12), so the row scales down as a unit instead of
   stacking. The old max-width:860px wrap and the fixed 40px height at 520px are
   both gone — they were what stacked the logos on a phone. */

/* ============================================================
   FOOTER base (shared)
   ============================================================ */
footer.base { background: var(--footer); padding: 40px 0; }
.fnav { display: flex; gap: 22px; flex-wrap: wrap; font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 14px; color: #9fb0bf; padding-bottom: 26px; margin-bottom: 26px; border-bottom: 1px solid var(--hairline-2); }
.fnav a { color: #9fb0bf; }
.fnav a:hover { color: var(--mint); }
.fbase { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; }
.fbase .f-tw img { height: 40px; width: auto; display: block; }

/* Corporate Brand USA lockup, bottom right, with its link under it. Sits
   opposite this event's Travel Week lockup so the pair reads as event-by-org
   (Kat, 2026-08-18). The logo is the white knockout on transparent, so it needs
   no treatment on the dark footer. */
/* The block sits on the right of the row, but the logo CENTERS over the URL
   under it (Kat, 2026-08-18) — the URL is the wider of the two, so right-aligning
   both left the mark hanging off its end. */
.f-tw, .f-org, .f-mark { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
/* 34px reads level with the 40px Travel Week lockup opposite it: that lockup is
   two lines of type, this mark is a tight two-line block with no padding (the
   source PNG was cropped to its artwork, it used to carry 89px of transparent
   margin and rendered about 18px tall). */
.f-org img { height: 34px; width: auto; display: block; }
/* The generic Travel Week lockup is a wide horizontal mark, so 34px made it the
   biggest thing in the row and it read as the page's own logo. 26px sits it
   level with the two marks either side. */
.f-mark img { height: 26px; width: auto; display: block; }
.f-org__link {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em;
  font-size: 11px; color: var(--mint);
}
.f-org__link:hover { text-decoration: underline; }

/* Copyright + contact on their own line under both logos, so neither gets
   crowded (it used to sit inline opposite the Travel Week lockup). */
.fmeta {
  display: flex; gap: 8px 22px; flex-wrap: wrap; align-items: center;
  margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--hairline-2);
  color: var(--text-faint); font-size: 13px;
}
.fmeta a { color: var(--mint); }
/* Asset hub, bottom right opposite the copyright — deliberately NOT in the
   footer link row above (Kat, 2026-08-21: "I dont like it being part of the
   list and, like, the NAV"). Lead-in is plain text, only the destination is a
   link. margin-left:auto pushes it to the far end; it wraps under on mobile
   because .fmeta already wraps. */
.fmeta__assets { margin-left: auto; }
@media (max-width: 620px) { .fmeta__assets { margin-left: 0; } }
@media (max-width: 620px) {
  .fbase { align-items: flex-start; }
  .f-tw, .f-org, .f-mark { align-items: flex-start; text-align: left; }   /* stacked: each URL falls in line under its own mark */
}

/* ============================================================
   UTILITIES & COMPONENT VARIANTS
   Exact replicas of former inline styles, centralised for
   consistency + template reuse. Placed last so they win ties.
   ============================================================ */
.m-0 { margin: 0; }
/* Clean list bullet. Used as <span class="badge badge--bullet">•</span> at the
   start of a .feature list item. Overrides the .badge pill so it renders as a
   simple mint dot instead of a green oval — one rule fixes every bullet list
   on every page/event. */
.badge--bullet {
  background: none;
  color: var(--mint);
  padding: 0;
  border-radius: 0;
  letter-spacing: 0;
  font-size: 20px;
  line-height: 1.5;
  margin-top: -1px;
  flex-shrink: 0;
}
/* Tighten the gap between the dot and its text (default .feature gap is 14px,
   too wide for a bullet). */
.feature:has(> .badge--bullet) { gap: 10px; }
.feature__title--sm { color: var(--mint); font-size: .95rem; letter-spacing: .08em; }
.list-plain { list-style: none; padding: 0; }
/* Two-column split (text + text). Was inline + fixed 2-col; now collapses on mobile. */
.grid-split { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
@media (max-width: 768px) { .grid-split { grid-template-columns: 1fr; gap: 32px; } }
/* Pricing rows + amount sizes (were repeated inline on the cost cards) */
.price-row { display: flex; justify-content: space-between; align-items: baseline; padding: 14px 0; }
.price-row--divided { border-bottom: 1px solid var(--hairline); }
.price-row--compact { display: flex; justify-content: space-between; padding: 8px 0; }
/* Right-align the amount cell so figures line up down the card. Rows whose
   amount carries a note underneath were the ones drifting left, because the
   wrapping <span> is an inline box (2026-08-12 design review). */
.price-row > :last-child,
.price-row--compact > :last-child { text-align: right; }
/* A lead sentence marked .note-lead sits on its own line above the rest. */
.price-card__note strong.note-lead { display: block; margin-bottom: 5px; }
.price-card__amount--sm { font-size: 1.6rem; }
.price-card__amount--xs { font-size: 1.4rem; }
.label-kicker { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; }

/* ============================================================
   BUYER LIST — company + country only (Cvent attendees API).
   Grouped by country with a flag header, then a grid of company
   tiles. Reusable across every Travel Week.
   ============================================================ */
.buyer-summary { color: var(--text-muted); font-size: 15px; margin: 0 0 30px; }
.buyer-summary strong { color: var(--mint); font-weight: 600; }

.buyer-group { margin-bottom: 44px; }
.buyer-group__head {
  display: flex; align-items: center; gap: 14px;
  padding-bottom: 14px; margin-bottom: 22px; border-bottom: 1px solid var(--hairline);
}
.buyer-group__flag { font-size: 30px; line-height: 1; flex-shrink: 0; }
.buyer-group__name {
  font-family: var(--font-display); font-weight: 500; text-transform: uppercase;
  letter-spacing: .04em; color: var(--white); font-size: clamp(18px, 2.4vw, 23px);
}
.buyer-group__count {
  margin-left: auto; font-family: var(--font-display); font-weight: 500;
  font-size: 13px; letter-spacing: .08em; color: var(--navy);
  background: var(--mint); border-radius: 20px; padding: 3px 12px;
}

.buyer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.buyer-tile {
  position: relative; background: var(--surface); border: 1px solid var(--hairline);
  border-left: 2px solid rgba(var(--mint-rgb),.5); border-radius: var(--radius);
  padding: 18px 20px; min-height: 76px; display: flex; align-items: center;
  transition: border-color .2s, transform .2s, box-shadow .2s; overflow: hidden;
}
.buyer-tile:hover {
  border-color: rgba(var(--mint-rgb),.55); border-left-color: var(--mint);
  transform: translateY(-2px); box-shadow: 0 12px 26px rgba(0,0,0,.26);
}
.buyer-tile__name { font-weight: 600; font-size: 15px; color: var(--white); line-height: 1.35; }
.buyer-tile__flag {
  position: absolute; right: -6px; bottom: -14px; font-size: 46px; line-height: 1;
  opacity: .10; pointer-events: none; filter: grayscale(1);
}
@media (max-width: 560px) { .buyer-grid { grid-template-columns: 1fr; } }

/* ============================================================
   The browsable schedule (live from Cvent)
   detailed-program.html. Distinct on purpose from .sched-* above,
   which is the fixed overview timeline rendered at build time.

   Refreshed 2026-09-08: it was a flat list of hairline-separated
   rows and Kat's read was "this page feels a little boring." It
   now uses the same language the speaker page was signed off on —
   a lit surface, hierarchy carried by the display face, square
   photo tiles — rather than decoration. The 2026-09-01 rule still
   holds: EVERY row renders identically. A tag says what a session
   is; nothing is coloured or faded to rank it.
   ============================================================ */

/* ---- A person, as a square tile ---------------------------- */
.ptile {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 7px; overflow: hidden; flex: 0 0 auto;
  container-type: inline-size;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(var(--mint-rgb),.16) 0%, rgba(var(--mint-rgb),0) 62%),
    linear-gradient(158deg, rgba(255,255,255,.14) 0%, rgba(150,192,228,.10) 45%, rgba(255,255,255,.03) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}
.ptile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.ptile .initials {
  font-family: var(--font-display); font-weight: 600; font-size: 38cqw; line-height: 1;
  color: transparent; -webkit-text-stroke: 1px rgba(var(--mint-rgb),.6);
}
.ptile--lg { width: 68px; height: 68px; border-radius: 9px; }
.ptile--lg .initials { -webkit-text-stroke-width: 1.5px; }

/* ---- Toolbar: track tabs, day row, then search + type ------ */
/* No chip wall and no native select. The first version had four
   days plus five session types plus two "All" options as chips —
   eleven buttons — and the second replaced them with selects,
   whose open list is drawn by the device and matches nothing else
   on the site. Both rejected 2026-09-08.
   Where it landed: the track is the tabs, the day is the quiet
   type row, and search plus session type are their own row below
   using the SHARED `toolbar` field, with the type on a dropdown
   this stylesheet draws (.filt). The one-off `.ag-bar` search
   field that used to live here is deleted — Kat 2026-09-09, "this
   search bar looks different than the search bar on every other
   page." Do not reintroduce a page-specific search field. */

/* The two control rows read as ONE stack, on ONE centre axis, and as two
   LEVELS. Kat 2026-09-09, on the program page: the track tabs and the day
   chips looked "very much similar", and "they kinda look like they should be
   centered to each other, but then also not. So the balance is off." Two rows
   of outlined buttons, both filling mint when active, one centred and one
   left-aligned.

   So the tabs keep their treatment and the day row gives one up: type with a
   rule under the active day, not a second row of buttons. Search drops onto
   its own line so nothing is fighting for the same row.

   SCOPED to .ag-controls on purpose. .trk-tab is also the home page's and
   schedule.html's control (all three surfaces are meant to match) and .chip is
   the exhibitor and speaker-page filter. None of those are being restyled. */
.ag-controls { margin-bottom: 34px; }
.ag-controls .trk-tabs { margin-bottom: 14px; }
.ag-controls .chip-row { justify-content: center; gap: 4px; }
.ag-controls .chip {
  background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0;
  padding: 6px 11px; font-size: 12px; color: var(--text-faint);
}
.ag-controls .chip:hover { color: var(--white); border-bottom-color: rgba(255,255,255,.28); }
.ag-controls .chip.is-active { background: none; color: var(--white); border-bottom-color: var(--mint); }

/* Search + type sit BELOW the tabs and days with real space above them, and
   they are the shared `toolbar` field, not a one-off. Kat 2026-09-09: "maybe
   all that's needed is some space between the days and the search bar, and
   then the search bar should go full width again with all the way on the
   right a drop down" — "it being lumped in with the buttons doesn't work."
   Coarse to fine, top to bottom: the track is which schedule you are looking
   at, the day narrows it, search and type find one thing inside it. */
.ag-find { margin-bottom: 38px; }

/* ---- A day ------------------------------------------------- */
/* The day sticks to the top of the viewport while its sessions
   scroll past, so you always know where you are in the week. */
.ag-day { margin-bottom: 34px; }
.ag-day__hd {
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: baseline; gap: 14px;
  padding: 14px 0 12px; margin-bottom: 14px;
  background: linear-gradient(180deg, var(--navy) 72%, rgba(16,31,54,0) 100%);
}
.ag-day__hd .day { font-family: var(--font-display); font-size: 30px; color: var(--white); line-height: 1; }
.ag-day__hd .date {
  font-family: var(--font-display); letter-spacing: .14em; text-transform: uppercase;
  font-size: 13px; color: var(--mint);
}
.ag-day__hd::after { content: ""; flex: 1; height: 1px; background: var(--hairline); }

/* ---- A session --------------------------------------------- */
.ag-list { display: grid; gap: 12px; }
/* ---- A programme session: the full card -------------------- */
/* A quiet, flat surface. The first version stacked a lit gradient
   on every card and Kat's read was "the gradient thing you did
   looks bad ... cheap looking and busy" — 43 lit panels in a
   column is not the same as one opened panel on a grid. */
.ag-item {
  display: grid; grid-template-columns: 158px 1fr; gap: 28px; width: 100%;
  text-align: left; font: inherit; color: inherit; cursor: pointer;
  padding: 28px 30px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--hairline);
  transition: border-color .18s, background-color .18s;
}
.ag-item:hover, .ag-item:focus-visible {
  border-color: rgba(var(--mint-rgb),.42); background: rgba(255,255,255,.05); outline: none;
}
/* The left rail: when, then what kind. Both start at the same
   height on every card, whatever the title does. */
.ag-item > span:first-child { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.ag-item__time {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .08em;
  font-size: 15px; color: var(--mint); padding-top: 2px;
}
.ag-item__room { display: block; margin-top: 7px; }
.ag-item__title { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.42rem; line-height: 1.2; }
.ag-item__meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 11px; }
.ag-item__desc {
  color: var(--text-muted); font-size: 15px; line-height: 1.7; margin-top: 14px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ---- A routine session: one quiet line -------------------- */
/* Appointments, meals, breaks and registration carry no
   description and no speaker. Given the same card as the
   programme they made a day read as 20 identical blocks
   (Kat 2026-09-08, on Tuesday: "everything's the same looking").
   Which type a session gets is decided by what it HAS, so this
   needs no per-event setup. */
.ag-item--slim {
  grid-template-columns: 158px 1fr auto; align-items: baseline;
  padding: 16px 30px; border-color: transparent; background: none;
  border-radius: 8px;
}
.ag-item--slim:hover, .ag-item--slim:focus-visible { background: rgba(255,255,255,.04); border-color: var(--hairline); }
.ag-item--slim .ag-item__time { font-size: 14px; color: var(--bgray); padding-top: 0; }
.ag-slim__title { font-size: 16px; color: #cfd8e2; }

/* Two kinds of tag, told apart by weight rather than by colour:
   the TRACK is who the session is for and carries the accent, the
   category is what kind of thing it is and sits back. Same pill,
   so this is not the ranked colour-coding she rejected on the
   overview schedule — it is one label being quieter than another. */
.ag-tag {
  font-family: var(--font-display); font-size: 12px; text-transform: uppercase; letter-spacing: .14em;
  color: var(--mint); border: 1px solid rgba(var(--mint-rgb),.32); border-radius: 999px; padding: 5px 12px;
}
.ag-tag--cat { color: var(--bgray); border-color: var(--hairline); }
.ag-room { color: var(--text-faint); font-size: 13.5px; }
/* The cast: one tile per speaker with the name under it, given
   enough size to be looked at rather than a row of thumbnails
   beside a faint list of names. */
.ag-cast { display: flex; flex-wrap: wrap; gap: 18px 22px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--hairline); }
.ag-cast__p { display: flex; align-items: center; gap: 11px; }
.ag-cast__n { color: #dbe3ec; font-size: 15px; line-height: 1.35; max-width: 20ch; }
.ptile--md { width: 52px; height: 52px; border-radius: 8px; }

/* ---- Session detail panel (shared with the speaker page) ---- */
.ag-modal__time { font-family: var(--font-display); text-transform: uppercase; letter-spacing: .1em; font-size: 13px; color: var(--mint); }
.ag-modal__hd { padding: 32px 34px 0; }
.ag-modal__title { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.9rem; line-height: 1.14; margin-top: 10px; }
/* Add to calendar wears the category's faded pill and sits at the right end of
   the meta row (Kat 2026-09-09). It is a button, so it needs the cursor, the
   hover and a real touch target - but WITHOUT growing, because "it's just kinda
   big" is what moved it here. The ::after is an invisible 44px hit area over a
   26px pill, which is how it stays small and still tappable on a phone. */
.ag-ics {
  margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
  position: relative; cursor: pointer; font-family: var(--font-display);
  /* It is a <button>, so the UA's own grey fill has to go or it reads as a
     filled chip beside the outlined ones. */
  background: transparent; -webkit-appearance: none; appearance: none;
  transition: color .18s, border-color .18s;
}
.ag-ics svg { width: 13px; height: 13px; flex: none; }
.ag-ics:hover { color: var(--mint); border-color: rgba(var(--mint-rgb),.42); }
.ag-ics::after {
  content: ""; position: absolute; left: 0; right: 0;
  top: 50%; transform: translateY(-50%); height: 44px;
}
/* On a phone this row already carries up to three tracks, a category and a
   room, so the pill drops to the icon alone rather than adding 150px of text
   to a row that is wrapping anyway. The aria-label and the title carry the
   name for anyone who cannot see the icon. */
@media (max-width: 620px) {
  .ag-ics span { display: none; }
  .ag-ics { gap: 0; padding: 6px 9px; }
  .ag-ics svg { width: 15px; height: 15px; }
}
.ag-modal__desc { color: var(--text-muted); font-size: 15.5px; line-height: 1.75; margin: 22px 0 0; white-space: pre-line; }
.spk-row { display: grid; grid-template-columns: 68px 1fr; gap: 16px; align-items: start; padding: 13px 0; }
.spk-row__name { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.05rem; }
.spk-row__role { color: var(--mint); font-size: 13px; font-weight: 600; margin-top: 2px; }
.spk-row__org { color: var(--text-muted); font-size: 13px; }
/* The cast goes SIDE BY SIDE on desktop. Kat 2026-09-09: "when there is more
   than two speakers, can we start doing a[n extra] grid ... or maybe we should
   do that all the time where they can be side by side on desktop view at
   least ... a two column layout for the speakers."

   TWO columns, not four: the row carries a name, a job title and a company,
   and Europe's real titles run long ("Senior Vice President, Public Relations
   & Chief Communications Officer"). At four across those wrap to three and
   four lines each and the block reads worse than the single column did. One
   column below 720px.

   The negative margin lives on the CONTAINER, not the row, so the two hover
   surfaces keep the full gap between them instead of meeting in the middle. */
.spk-rows { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 20px; margin: 0 -12px; }
/* An ODD LAST speaker takes the whole bottom row, so the block never ends on a
   gap. Kat 2026-09-09: "if there's three speakers, it's two side by side and
   then one taking up the whole bottom row. So we're not left with a gap."
   One speaker spans by the same rule. 1 spans, 2 don't, 3 -> 2 + 1 full, 4
   don't, 5 -> 2 + 2 + 1 full. Supersedes the earlier rule that spanned only a
   lone speaker and left the fifth of five sitting in half a row. */
.spk-rows .spk-row:last-child:nth-child(odd) { grid-column: 1 / -1; }
.spk-rows .spk-row { padding-left: 12px; padding-right: 12px; }
.spk-rows .spk-row--link { margin: 0; }

/* A cast member in a session's detail goes through to their profile with it
   already open (Kat 2026-09-09). It is a real anchor, so the row needs to look
   like one: the whole row is the target, the chevron sits at the right edge and
   is always visible because a hover state is invisible on a phone. */
.spk-row--link {
  grid-template-columns: 68px 1fr auto; text-decoration: none; color: inherit;
  border-radius: 6px; margin: 0 -12px; padding: 13px 12px; transition: background .18s, color .18s;
}
.spk-row--link:hover { background: rgba(255,255,255,.045); }
.spk-row--link:hover .spk-row__name { color: var(--mint); }
.spk-row__go { align-self: center; color: var(--text-faint); flex: none; transition: color .18s, transform .18s; }
.spk-row--link:hover .spk-row__go { color: var(--mint); transform: translateX(2px); }
.ag-panel { background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 4px 22px 8px; margin-top: 28px; }
.ag-panel__hd { display: flex; align-items: center; gap: 12px; padding: 16px 0 12px; border-bottom: 1px solid var(--hairline); }
.ag-panel__hd h3 { font-family: var(--font-display); font-weight: 500; text-transform: uppercase; letter-spacing: .16em; font-size: 13px; color: var(--mint); margin: 0; }

/* ---- The Sessions page on a phone --------------------------
   ONE block. There used to be three separate max-width:620px
   blocks setting the same properties against each other, and the
   last one won with `padding-right: 0`, which is why every card's
   text ran into its own right edge. Reviewed with Kat 2026-09-09:
   "I looked at it on my phone and it's not great on mobile."
   The whole page was rendering at the desktop type scale in a
   350px column - 26 sessions came to 8,050px of scrolling and a
   single four-speaker card filled the screen on its own. */
@media (max-width: 620px) {
  /* THE CARD CARRIES LESS, NOT SMALLER. Kat 2026-09-09, on the first mobile
     pass: "all the text is small and cramped ... way too much information all
     crammed in your face ... the individual card should probably only have,
     like, the time, the name, and maybe a brief description, and maybe just
     the speaker photo, not the name."

     The reference is her own speaker page on a phone, which she called
     "bigger and cleaner and more appealing": one card per row, three short
     lines, an 18.4px name, generous padding — and 13,935px of page for 26
     speakers. Page length was never the problem; density was. So the card
     keeps FOUR things — time, title, two lines of description, faces — and
     everything else waits for the tap. */
  .ag-item { grid-template-columns: 1fr; gap: 13px; padding: 22px 20px; border-radius: 10px; }
  /* A quiet row is time | title, with the room under the title. At `1fr auto`
     the title was landing in the right-hand cell and the room under the TIME,
     so "Registration" sat hard right with its room beneath the clock. */
  .ag-item--slim { grid-template-columns: auto 1fr; gap: 3px 14px; padding: 16px 20px; }
  .ag-item--slim .ag-item__time { grid-column: 1; grid-row: 1; }
  .ag-item--slim .ag-slim__title { grid-column: 2; grid-row: 1; }
  .ag-item--slim .ag-room { grid-column: 2; grid-row: 2; }
  .ag-item > span:first-child { gap: 0; }
  .ag-item__time { padding-top: 0; font-size: 14px; }
  .ag-item--slim .ag-item__time { font-size: 13.5px; }
  .ag-item__title { font-size: 20px; line-height: 1.25; }
  .ag-item__desc { font-size: 15px; line-height: 1.6; margin-top: 10px; }
  .ag-slim__title { font-size: 16px; }
  .ag-room { font-size: 13px; }
  .ag-day__hd { flex-wrap: wrap; }
  .ag-day__hd .day { font-size: 26px; }

  /* Off the card and onto the detail: the session type and the room. The tap
     is what they are for. */
  .ag-item:not(.ag-item--slim) .ag-tag--cat,
  .ag-item__room { display: none; }

  /* Faces only. The names were four more lines on a card whose job is to be
     scanned; they are on the detail with their roles and companies. */
  .ag-cast { gap: 10px; margin-top: 4px; padding-top: 14px; }
  .ag-cast__p { gap: 0; }
  .ag-cast__n { display: none; }
  .ptile--md { width: 44px; height: 44px; }

  /* THE CARD GIVES UP ITS PLACE. Kat 2026-09-09: "if on mobile you're gonna
     have it open on page like that, then the original card needs to disappear,
     because right now it's opening below it and so you still have both." Same
     ruling she made on the speaker page on 9/8 for the same reason — the card
     and the panel under it were the same time and title twice over. */
  .ag-item.is-open { display: none; }

  /* The detail, in the row's own place rather than a 743px popup inside an
     844px screen with its own separate scroll. Same TW.sessionDetail the
     desktop popup renders — one renderer, different container. */
  .ag-open {
    position: relative; padding: 4px 0 0;
    background: var(--navy-2); border: 1px solid rgba(var(--mint-rgb),.42);
    border-radius: 10px;
  }
  .ag-open .ag-modal__hd { padding: 20px 20px 0; }
  .ag-open .ex-modal__body { padding: 0 20px 22px; }
  .ag-open .ag-modal__title { font-size: 20px; line-height: 1.25; padding-right: 40px; }
  .ag-open .ag-modal__desc { font-size: 15px; line-height: 1.65; }
  .ag-open .spk-rows { grid-template-columns: 1fr; margin: 0; }
  .ag-open .spk-rows .spk-row { padding-left: 0; padding-right: 0; }
  .ag-open__close {
    position: absolute; top: 12px; right: 12px; z-index: 2; width: 36px; height: 36px;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    background: rgba(var(--navy-rgb),.7); border: 1px solid var(--hairline);
    border-radius: 50%; color: var(--white);
  }

  /* Controls: three tabs on one even row instead of two-then-one, and the day
     row tall enough to hit. */
  .ag-controls .trk-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .trk-tab { padding: 13px 4px; font-size: 11.5px; letter-spacing: .08em; }
  .ag-controls .chip { min-height: 44px; display: inline-flex; align-items: center; padding: 6px 9px; }
  /* Search and the type filter share one line rather than the filter being
     stranded under a full-width field. */
  .ag-find { flex-wrap: nowrap; gap: 10px; }
  .ag-find input[type="search"] { flex: 1 1 auto; min-width: 0; }
  .ag-find .filt { flex: 0 0 auto; }
  /* 43px, one pixel under the target everything else on this page clears. */
  .ag-find .filt__btn { min-height: 44px; }

  /* The session panel. Desktop side padding left ~280px of usable width. */
  .ex-modal__panel--wide .ag-modal__hd { padding: 26px 20px 0; }
  .ex-modal__panel--wide .ex-modal__body { padding: 0 20px 24px; }
  .ag-modal__title { font-size: 22px; line-height: 1.18; }
  .ag-modal__desc { font-size: 15px; line-height: 1.6; margin-top: 18px; }
  .ag-modal__time { font-size: 12px; }
  .ex-modal__panel--wide .ag-item__meta { gap: 7px; margin-top: 12px; }
  .ex-modal__panel--wide .ex-modal__close { top: 10px; right: 10px; width: 34px; height: 34px; }

  .spk-row { grid-template-columns: 44px 1fr; gap: 12px; }
  .spk-rows { grid-template-columns: 1fr; }
  .spk-row--link { grid-template-columns: 44px 1fr auto; }
  .ptile--lg { width: 44px; height: 44px; }
}

/* ---- Speaker directory cards -------------------------------
   Cards, not circles (Kat 2026-09-08): a square photo with the
   name, title and company in a box underneath, built on the same
   bones as the exhibitor card so the two grids read as one site.

   The tile carries a GRADIENT rather than a flat fill because
   several Cvent headshots are cut-out PNGs with a transparent
   background — on the bare navy they read as floating heads.
   Verified 2026-09-08: 4 of the first 8 Europe photos are
   colour-type-6 PNGs with an alpha channel. The gradient sits
   behind every photo, so it fixes those and is invisible under
   the opaque JPEGs. She ruled out flat 50% white for it.
   Tinted off --mint-rgb, so each event's own accent tints it. */
.spk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(228px, 1fr)); gap: 24px; }
.spk-card {
  display: flex; flex-direction: column; width: 100%; text-align: left; padding: 0;
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius);
  overflow: hidden; font: inherit; color: inherit; cursor: pointer;
  transition: border-color .2s, transform .2s, box-shadow .2s;
}
.spk-card:hover, .spk-card:focus-visible {
  border-color: rgba(var(--mint-rgb),.45); transform: translateY(-3px);
  box-shadow: 0 14px 30px rgba(0,0,0,.28); outline: none;
}
/* EVERY tile is the same square, whatever the source photo's shape.
   The image is positioned ABSOLUTELY rather than sized at 100% —
   as a flex item its `min-height: auto` let a tall portrait push
   the box past its own aspect-ratio, so Stephen Rose's tile
   rendered 326x489 against everyone else's 326x326 (measured
   2026-09-08, Kat spotted it by eye first). Cvent photos range
   from 2:3 to 6:5, so this cannot be left to the data.

   The gradient behind the photo is the whole treatment: a photo
   that arrives cut out sits ON it, a photo that arrives with its
   own background keeps that background (Kat 2026-09-08, after we
   tried replacing everyone's background and it was more trouble
   than it was worth). Which is which is measured per photo in
   speakers.html, not assumed. */
.spk-card__tile {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(var(--mint-rgb),.16) 0%, rgba(var(--mint-rgb),0) 62%),
    linear-gradient(158deg, rgba(255,255,255,.14) 0%, rgba(150,192,228,.10) 45%, rgba(255,255,255,.03) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}
.spk-card__tile img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center top; display: block;
  /* A hair of overscan. Source photos turn up with a stray edge row —
     Philipp Detmer's last pixel row is white (luminance 249 against 91
     above it), which drew a white line across the bottom of his card.
     Cropping ~1% kills any one-pixel edge without visibly reframing. */
  transform: scale(1.012); transform-origin: center top;
}

/* A cut-out photo spans the full width of its frame and is nudged
   DOWN so the head isn't against the top edge. It is not scaled to
   fit its subject and it is never cropped at the sides — that
   version chopped Aaron Wodin-Schwartz's arms off and shrank him,
   when all he needed was margin above his head (Kat 2026-09-08).
   Spanning the full width also matters for a subject whose arm is
   already clipped at the file's edge, like Janette Roush: her arm
   reaches the frame edge instead of ending in mid-air.
   `height: auto` keeps the photo's own ratio, so nothing can
   squash — the previous version sized both axes in percentages and
   let `object-fit: fill` distort whenever the column reflowed. */
.spk-card__tile img.is-cut, .spk-open__photo img.is-cut {
  inset: auto; left: 0; width: 100%; height: auto; object-fit: contain; transform: none;
}

/* No photo in Cvent: the initials drawn as outlined display type
   on the gradient. The first attempt put one big brand star in
   the tile and Kat rejected it outright — "that looks like
   Hollywood Walk of Fame". Type, not decoration. */
.spk-card__tile--ph, .spk-open__photo--ph {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
}
.spk-card__tile .initials, .spk-open__photo .initials {
  font-family: var(--font-display); font-weight: 600; letter-spacing: .03em; line-height: .9;
  color: transparent; -webkit-text-stroke: 2px rgba(var(--mint-rgb),.6);
}
.spk-card__tile { container-type: inline-size; }
.spk-card__tile .initials { font-size: 40cqw; }
.spk-open__photo .initials { font-size: 34cqw; -webkit-text-stroke-width: 2.5px; }
/* A short accent rule under the initials, so the empty tile reads as a
   composition rather than as a missing image. */
.spk-card__tile--ph::after, .spk-open__photo--ph::after {
  content: ""; width: 44px; height: 2px; background: rgba(var(--mint-rgb),.6);
}
.spk-open__photo--ph::after { width: 64px; }

.spk-card__body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 4px; }
.spk-card__name { font-family: var(--font-display); font-weight: 500; color: var(--white); font-size: 1.15rem; line-height: 1.2; }
.spk-card__role { color: var(--mint); font-size: 12.5px; font-weight: 600; line-height: 1.35; }
.spk-card__org { color: var(--text-muted); font-size: 12.5px; }

/* ---- A speaker, opened in place ----------------------------
   Rebuilt 2026-09-08 (Kat's call). Not a popup: tapping a card
   splits the grid open under that card's row and lays the speaker
   out across the full width. Every popup version failed the same
   way — a panel sized by the bio either left a dead column beside
   a long bio or stretched the photo beside a short one.

   TWO columns, not three. Three was tried and read as squished:
   "three columns is too many columns." So the left column is the
   identity — picture, name, role, and what they're speaking at —
   and the bio has the right side to itself.

   The panel is a grid item spanning every column, inserted after
   the last card of the clicked card's row (speakers.html works
   out where that is). */
.spk-open {
  grid-column: 1 / -1; position: relative; overflow: hidden;
  border-radius: 16px; padding: 34px 36px 36px; margin: 2px 0 10px;
  /* Depth without another gradient competing with the ones behind
     the photos: a surface lit from the top, a real shadow to lift
     it off the grid, and a hairline highlight along the top edge.
     Kat 2026-09-08 — the flat panel with a mint border was "a
     little blur". The accent is a single fading rule at the top,
     which reads as an opened drawer rather than a boxed-in card. */
  background:
    linear-gradient(180deg, rgba(255,255,255,.055) 0%, rgba(255,255,255,.012) 42%, rgba(255,255,255,0) 100%),
    linear-gradient(180deg, var(--navy-2) 0%, var(--ink) 100%);
  border: 1px solid var(--hairline);
  box-shadow: 0 26px 60px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.07);
}
.spk-open::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--mint) 0%, rgba(var(--mint-rgb),.35) 32%, rgba(var(--mint-rgb),0) 72%);
}
.spk-open__grid { display: grid; grid-template-columns: minmax(280px, 340px) 1fr; gap: 40px; align-items: start; }
/* No photo: one column, full width. */
.spk-open__grid--solo { grid-template-columns: 1fr; }
.spk-open__grid--solo .spk-open__bio { max-width: 78ch; }
/* 44px, not 34: this is the only way out of an opened speaker on a
   phone, so it gets a full touch target. */
.spk-open__close {
  position: absolute; top: 14px; right: 14px; width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.06); border: 1px solid var(--hairline); color: var(--text-muted);
  cursor: pointer; transition: background-color .15s, color .15s, border-color .15s;
}
.spk-open__close:hover { background: var(--mint); color: var(--navy); border-color: var(--mint); }

/* The photo keeps the card's square shape and gradient, so opening
   a card reads as the same picture getting bigger. */
.spk-open__photo {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden; border-radius: 10px;
  container-type: inline-size;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(var(--mint-rgb),.16) 0%, rgba(var(--mint-rgb),0) 62%),
    linear-gradient(158deg, rgba(255,255,255,.14) 0%, rgba(150,192,228,.10) 45%, rgba(255,255,255,.03) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}
.spk-open__photo img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center top; display: block;
  transform: scale(1.012); transform-origin: center top;
}

.spk-open__name {
  font-family: var(--font-display); font-weight: 500; color: var(--white);
  font-size: clamp(1.7rem, 2.4vw, 2.1rem); line-height: 1.06;
}
.spk-open__role { color: var(--mint); font-size: 14.5px; font-weight: 600; line-height: 1.4; margin-top: 10px; }
.spk-open__org {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .18em;
  font-size: 11.5px; color: var(--text-faint); margin-top: 7px;
}
/* The rule under the company line is what separates who they are
   from what they've written, now that both sit in the same column. */
.spk-open__bio {
  color: var(--text-muted); font-size: 15px; line-height: 1.78; white-space: pre-line;
  margin: 22px 0 0; padding-top: 20px; border-top: 1px solid var(--hairline); max-width: 70ch;
}

/* The card you opened, marked so the panel below it has an owner. */
.spk-card.is-active { border-color: rgba(var(--mint-rgb),.5); }
/* On a single-column grid the panel takes the card's place instead of
   repeating the same photo and name directly above itself. The class is
   applied by speakers.html only when the grid resolves to one column. */
.spk-card.is-replaced { display: none; }

@media (max-width: 760px) {
  .spk-open { padding: 26px 22px 28px; }
  .spk-open__grid { grid-template-columns: 1fr; gap: 26px; }
}

/* "Speaking at". NOT a timeline: the rail with a dot per session
   made a single dot the loudest thing on most profiles, and most
   of these speakers appear once (Kat 2026-09-08 — "it just kind of
   emphasizes the point that they're not speaking more than once").
   Each session is its own block instead, so one reads as a
   statement and several read as a set.
   The session title leads, with the day and time above it. */
.spk-sessions { margin-top: 26px; }
.spk-sessions__hd {
  font-family: var(--font-display); font-weight: 500; text-transform: uppercase;
  letter-spacing: .2em; font-size: 11.5px; color: var(--text-faint);
  display: flex; align-items: center; gap: 12px; margin-bottom: 14px;
}
.spk-sessions__hd::after { content: ""; flex: 1; height: 1px; background: var(--hairline); }
.spk-ses { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.spk-ses li {
  background: var(--surface); border: 1px solid var(--hairline); border-radius: var(--radius);
  border-left: 2px solid rgba(var(--mint-rgb),.55); overflow: hidden;
}
/* The whole block is the link: it goes to the schedule page with this
   session already open, rather than stacking a second panel on this one. */
/* The whole block is the control: it opens the session's detail
   panel on this page, the same one the schedule page opens.
   No corner arrow — Kat 2026-09-08: "I don't like the arrow in
   the corner." */
.spk-ses__link {
  display: block; width: 100%; text-align: left; position: relative;
  padding: 16px 20px; background: none; border: 0; font: inherit; color: inherit;
  cursor: pointer; text-decoration: none; transition: background-color .15s;
}
.spk-ses__link:hover, .spk-ses__link:focus-visible { background: rgba(255,255,255,.045); outline: none; }
.spk-ses__link:focus-visible { box-shadow: inset 2px 0 0 var(--mint); }
.spk-ses__when {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em;
  font-size: 11.5px; color: var(--mint); display: block; margin-bottom: 7px;
}
.spk-ses__title { color: var(--white); font-size: 17px; line-height: 1.35; display: block; }
.spk-ses__room { display: block; color: var(--text-faint); font-size: 12.5px; margin-top: 6px; }

@media (max-width: 720px) {
  .spk-profile { grid-template-columns: 1fr; }
  .spk-head { padding: 28px 24px 0; }
  .spk-body { padding: 0 24px 30px; }
}

/* Wide modal for long text. Cvent bios run several hundred words,
   which at the standard 640px panel is a very tall column. Only
   the panels that opt in get it; the exhibitor modal is unchanged. */
.ex-modal__panel--wide { width: min(920px, 100%); }
.spk-card--btn:hover, .spk-card--btn:focus-visible { background: rgba(255,255,255,.03); outline: none; }


/* Custom session fields inside a session's detail. Name and value
   on one line each, so a Track or a Level reads as a fact rather
   than a paragraph. */
.ag-fields { display: grid; grid-template-columns: auto 1fr; gap: 8px 18px; margin: 24px 0 0; padding-top: 20px; border-top: 1px solid var(--hairline); }
.ag-fields dt {
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .14em;
  font-size: 11.5px; color: var(--text-faint); padding-top: 3px;
}
.ag-fields dd { margin: 0; color: var(--white); font-size: 15px; }

/* ---------- Language switcher ----------------------------------------
   Only renders on a market whose event-config declares `languages`
   (Latin America today); the English-only markets never see it, so their
   headers are unchanged. Sits between the menu and the mobile trigger.
   Kat 2026-09-09: the toggle is the mechanism, and location/device detection
   layers on top of it later rather than replacing it. */
.langsw { position: relative; margin-left: 18px; }
.langsw__btn { display: inline-flex; align-items: center; gap: 7px; background: transparent;
  border: 1px solid rgba(255,255,255,.22); border-radius: 2px; cursor: pointer;
  font-family: var(--font-display); text-transform: uppercase; letter-spacing: .12em;
  font-size: 12px; color: var(--text-muted); padding: 9px 13px; transition: .2s; }
.langsw__btn:hover { border-color: var(--mint); color: var(--white); }
.langsw__btn svg { flex-shrink: 0; opacity: .8; }
.langsw__menu { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  list-style: none; margin: 0; padding: 6px; min-width: 190px;
  background: var(--navy-2); border: 1px solid var(--hairline); border-radius: 4px;
  box-shadow: 0 14px 34px rgba(0,0,0,.34); }
.langsw__menu a { display: block; padding: 9px 12px; border-radius: 2px; font-size: 14px;
  color: var(--text-muted); }
.langsw__menu a:hover { background: rgba(var(--mint-rgb),.10); color: var(--white); }
.langsw__menu .is-current a { color: var(--mint); }
/* The trigger is hidden with the desktop menu; the panel carries the languages
   instead, so a phone never loses the switch. */
.mobile-panel__langs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px;
  padding-top: 18px; border-top: 1px solid var(--hairline); }
.mobile-panel__langs a { padding: 10px 14px; border: 1px solid rgba(255,255,255,.22);
  border-radius: 2px; font-size: 14px; color: var(--text-muted); }
.mobile-panel__langs a.is-current { border-color: var(--mint); color: var(--mint); }
@media (max-width: 1080px) { .langsw { display: none; } }

/* ---------- Draft-layout notice ------------------------------------
   Injected by build.js on any slug listed in an event's `templatePages`.
   Kat 2026-09-10, ahead of showing the team pages whose copy does not exist
   yet: they need to see the shape to know what to send back, and the page has
   to be unmistakable about the words being a guess. Deliberately loud - accent
   rule, accent heading - rather than a quiet grey strip that reads as chrome.
   Remove the slug from templatePages and this disappears with it. */
.tmpl-note {
  border-top: 3px solid var(--mint);
  background: rgba(var(--mint-rgb), .09);
  color: var(--text);
  font-size: 14px; line-height: 1.55;
  padding: 16px 24px;
  text-align: center;
}
.tmpl-note strong { color: var(--mint); font-family: var(--font-display);
  text-transform: uppercase; letter-spacing: .08em; font-size: 13px;
  display: block; margin-bottom: 4px; }
@media (max-width: 600px) { .tmpl-note { padding: 14px 18px; font-size: 13px; } }

/* The switcher's full language name is what squeezed the header once Latin
   America un-hid its pre-registration pages: the menu itself is SHORTER than
   Europe's (60 characters against 65) but Europe has no switcher in the row, so
   "Brand USA" wrapped to two lines between roughly 1080 and 1250px. Measured,
   not guessed - a wrapped item goes from 46px to 69px.
   Below 1250px the button shows the globe and the language code instead. */
/* The button shows the globe and the language CODE at every width, not the
   full language name. The header row is capped by `.wrap`, so a wider screen
   buys nothing - Latin America's eleven items were wrapping "Brand USA" onto a
   second line even at 1700px, and squeezing the logo from 131px to 109px. The
   full name lives in the open menu, where there is room for it. */
.langsw__full { display: none; }
.langsw__short { display: inline; }
@media (max-width: 1250px) { .langsw { margin-left: 12px; } .langsw__btn { padding: 9px 11px; } }



/* The band between the burger breakpoint (1080px) and about 1200px, on a market
   that carries a language switcher in the header row. Menu items give up side
   padding rather than wrapping. Deliberately padding ONLY - an earlier attempt
   added `white-space: nowrap` here and the row stopped wrapping by crushing the
   logo to 17px instead, which is worse than the problem. */
@media (min-width: 1081px) and (max-width: 1200px) {
  .menu > li > a, .menu > li > span { padding-left: 7px; padding-right: 7px; }
  .menu { gap: 0; }
}
