/* IBM Plex Mono · loaded from Google Fonts so the deck mono matches the
   InDesign dossier artiste (same family, same Adobe Fonts activation). */
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&display=swap');

:root {
  --bg: #F4F1EA;
  --ink: #0E0E0E;
  --muted: #8A8A8A;
  --accent: #E63A1F;
  --inverse-bg: #1F1D1A;
  --inverse-ink: #F4F1EA;
  --pad-y: 8vh;
  --pad-x: 8vw;
  --font: "Helvetica Neue", "Inter", "Arial", sans-serif;
  --mono: "IBM Plex Mono", "JetBrains Mono", "Menlo", "Courier New", monospace;
}

/* ── Dark theme ──────────────────────────────────────────────────
   Triggered by the inline <head> script setting <html data-theme="dark">.
   Inverts --bg and --ink and slightly cools --muted so the muted text
   stays legible on the dark paper. The accent stays the same — the
   orange-red works against both palettes.                            */
html[data-theme="dark"] {
  --bg: #1F1D1A;
  --ink: #F4F1EA;
  --muted: #9A958B;
  --inverse-bg: #F4F1EA;
  --inverse-ink: #1F1D1A;
}
/* Smooth palette swap. Limited to the few properties actually
   affected so we never animate layout-relevant properties. */
html, body, .slide, .meta-bar, .foot-bar,
.title-1, .title-3, .body, .lead, .label, .subtle, .subtitle,
.who-list li, .editions .edition, .venue-fact, .facts li,
.brand-cell, .brand-list, .logo-cell, .tt > div,
.team-link, .modal-box, .pdf-loading {
  transition: background-color 0.25s ease, color 0.25s ease,
              border-color 0.25s ease;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html {
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}
html, body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Korean text would otherwise wrap mid-syllable, leaving lone characters
     dangling on the next line. `keep-all` makes CJK break only at spaces
     (the same behaviour as English/French) so word boundaries stay intact.
     Scoped to `[lang="ko"]` so EN/FR copy keeps the default break rules. */
}
html[lang="ko"], html[lang="ko"] body {
  word-break: keep-all;
  overflow-wrap: break-word;
}
a { color: inherit; text-decoration: none; }
.meta-bar a, .foot-bar a { border-bottom: none; }

.slide {
  height: 100vh;
  min-height: 640px;
  padding: var(--pad-y) var(--pad-x);
  display: flex;
  flex-direction: column;
  position: relative;
  border-bottom: 1px solid var(--ink);
  overflow: hidden;
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

.meta-bar, .foot-bar {
  position: absolute;
  left: var(--pad-x);
  right: var(--pad-x);
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}
.meta-bar { top: 4vh; }
.foot-bar { bottom: 4vh; }

.dl-link {
  cursor: pointer;
  color: var(--accent);
  background: none;
  border: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  padding: 0;
  margin-right: 14px;
  transition: color 0.2s;
  font-weight: 700;
}
.dl-link:hover { color: var(--ink); }
.dl-link:disabled { opacity: 0.5; cursor: wait; }

/* "Book a Call" CTA — orange, beside the download link in every meta-bar.
   Inherits the meta-bar's uppercase/letter-spacing so it matches .dl-link.
   Opens the Google scheduling page in a new tab. */
.talk-link {
  color: var(--accent);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  margin-right: 14px;
  transition: color 0.2s;
}
.talk-link:hover { color: var(--ink); }
.ctrl-sep {
  display: inline-block;
  width: 1px;
  height: 10px;
  margin-right: 12px;
  background: var(--muted);
  opacity: 0.55;
  vertical-align: middle;
}
body.pdf-capture .talk-link,
body.pdf-capture .ctrl-sep { display: none !important; }

/* ── Meta-bar toggles (FR/EN + light/dark) ──────────────────────
   Both sit just to the left of the .dl-link in every meta-bar.
   Markup is injected by scripts/i18n-theme.js. The pill switch
   takes its visual cue from the on/off mock the user shared:
   a dark capsule with a smaller light "thumb" carrying the
   active label.                                                   */
.lang-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding: 2px;
  margin-right: 10px;
  border: none;
  border-radius: 999px;
  background: var(--ink);
  color: var(--bg);
  font: inherit;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  vertical-align: middle;
  -webkit-tap-highlight-color: transparent;
}
.lang-toggle .lt-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  /* Three equal segments — each segment is 1/3 of the inner width.
     The 4px adjustment accounts for the 2px padding on either side. */
  width: calc((100% - 4px) / 3);
  height: calc(100% - 4px);
  background: var(--bg);
  border-radius: 999px;
  transition: transform 0.22s cubic-bezier(0.4, 0.1, 0.3, 1);
  pointer-events: none;
}
.lang-toggle[data-active="fr"] .lt-thumb { transform: translateX(0); }
.lang-toggle[data-active="en"] .lt-thumb { transform: translateX(100%); }
.lang-toggle[data-active="ko"] .lt-thumb { transform: translateX(200%); }
.lang-toggle .lt-lbl {
  position: relative;
  z-index: 1;
  width: 26px;
  text-align: center;
  transition: color 0.18s;
  pointer-events: none;
}
.lang-toggle[data-active="fr"] .lt-fr,
.lang-toggle[data-active="en"] .lt-en,
.lang-toggle[data-active="ko"] .lt-ko { color: var(--ink); }
.lang-toggle[data-active="fr"] .lt-en,
.lang-toggle[data-active="fr"] .lt-ko,
.lang-toggle[data-active="en"] .lt-fr,
.lang-toggle[data-active="en"] .lt-ko,
.lang-toggle[data-active="ko"] .lt-fr,
.lang-toggle[data-active="ko"] .lt-en { color: var(--bg); opacity: 0.55; }

/* Theme toggle: round outlined button. Sun visible in dark mode
   (so a click sends you back to light); moon visible in light. */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-right: 8px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--ink);
  border-radius: 999px;
  color: var(--ink);
  cursor: pointer;
  vertical-align: middle;
  transition: background-color 0.2s, color 0.2s, border-color 0.2s;
  -webkit-tap-highlight-color: transparent;
}
.theme-toggle:hover { background: var(--ink); color: var(--bg); }
.theme-toggle .tt-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 12px;
  height: 12px;
}
.theme-toggle .tt-icon svg { width: 12px; height: 12px; display: block; }
.theme-toggle .tt-sun  { display: none; }
.theme-toggle .tt-moon { display: inline-flex; }
.theme-toggle[data-theme="dark"] .tt-sun  { display: inline-flex; }
.theme-toggle[data-theme="dark"] .tt-moon { display: none; }

