/* Glossy Finish — shared styles */
@font-face {
  font-family: 'Swiss 721 Cn';
  src: url('/assets/fonts/swiss721-condensed-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Swiss 721 Ex';
  src: url('/assets/fonts/swiss721-black-extended.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Swiss 721';
  src: url('/assets/fonts/swiss721-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Swiss 721';
  src: url('/assets/fonts/swiss721-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
/* Eight display rules ask for 900 and four for 800. With only Bold loaded the
   browser was synthesising those, which smears the letterforms. 800 resolves
   up to this face under the CSS font-matching rules. */
@font-face {
  font-family: 'Swiss 721';
  src: url('/assets/fonts/swiss721-900.woff2') format('woff2');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
:root {
  --red: #E21A23;
  --red-dark: #B8121A;
  --blue: #005187;
  /* Navy ground. Brand blue #005187 is a fill colour, not a text colour: on
     this background it measures 2.07:1, which is unreadable. --sky is a
     lightened tint of the same hue (204deg) for small text, at 5.9:1. */
  --ink: #0B1B33;
  --ink-2: #0E2340;
  --panel: #122B4D;
  --panel-2: #17345C;
  --line: #1E3A63;
  --text: #F4F6F8;
  --muted: #C9D3DC;
  --dim: #9FB0BF;
  --sky: #4A9FD8;
  --disp: 'Swiss 721', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* Section headings. Black Extended is a good deal wider than --disp, so
     anything set in it needs its own size scale. */
  --disp-ex: 'Swiss 721 Ex', 'Swiss 721', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* Swiss 721 Roman for body copy. The face has no prime (inch) mark or down
     arrow, so those fall back -- Helvetica is first in line because Swiss 721
     is a Helvetica clone and the substitution is near-invisible. */
  --body: 'Swiss 721', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* Labels, kickers and captions. Condensed Bold rather than a monospace, so
     the whole site sits in one family: Extended for section headings, Roman
     for body, Condensed for the small uppercase labels. */
  --label: 'Swiss 721 Cn', 'Swiss 721', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --pad: 16px;
  --topbar: 66px;
  /* Content stops widening past --maxw and centres instead. --gutter is built
     from 100vw rather than 100%: the colour bands (stats, moment, closers)
     have half-width children, where a percentage would resolve against the
     child and compute the wrong inset. */
  --maxw: 1440px;
  --gutter: max(var(--pad), (100vw - var(--maxw)) / 2);
}
@media (min-width: 900px) { :root { --pad: 56px; } }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--topbar) + 8px); -webkit-text-size-adjust: 100%; }
body { margin: 0; background: var(--ink); color: var(--text); font-family: var(--body); line-height: 1.5; }
img, video { display: block; max-width: 100%; }
/* No long-press "Save image" on iOS and no drag-out on desktop Safari/Chrome.
   site.js handles right-click. */
img, video { -webkit-touch-callout: none; -webkit-user-drag: none; user-select: none; }
a { color: var(--sky); }
a:hover { color: #B5D8F1; }
:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 3px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Hidden until a keyboard user tabs to it, then it sits over the header. */
.skip-link { position: absolute; top: 8px; left: 8px; z-index: 100; padding: 10px 16px; border-radius: 6px; background: #FFFFFF; color: var(--ink); font-weight: 700; text-decoration: none; transform: translateY(-200%); }
.skip-link:focus { transform: none; }
.wrap { padding-left: var(--gutter); padding-right: var(--gutter); }

/* Type helpers */
.disp { font-family: var(--disp); text-transform: uppercase; letter-spacing: 0.01em; }
.mono { font-family: var(--label); letter-spacing: 0.06em; text-transform: uppercase; }
.h1 { font-family: var(--disp); text-transform: uppercase; font-weight: 700; line-height: 0.94; letter-spacing: -0.02em; margin: 0; font-size: clamp(38px, 5.4vw, 80px); }
.h2 { font-family: var(--disp-ex); text-transform: uppercase; font-weight: 900; line-height: 1.02; letter-spacing: -0.01em; margin: 0; font-size: clamp(22px, 2.7vw, 40px); }
.accent { color: var(--red); }
.accent-sky { color: var(--sky); }
.lead { font-size: 16px; color: var(--muted); margin: 0; max-width: 560px; }
@media (min-width: 900px) { .lead { font-size: 18px; } }
.kick { font-family: var(--disp); font-weight: 900; text-transform: uppercase; letter-spacing: 0.12em; display: inline-flex; align-self: flex-start; padding: 4px 12px; font-size: 14px; color: #FFFFFF; background: var(--red); transform: skewX(-12deg); }
.kick.blue { background: var(--blue); }
@media (min-width: 900px) { .kick { font-size: 16px; padding: 5px 14px; } }

/* Buttons */
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 54px; padding: 0 clamp(14px, 1.6vw, 26px); border-radius: 8px; font-weight: 700; font-size: clamp(13px, 1.15vw, 16px); text-transform: uppercase; letter-spacing: 0.03em; max-width: 100%; text-decoration: none; border: 0; cursor: pointer; font-family: var(--body); }
.btn-red { background: var(--red); color: #FFFFFF; }
.btn-red:hover { background: var(--red-dark); color: #FFFFFF; }
.btn-ghost { border: 1px solid rgba(255,255,255,0.5); color: #FFFFFF; background: rgba(11,27,51,0.4); font-weight: 600; }
.btn-ghost:hover { border-color: #FFFFFF; color: #FFFFFF; }
.btn-white { background: #FFFFFF; color: var(--ink); }
.btn-white:hover { color: var(--ink); background: #E3EDF5; }
.btn-dark { background: var(--ink); color: #FFFFFF; }
.btn-dark:hover { color: #FFFFFF; background: #000000; }
.btn-row { display: flex; gap: 10px; flex-wrap: wrap; }
.btn-row .btn { flex: 1 1 auto; }
@media (min-width: 900px) { .btn-row .btn { flex: 0 0 auto; } }

/* Top bar */
.topbar { position: sticky; top: 0; z-index: 50; }
.header { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 10px var(--gutter); background: var(--ink); border-bottom: 1px solid #16305A; }
.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; color: var(--text); text-decoration: none; }
.brand img { width: 36px; height: 36px; }
.brand span { font-family: var(--disp); text-transform: uppercase; font-weight: 900; font-size: 19px; letter-spacing: 0.04em; white-space: nowrap; }
.nav { display: none; }
.nav a { color: var(--muted); text-decoration: none; font-weight: 600; font-size: clamp(13px, 1.12vw, 15px); white-space: nowrap; }
.nav a:hover { color: #FFFFFF; }
.header-actions { display: flex; align-items: center; gap: 8px; }
.header-actions .btn { min-height: 44px; padding: 0 14px; font-size: 14px; border-radius: 6px; }
.menu-btn { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: transparent; border: 1px solid var(--line); border-radius: 6px; color: var(--text); cursor: pointer; }
/* Below ~380px the brand, the Register button and the menu button together
   overflow the bar and the button paints over the wordmark. Everything steps
   down rather than the name getting clipped. */
@media (max-width: 400px) {
  .header { gap: 6px; padding-left: 10px; padding-right: 10px; }
  .brand { gap: 7px; }
  .brand img { width: 30px; height: 30px; }
  .brand span { font-size: 16px; letter-spacing: 0.02em; }
  .header-actions { gap: 5px; }
  .header-actions .btn { padding: 0 9px; font-size: 12px; letter-spacing: 0.01em; }
  .menu-btn { width: 40px; height: 40px; }
}
/* Even stepped down, the bar needs 318px, and anything wider than the screen
   widens the whole page, which then scrolls sideways and clips the sticky CTA.
   Under 320px the wordmark shrinks with the screen, reaching 12px at 280px
   (a folded Galaxy Z Fold). */
@media (max-width: 319px) {
  .brand span { font-size: calc(16px - (320px - 100vw) * 0.1); }
  .header-actions .btn { padding: 0 7px; }
}
/* The six nav items need roughly 700px on one line. Below this the header
   keeps the menu button instead of wrapping them into three stacked lines. */
@media (min-width: 1120px) {
  .nav { display: flex; align-items: center; gap: clamp(12px, 1.5vw, 28px); min-width: 0; }
  .menu-btn, .mobile-nav, .mobile-nav.open { display: none; }
}
.mobile-nav { display: none; flex-direction: column; background: var(--ink); border-bottom: 1px solid var(--line); padding: 8px var(--pad) 16px; }
.mobile-nav.open { display: flex; }
.mobile-nav a { color: var(--text); text-decoration: none; font-weight: 600; font-size: 17px; padding: 12px 0; border-bottom: 1px solid var(--line); }

/* Partners dropdown (desktop nav) */
.nav-drop { position: relative; display: flex; }
.nav-drop-btn { display: inline-flex; align-items: center; gap: 6px; padding: 0; background: transparent; border: 0; cursor: pointer; color: var(--muted); font-family: var(--body); font-weight: 600; font-size: clamp(13px, 1.12vw, 15px); line-height: 1.5; white-space: nowrap; }
.nav-drop-btn:hover, .nav-drop-btn[aria-expanded="true"] { color: #FFFFFF; }
.nav-drop-btn svg { transition: transform .2s ease; }
.nav-drop-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.nav-drop-menu { position: absolute; top: calc(100% + 14px); left: 50%; transform: translateX(-50%); z-index: 60; display: flex; flex-direction: column; min-width: 284px; padding: 8px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 24px 48px rgba(0,0,0,0.55); }
.nav-drop-menu[hidden] { display: none; }
.nav-drop-menu a { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 8px; font-size: 15px; }
.nav-drop-menu a:hover { background: var(--panel-2); color: #FFFFFF; }
.nav-drop-menu a[aria-current="page"] { background: var(--panel-2); color: #FFFFFF; }
.nav-drop-menu img { width: 28px; height: 28px; object-fit: contain; flex-shrink: 0; }

/* Partners group (mobile menu) */
.mobile-nav-label { padding: 16px 0 6px; font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; color: var(--dim); }
.mobile-nav a.mobile-nav-partner { display: flex; align-items: center; gap: 12px; font-size: 16px; color: var(--muted); }
.mobile-nav a.mobile-nav-partner img { width: 24px; height: 24px; object-fit: contain; flex-shrink: 0; }
.mobile-nav a[aria-current="page"] { color: #FFFFFF; }
@media (min-width: 900px) {
  .header { padding-top: 12px; padding-bottom: 12px; }
  .brand img { width: 44px; height: 44px; }
  .brand span { font-size: 26px; }
  .header-actions .btn { min-height: 46px; padding: 0 22px; font-size: 15px; }
}

/* Pulsing status dot (registration embed bar) */
.dot { width: 7px; height: 7px; border-radius: 50%; background: #FFFFFF; animation: pulse 1.4s ease-in-out infinite; }

/* Marquees */
.marquee { overflow: hidden; }
.marquee-track { display: flex; width: max-content; animation: slide var(--speed, 40s) linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
@keyframes kb { from { transform: scale(1.02); } to { transform: scale(1.14); } }

/* Sections */
.section { padding-top: 44px; padding-bottom: 44px; display: flex; flex-direction: column; gap: 16px; }
.section.alt { background: var(--ink-2); }
@media (min-width: 900px) { .section { padding-top: 88px; padding-bottom: 88px; gap: 28px; } }
.section-head { display: flex; flex-direction: column; gap: 12px; }
@media (min-width: 900px) { .section-head.split { flex-direction: row; justify-content: space-between; align-items: flex-end; gap: 48px; } .section-head.split > p { text-align: right; max-width: 440px; } }
.section-head > div { display: flex; flex-direction: column; gap: 12px; }

/* Hero (home) */
/* Home hero headline in Black Extended, matching the section headings. The
   extended face is far wider, so this needs its own scale -- and the copy
   column has to widen with it or "CAPTURING" will not fit on one line. */
.hero-copy .h1 { font-family: var(--disp-ex); font-weight: 900; line-height: 1; letter-spacing: -0.012em; font-size: clamp(30px, 4.4vw, 64px); }
.hero { position: relative; }
.hero-media { position: relative; height: 560px; overflow: hidden; background: var(--ink-2); }
.hero-media video, .hero-media img.cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(11,27,51,0.96) 8%, rgba(11,27,51,0.35) 50%, rgba(11,27,51,0.55) 100%); }
.chips { position: absolute; z-index: 2; top: 14px; left: var(--gutter); display: flex; box-shadow: 0 6px 20px rgba(0,0,0,0.5); }
.chip-red { display: flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--red); color: #FFFFFF; font-family: var(--disp); font-weight: 900; text-transform: uppercase; letter-spacing: 0.08em; font-size: 13px; }
.chip-white { display: flex; align-items: center; padding: 4px 10px; background: #FFFFFF; color: var(--blue); font-family: var(--label); font-weight: 700; font-size: 11px; letter-spacing: 0.06em; }
.banners { display: flex; flex-direction: column; align-items: flex-start; }
.banners span { font-family: var(--disp); text-transform: uppercase; transform: skewX(-12deg); color: #FFFFFF; }
.banners span:first-child { padding: 4px 12px; background: var(--red); font-weight: 900; letter-spacing: 0.12em; font-size: 13px; }
.banners span:last-child { padding: 6px 12px; background: var(--blue); font-weight: 800; letter-spacing: 0.04em; font-size: 15px; }
.hero-media .banners { position: absolute; z-index: 2; left: var(--gutter); bottom: 18px; }
.hero-copy { padding: 26px var(--gutter) 28px; display: flex; flex-direction: column; gap: 14px; }
.hero-copy .banners { display: none; }
@media (min-width: 900px) {
  .hero-media { height: 700px; }
  .hero-media::after { background: linear-gradient(to right, rgba(11,27,51,0.94) 0%, rgba(11,27,51,0.78) 38%, rgba(11,27,51,0.25) 75%, rgba(11,27,51,0.1) 100%); }
  .hero-media .banners { display: none; }
  .chips { top: 28px; }
  .chip-red { font-size: 15px; padding: 6px 12px; }
  .chip-white { font-size: 12px; padding: 6px 12px; }
  .hero-copy { position: absolute; z-index: 3; left: var(--gutter); top: 110px; bottom: 56px; width: min(640px, 55vw); padding: 0; justify-content: center; gap: 22px; }
  .hero-copy .banners { display: flex; }
  .banners span:first-child { font-size: 15px; padding: 5px 14px; }
  .banners span:last-child { font-size: 17px; padding: 7px 14px; }
  .hero-copy .h1 { text-shadow: 0 6px 30px rgba(0,0,0,0.6); }
  .hero-copy .lead { color: #D6DEE5; text-shadow: 0 2px 12px rgba(0,0,0,0.6); }
}

/* Partners */
.partners { padding-top: 8px; padding-bottom: 32px; display: flex; flex-direction: column; gap: 14px; border-bottom: 1px solid #16305A; }
.partners-head { display: flex; flex-direction: column; gap: 6px; }
.partners-head p { margin: 0; font-size: 14px; color: var(--dim); }
.logo-tile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; width: 132px; height: 128px; margin-right: 10px; padding: 10px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; color: var(--text); text-decoration: none; text-align: center; font-size: 12px; font-weight: 700; line-height: 1.2; transition: border-color .2s ease, transform .2s ease; }
.logo-row { display: flex; flex-wrap: wrap; gap: 12px; }
.logo-tile:hover { border-color: var(--red); transform: translateY(-3px); color: #FFFFFF; }
.partners .marquee { padding-block: 6px; }
.logo-tile img { width: 64px; height: 64px; border-radius: 12px; }
.partners-note { margin: 0; font-size: 14px; color: var(--muted); }
@media (min-width: 900px) {
  .partners { padding-top: 36px; padding-bottom: 40px; gap: 20px; }
  .partners-head { flex-direction: row; align-items: center; justify-content: space-between; }
  .partners-head > div { display: flex; align-items: center; gap: 16px; }
  .logo-tile { width: 210px; height: 160px; margin-right: 16px; padding: 14px; font-size: 14px; }
  .logo-tile img { width: 88px; height: 88px; border-radius: 16px; }
}

/* Product */
.product { display: grid; gap: 22px; }
.product-visual { display: flex; flex-direction: column; align-items: center; gap: 18px; }
.product-visual img { width: 100%; max-width: 520px; height: auto; object-fit: contain; filter: drop-shadow(0 30px 40px rgba(0,0,0,0.5)); }
.benefits { display: flex; flex-direction: column; gap: 16px; }
.benefit { display: flex; gap: 14px; }
.benefit::before { content: ''; flex-shrink: 0; width: 9px; background: var(--red); transform: skewX(-12deg); }
.benefit.blue::before { background: var(--blue); }
.benefit h3 { margin: 0; font-family: var(--disp); text-transform: uppercase; font-weight: 800; font-size: 22px; }
.benefit p { margin: 2px 0 0; color: var(--muted); font-size: 15px; }
@media (min-width: 900px) { .product { grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; } .product-copy { display: flex; flex-direction: column; gap: 22px; } .benefit h3 { font-size: 26px; } .benefit p { font-size: 16px; } }
.product-copy { display: flex; flex-direction: column; gap: 18px; }

/* Stats */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); background: var(--blue); }
.stat { padding: 16px 8px; text-align: center; border-right: 1px solid rgba(255,255,255,0.18); }
.stat:last-child { border-right: 0; }
.stat strong { display: block; font-family: var(--disp); font-size: 26px; font-weight: 700; letter-spacing: -0.01em; white-space: nowrap; }
.stat span { display: block; font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; color: #D6E6F2; margin-top: 4px; }
.stat.hide-sm { display: none; }
@media (min-width: 900px) { .stats { grid-template-columns: repeat(4, 1fr); } .stat.hide-sm { display: block; } .stats { padding-inline: var(--gutter); } .stat { padding: 26px 32px; text-align: left; } .stat:first-child { padding-left: 0; } .stat:last-child { padding-right: 0; } .stat strong { font-size: 44px; } .stat span { font-size: 11px; } }

/* Highlight strip */
.tile { position: relative; flex-shrink: 0; width: 168px; height: 224px; margin: 0 10px 0 0; border-radius: 8px; overflow: hidden; background: var(--panel-2); }
.tile img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.tile:hover img { transform: scale(1.06); }
.tile figcaption { position: absolute; left: 8px; bottom: 8px; padding: 3px 7px; background: rgba(11,27,51,0.8); border-radius: 4px; font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; font-weight: 700; }
@media (min-width: 900px) { .tile { width: 270px; height: 360px; margin-right: 14px; border-radius: 10px; } .tile figcaption { font-size: 10px; left: 12px; bottom: 12px; } }

/* Registration */
.register { position: relative; overflow: hidden; }
.register-bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 55%; }
.register::before { content: ''; position: absolute; inset: 0; z-index: 1; background: linear-gradient(to bottom, rgba(11,27,51,0.55), var(--ink) 260px); }
.register > * { position: relative; z-index: 2; }
.register > .register-bg { position: absolute; z-index: 0; }
.register-grid { display: grid; gap: 20px; }
.register-copy { display: flex; flex-direction: column; gap: 14px; }
.register-copy .h2 { font-size: clamp(20px, 2.3vw, 36px); }
.embed { border-radius: 12px; overflow: hidden; border: 1px solid var(--line); background: #FFFFFF; box-shadow: 0 30px 60px rgba(0,0,0,0.5); }
.embed-bar { display: flex; align-items: center; justify-content: space-between; padding: 10px 16px; background: var(--blue); }
.embed-bar span:first-child { display: flex; align-items: center; gap: 8px; font-family: var(--disp); font-weight: 900; text-transform: uppercase; letter-spacing: 0.08em; font-size: 15px; }
.embed-bar span:last-child { font-family: var(--label); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: #D6E6F2; }
/* The registration form is a 100%-height layout: it reflows to whatever the
   iframe gives it rather than reporting its own size, so an over-tall frame
   just stretches it and leaves white space. Measured: it does not scroll at
   390px wide down to 560px tall, or at 1280px wide down to ~620px. */
.embed iframe { display: block; width: 100%; height: 720px; border: 0; background: #FFFFFF; }
.fineprint { margin: 0; font-size: 13px; color: var(--dim); }
@media (min-width: 900px) {
  .register::before { background: linear-gradient(to right, rgba(11,27,51,0.96) 30%, rgba(11,27,51,0.8)); }
  .register-grid { grid-template-columns: 1fr 2fr; gap: 48px; align-items: start; }
  .embed iframe { height: 780px; }
}

/* Steps */
.steps { display: grid; gap: 12px; }
.step { display: flex; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--line); }
.step-n { flex-shrink: 0; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: var(--blue); border-radius: 6px; font-family: var(--label); font-weight: 700; font-size: 16px; }
.step h3 { margin: 0; font-family: var(--disp); text-transform: uppercase; font-weight: 800; font-size: clamp(15px, 1.6vw, 21px); }
.step p { margin: 2px 0 0; color: var(--muted); font-size: 14px; }
@media (min-width: 900px) {
  .steps { grid-template-columns: repeat(4, 1fr); gap: 16px; }
  .step { flex-direction: column; padding: 24px; background: var(--panel); border: 1px solid var(--line); border-top: 3px solid var(--red); border-radius: 10px; }
  .step-n { background: transparent; width: auto; height: auto; justify-content: flex-start; font-size: 34px; color: var(--sky); }
  .step h3 { font-size: clamp(16px, 1.9vw, 26px); }
  .step p { font-size: 15px; }
}
.step-icon { flex-shrink: 0; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: var(--blue); border-radius: 8px; }
@media (min-width: 900px) { .step .step-icon { width: 52px; height: 52px; } }

/* Packages */
.packages { display: grid; gap: 14px; }
@media (min-width: 900px) { .packages { grid-template-columns: repeat(2, 1fr); gap: 20px; } .packages.three { grid-template-columns: 1fr 1fr 1fr; gap: 24px; } }
.card { display: flex; flex-direction: column; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.card.featured { border-color: var(--red); }
.card-flag { padding: 5px 16px; background: var(--red); color: #FFFFFF; font-family: var(--disp); font-weight: 900; text-transform: uppercase; letter-spacing: 0.1em; font-size: 13px; }
.card-body { padding: 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.card-meta { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 10px; color: var(--sky); }
.card h3 { margin: 0; font-family: var(--disp); text-transform: uppercase; font-weight: 800; font-size: 26px; line-height: 1.02; }
.card p { margin: 0; color: var(--muted); font-size: 14px; }
.card-foot { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 12px 18px; background: var(--ink); border-top: 1px solid var(--line); }
.price { font-family: var(--label); font-weight: 700; font-size: 26px; }
.price-note { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 10px; color: var(--dim); text-align: right; }
.card-foot.blue { background: var(--blue); border-top: 0; font-family: var(--disp); font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; font-size: 16px; }
@media (min-width: 900px) { .card-body { padding: 28px; gap: 12px; } .card h3 { font-size: clamp(24px, 2.4vw, 34px); } .card p { font-size: 16px; } .card-foot { padding: 18px 28px; } .price { font-size: 42px; } .price-note { font-size: 12px; } .card-flag { padding: 6px 28px; font-size: 14px; } }
.addon { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 12px; padding: 14px 18px; border-radius: 10px; border: 1px dashed #3C5B86; }
.addon strong { display: block; font-size: 16px; }
.addon span { font-size: 13px; color: var(--dim); }

/* Posters */
.posters { display: flex; gap: 12px; overflow-x: auto; padding: 6px var(--pad) 10px 0; scrollbar-width: none; scroll-snap-type: x mandatory; }
.posters::-webkit-scrollbar { display: none; }
.poster { flex-shrink: 0; width: 176px; margin: 0; display: flex; flex-direction: column; gap: 8px; scroll-snap-align: start; }
/* 13x19 is the printed poster size, so the frame holds that ratio whatever
   the source file measures and whatever width the column lands at.
   height:auto is load-bearing: the img tags carry width/height attributes,
   which the browser maps to CSS presentational hints. Declaring width alone
   leaves height:2000px standing, and aspect-ratio is ignored when both
   dimensions are already definite. */
.poster img { width: 100%; height: auto; aspect-ratio: 13 / 19; object-fit: cover; border-radius: 4px; box-shadow: 0 14px 30px rgba(0,0,0,0.5); transition: transform .3s ease; }
.poster img:hover { transform: translateY(-6px) rotate(-1deg); }
.poster figcaption { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 9px; color: var(--dim); }
.section.posters-sec { padding-right: 0; }
@media (min-width: 900px) { .section.posters-sec { padding-right: var(--gutter); } .posters { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 210px)); justify-content: start; gap: 20px; overflow: visible; padding: 0; } .poster { width: auto; } .poster figcaption { font-size: 10px; } }

/* Moment band */
.moment { display: grid; }
.moment-img { position: relative; height: 420px; overflow: hidden; }
.moment-img img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; }
.moment-copy { padding: 32px var(--gutter) 40px; display: flex; flex-direction: column; gap: 16px; background: var(--blue); }
/* .h2 sets line-height 0.9, but an inline background paints the font's full
   content box (~1.2em), so as a plain inline this bled up into the line
   above. inline-block makes the line box account for its height. */
.moment-copy .h2 .tag { display: inline-block; background: var(--red); color: #FFFFFF; padding: 0.04em 10px 0.1em; line-height: 0.9; }
.moment-copy p { margin: 0; color: #E3EDF5; max-width: 460px; }
@media (min-width: 900px) { .moment { grid-template-columns: 1fr 1fr; min-height: 640px; } .moment-img { height: auto; } .moment-copy { padding: 72px max(64px, var(--gutter)) 72px 64px; justify-content: center; } .moment-copy .h2 { font-size: 84px; } .moment-copy p { font-size: 18px; } }

/* FAQ */
.faq-grid { display: grid; gap: 16px; }
@media (min-width: 900px) { .faq-grid { grid-template-columns: 1fr 2fr; gap: 48px; } }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary { list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 12px; min-height: 56px; padding: 14px 0; cursor: pointer; font-weight: 700; font-size: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; flex-shrink: 0; color: var(--sky); font-size: 24px; font-weight: 400; line-height: 1; }
.faq details[open] summary::after { content: '–'; }
.faq details p { margin: 0; padding: 0 0 18px; color: var(--muted); font-size: 15px; max-width: 760px; }
@media (min-width: 900px) { .faq summary { min-height: 64px; padding: 18px 0; font-size: 18px; } .faq details p { font-size: 16px; } }

/* Closing bands + footer */
.closers { display: grid; }
.closer { padding: 36px var(--gutter); display: flex; flex-direction: column; gap: 12px; }
.closer.red { background: var(--red); color: #FFFFFF; }
.closer.panel { background: var(--panel); }
.closer .h3 { font-family: var(--disp); text-transform: uppercase; font-weight: 900; font-size: 30px; line-height: 0.95; margin: 0; }
.closer p { margin: 0; }
@media (min-width: 900px) { .closers { grid-template-columns: 1fr 1fr; } .closer { padding: 56px; } .closer:first-child { padding-left: max(56px, var(--gutter)); } .closer:last-child { padding-right: max(56px, var(--gutter)); } .closer .h3 { font-size: clamp(26px, 3vw, 44px); } }
.footer { padding: 32px var(--gutter) 120px; display: flex; flex-direction: column; gap: 16px; background: var(--ink); border-top: 1px solid #16305A; }
.footer-brand { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.footer-brand .disp { font-weight: 900; font-size: 22px; white-space: nowrap; }
.footer-links { display: flex; flex-wrap: wrap; gap: 12px 20px; font-size: 15px; }
.footer-links a { color: var(--muted); text-decoration: none; font-weight: 600; white-space: nowrap; }
.footer-links a:hover { color: #FFFFFF; }
.footer small { color: var(--dim); font-size: 13px; }
@media (min-width: 900px) {
  .footer { flex-direction: row; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 20px 32px; padding-bottom: 36px; }
  .footer-links { flex: 1; justify-content: flex-end; }
  .footer small { flex-basis: 100%; }
}

/* Sticky mobile CTA */
.sticky-cta { position: fixed; left: 10px; right: 10px; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 60; display: flex; align-items: center; gap: 10px; padding: 8px 8px 8px 14px; border-radius: 12px; background: rgba(15,27,38,0.92); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); border: 1px solid #2B4A77; box-shadow: 0 12px 30px rgba(0,0,0,0.5); transform: translateY(140%); transition: transform .35s ease; }
.sticky-cta.show { transform: translateY(0); }
.sticky-cta div { flex: 1; font-size: 12px; color: var(--muted); line-height: 1.3; }
.sticky-cta div strong { display: block; color: var(--text); font-size: 14px; }
.sticky-cta .btn { min-height: 46px; padding: 0 16px; font-size: 15px; }
@media (min-width: 900px) { .sticky-cta { display: none; } }

/* Event page bits */
.ev-hero { position: relative; overflow: hidden; }
.ev-hero-media { position: relative; height: 450px; overflow: hidden; }
.ev-hero-media img.cover { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; }
.ev-hero-media::after { content: ''; position: absolute; inset: 0; background: linear-gradient(to top, rgba(11,27,51,0.98) 32%, rgba(11,27,51,0.25) 75%); }
/* Anchor the plate to the top of the frame. For a portrait photograph used
   as a wide hero the cover scale throws away most of the height -- at 1440
   wide the Cooperstown plate renders 2160px tall into a 680px window -- so
   the default 20% offset lands below the faces. The zoom shares the origin,
   otherwise it crops back down from the top as it runs. Desktop only: the
   mobile hero is shorter and keeps far more of the frame. */
@media (min-width: 900px) {
  .ev-hero-media.art-top img.cover { object-position: 50% 0; transform-origin: 50% 0; }
}
.ev-badge { display: flex; align-items: center; gap: 10px; }
.ev-badge img { width: 56px; height: 56px; border-radius: 12px; }
.ev-copy { position: absolute; z-index: 2; left: var(--gutter); right: var(--gutter); bottom: 20px; display: flex; flex-direction: column; gap: 10px; }
.ev-copy .lead { color: #D6DEE5; font-size: 15px; }
.ev-cta { padding: 16px var(--gutter) 8px; display: flex; flex-direction: column; gap: 12px; }
.ev-cta .ev-actions { display: flex; }
.deadline { display: flex; gap: 12px; padding: 14px 16px; border-radius: 10px; background: rgba(226,26,35,0.14); border: 1px solid var(--red); }
.deadline h2 { margin: 0; font-family: var(--disp); text-transform: uppercase; font-weight: 900; letter-spacing: 0.04em; font-size: 18px; }
.deadline p { margin: 2px 0 0; font-size: 14px; color: #E3EAF0; }
@media (min-width: 900px) {
  .ev-hero-media { height: 680px; }
  .ev-hero-media::after { background: linear-gradient(to right, rgba(11,27,51,0.96) 25%, rgba(11,27,51,0.55) 60%, rgba(11,27,51,0.15)); }
  .ev-badge img { width: 80px; height: 80px; border-radius: 16px; }
  .ev-copy { left: var(--gutter); right: auto; top: 48px; bottom: 48px; width: min(700px, 55vw); justify-content: center; gap: 22px; }
  .ev-copy .lead { font-size: 18px; }
  .ev-cta { position: absolute; z-index: 3; right: var(--gutter); bottom: 48px; width: 400px; padding: 0; }
  .ev-cta .ev-actions { display: none; }
  .deadline { background: rgba(11,27,51,0.9); padding: 20px; box-shadow: 0 24px 50px rgba(0,0,0,0.5); }
  .deadline h2 { font-size: 20px; }
  .deadline p { font-size: 15px; }
}
/* Layered event hero: blurred background plate with a cut-out foreground. */
/* Constrained on both axes so one rule serves a landscape cut-out (AYF) and a
   portrait one (About, Portfolio). Capping width alone let the tall ones run
   past the top of the hero and crop at the head. */
.ev-hero-media .hero-fg { position: absolute; z-index: 1; top: 0; right: -4%; width: auto; height: auto; max-width: 92%; max-height: 80%; pointer-events: none; filter: drop-shadow(0 20px 36px rgba(0,0,0,0.6)); transform-origin: 72% 100%; animation: fg-in 1.1s cubic-bezier(0.16, 0.84, 0.44, 1) both, fg-kb 18s ease-in-out 1.1s infinite alternate; }
@media (min-width: 900px) { .ev-hero-media .hero-fg { top: auto; bottom: 0; right: var(--gutter); max-width: 62%; max-height: 112%; } }
/* Static heroes (About, Portfolio) drift to 1.09, the same headroom problem
   as the rotating CASV cut-outs: 112% cropped the head on desktop, and on
   mobile the zoom grew up past the top edge. 74% and 90% x 1.09 end the same
   size as CASV's figures, growing downward from the top on mobile. */
.ev-hero-media:not([data-hero-rotate]) .hero-fg { max-height: 74%; transform-origin: 72% 0; }
@media (min-width: 900px) { .ev-hero-media:not([data-hero-rotate]) .hero-fg { max-height: 90%; transform-origin: 72% 100%; } }
/* Entrance then a slow drift, so the cut-out moves with the plate behind it
   rather than sitting still against a panning background. The two run in
   sequence: fg-kb is delayed past fg-in, and being later in the list it owns
   the transform once it starts. */
/* Rotating hero pairs. Each slide is one plate plus its matching cut-out, so
   the two always change together rather than the figure swapping against a
   background that stayed put. */
.hero-slide { position: absolute; inset: 0; opacity: 0; transition: opacity 1.2s ease; }
.hero-slide.is-on { opacity: 1; }
/* Rotating heroes push the zoom much further and run it once per slide,
   7.4s against a 7s interval so it never visibly stops before the change.
   Static heroes keep the gentle back-and-forth drift. */
[data-hero-rotate] .hero-fg { animation: fg-live 7.4s cubic-bezier(0.22, 0.61, 0.36, 1) both; }
[data-hero-rotate] .cover.kb { animation: kb-live 7.4s linear both; }
/* Zoom through the slide, then leave. Used where the cut-out changes over a
   background that stays put, so the exit has to read as a departure rather
   than a cross-fade in place. */
[data-hero-rotate].hold-plate .cover.kb { animation: kb 20s ease-in-out infinite alternate; }
/* The exit only runs once site.js has started the rotation (.is-rotating).
   Without JS the first cut-out falls back to fg-live, which holds at the end,
   rather than leaving with nothing to replace it. 8.2s is the 7s interval
   plus the exit, so the figure leaves as the next one arrives. */
[data-hero-rotate].hold-plate.is-rotating .hero-fg { animation: fg-pan 8.2s cubic-bezier(0.33, 0, 0.2, 1) both; }
/* These slides hold only the cut-out, so they sit above the ::after gradient.
   A slide mid-fade is its own stacking context, and without the z-index the
   figure drops under the gradient for every change. The cut-out does its own
   fading, so the slide switches instantly on arrival and waits out the exit
   before it hides. */
.hold-plate .hero-slide { z-index: 1; transition: opacity 0s linear 1.3s; }
.hold-plate .hero-slide.is-on { transition-delay: 0s; }
/* fg-live and fg-pan scale to 1.26, so the portrait cut-outs need headroom:
   78% x 1.26 stays inside the hero. On mobile the figure hangs from the top,
   so it grows downward instead of up past the edge, and 64% keeps it clear of
   the copy at the foot of the hero as it does. */
.hold-plate .hero-fg { max-height: 64%; transform-origin: 72% 0; }
@media (min-width: 900px) { .hold-plate .hero-fg { max-height: 78%; transform-origin: 72% 100%; } }
@keyframes fg-pan {
  0%   { opacity: 0; transform: translateX(9%) scale(1.02); }
  11%  { opacity: 1; transform: translateX(0) scale(1.06); }
  85%  { opacity: 1; transform: translateX(0) scale(1.22); }
  100% { opacity: 0; transform: translateX(-12%) scale(1.26); }
}
@keyframes fg-live {
  0%   { opacity: 0; transform: translateX(6%) scale(1.02); }
  14%  { opacity: 1; transform: translateX(0) scale(1.06); }
  100% { opacity: 1; transform: translateX(0) scale(1.26); }
}
@keyframes kb-live { from { transform: scale(1.03); } to { transform: scale(1.16); } }
@keyframes fg-in { from { opacity: 0; transform: translateX(7%) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes fg-kb { from { transform: scale(1); } to { transform: scale(1.09); } }
.ev-hero .ev-copy .btn-row.desktop-only { display: none; }
@media (min-width: 900px) { .ev-hero .ev-copy .btn-row.desktop-only { display: flex; } }
.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.checklist li { display: flex; gap: 10px; align-items: flex-start; font-size: 15px; line-height: 1.4; }
.checklist svg { flex-shrink: 0; }
@media (min-width: 900px) { .checklist { grid-template-columns: 1fr 1fr; gap: 16px 24px; } .checklist li { font-size: 16px; } }
/* Grid items default to min-width:auto, so a long word -- PROFESSIONAL-GRADE,
   PHOTOGRAPHER -- forces the cell wider than its track and pushes the page
   into horizontal scroll on a 320px screen. */
.two-col > *, .closers > *, .packages > *, .register-grid > *, .gallery > * { min-width: 0; }
.two-col { display: grid; gap: 24px; }
@media (min-width: 900px) { .two-col { grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; } }
.help-card { display: flex; flex-direction: column; gap: 12px; padding: 24px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); }
.help-card h3 { margin: 0; font-family: var(--disp); text-transform: uppercase; font-weight: 900; font-size: 28px; line-height: 0.95; }
.help-card p { margin: 0; color: var(--muted); }
.reminders { display: flex; flex-direction: column; gap: 12px; }
.reminder { display: flex; gap: 12px; }
.reminder::before { content: ''; flex-shrink: 0; width: 9px; background: var(--red); transform: skewX(-12deg); }
.reminder.blue::before { background: var(--blue); }
.reminder strong { display: block; }
.reminder span { font-size: 14px; color: var(--dim); }
.placeholder-img { display: flex; align-items: center; justify-content: center; min-height: 260px; border-radius: 14px; border: 1px dashed #3C5B86; background: var(--panel); color: var(--dim); font-family: var(--label); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; text-align: center; padding: 20px; }
@media (min-width: 900px) { .placeholder-img { min-height: 420px; } }
.licensed { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; color: var(--sky); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .marquee-track, .dot, .kb, .hero-fg { animation: none !important; }
  .sticky-cta, .promo-banner img { transition: none; }
}
.kb { animation: kb 14s ease-in-out infinite alternate; }
.ev-copy .h1 { font-size: clamp(32px, 6.6vw, 74px); overflow-wrap: anywhere; }

/* Portfolio gallery. Columns rather than a fixed grid: the set mixes
   landscape frames, portrait frames, transparent cut-outs and 13x19 posters,
   and columns keep every one at its own ratio instead of cropping to fit. */
.filters { display: flex; flex-wrap: wrap; gap: 8px; }
.filter { font-family: var(--label); text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; font-weight: 700; padding: 9px 16px; border-radius: 999px; cursor: pointer; color: var(--muted); background: transparent; border: 1px solid var(--line); }
.filter:hover { color: #FFFFFF; border-color: var(--sky); }
.filter.is-on { background: var(--red); border-color: var(--red); color: #FFFFFF; }
.gallery { column-count: 2; column-gap: 12px; }
@media (min-width: 700px) { .gallery { column-count: 3; } }
@media (min-width: 1100px) { .gallery { column-count: 4; column-gap: 16px; } }
.gallery-item { break-inside: avoid; margin: 0 0 12px; border-radius: 10px; overflow: hidden; background: var(--panel); }
@media (min-width: 1100px) { .gallery-item { margin-bottom: 16px; } }
.gallery-item img { display: block; width: 100%; height: auto; transition: transform .4s ease; }
.gallery-item:hover img { transform: scale(1.04); }
.gallery-item[hidden] { display: none; }

/* Section photo backgrounds. The overlay is brand navy, not brand blue:
   measured over a blown-out white region of a photograph, blue at 0.90 drops
   the dim caption colour to 2.94:1, under the 4.5 minimum. Navy at this range
   holds body text above 10:1 and dim captions above 5:1, so the photograph
   reads as texture without costing legibility anywhere. */
.section.photo {
  background-image: linear-gradient(180deg, rgba(11,27,51,0.93) 0%, rgba(11,27,51,0.88) 55%, rgba(11,27,51,0.94) 100%), var(--photo);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
@media (min-width: 900px) { .section.photo { background-attachment: scroll; } }

@media (max-width: 400px) {
  /* PHOTOGRAPHER / PHOTOGRAPHERS do not fit these cards at 320px */
  .closer .h3 { font-size: 26px; }
  .help-card h3 { font-size: 22px; }
}

/* Uniform media rows. Every cell the same size whatever the source measures:
   ratio-poster for product shots, which sit on the page background rather
   than a panel so transparent art has nothing showing behind it;
   ratio-wide for photographs, cropped to fill. */
.media-row { display: grid; gap: 14px; grid-template-columns: repeat(2, 1fr); }
@media (min-width: 700px) { .media-row { grid-template-columns: repeat(var(--cols, 3), 1fr); gap: 18px; } }
.media-row > figure { margin: 0; min-width: 0; }
.media-row img { display: block; width: 100%; }
.media-row.ratio-poster img { aspect-ratio: 13 / 19; height: auto; object-fit: contain; }
.media-row.ratio-wide img { aspect-ratio: 3 / 2; height: auto; object-fit: cover; border-radius: 10px; }

/* The graphic sits above the copy at full strength rather than washed in
   behind it. On the stacked mobile list there is no card to bleed into, so
   the art stays a contained box. */
.step.has-art { flex-direction: column; align-items: stretch; }
.step-art { display: block; width: 100%; min-width: 0; height: 130px; object-fit: contain; object-position: center; margin-bottom: 10px; }

/* From the card breakpoint the art runs the full width of the card with the
   red rule under it, so each step reads as a picture with a caption rather
   than a padded box. The card drops its own padding and the copy carries it
   instead; rounding the image corners rather than clipping with
   overflow:hidden keeps the grid item's automatic minimum size intact.
   Photographs fill the band. The badge and the phones are transparent
   cut-outs, so they sit whole on a flat panel -- cropping would lose the
   subject, and any shading behind them reads as a smudge on the card. */
@media (min-width: 900px) {
  .step.has-art { padding: 0; border-top: 1px solid var(--line); }
  .step.has-art > .step-n { padding: 18px 24px 0; }
  .step.has-art > div { padding: 0 24px 24px; }
  .step.has-art .step-art {
    height: clamp(180px, 15vw, 232px);
    margin: 0 0 4px;
    object-fit: cover;
    border-bottom: 3px solid var(--red);
    border-radius: 9px 9px 0 0;
    background: var(--panel-2);
  }
  .step.has-art .step-art.is-cutout { object-fit: contain; padding: 16px 16px 12px; }
}

/* Partners page cards. The logo tile from the home page marquee, grown to
   carry a name and a line of copy, with the same red border and 3px lift on
   hover. */
.partner-grid { display: grid; gap: 14px; }
@media (min-width: 700px) { .partner-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .partner-grid { grid-template-columns: repeat(3, 1fr); gap: 18px; } }
.partner-card { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; color: var(--text); text-decoration: none; transition: border-color .2s ease, transform .2s ease; }
.partner-card:hover { border-color: var(--red); transform: translateY(-3px); }
.partner-card img { width: 72px; height: 72px; border-radius: 14px; }
.partner-card h3 { margin: 4px 0 0; font-family: var(--disp); text-transform: uppercase; font-weight: 900; font-size: 22px; line-height: 1; }
.partner-card p { margin: 0; color: var(--muted); font-size: 15px; }
.partner-link { margin-top: auto; padding-top: 6px; font-family: var(--label); font-size: 14px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sky); }
@media (min-width: 900px) { .partner-card { padding: 28px; } .partner-card img { width: 88px; height: 88px; border-radius: 16px; } .partner-card h3 { font-size: 26px; } }

/* Work with us. The coverage map is a flat graphic on a dark plate, so it
   sits on a panel rather than bleeding into the navy. */
.map-img { display: block; width: 100%; height: auto; border-radius: 14px; background: var(--panel); }
.quote-grid { display: grid; gap: 16px; }
@media (min-width: 900px) { .quote-grid { grid-template-columns: 1fr 1fr; gap: 28px; } }
.quote-card { display: flex; flex-direction: column; gap: 18px; margin: 0; padding: 22px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; }
.quote-card img { width: 120px; height: 180px; object-fit: cover; object-position: 50% 15%; border-radius: 10px; }
.quote-card blockquote { margin: 0; }
.quote-card blockquote p { margin: 0; font-size: 17px; line-height: 1.5; }
.quote-card figcaption { margin-top: 14px; font-family: var(--label); font-size: 15px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sky); }
@media (min-width: 700px) { .quote-card { flex-direction: row; align-items: flex-start; } .quote-card img { flex-shrink: 0; width: 150px; height: 230px; } }
/* Award art is a white badge, contained so the lettering round its edge is
   never cropped. */
.award-row { display: flex; flex-wrap: wrap; gap: 16px; }
.award-row img { width: 150px; height: 150px; object-fit: contain; padding: 10px; background: #FFFFFF; border-radius: 12px; }
@media (min-width: 900px) { .award-row { gap: 28px; } .award-row img { width: 220px; height: 220px; } }
/* ADP renders the openings list with its own light styling. */
.jobs-embed { min-height: 160px; padding: 16px; background: #FFFFFF; color: #1A1A1A; border-radius: 12px; overflow-x: auto; }
@media (min-width: 900px) { .jobs-embed { padding: 28px; } }

/* Contact page: copy beside the form, the same split as registration. On a
   phone the form follows the intro directly; the photo and the pointers to
   other pages come after it. */
.contact-grid { display: grid; gap: 20px; }
.contact-grid > * { min-width: 0; }
.contact-img { display: block; width: 100%; height: auto; border-radius: 14px; }
.contact-aside { order: 1; }
@media (min-width: 900px) {
  .contact-grid { grid-template-columns: 1fr 1.4fr; column-gap: 48px; row-gap: 20px; align-items: start; }
  .contact-embed { grid-column: 2; grid-row: 1 / span 2; }
  .contact-aside { grid-column: 1; grid-row: 2; }
}

/* Press page. Titles run long and several are quoted headlines, so they set
   in the body face rather than the uppercase display. */
.press-list { display: grid; gap: 14px; }
@media (min-width: 900px) { .press-list { grid-template-columns: 1fr 1fr; gap: 18px; } }
.press-card { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 22px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; }
.press-outlet { font-family: var(--label); font-size: 14px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sky); }
.press-card h3 { margin: 0; font-size: 20px; line-height: 1.25; overflow-wrap: anywhere; }
.press-card p { margin: 0; color: var(--muted); font-size: 15px; }
.press-link { margin-top: auto; padding-top: 4px; font-weight: 700; }
@media (min-width: 900px) { .press-card { padding: 28px; } .press-card h3 { font-size: 22px; } }
/* Cognito renders the contact form inline, sized to its fields. Its embed
   script only draws inside an element with the class "cognito" -- without it
   the form loads and silently renders nothing. */
.contact-form { min-height: 260px; padding: 12px 16px 20px; color: #1A1A1A; }
@media (min-width: 900px) { .contact-form { padding: 16px 28px 28px; } }

/* The package-card footers are links into the registration form. The card
   clips its corners, so the focus ring sits inside the bar, not outside. */
a.card-foot { color: #FFFFFF; text-decoration: none; transition: background-color 0.15s; }
a.card-foot::after { content: "\2192"; font-family: var(--body); font-weight: 400; }
a.card-foot:hover { background: var(--red); color: #FFFFFF; }
a.card-foot:focus-visible { outline-offset: -5px; }

/* Until the registration form loads, the frame is transparent over a navy
   panel that says so. The form's own page has no background, so site.js
   adds .is-loaded on the iframe's load event to turn the frame white. */
.embed { display: grid; background: var(--ink); }
.embed::after { content: "Loading registration\2026"; grid-row: 2; grid-column: 1; align-self: start; justify-self: center; margin-top: 120px; font-family: var(--label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; font-size: 13px; color: var(--dim); }
.embed > .cognito { grid-row: 2; grid-column: 1; position: relative; z-index: 1; }
.embed iframe { background: transparent; }
.embed.is-loaded iframe { background: #FFFFFF; }
.embed.is-loaded::after { content: none; }

/* Package artwork. The source is a square on a flat ground, so it sits
   contained on a band painted that same colour -- cropping a square to the
   band ratio would cut the outer photographs off. --art-bg carries the colour
   per card, the way --photo carries a section background, because it has to
   match the file rather than the palette. The flag rides on the artwork as a
   pill instead of the full-width bar it is on cards with no art. */
.card-art { position: relative; background: var(--art-bg, var(--panel-2)); }
.card-art img { display: block; width: 100%; height: auto; aspect-ratio: 2 / 1; object-fit: contain; }
.card-art .card-flag { position: absolute; top: 12px; left: 12px; padding: 5px 14px; background: var(--ink); border-radius: 999px; }
@media (min-width: 900px) { .card-art .card-flag { padding: 6px 16px; } }

/* Partner banner. The zoom is on the image inside a clipping frame, so it
   cannot overhang the way a lift on the frame itself would. */
/* Capped and centred: full column width made the sponsor banner the largest
   thing on the page. */
.promo-banner { display: block; overflow: hidden; border-radius: 10px; line-height: 0; max-width: 720px; margin-inline: auto; }
.promo-banner img { display: block; width: 100%; height: auto; transition: transform .4s ease; }
.promo-banner:hover img, .promo-banner:focus-visible img { transform: scale(1.02); }

/* Portrait photographs in a uniform row. Volleyball frames come off the body
   in 2:3, and the sample rows are all one orientation, so they crop to fill
   like ratio-wide rather than sitting contained like a poster. */
.media-row.ratio-portrait img { aspect-ratio: 2 / 3; height: auto; object-fit: cover; border-radius: 10px; }

/* A section carrying a single package. The card spans the column rather than
   sitting at half width with nothing beside it, and the gallery underneath
   carries the picture. */
.packages.one-up { grid-template-columns: 1fr; }

/* One line between a package and its gallery, saying what the gallery proves.
   Without it the two rows of photographs look like the same thing twice. */
.gallery-note { margin: 22px 0 -2px; color: var(--muted); font-size: 15px; }

/* Photo mosaic on a package card. Tiles are placed rather than auto-flowed so
   the portrait frames land in cells a tall crop suits and the catcher
   close-up gets the wide one -- auto-flow would put a 2:3 frame in a wide
   cell and cut the player's head off.

   The column count follows the width of the card, not the viewport, which is
   why the five-column layout waits until 1100: packages go two-up at 900, so
   a card there is about 420px and five columns would make 76px tiles. Each
   step keeps the cell count exact so the grid never ends on a hole. */
.card-art.card-mosaic { background: var(--ink); }
.mosaic { display: grid; gap: 3px; grid-template-columns: repeat(2, 1fr); }
/* min-height:0 is load-bearing: a grid item defaults to min-height:auto,
   which refuses to shrink below the image's intrinsic height and lets a
   portrait tile stretch its row taller than the track asked for. */
.mosaic img { display: block; width: 100%; height: 100%; min-width: 0; min-height: 0; object-fit: cover; aspect-ratio: 4 / 3; }
.mosaic img.wide { grid-column: span 2; aspect-ratio: 8 / 3; }

/* 7 tiles, one spanning two columns: 8 cells, two clean rows. */
@media (min-width: 560px) {
  .mosaic { grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, 1fr); aspect-ratio: 2 / 1; }
  .mosaic img, .mosaic img.wide { aspect-ratio: auto; }
}

/* 7 tiles, one spanning two columns and two spanning two rows: 10 cells. */
@media (min-width: 1100px) {
  .mosaic { grid-template-columns: repeat(5, 1fr); aspect-ratio: 5 / 2; }
  .mosaic img.tall { grid-row: span 2; }
}

/* The claim sits on the artwork, over a scrim so it stays legible whatever
   the tile beneath it happens to be. */
.mosaic-claim { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; display: flex; align-items: center; gap: 10px; padding: 26px 14px 10px; background: linear-gradient(to top, rgba(11,27,51,0.97) 0%, rgba(11,27,51,0.93) 40%, rgba(11,27,51,0.55) 75%, rgba(11,27,51,0) 100%); font-family: var(--disp); font-weight: 800; text-transform: uppercase; letter-spacing: 0.02em; font-size: clamp(14px, 1.7vw, 20px); color: #FFFFFF; }
.mosaic-claim svg { flex-shrink: 0; }

/* Partners is a link to the partner index with its own toggle for the menu,
   rather than a button that only opens it. Two controls, so a click on the
   word navigates and a click on the chevron opens -- a single control cannot
   do both without guessing which one the visitor meant. */
.nav-drop-link { font-weight: 600; font-size: clamp(13px, 1.12vw, 15px); line-height: 1.5; white-space: nowrap; }
.nav-drop-btn { margin-left: 4px; }

/* The whole package card is a link to the registration form. The anchor sits
   over the card rather than wrapping it, so the card keeps its grid layout
   and the price and copy stay selectable. */
.card.is-linked { position: relative; }
.card.is-linked .card-cta { position: absolute; inset: 0; z-index: 2; border-radius: inherit; text-indent: -9999px; overflow: hidden; }
.card.is-linked .card-cta:focus-visible { outline: 3px solid var(--sky); outline-offset: -3px; }
.card.is-linked:hover { border-color: var(--sky); }
.card.featured.is-linked:hover { border-color: var(--red); }

/* The individual package shows one player across the two games the package
   guarantees, so the two establishing frames lead at double width with the
   game marked on them, and the other four run underneath. The top row takes
   the larger share because five of the six frames are portrait and a short
   wide cell would crop them to a torso. */
.mosaic.mosaic-games { grid-template-columns: repeat(2, 1fr); }
/* Five of the six frames are portrait and these cells are wide, so a
   centred crop takes the vertical middle and leaves the heads out of
   frame. Each tile carries its own focal point. */
.mosaic-games img { object-position: var(--pos, 50% 50%); }
/* min-height:0 again, this time on the figure. Without it the wrapper
   refuses to shrink to its fr share, row one swells to the image's
   intrinsic height and row two is squeezed to nothing -- the four lower
   tiles collapsed to zero height at tablet. */
.mosaic-games .game-tile { position: relative; margin: 0; min-width: 0; min-height: 0; height: 100%; grid-column: span 2; }
.mosaic-games .game-tile img { aspect-ratio: 2 / 1; }
.mosaic-games figcaption { position: absolute; top: 8px; left: 8px; padding: 4px 10px; border-radius: 999px; background: var(--ink); color: #FFFFFF; font-family: var(--label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; font-size: 11px; }
@media (min-width: 560px) {
  .mosaic.mosaic-games { grid-template-columns: repeat(4, 1fr); grid-template-rows: 1.6fr 1fr; aspect-ratio: 2 / 1; }
  .mosaic-games .game-tile img { aspect-ratio: auto; height: 100%; }
}

/* The face on the claim is a crop of the same player the frames show, so the
   claim and the artwork are making the same point.

   Scoped to .mosaic-claim, not bare .claim-face: the avatar sits inside
   .card-art, and `.card-art img` already sets width:100%. At equal-ish weight
   that rule wins on specificity, which blew the 34px avatar up to the full
   708px card and pushed the text clean out of the column. */
.mosaic-claim .claim-face { width: 34px; height: 34px; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 50%; flex-shrink: 0; border: 2px solid rgba(255,255,255,0.85); }


/* Partners hover. The word and the chevron are two controls but read as one
   tab, so hovering either lights both and opens the menu -- the chevron alone
   is too small a target to find without landing on the word. This is CSS, not
   site.js, so it can't be lost to a stale script. The strip above the menu
   covers the 14px gap under the tab, so the pointer stays inside .nav-drop on
   its way down and the menu doesn't close under it. Touch screens have no
   hover and keep the chevron toggle. */
.nav-drop:hover .nav-drop-link, .nav-drop:hover .nav-drop-btn { color: #FFFFFF; }
.nav-drop-menu::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 16px; }
@media (hover: hover) {
  .nav-drop:hover .nav-drop-menu[hidden] { display: flex; }
  .nav-drop:hover .nav-drop-btn svg { transform: rotate(180deg); }
}

/* Home page package cards already end in a "Pre-register" button, so the
   button's hit area is stretched over the card instead of adding a second
   link: one tab stop, and the button still turns red wherever the card is
   hovered. */
.card.is-linked > a.card-foot::before { content: ""; position: absolute; inset: 0; z-index: 2; border-radius: inherit; }

/* Product names under the sample product shots (Ripken "What you can take
   home"), in the same label type as the home page poster captions. */
.media-row figcaption { margin-top: 10px; text-align: center; font-family: var(--label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; font-size: 12px; color: var(--muted); }
@media (min-width: 900px) { .media-row figcaption { font-size: 13px; } }

/* Event search. On desktop the field sits in the bar beside Register. At
   1120px the bar has about 200px to spare once the six nav items show, so the
   field starts at 170px and grows with the screen. Below 1120px it moves to a
   row under the bar, because a 320px bar has no room left. The results float
   over the page rather than pushing the hero down. */
.event-search { position: relative; }
.header-actions .event-search { display: none; width: clamp(170px, 15vw, 300px); }
@media (min-width: 1120px) { .header-actions .event-search { display: block; } }
.search-row { position: relative; z-index: 40; padding: 10px var(--gutter); background: var(--ink); border-bottom: 1px solid var(--line); }
@media (min-width: 1120px) { .search-row { display: none; } }
.event-search-input { width: 100%; min-height: 44px; padding: 0 14px; border-radius: 6px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-family: var(--body); font-size: 16px; }
.header-actions .event-search-input { font-size: 15px; }
.event-search-input::placeholder { color: var(--dim); }
.event-search-input:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 0; }
.event-search-results, .event-search-empty { position: absolute; top: calc(100% + 8px); right: 0; z-index: 60; width: 100%; margin: 0; padding: 8px; border-radius: 12px; background: var(--panel); border: 1px solid var(--line); box-shadow: 0 24px 48px rgba(0,0,0,0.55); }
.header-actions .event-search-results, .header-actions .event-search-empty { width: max(100%, 340px); }
.event-search-results { list-style: none; display: flex; flex-direction: column; }
.event-search-results[hidden], .event-search-empty[hidden] { display: none; }
.event-search-results li { display: flex; flex-direction: column; padding: 10px 12px; border-radius: 8px; cursor: pointer; color: var(--text); font-weight: 600; font-size: 15px; }
.event-search-results li span { color: var(--dim); font-weight: 400; font-size: 13px; }
.event-search-results li:hover, .event-search-results li[aria-selected="true"] { background: var(--panel-2); }
.event-search-empty { color: var(--dim); font-size: 15px; padding: 18px 20px; }

/* AYF Elite 300 card art: the blue-toned photo fades in from the left so the
   ELITE 300 mark can sit over the navy. The mark is sized off the card width
   (cqi), not the viewport -- at 900 the cards are two-up and a vw size would
   run the 300 off the edge. Slanted with the same skew as .kick rather than a
   synthetic italic. */
.card-art.elite-art { --art-bg: var(--ink-2); aspect-ratio: 9 / 4; min-height: 150px; overflow: hidden; container-type: inline-size; }
.card-art.elite-art img { position: absolute; top: 0; right: 0; width: 82%; height: 100%; aspect-ratio: auto; object-fit: cover; object-position: 50% 40%; -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 30%); mask-image: linear-gradient(90deg, transparent 0%, #000 30%); }
.elite-mark { position: absolute; left: 18px; bottom: 8px; display: flex; align-items: baseline; gap: 0.12em; font-family: var(--disp); font-weight: 900; text-transform: uppercase; line-height: 0.8; letter-spacing: -0.02em; color: #FFFFFF; font-size: clamp(36px, 14cqi, 112px); transform: skewX(-12deg); transform-origin: 0 100%; }
.elite-mark span:last-child { color: var(--red); font-size: 1.25em; }
@media (min-width: 900px) { .elite-mark { left: 28px; } }

/* Contact form card. It shares .embed with the registration iframes, but
   Cognito draws this form inline, so there is no iframe to fire the load
   event that clears "Loading registration..." and turns the panel white.
   Without these the message sat in the form's grid cell for good, pushing the
   form below it, and the form's dark text landed on the navy panel. */
.contact-embed { background: #FFFFFF; }
.contact-embed::after { content: none; }
.contact-form { font-family: var(--body); }

/* Poster tiles. Same marquee as the photo reel, but at the 13x19 print shape:
   the 3:4 photo tile would crop the player's name off the poster's edge. */
.tile.tile-poster { width: 160px; height: auto; aspect-ratio: 13 / 19; }
@media (min-width: 900px) { .tile.tile-poster { width: 250px; } }

/* Team mosaic focus points. The Ripken frames are uncropped portraits, so each
   tile says where the player is, the way .mosaic-games already does. */
.mosaic img { object-position: var(--pos, 50% 50%); }

/* Four-tile team mosaic (AAU): 2x2 on phones, one row of four from 560 up.
   Two classes outrank the 1100 five-column .mosaic rule regardless of order. */
.mosaic.mosaic-four { grid-template-columns: repeat(2, 1fr); }
@media (min-width: 560px) { .mosaic.mosaic-four { grid-template-columns: repeat(4, 1fr); grid-template-rows: 1fr; aspect-ratio: 2 / 1; } }

/* Cooperstown and Ripken call-outs under the home page logos. Both venues'
   marketing links to the home page rather than their event page, so each half
   is one link that sends those families on, given equal weight side by side.
   The hover changes the border rather than lifting the card, because a lift
   clips against the section edge. */
.callout-grid { display: grid; gap: 16px; }
@media (min-width: 900px) { .callout-grid { grid-template-columns: 1fr 1fr; gap: 20px; } }
.event-callout { position: relative; isolation: isolate; display: flex; flex-direction: column; align-items: flex-start; gap: 12px; min-width: 0; padding: 22px; border-radius: 14px; border: 2px solid var(--line); overflow: hidden; color: var(--text); text-decoration: none; background: var(--panel) var(--photo) center / cover no-repeat; transition: border-color .2s ease; }
.event-callout::before { content: ''; position: absolute; inset: 0; z-index: -1; background: linear-gradient(to top, rgba(11,27,51,0.95) 35%, rgba(11,27,51,0.7) 100%); }
.event-callout:hover, .event-callout:focus-visible { border-color: var(--red); color: var(--text); }
.event-callout:focus-visible { outline: 3px solid var(--sky); outline-offset: 3px; }
.event-callout-logo { width: 64px; height: 64px; border-radius: 14px; }
.event-callout-title { font-family: var(--disp-ex); font-weight: 900; text-transform: uppercase; line-height: 1; font-size: clamp(22px, 2.6vw, 32px); overflow-wrap: anywhere; }
.event-callout-text { color: var(--muted); font-size: 15px; }
.event-callout-btn { margin-top: auto; }
.event-callout:hover .event-callout-btn { background: var(--red-dark); }
@media (min-width: 900px) {
  .event-callout { gap: 14px; padding: 32px; min-height: 340px; }
  .event-callout-logo { width: 80px; height: 80px; border-radius: 16px; }
  .event-callout-text { font-size: 16px; }
}

/* Tall portrait cut-outs (Babe Ruth). At the default 112% and a zoom to 1.26
   their heads ran off the top of the hero. Sized so the cut-out at full zoom
   still fits: 88% x 1.1 on desktop, growing up from the bottom edge; on
   phones it hangs from the top at 58% x 1.1 and grows downward, which keeps
   it above most of the copy at the foot of the hero. */
.ev-hero-media.fg-contained .hero-fg { max-height: 58%; transform-origin: 72% 0; animation-name: fg-live-soft; }
@media (min-width: 900px) { .ev-hero-media.fg-contained .hero-fg { max-height: 88%; transform-origin: 72% 100%; } }
@keyframes fg-live-soft {
  0%   { opacity: 0; transform: translateX(6%) scale(1); }
  14%  { opacity: 1; transform: translateX(0) scale(1.02); }
  100% { opacity: 1; transform: translateX(0) scale(1.1); }
}

/* CASV-style cut-out motion on the paired heroes (AAU, AYF, Babe Ruth): each
   cut-out slides in from the right, zooms through its slide and slides out to
   the left as the next pair arrives, while the plates cross-fade behind. Same
   timing as fg-pan; only runs once site.js has started the rotation, so
   without JS the first cut-out keeps fg-live. Sized the way .hold-plate is so
   the zoom never pushes a head past the frame: hung from the top and growing
   down on phones, standing on the bottom edge and growing up from 900px. */
[data-hero-rotate]:not(.hold-plate) .hero-fg { max-height: 64%; transform-origin: 72% 0; }
@media (min-width: 900px) { [data-hero-rotate]:not(.hold-plate) .hero-fg { max-height: 78%; transform-origin: 72% 100%; } }
[data-hero-rotate].is-rotating:not(.hold-plate) .hero-fg { animation: fg-pan-pair 8.2s cubic-bezier(0.33, 0, 0.2, 1) both; }
@keyframes fg-pan-pair {
  0%   { opacity: 0; transform: translateX(9%) scale(var(--fg-z0, 1.02)); }
  11%  { opacity: 1; transform: translateX(0) scale(var(--fg-z1, 1.06)); }
  85%  { opacity: 1; transform: translateX(0) scale(var(--fg-z2, 1.22)); }
  100% { opacity: 0; transform: translateX(-12%) scale(var(--fg-z3, 1.26)); }
}
/* Babe Ruth's tall cut-outs keep their larger size and gentler zoom. */
.ev-hero-media.fg-contained { --fg-z0: 1; --fg-z1: 1.02; --fg-z2: 1.08; --fg-z3: 1.1; }
[data-hero-rotate].fg-contained:not(.hold-plate) .hero-fg { max-height: 58%; }
@media (min-width: 900px) { [data-hero-rotate].fg-contained:not(.hold-plate) .hero-fg { max-height: 88%; } }

/* Step 1's phone mockup is cropped by design: the phone runs off the bottom
   of its art band. On phones the steps are not cards, so at the default
   130px "contain" it shrank to a small phone cut off mid-air. Below 900 it
   gets the same band the desktop card has: full width, filled from the top,
   on the panel colour, ending on the red rule so the crop reads as an edge. */
@media (max-width: 899px) {
  .step.has-art .step-art.step-art-band { height: auto; aspect-ratio: 1200 / 889; max-height: 300px; object-fit: cover; object-position: 50% 0; background: var(--panel-2); border-radius: 9px 9px 0 0; border-bottom: 3px solid var(--red); }
}

/* The other three steps take the same band on phones, so all four pictures
   are one size: the photo fills it, the cut-outs sit whole on the panel. */
@media (max-width: 899px) {
  .step.has-art .step-art { height: auto; aspect-ratio: 1200 / 889; max-height: 300px; object-fit: cover; background: var(--panel-2); border-radius: 9px 9px 0 0; border-bottom: 3px solid var(--red); }
  .step.has-art .step-art.is-cutout { object-fit: contain; padding: 16px 16px 12px; }
}

/* "Become a Partner" closes the Partners dropdown: centred under a hairline,
   smaller than the event links so it reads as a footnote, not a sixth event.
   Two classes outrank the .nav-drop-menu a padding and size above. */
.nav-drop-menu a.nav-drop-become { justify-content: center; margin-top: 4px; padding: 10px 12px 6px; border-top: 1px solid var(--line); border-radius: 0 0 8px 8px; font-size: 13px; color: var(--sky); }
.nav-drop-menu a.nav-drop-become:hover { background: transparent; color: #FFFFFF; }

/* Reviews page. A one-line proof strip under the hero: short phrases at one
   size, each led by the skewed red tick of the .kick label. Stacked below
   1280, where three in a row would each wrap to two lines. */
.proof-strip { background: var(--blue); padding: 18px var(--gutter); display: flex; flex-direction: column; gap: 10px; }
.proof-strip p { margin: 0; font-family: var(--disp); font-weight: 700; font-size: 15px; text-transform: uppercase; letter-spacing: 0.04em; }
.proof-strip p::before { content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 12px; vertical-align: 0.05em; background: var(--red); transform: skewX(-12deg); }
.proof-strip b { font-size: 1.3em; white-space: nowrap; }
@media (min-width: 1280px) {
  .proof-strip { flex-direction: row; justify-content: space-between; gap: 28px; }
  .proof-strip p { font-size: clamp(14px, 1.35vw, 19px); }
}
.review-grid { columns: 1; column-gap: 16px; }
@media (min-width: 700px) { .review-grid { columns: 2; } }
@media (min-width: 1100px) { .review-grid { columns: 3; column-gap: 20px; } }
.review-card { break-inside: avoid; margin: 0 0 16px; padding: 22px; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; display: flex; flex-direction: column; gap: 14px; }
.review-card blockquote { margin: 0; }
.review-card blockquote p { margin: 0; font-size: 16px; line-height: 1.55; overflow-wrap: anywhere; }
.review-card blockquote p::before { content: "\201C"; } .review-card blockquote p::after { content: "\201D"; }
.review-card figcaption { font-family: var(--label); font-size: 13px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sky); }

/* Recent registrations popup (site.js). Desktop only: phones have the sticky
   register bar in this corner. The card is light so it reads as a notice,
   not part of the page. */
.reg-proof { position: fixed; left: 24px; bottom: 24px; z-index: 55; max-width: min(400px, calc(100vw - 48px)); opacity: 0; transform: translateY(20px); pointer-events: none; transition: opacity .35s ease, transform .35s ease; }
.reg-proof.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.reg-proof-card { position: relative; display: flex; align-items: center; gap: 14px; padding: 12px 36px 12px 12px; border-radius: 10px; background: var(--text); color: var(--ink); box-shadow: 0 12px 30px rgba(0,0,0,0.45); }
.reg-proof-card img { flex: none; width: 64px; height: 64px; border-radius: 8px; object-fit: cover; }
.reg-proof-card div { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 13px; line-height: 1.35; }
.reg-proof-card strong { font-size: 16px; }
.reg-proof-what { color: var(--red-dark); font-size: 14px; }
.reg-proof-where { color: var(--panel); }
.reg-proof-close { position: absolute; top: 4px; right: 4px; width: 28px; height: 28px; border: 0; border-radius: 6px; background: none; color: var(--panel); font-size: 20px; line-height: 1; cursor: pointer; }
.reg-proof-close:hover, .reg-proof-close:focus-visible { background: rgba(11,27,51,0.08); }
@media (max-width: 899px) { .reg-proof { display: none; } }
@media (prefers-reduced-motion: reduce) { .reg-proof { transition: none; transform: none; } }

/* Same type everywhere. Buttons and inputs don't inherit the page font by
   default, so they get it here (class rules that set their own still win).
   The Cognito contact form sets its fonts to Arial through variables on the
   form and its dropdowns; this outranks that and points them at our faces. */
button, input, select, textarea { font-family: inherit; }
html .cog-cognito.cog-cognito--styled {
  --font-family: var(--body);
  --a__font-family: var(--body);
  --label__font-family: var(--body);
  --header__font-family: var(--disp);
  --heading__font-family: var(--disp);
  --button-primary__font-family: var(--body);
  --button-secondary__font-family: var(--body);
}

/* Page hero headings in the home hero's face: Swiss 721 Black Extended. It is
   much wider than the bold, so the size is set by the longest word on any
   hero, COOPERSTOWN (about 10.9em): 8vw keeps it inside the column at 320,
   and on desktop the 700px copy column holds it up to 62px. */
.ev-copy .h1 { font-family: var(--disp-ex); font-weight: 900; line-height: 1; letter-spacing: -0.012em; font-size: clamp(25px, 8vw, 56px); }
@media (min-width: 900px) { .ev-copy .h1 { font-size: clamp(30px, 4.4vw, 62px); } }

/* Become a Partner form on /partners. The contact form's card (Cognito draws
   inline, white panel, site fonts), held to a readable width and centred. */
.partner-embed { width: 100%; max-width: 820px; margin-inline: auto; }

/* Reviews: a quote's event name links to that event's page when it has one. */
.review-card figcaption a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.review-card figcaption a:hover, .review-card figcaption a:focus-visible { color: var(--text); }

/* Click-to-play video (site.js). A poster button the size of the video; the
   player replaces it on press, at the same shape so nothing jumps. */
.video-facade { position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; padding: 0; border: 0; border-radius: 14px; overflow: hidden; background: var(--panel-2); cursor: pointer; }
.video-facade img { display: block; width: 100%; height: 100%; object-fit: cover; }
.video-play { position: absolute; inset: 0; margin: auto; width: 76px; height: 76px; border-radius: 50%; display: grid; place-items: center; background: var(--red); box-shadow: 0 12px 30px rgba(0,0,0,0.45); transition: transform .2s ease; }
.video-facade:hover .video-play { transform: scale(1.08); }
.video-facade:focus-visible { outline: 3px solid #FFFFFF; outline-offset: 3px; }
.video-player { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 14px; background: #000000; }
@media (min-width: 900px) { .video-play { width: 96px; height: 96px; } }
@media (prefers-reduced-motion: reduce) { .video-play { transition: none; } }

/* Ripken FAQ: what happens after you register. Separate notes rather than
   a sequence, so they sit as a grid of panels, not a numbered list. */
.faq-steps { display: grid; gap: 14px; }
@media (min-width: 700px) { .faq-steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .faq-steps { grid-template-columns: repeat(3, 1fr); gap: 18px; } }
.faq-step { min-width: 0; padding: 20px 22px; background: rgba(11,27,51,0.88); border: 1px solid var(--line); border-top: 3px solid var(--red); border-radius: 10px; }
.faq-step h3 { margin: 0 0 6px; font-family: var(--disp); text-transform: uppercase; font-weight: 800; font-size: 17px; line-height: 1.2; }
.faq-step p { margin: 0; color: var(--muted); font-size: 15px; }

/* Stat strips with three numbers (Home, About, Partners) fill the row on
   desktop instead of leaving the fourth column empty. */
@media (min-width: 900px) { .stats.stats-three { grid-template-columns: repeat(3, 1fr); } }

/* Package cards side by side: above 1100 the five-column team mosaic was
   5:2 and the game-by-game one 2:1, so the titles under them sat at
   different heights. Every package mosaic is 2:1 there, so they line up. */
@media (min-width: 1100px) { .packages .mosaic { aspect-ratio: 2 / 1; } }

/* "Register my athlete" in the header. The label is longer than "Register",
   so it never wraps: up to 519px the wordmark and button text step down a
   size to make room, and below 375px the wordmark steps aside for it (the G
   mark stays, and the name stays readable to screen readers). */
.header-actions .btn-red { white-space: nowrap; }
@media (max-width: 519px) {
  .brand span { font-size: 14px; letter-spacing: 0.01em; }
  .header-actions .btn-red { padding: 0 8px; font-size: 11.5px; letter-spacing: 0; }
}
@media (max-width: 374px) {
  .brand span { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
}
/* Same label on the sticky phone bar: one line, a size smaller on narrow
   phones so the event name beside it keeps some room. */
.sticky-cta .btn { white-space: nowrap; }
@media (max-width: 419px) { .sticky-cta .btn { padding: 0 11px; font-size: 13px; } .sticky-cta div strong { font-size: 13px; } }

/* Cut-outs that stop at the waist (the FBU plates) end in a hard edge on
   phones, where the cut-out sits at the top of the hero over the photo
   rather than on its bottom edge. .fg-fade fades the lower part out so the
   player blends into the plate instead of floating. Desktop is unchanged:
   there the cut-out stands on the hero's bottom edge. */
@media (max-width: 899px) {
  .ev-hero-media.fg-fade .hero-fg {
    -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 92%);
    mask-image: linear-gradient(to bottom, #000 55%, transparent 92%);
  }
}

/* /photographers: the crew guide. Reuses the .faq-step panels; these add
   tick lists, the example photos and the partner logo row. */
.crew-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.crew-list li { position: relative; padding-left: 24px; color: var(--muted); font-size: 15px; }
.crew-list li::before { content: "\2713"; position: absolute; left: 0; top: 0; color: var(--sky); font-weight: 700; }
.crew-list.crew-no li::before { content: "\2715"; color: var(--red); }
.faq-steps.crew-stack { grid-template-columns: 1fr; }
@media (min-width: 700px) { .faq-steps.crew-two { grid-template-columns: repeat(2, 1fr); } }
.crew-figure { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.crew-figure img { display: block; width: 100%; height: auto; border-radius: 12px; }
/* Example photos show whole: never cropped, held to a readable height. */
.crew-photo { display: block; width: auto; max-width: 100%; height: auto; max-height: 680px; margin-inline: auto; border-radius: 12px; }
.crew-figure figcaption { color: var(--dim); font-size: 14px; }
.crew-formulas { display: grid; gap: 14px; grid-template-columns: 1fr; }
@media (min-width: 600px) { .crew-formulas { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .crew-formulas { grid-template-columns: repeat(4, 1fr); gap: 18px; } }
.crew-formula { margin: 0; min-width: 0; display: block; background: var(--panel); border: 1px solid var(--line); border-top: 3px solid var(--red); border-radius: 10px; overflow: hidden; }
.crew-formula img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; object-position: var(--pos, 50% 25%); }
.crew-formula figcaption { padding: 16px 18px 20px; }
.crew-formula h3 { margin: 0 0 6px; font-family: var(--disp); text-transform: uppercase; font-weight: 800; font-size: 17px; }
.crew-formula p { margin: 0; color: var(--muted); font-size: 15px; }
.crew-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.crew-pair img { display: block; width: 100%; height: auto; border-radius: 12px; }
.crew-logos { display: flex; flex-wrap: wrap; gap: 14px; }
.crew-logos img { display: block; width: 72px; height: 72px; border-radius: 14px; }
@media (min-width: 900px) { .crew-logos img { width: 88px; height: 88px; } }

/* Ripken plaque: one image per location, stacked in the image column and
   labeled with a pill like the mosaic game labels. */
.plaque-pair { display: grid; gap: 14px; }
.plaque-pair figure { position: relative; margin: 0; }
.plaque-pair img { display: block; width: 100%; height: auto; border-radius: 14px; }
.plaque-pair figcaption { position: absolute; top: 12px; left: 12px; padding: 4px 12px; border-radius: 999px; background: var(--ink); color: #FFFFFF; font-family: var(--label); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; font-size: 12px; }

/* Press articles (/press/<slug>/): a single reading column. The old posts'
   photos are small newspaper thumbnails, so they float beside the text. */
/* .wrap pads by --gutter, which grows past --maxw (560px a side at 2560), so
   the cap has to include it or the column is 0px wide. */
.press-article { max-width: calc(760px + 2 * var(--gutter)); margin-inline: auto; gap: 18px; }
.press-back { font-weight: 700; font-size: 15px; }
.press-article .h2 { overflow-wrap: anywhere; text-wrap: balance; }
.press-body { display: flex; flex-direction: column; gap: 14px; color: var(--muted); font-size: 17px; line-height: 1.65; }
.press-body p, .press-body blockquote, .press-body ul { margin: 0; }
.press-body strong, .press-body b { color: var(--text); }
.press-body img { float: right; max-width: 45%; height: auto; margin: 4px 0 12px 18px; border-radius: 8px; }
.press-body iframe { display: block; width: 100%; margin-top: 8px; border-radius: 8px; }
.press-body::after { content: ""; display: block; clear: both; }
.press-body blockquote { padding: 4px 0 4px 18px; border-left: 3px solid var(--red); color: var(--text); }
.press-body figure { align-self: flex-start; width: min(298px, 100%); margin: 4px 0; }
.press-body figure img { float: none; display: block; width: 100%; max-width: none; margin: 0; }
.press-body figcaption { margin-top: 6px; font-size: 13px; line-height: 1.4; }

/* Keeps a short phrase on one line, e.g. "on-site" in a heading. */
.nowrap { white-space: nowrap; }

/* "COOPERSTOWN" is 243px at 22px; the card leaves 240px below 360. */
@media (max-width: 359px) { .event-callout-title { font-size: 20px; } }

/* Below 360 the one-line button left the label 86px, four or five lines.
   Let the button take two lines instead. */
@media (max-width: 359px) {
  .sticky-cta .btn { white-space: normal; max-width: 112px; padding: 0 10px; line-height: 1.1; text-align: center; }
}

/* Embed bar labels need room between them when they share a narrow bar. */
.embed-bar { gap: 12px; }

/* Hero headlines sit on photos and cut-outs, some of them white uniforms. */
.ev-copy .h1 { text-shadow: 0 2px 4px rgba(11,27,51,0.55), 0 6px 26px rgba(11,27,51,0.7); }

/* About page partner tiles fill the row instead of leaving a gap. */
.logo-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
.logo-row .logo-tile { width: auto; margin-right: 0; }
@media (min-width: 900px) { .logo-row { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); } }