/* Hide the toggles during the cover intro so they don't peek above
   the splash overlay. They reappear as soon as the intro dismisses. */
html:not(.cover-intro-done) .lang-toggle,
html:not(.cover-intro-done) .theme-toggle { visibility: hidden; }

/* Suppress every text element of the cover slide until the intro
   has revealed it. This is belt-and-suspenders: the splash overlay
   already covers the viewport at z-index 9999, but on slow first
   paints (cold cache, mobile Safari race conditions) a single
   frame can sometimes show the meta-bar's "DIGITAL AF · 하나됨"
   left text or the foot-bar's date string, which the user reads
   as a flash. The selector targets only the FIRST .slide so we
   never affect the rest of the deck. */
html:not(.cover-intro-done) .slide:first-of-type .meta-bar,
html:not(.cover-intro-done) .slide:first-of-type .foot-bar {
  visibility: hidden !important;
}

/* Hide them from PDF capture so the printed deck stays clean. */
body.pdf-capture .lang-toggle,
body.pdf-capture .theme-toggle { display: none !important; }

/* Navigation arrows — minimal, no fill, just a thin chevron in ink */
.nav-arrows {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 9998;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.nav-arrow {
  width: 28px;
  height: 28px;
  background: transparent;
  color: var(--ink);
  border: 0;
  cursor: pointer;
  font-size: 18px;
  font-weight: 400;
  font-family: var(--mono);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, opacity 0.15s, transform 0.15s;
  padding: 0;
  line-height: 1;
  opacity: 0.55;
}
.nav-arrow:hover { opacity: 1; color: var(--accent); }
.nav-arrow:active { transform: translateY(1px); }
.nav-arrow:disabled { opacity: 0.18; cursor: not-allowed; }
.nav-arrow:disabled:hover { color: var(--ink); }

/* PDF loading indicator */
.pdf-loading {
  position: fixed;
  inset: 0;
  background: var(--bg);
  color: var(--ink);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  flex-direction: column;
  padding: 20px;
}
.pdf-loading.active { display: flex; }
.pdf-loading.ready .spinner { display: none; }
.pdf-loading.ready .pdf-loading-kicker { margin-top: 0; }
.pdf-loading .spinner {
  width: clamp(64px, 10vh, 96px);
  height: clamp(64px, 10vh, 96px);
  border: 3px solid var(--ink);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
.pdf-loading-kicker {
  margin-top: clamp(28px, 4vh, 48px);
  font-family: var(--mono);
  font-size: clamp(10px, 1.2vh, 12px);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--muted);
}
.pdf-loading-title {
  margin-top: clamp(10px, 1.4vh, 16px);
  font-size: clamp(28px, 5vh, 56px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  text-align: center;
}
.pdf-loading-step {
  margin-top: clamp(14px, 2vh, 22px);
  font-family: var(--mono);
  font-size: clamp(12px, 1.5vh, 15px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
}
.pdf-loading-progress {
  margin-top: clamp(16px, 2.4vh, 24px);
  width: clamp(180px, 28vw, 320px);
  height: 2px;
  background: rgba(14, 14, 14, 0.15);
  position: relative;
  overflow: hidden;
}
.pdf-loading-progress::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(var(--pdf-progress, 0));
  transition: transform 0.3s ease;
}
.pdf-loading-hint {
  margin-top: clamp(16px, 2.2vh, 22px);
  font-size: clamp(12px, 1.4vh, 14px);
  color: var(--muted);
  max-width: 360px;
  text-align: center;
  line-height: 1.45;
}
.pdf-loading-close {
  position: absolute;
  top: clamp(18px, 2.5vh, 28px);
  right: clamp(18px, 2.5vw, 32px);
  background: none;
  border: 0;
  color: var(--ink);
  font-size: clamp(28px, 3.5vh, 40px);
  font-weight: 400;
  cursor: pointer;
  line-height: 1;
  width: clamp(36px, 4.5vh, 48px);
  height: clamp(36px, 4.5vh, 48px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: background 0.2s, color 0.2s;
}
.pdf-loading-close:hover { background: var(--ink); color: var(--bg); }
@keyframes spin { to { transform: rotate(360deg); } }

/* ─── Cover intro animation (Pixar-style 화합 bounce) ─── */
/* Hide cover title and 하나됨 from the very first paint until JS reveals them
   at the end of the intro. Prevents the half-second flash where the rested
   slide shows before the overlay catches up. */
html:not(.cover-intro-done) #cover-title,
html:not(.cover-intro-done) #cover-hana {
  visibility: hidden;
}
.cover-top { display: inline-block; }
.cover-top .cover-word { display: inline-flex; }
.cover-top .cover-gap  { display: inline-block; width: 0.32em; }
.cover-top .ltr { display: inline-block; will-change: transform; }

.cover-intro-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 9999;
  pointer-events: none;
}
.cover-intro-overlay.dismissed { display: none; }
.cover-intro-clones { position: fixed; inset: 0; pointer-events: none; }
.cover-intro-clone {
  position: fixed;
  will-change: transform, opacity;
  transform-origin: 50% 50%;
}
.cover-intro-clone .ltr {
  display: inline-block;
  transform-origin: 50% 100%;
}
.cover-intro-hana-anim {
  position: fixed;
  font-family: inherit;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.04em;
  line-height: 0.9;
  will-change: transform, opacity, font-size;
  transform-origin: 50% 50%;
  white-space: nowrap;
}
.cover-intro-hana-anim .hch { display: inline-block; transform-origin: 50% 50%; }

/* Hide intro entirely during PDF capture so it never leaks into the rendered slide */
body.pdf-capture .cover-intro-overlay,
body.pdf-capture .cover-intro-clones,
body.pdf-capture .cover-intro-hana-anim { display: none !important; }
/* Force cover title + 하나됨 visible during PDF capture (override the
   :not(.cover-intro-done) hide rule, in case the user clicks Download before
   the intro has finished). */
body.pdf-capture #cover-title,
body.pdf-capture #cover-hana { visibility: visible !important; }

/* CTA bar (Partnership slide) */
.cta-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(10px, 2vh, 20px);
  margin-top: clamp(16px, 2.5vh, 28px);
  padding: clamp(14px, 2.2vh, 22px) clamp(18px, 2vw, 28px);
  background: var(--accent);
  color: var(--bg);
}
.cta-text {
  font-size: clamp(14px, 1.9vh, 22px);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.cta-btn {
  font-family: inherit;
  font-size: clamp(13px, 1.7vh, 18px);
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--bg);
  color: var(--accent);
  border: 0;
  padding: clamp(10px, 1.6vh, 16px) clamp(18px, 2.2vw, 28px);
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
  text-transform: uppercase;
}
.cta-btn:hover { background: var(--ink); color: var(--bg); }

/* Contact modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  padding: 20px;
}
.modal-overlay.active { display: flex; }
.modal-box {
  background: var(--bg);
  width: 100%;
  max-width: 480px;
  padding: clamp(24px, 4vh, 40px);
  border: 2px solid var(--ink);
  position: relative;
  max-height: 90vh;
  overflow-y: auto;
}
.modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
  background: none;
  border: 0;
  font-size: 22px;
  font-weight: 700;
  cursor: pointer;
  color: var(--ink);
  line-height: 1;
}
.modal-label {
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}
.modal-title {
  font-size: clamp(22px, 3.5vh, 34px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: 8px;
}
.modal-body {
  font-size: 14px;
  color: var(--muted);
  margin-top: 10px;
  line-height: 1.5;
}
.modal-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 18px;
}
.modal-field label {
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}
.modal-field input,
.modal-field textarea {
  font-family: inherit;
  font-size: 14px;
  padding: 10px 12px;
  border: 1px solid var(--ink);
  background: var(--bg);
  color: var(--ink);
  border-radius: 0;
  outline: none;
  resize: vertical;
}
.modal-field input:focus,
.modal-field textarea:focus { border-color: var(--accent); }
.modal-submit {
  margin-top: 22px;
  width: 100%;
  background: var(--accent);
  color: var(--bg);
  border: 0;
  padding: 14px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s;
}
.modal-submit:hover { background: var(--ink); }
.modal-submit:disabled { opacity: 0.6; cursor: wait; }
.modal-status {
  margin-top: 14px;
  min-height: 18px;
  font-size: 13px;
  line-height: 1.4;
  font-weight: 500;
}
.modal-status.success { color: #1d7a3a; }
.modal-status.error   { color: var(--accent); }

/* Subtitle (under main titles on Art show, Esport, Hackathon, Party) */
.subtitle {
  font-size: clamp(16px, 2.4vh, 28px);
  font-weight: 400;
  color: var(--muted);
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.mt-xs { margin-top: clamp(4px, 0.8vh, 10px); }

/* Local video wrap (Esport) */
.video-wrap {
  position: relative;
  width: 100%;
  max-width: 720px;
  aspect-ratio: 16 / 9;
  max-height: 38vh;
  margin-top: clamp(10px, 2vh, 24px);
  background: var(--ink);
  overflow: hidden;
  cursor: zoom-in;
  transition: opacity 0.2s;
}
.video-wrap:hover { opacity: 0.92; }
.video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Venue images — clickable zoom */
.venue-grid > div.zoomable { cursor: zoom-in; transition: opacity 0.2s; }
.venue-grid > div.zoomable:hover { opacity: 0.85; }

/* Lightbox */
.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  cursor: zoom-out;
  padding: 40px;
}
.lightbox-overlay.active { display: flex; }
/* When the lightbox is open we lock html and body so wheel scroll, swipe
   gestures and any default browser arrow-key scrolling do not move the
   deck behind the overlay. The keyboard hijack in lightbox.js is the first
   line of defense, this is the second. */
html.lightbox-open,
html.lightbox-open body { overflow: hidden !important; overscroll-behavior: contain; }
.lightbox-overlay img,
.lightbox-overlay video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  box-shadow: 0 10px 40px rgba(0,0,0,0.5);
  display: none;
}
.lightbox-overlay iframe {
  width: min(92vw, calc(92vh * 16 / 9));
  height: min(92vh, calc(92vw * 9 / 16));
  border: 0;
  background: #000;
  display: none;
}
.lightbox-overlay.show-img    img    { display: block; }
.lightbox-overlay.show-video  video  { display: block; }
.lightbox-overlay.show-iframe iframe { display: block; }
/* Hide nav arrows when not in image-gallery mode */
.lightbox-overlay:not(.show-img) .lightbox-nav { display: none; }
.lightbox-close {
  position: absolute;
  top: 18px;
  right: 24px;
  background: none;
  border: 0;
  color: var(--bg);
  font-size: 30px;
  font-weight: 700;
  cursor: pointer;
  line-height: 1;
}
/* Lightbox nav — minimal chevrons, no background, no border */
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  color: var(--bg);
  width: 40px;
  height: 40px;
  font-size: 28px;
  font-weight: 300;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  opacity: 0.55;
  transition: opacity 0.15s, transform 0.15s;
}
.lightbox-nav:hover { opacity: 1; }
.lightbox-nav:active { transform: translateY(-50%) scale(0.92); }
.lightbox-prev { left: 28px; }
.lightbox-next { right: 28px; }
body.pdf-capture .lightbox-overlay,
body.pdf-capture .video-wrap video { display: none !important; }

/* Team names (Contact slide) */
.team-names { list-style: none; }
.team-names li {
  border-bottom: 1px solid var(--ink);
  padding: clamp(6px, 1.2vh, 14px) 0;
}
.team-names li:last-child { border-bottom: 0; }
.team-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  text-decoration: none;
  color: var(--ink);
  transition: color 0.2s;
}
.team-link:hover { color: var(--accent); }
.team-name {
  font-size: clamp(18px, 2.6vh, 28px);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.team-in,
.team-ig {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(22px, 3vh, 30px);
  height: clamp(22px, 3vh, 30px);
  color: #fff;
  font-size: clamp(10px, 1.3vh, 14px);
  font-weight: 800;
  font-family: Arial, Helvetica, sans-serif;
  font-style: italic;
  letter-spacing: -0.02em;
  border-radius: 3px;
  flex-shrink: 0;
}
.team-in { background: var(--ink); color: var(--bg); }
.team-ig { background: var(--ink); color: var(--bg); font-style: normal; }

/* Partnership brand grid — 2-cell variant */
.brand-grid.brand-grid-2 { grid-template-columns: 1fr 1fr; }
body.pdf-capture .cta-bar,
body.pdf-capture .modal-overlay { display: none !important; }

/* PDF capture mode — fixed slide dimensions */
body.pdf-capture {
  background: var(--bg);
}
body.pdf-capture .slide {
  width: 1920px !important;
  height: 1080px !important;
  min-height: 1080px !important;
  max-height: 1080px !important;
  padding: 70px 120px !important;
  page-break-after: always !important;
  break-after: page !important;
  page-break-inside: avoid !important;
  break-inside: avoid !important;
  overflow: hidden !important;
  border: 0 !important;
}
body.pdf-capture .nav-arrows,
body.pdf-capture .dl-link { display: none !important; }
/* Note: .pdf-loading is NOT hidden during capture — it stays visible
   so the user sees progress. html2canvas captures only .slide elements
   individually, so the fixed overlay doesn't leak into the PDF. */

/* Iframe placeholders for PDF */
.iframe-placeholder {
  width: 100%;
  height: 100%;
  background: var(--ink);
  color: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: center;
  padding: 20px;
}

/* Typography scales with viewport HEIGHT so slides fit vertically */
.display    { font-size: clamp(56px, 15vh, 200px); font-weight: 700; line-height: 0.9; letter-spacing: -0.045em; }
h1.display  { font-size: clamp(72px, 19vh, 260px); }  /* Cover slide title — bumped up so the Korean tagline can match its width without feeling cramped */
.title-1    { font-size: clamp(32px, 7vh, 86px); font-weight: 700; line-height: 1; letter-spacing: -0.035em; }
.title-1-xl { font-size: clamp(48px, 12vh, 140px); font-weight: 700; line-height: 0.95; letter-spacing: -0.04em; }
.title-3    { font-size: clamp(14px, 2.1vh, 24px); font-weight: 700; line-height: 1.2; text-transform: uppercase; }
.lead       { font-size: clamp(17px, 2.7vh, 30px); line-height: 1.35; max-width: 28ch; }
.body       { font-size: clamp(13px, 1.7vh, 18px); line-height: 1.5; max-width: 60ch; }
.label      { font-size: clamp(10px, 1.1vh, 11px); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
.red        { color: var(--accent); }
.subtle     { color: var(--muted); }

.middle { margin-top: auto; margin-bottom: auto; }
.mt-s  { margin-top: clamp(8px, 1.2vh, 12px); }
.mt-m  { margin-top: clamp(14px, 2.5vh, 24px); }
.mt-l  { margin-top: clamp(20px, 4vh, 48px); }
.mt-xl { margin-top: clamp(32px, 6.5vh, 80px); }
hr.rule { border: 0; border-top: 1px solid var(--ink); margin: 24px 0; }
.col-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 5vw; }

/* Editions (Track Record) */
.editions { border-top: 1px solid var(--ink); }

/* Artist external link icon (globe) — sits inline next to the name. */
.artist-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.05em;
  height: 1.05em;
  margin-left: 0.45em;
  vertical-align: -0.15em;
  color: var(--muted);
  transition: color 0.15s, transform 0.15s;
}
.artist-link:hover { color: var(--accent); transform: translateY(-1px); }
.artist-link svg { width: 100%; height: 100%; display: block; }

/* Track Record bottom media strip — 3 equal 16:9 cells, absolute so editions never move.
   Cell size adapts to available width × 9/16, capped so it never overflows the slide. */
.track-media {
  position: absolute;
  left: var(--pad-x);
  right: var(--pad-x);
  bottom: calc(4vh + clamp(28px, 4vh, 48px));
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: clamp(10px, 1.2vw, 18px);
  /* Cap height so the strip never collides with the editions list */
  max-height: 36vh;
}
.track-media-cell {
  position: relative;
  aspect-ratio: 16 / 9;
  max-height: 100%;
  background: transparent;
  overflow: hidden;
  cursor: zoom-in;
  transition: opacity 0.2s;
}
.track-media-cell:hover { opacity: 0.88; }
.track-media-cell img,
.track-media-cell video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* YouTube branding crop trick: scale the iframe up so the chrome (title,
   logo, controls) falls outside the visible cell. Pointer-events:none
   prevents hover/click reveal of controls. Aggressive 150% crop to make
   sure the bottom watermark + top title bar are fully outside. */
.track-media-cell.yt-cell { background: var(--ink); }
.track-media-cell.yt-cell iframe {
  position: absolute;
  top: -25%;
  left: -25%;
  width: 150%;
  height: 150%;
  border: 0;
  pointer-events: none;
}

/* Mobile: stack the strip vertically so each video has decent size */
@media (max-width: 768px) {
  .track-media {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    bottom: calc(4vh + 36px);
    max-height: 38vh;
  }
}

body.pdf-capture .track-media-cell video,
body.pdf-capture .track-media-cell.yt-cell iframe { display: none !important; }
.edition {
  padding: clamp(12px, 2.2vh, 22px) 0 clamp(10px, 1.8vh, 18px) 0;
  border-bottom: 1px solid var(--ink);
  display: grid;
  grid-template-columns: clamp(120px, 13vw, 170px) clamp(160px, 18vw, 240px) 1fr;
  gap: clamp(14px, 2.5vw, 32px);
  align-items: center;
}
.edition.highlight { padding: clamp(12px, 2.2vh, 22px) 0 clamp(10px, 1.8vh, 18px) 0; }
.edition-year {
  font-size: clamp(14px, 2vh, 20px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.edition.highlight .edition-year { font-size: clamp(14px, 2vh, 20px); color: var(--ink); }
.edition-title {
  font-size: clamp(14px, 2vh, 20px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.edition.highlight .edition-title { font-size: clamp(14px, 2vh, 20px); }
.edition-stats {
  font-size: clamp(11px, 1.55vh, 16px);
  color: var(--ink);
  font-weight: 400;
}
.edition.highlight .edition-stats {
  color: var(--ink);
  font-size: clamp(11px, 1.55vh, 16px);
}

/* Who — name list */
.who-list { list-style: none; border-top: 1px solid var(--ink); }
.who-list li {
  display: grid;
  grid-template-columns: clamp(44px, 5vh, 60px) minmax(160px, 1fr) 1.6fr;
  align-items: center;
  gap: 3vw;
  padding: clamp(6px, 1vh, 14px) 0 clamp(6px, 1vh, 12px) 0;
  border-bottom: 1px solid var(--ink);
}
.who-num { font-size: clamp(9px, 1.1vh, 11px); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.who-name {
  font-size: clamp(20px, 4.5vh, 48px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}
.who-desc {
  color: var(--accent);
  font-size: clamp(11px, 1.5vh, 16px);
  line-height: 1.4;
  font-weight: 500;
  max-width: 48ch;
}

/* "They are already with us" · committed-sponsor band on the Who slide.
   Logos are monochrome ink silhouettes (black on transparent). In dark
   mode they are inverted to off-white so they track the --ink token and
   sit consistently next to the .al-word text marks. */
.already { margin-top: auto; text-align: center; }
.already .label { font-size: clamp(14px, 2.1vh, 20px); }
.already-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  max-width: 1000px;
  margin: 0 auto;
  gap: clamp(18px, 3vh, 32px) clamp(28px, 3.4vw, 52px);
}
.al-logo {
  height: clamp(26px, 4.4vh, 46px);
  width: auto;
  object-fit: contain;
  display: block;
}
/* Cross The Ages is a tall, thin monogram — render it taller so it reads
   at the same visual weight as the wordmark logos. */
.al-logo.al-cta { height: clamp(40px, 6.6vh, 66px); }
.al-word {
  font-size: clamp(19px, 3.4vh, 34px);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
  white-space: nowrap;
}
html[data-theme="dark"] .al-logo { filter: invert(1) brightness(0.97); }

/* Facts */
.facts { list-style: none; }
.facts li {
  display: flex;
  justify-content: space-between;
  padding: clamp(8px, 1.6vh, 18px) 0;
  border-bottom: 1px solid var(--ink);
  font-size: clamp(13px, 1.8vh, 20px);
  gap: 4vw;
}
.facts li .k { color: var(--muted); text-transform: uppercase; letter-spacing: 0.18em; font-size: clamp(9px, 1.1vh, 11px); padding-top: 5px; min-width: 30%; }
.facts li .v { font-weight: 700; text-align: right; max-width: 65%; }

/* Venue mosaic */
.venue-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 1px;
  background: var(--ink);
  border: 1px solid var(--ink);
  height: 48vh;
  margin-top: 48px;
}
.venue-grid > div {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* Inline <img> children — used by the mobile layout below to display each
   venue photo at its native aspect ratio. Hidden on desktop because the
   desktop grid relies on the background-image-cover crop to fill cells. */
.venue-grid > div .vg-img { display: none; }
.venue-hero { grid-row: span 2; background-color: var(--bg); }
.venue-plan { background-color: var(--bg); background-size: contain !important; }

.venue-facts {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--ink);
  border: 1px solid var(--ink);
  margin-top: 48px;
}
.venue-fact {
  background: var(--bg);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.vf-k { font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
.vf-v { font-size: clamp(14px, 1.2vw, 18px); font-weight: 700; letter-spacing: -0.01em; }

/* Art / N2EXISTENCE layout */
.art-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5vw;
  align-items: start;
  margin-top: clamp(16px, 3vh, 40px);
}
.luma-wrap {
  width: 100%;
  aspect-ratio: 4 / 5;
  max-height: 52vh;
  background: var(--ink);
}
.luma-wrap iframe { width: 100%; height: 100%; border: 0; display: block; }

/* YouTube */
.yt-wrap {
  position: relative;
  width: 100%;
  max-width: 720px;
  aspect-ratio: 16 / 9;
  max-height: 38vh;
  margin-top: clamp(10px, 2vh, 24px);
  background: var(--ink);
  overflow: hidden;
  cursor: zoom-in;
  transition: opacity 0.2s;
}
.yt-wrap:hover { opacity: 0.92; }
/* Crop YouTube branding (title bar + watermark + bottom progress) by
   scaling the iframe up. Pointer-events:none on iframe so clicks bubble
   to the .yt-wrap parent which opens the lightbox. */
.yt-wrap iframe {
  position: absolute;
  top: -22%;
  left: -22%;
  width: 144%;
  height: 144%;
  border: 0;
  pointer-events: none;
}

/* Party slide override — source video is portrait, so we render it
   letterboxed inside the 16:9 wrap (black bars on the sides) instead
   of being cropped by the default 144% YT-branding-crop trick. */
#party-slide .yt-wrap { background: #000; }
#party-slide .yt-wrap iframe {
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* Timetable */
.tt-wrap { margin: auto 0; width: 100%; }
.tt {
  display: grid;
  grid-template-columns: 124px repeat(5, 1fr);
  background: var(--ink);
  gap: 1px;
  border: 1px solid var(--ink);
}
.tt > div {
  background: var(--bg);
  padding: clamp(6px, 1vh, 12px) clamp(6px, 0.9vw, 12px);
  min-height: clamp(42px, 6.5vh, 64px);
  display: flex;
  flex-direction: column;
}
.tt .corner { min-height: clamp(40px, 6vh, 56px); }
.tt .day { min-height: clamp(40px, 6vh, 56px); padding: clamp(8px, 1.4vh, 14px); }
.tt .day-name { font-size: clamp(9px, 1.1vh, 11px); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
.tt .day-num { font-size: clamp(14px, 2.2vh, 24px); font-weight: 700; margin-top: 2px; }
.tt .time-hour { font-size: clamp(13px, 1.5vh, 17px); font-weight: 700; letter-spacing: -0.02em; white-space: nowrap; }
.tt .time-label { font-size: clamp(9px, 1vh, 10px); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); margin-top: 4px; }
.tt .cell { font-size: clamp(11px, 1.55vh, 16px); font-weight: 700; line-height: 1.35; }
.tt .cell-sub { font-size: clamp(9px, 1.2vh, 12px); font-weight: 500; color: var(--accent); margin-top: 3px; letter-spacing: 0.04em; }
.tt .cell-empty { position: relative; }
.tt .cell-empty::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 10px; height: 1px;
  background: var(--muted);
  transform: translate(-50%, -50%);
}
.tt .cell-accent { background: var(--accent); color: var(--bg); }
.tt .cell-accent .cell-sub { color: rgba(244, 241, 234, 0.7); }

/* Legacy — 3 column grid */
.legacy-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--ink);
  border: 1px solid var(--ink);
  margin-top: 32px;
}
.legacy-cell {
  background: var(--bg);
  padding: clamp(14px, 2.2vh, 24px) clamp(14px, 1.8vw, 22px);
  min-height: auto;
  display: flex;
  flex-direction: column;
}
.legacy-tag {
  font-size: clamp(9px, 1.1vh, 11px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}
.legacy-title {
  font-size: clamp(17px, 2.6vh, 30px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-top: clamp(8px, 1.4vh, 14px);
}
.legacy-body {
  font-size: clamp(12px, 1.5vh, 16px);
  line-height: 1.5;
  margin-top: clamp(10px, 1.8vh, 18px);
}

/* Partnership — 3 column brand grid */
.brand-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--ink);
  border: 1px solid var(--ink);
  margin-top: 32px;
}
.brand-cell {
  background: var(--bg);
  padding: clamp(14px, 2.2vh, 24px) clamp(14px, 1.8vw, 22px);
  min-height: auto;
  display: flex;
  flex-direction: column;
}
.brand-tag {
  font-size: clamp(9px, 1.1vh, 11px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 700;
}
.brand-title {
  font-size: clamp(15px, 2.2vh, 24px);
  font-weight: 700;
  line-height: 1.15;
  margin-top: 8px;
  padding-bottom: clamp(8px, 1.4vh, 14px);
  border-bottom: 1px solid var(--ink);
}
.brand-list { list-style: none; margin-top: clamp(10px, 1.8vh, 16px); }
.brand-list li {
  font-size: clamp(11px, 1.4vh, 15px);
  line-height: 1.45;
  padding: clamp(3px, 0.6vh, 6px) 0;
  padding-left: 18px;
  position: relative;
}
.brand-list li::before {
  content: "→";
  position: absolute;
  left: 0;
  color: var(--muted);
}

/* Logo grid */
.logo-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 1px;
  background: var(--ink);
  border: 1px solid var(--ink);
  margin: auto 0;
}
.logo-cell {
  background: var(--bg);
  height: clamp(80px, 12vh, 120px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(13px, 1.8vh, 20px);
  font-weight: 700;
  text-align: center;
  padding: 14px;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.logo-cell.red { color: var(--accent); }

/* Team roster */
.team-layout {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  gap: 5vw;
  align-items: stretch;
  margin-top: 48px;
  min-height: 55vh;
}
.team-photo-main {
  width: 100%;
  min-height: 55vh;
  background-image: url('images/team-portrait.png');
  background-size: cover;
  background-position: center top;
  background-color: var(--ink);
}
.roster { list-style: none; }
.roster li {
  display: grid;
  grid-template-columns: clamp(32px, 4.5vh, 44px) 1fr;
  align-items: center;
  gap: 14px;
  padding: clamp(3px, 0.6vh, 6px) 0;
  border-bottom: 1px solid var(--ink);
}
.roster li:last-child { border-bottom: 0; }
.roster .thumb {
  width: clamp(32px, 4.5vh, 44px);
  height: clamp(32px, 4.5vh, 44px);
  background-image: url('images/team-portrait.png');
  background-size: cover;
  background-position: center 20%;
  background-color: var(--ink);
  filter: grayscale(100%) contrast(1.05);
}
.roster .info { display: flex; flex-direction: column; gap: 2px; }
.roster .role { font-size: clamp(8px, 1vh, 10px); letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted); }
.roster .name { font-size: clamp(12px, 1.5vh, 17px); font-weight: 700; line-height: 1.2; }


/* ═══════════════════════════════════════════════════
   RESPONSIVE — 4 tiers: large / laptop / tablet / mobile
   ═══════════════════════════════════════════════════ */

/* LAPTOP & small desktop (≤ 1400px) */
@media (max-width: 1400px) {
  :root { --pad-x: 6vw; --pad-y: 6vh; }
  .art-layout { gap: 4vw; }
  .luma-wrap { aspect-ratio: 5 / 6; max-height: 46vh; }
  .yt-wrap { max-height: 32vh; }
  .venue-grid { height: 42vh; }
}

/* TABLET & small laptop (≤ 1100px) */
@media (max-width: 1100px) {
  :root { --pad-x: 5vw; --pad-y: 5vh; }
  /* Below 1100px the venue/timetable grids grow past 100vh. Disable snap and
     let each slide flow + scroll instead of clipping content under the
     absolutely-positioned foot-bar. */
  html { scroll-snap-type: none; }
  .slide {
    height: auto;
    min-height: 100vh;
    overflow: visible;
    scroll-snap-align: none;
    padding-top: 90px;
    padding-bottom: 90px;
  }
  .meta-bar { top: 24px; }
  .foot-bar { bottom: 24px; }

  .col-2 { grid-template-columns: 1fr; gap: 40px; }
  .art-layout { grid-template-columns: 1fr; gap: 48px; }
  .team-layout { grid-template-columns: 1fr; gap: 40px; min-height: auto; }
  .team-photo-main { min-height: 50vh; max-height: 70vh; }

  .luma-wrap { max-width: 420px; margin: 0 auto; aspect-ratio: 281 / 500; max-height: 65vh; }

  .venue-grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 30vh 30vh 30vh;
    height: auto;
  }
  .venue-hero { grid-row: 1 / 2; grid-column: 1 / 3; }
  .venue-facts { grid-template-columns: repeat(2, 1fr); }

  .logo-grid { grid-template-columns: repeat(4, 1fr); }
  .logo-cell { height: 90px; }

  .legacy-grid, .brand-grid { grid-template-columns: 1fr; }
  .brand-cell { min-height: auto; }
  .legacy-cell { min-height: auto; }

  .edition { grid-template-columns: 140px 1fr; gap: 3vw; }

  .tt { grid-template-columns: 68px repeat(5, 1fr); font-size: 11px; }
  .tt > div { padding: 7px 6px; min-height: 52px; }
  .tt .time-hour, .tt .day-num { font-size: 15px; }
  .tt .cell { font-size: 11px; }
  .tt .cell-sub { font-size: 9.5px; }

  .stats-grid { grid-template-columns: repeat(3, 1fr); }
  .dl-link { margin-right: 10px; }

  .who-list li {
    grid-template-columns: 60px minmax(160px, 1fr) 1.4fr;
    gap: 24px;
  }
  .who-desc { font-size: 14px; }
}

/* MOBILE / PORTRAIT TABLET (≤ 768px) */
@media (max-width: 768px) {
  :root { --pad-x: 5vw; --pad-y: 4vh; }

  /* Disable snap-scroll on phones — let content flow naturally */
  html { scroll-snap-type: none; scroll-behavior: smooth; }
  .slide {
    height: auto;
    min-height: 100vh;
    overflow: visible;
    padding-top: 80px;
    padding-bottom: 80px;
    scroll-snap-align: none;
  }

  .display { font-size: clamp(44px, 12vw, 80px); line-height: 1; word-break: break-word; }
  .title-1 { font-size: clamp(30px, 7.5vw, 48px); line-height: 1.05; }
  .title-1-xl { font-size: clamp(40px, 11vw, 72px); line-height: 1.05; }
  .lead { font-size: clamp(17px, 3.5vw, 22px); }
  .body { font-size: clamp(14px, 3vw, 16px); }

  .meta-bar, .foot-bar { font-size: 9px; letter-spacing: 0.14em; }
  .meta-bar { top: 18px; }
  .foot-bar { bottom: 18px; }

  .logo-grid { grid-template-columns: repeat(3, 1fr); }
  .logo-cell { height: 76px; font-size: 10px; padding: 10px; }

  .edition { grid-template-columns: 1fr; gap: 4px; padding: 14px 0 12px; }
  .edition-year { font-size: clamp(16px, 4vw, 20px); }
  .edition.highlight .edition-year { font-size: clamp(16px, 4vw, 20px); }
  .edition-content .edition-title { font-size: 14px; }
  .edition.highlight .edition-title { font-size: 14px; }
  .edition-content .edition-stats, .edition.highlight .edition-stats { font-size: 12px; }

  .facts li { flex-direction: column; align-items: flex-start; gap: 6px; padding: 14px 0; }
  .facts li .k { min-width: 0; padding-top: 0; }
  .facts li .v { text-align: left; max-width: 100%; font-size: 15px; }

  .who-list li {
    grid-template-columns: 30px 1fr;
    grid-template-areas: "num name" "num desc";
    gap: 4px 14px;
    padding: 14px 0 12px;
  }
  .who-num { grid-area: num; font-size: 9px; padding-top: 6px; }
  .who-name { grid-area: name; font-size: clamp(22px, 6.5vw, 36px); }
  .who-desc { grid-area: desc; font-size: 13px; max-width: 100%; }

  .team-layout { gap: 32px; }
  .team-photo-main { min-height: 40vh; max-height: 60vh; }
  .roster li { grid-template-columns: 40px 1fr; gap: 14px; padding: 8px 0; }
  .roster .thumb { width: 40px; height: 40px; }
  .roster .name { font-size: 14px; }

  .venue-grid {
    grid-template-columns: 1fr;
    grid-template-rows: repeat(5, 22vh);
  }
  .venue-hero, .venue-plan,
  .venue-grid > div { grid-column: 1 / 2 !important; }
  .venue-hero { grid-row: 1 / 2 !important; }
  .venue-facts { grid-template-columns: 1fr 1fr; }
  .venue-fact { padding: 12px 14px; }

  .tt {
    grid-template-columns: 52px repeat(5, 1fr);
    font-size: 9px;
  }
  .tt > div { padding: 8px 5px; min-height: 54px; }
  .tt .time-hour { font-size: 14px; }
  .tt .day-num { font-size: 13px; }
  .tt .day-name, .tt .time-label { font-size: 8px; letter-spacing: 0.14em; }
  .tt .cell { font-size: 10px; }
  .tt .cell-sub { font-size: 8px; }

  .stats-grid { grid-template-columns: repeat(2, 1fr); }

  .nav-arrows { right: 16px; bottom: 16px; gap: 8px; }
  .nav-arrow { width: 24px; height: 24px; font-size: 16px; }

  .luma-wrap { max-width: 100%; aspect-ratio: 3 / 4; max-height: 50vh; }
  .yt-wrap { max-height: none; aspect-ratio: 16 / 9; }
}

/* VERY SMALL (≤ 440px) */
@media (max-width: 440px) {
  :root { --pad-x: 6vw; }
  .meta-bar, .foot-bar { font-size: 8px; letter-spacing: 0.12em; }
  .dl-link { margin-right: 8px; }
  .logo-grid { grid-template-columns: repeat(2, 1fr); }
  .logo-cell { height: 64px; }
}

/* ──────────────────────────────────────────────────────────────────────
   MOBILE-ONLY POLISH (≤ 768px) — comprehensive cleanup, no impact on desktop.
   Cover intro is skipped on mobile via JS, so the cover renders flat.
   ────────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
  /* Cover h1 — override the desktop h1.display clamp (which used 17vh). */
  h1.display {
    font-size: clamp(40px, 11vw, 64px);
    line-height: 1;
    letter-spacing: -0.04em;
  }
  .cover-top { display: block; max-width: 100%; }
  .cover-top .cover-word { display: inline-flex; flex-wrap: wrap; }
  .cover-top .cover-gap { width: 0.18em; }

  /* "Already with us" band — single horizontal-scroll row on mobile so all
     marks stay reachable without overflowing the fixed-height Who slide. */
  .already { margin-top: clamp(16px, 3vh, 26px); }
  .already-row {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 24px;
    padding-bottom: 4px;
  }
  .already-row::-webkit-scrollbar { display: none; }
  .al-logo { height: 22px; }
  .al-logo.al-cta { height: 34px; }
  .al-word { font-size: 16px; }

  /* Track Record media strip — switch from absolute to in-flow on mobile so
     it never overlaps the editions list. Single column stack, centred
     within the slide's natural padding. Each cell is locked to a 16:9
     (1920x1080) frame on mobile per sponsor request — images cover-fit. */
  .track-media {
    position: static;
    margin: clamp(20px, 4vh, 32px) auto 0;
    width: 100%;
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    max-height: none;
    height: auto;
    gap: 10px;
    justify-items: center;
  }
  .track-media-cell {
    aspect-ratio: 16 / 9;
    width: 100%;
    max-width: 100%;
    height: auto;
  }
  .track-media-cell img,
  .track-media-cell video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  /* Venue gallery — show each photo via the inline <img> child so the
     native aspect ratio is preserved (no crop). The background-image
     used by desktop is hidden. */
  .venue-grid {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    gap: 10px !important;
    justify-items: center;
    grid-template-rows: auto !important;
    grid-template-columns: 1fr !important;
    height: auto !important;
  }
  .venue-grid > div {
    aspect-ratio: auto !important;
    width: 100% !important;
    height: auto !important;
    background: none !important;
    grid-row: auto !important;
  }
  .venue-grid > div .vg-img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: contain;
  }

  /* Timetable — allow horizontal scroll on small screens instead of squeezing. */
  .tt-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: auto -5vw;
    padding: 0 5vw;
  }
  .tt {
    min-width: 640px;
    grid-template-columns: 60px repeat(5, minmax(110px, 1fr));
    font-size: 10px;
  }
  .tt > div { padding: 8px 6px; min-height: 56px; }
  .tt .cell { font-size: 11px; }
  .tt .cell-sub { font-size: 9px; }

  /* Slide 03 editions — already 1-col on mobile, just ensure no stray gaps. */
  .editions { margin-top: clamp(16px, 3vh, 24px); }

  /* Logos (Trusted by) — slightly smaller, prevent overflow. */
  .logo-cell { font-size: clamp(11px, 3.5vw, 14px); padding: 8px; }

  /* Brand grid (Partnership) — force 1 column even for the .brand-grid-2 variant.
     The base 1100px rule didn't win over .brand-grid.brand-grid-2 specificity. */
  .brand-grid, .brand-grid.brand-grid-2 { grid-template-columns: 1fr; gap: 18px; }
  .brand-cell { padding: 22px 18px; }
  .brand-tag { font-size: 9px; }
  .brand-title { font-size: clamp(18px, 5vw, 24px); }
  .brand-list li { font-size: 14px; line-height: 1.5; }

  /* Team roster — bigger tap targets for the LinkedIn/IG links. */
  .team-link { padding: 12px 0; }
  .team-name { font-size: clamp(20px, 5.2vw, 28px); }
  .team-in, .team-ig { width: 26px; height: 26px; font-size: 11px; }

  /* Contact form on mobile — full padding, no horizontal squeeze. */
  .modal-overlay { padding: 12px; }
  .modal-box { padding: 22px 18px; max-height: 90vh; }

  /* CTA bar (Sponsoring opportunity) — stack on phone. */
  .cta-bar { flex-direction: column; align-items: stretch; gap: 14px; }
  .cta-btn { width: 100%; padding: 14px; }
  .cta-text { font-size: clamp(13px, 3.6vw, 18px); }

  /* Slide vertical rhythm — slightly tighter for phones. */
  .mt-l  { margin-top: clamp(18px, 3vh, 28px); }
  .mt-xl { margin-top: clamp(28px, 5vh, 56px); }
}

/* ─── Comprehensive responsive polish ─── */

/* Touch / coarse-pointer devices: bump nav arrows + lightbox arrows up to
   minimum-44px tap targets (Apple HIG / Material guideline). Keep desktop
   minimal arrows untouched. */
@media (pointer: coarse), (max-width: 768px) {
  .nav-arrow { width: 44px; height: 44px; font-size: 18px; opacity: 0.7; }
  .lightbox-nav { width: 56px; height: 56px; font-size: 32px; opacity: 0.7; }
  .lightbox-prev { left: 8px; }
  .lightbox-next { right: 8px; }
}

/* iPad portrait & similar (640–900px wide): keep desktop layout but with
   tighter padding. Avoids the phone treatment on tablets which have plenty
   of room for the regular 2-column grids. */
@media (min-width: 640px) and (max-width: 900px) {
  :root { --pad-x: 5vw; --pad-y: 5vh; }
  /* Cover h1 a touch smaller for portrait tablet */
  h1.display { font-size: clamp(56px, 13vh, 180px); }
  /* Editions strip — keep 3-column flow on tablets, just tighter */
  .edition { grid-template-columns: clamp(110px, 15vw, 160px) clamp(140px, 22vw, 220px) 1fr; gap: 2vw; }
}

/* Modal & PDF loading overlay on small screens */
@media (max-width: 640px) {
  .modal-box { padding: 22px 18px; max-height: 88vh; }
  .modal-title { font-size: clamp(20px, 5.5vw, 26px); }
  .modal-field input, .modal-field textarea { font-size: 16px; /* iOS doesn't auto-zoom on focus when ≥16px */ }
  .pdf-loading-title { font-size: clamp(22px, 6vw, 32px); }
  .pdf-loading-step { font-size: clamp(11px, 3vw, 14px); }
  /* Track Record strip stacks vertically on phones (already declared at
     768px) — make sure each cell stays a reasonable height. */
  .track-media { gap: 8px; max-height: 52vh; }
}

/* Phone landscape (low height): cover h1 must shrink to fit */
@media (max-height: 480px) and (orientation: landscape) {
  h1.display { font-size: clamp(40px, 22vh, 120px); line-height: 0.85; }
  .title-1 { font-size: clamp(24px, 10vh, 56px); }
  .slide { padding-top: 56px; padding-bottom: 56px; }
}

