/* Motion edition: scroll scenes, smooth scrolling and the season's balls.
   Anything here that starts hidden, zoomed or pinned is gated on .motion, which js.js sets only
   when the visitor has not asked for reduced motion (and removes again if motion.js never runs).
   motion.js writes the scrubbed values (transforms, opacity and a few custom properties). */

:root { --nav-h: 72px; }
@media (max-width: 60rem) { :root { --nav-h: 64px; } }

/* ---------- Smooth scrolling (Lenis) ---------- */
html.lenis, html.lenis body { height: auto; }
html.lenis { scroll-behavior: auto; }
.lenis:not(.lenis-autoToggle).lenis-stopped { overflow: clip; }
.lenis.lenis-smooth iframe { pointer-events: none; }
.lenis [data-lenis-prevent] { overscroll-behavior: contain; }
/* Jumps land just under the sticky masthead (Lenis reads this too). */
html { scroll-padding-top: var(--nav-h); }

/* ---------- The masthead stays; once the page moves it gets a printed rule ---------- */
.masthead { position: sticky; top: 0; z-index: var(--z-sticky-nav); transition: background-color var(--dur-long) var(--ease-out); }
.masthead__row { min-height: var(--nav-h); border-bottom: 0; }
.masthead.is-scrolled { background: var(--color-paper); }
.masthead__tickets, .cta, .sport-card__go { translate: var(--mx, 0) var(--my, 0); }
.masthead__tickets { transition: transform var(--dur-micro) var(--ease-out), background-color var(--dur-short) var(--ease-out), translate 320ms var(--ease-out); }
.cta { transition: transform var(--dur-micro) var(--ease-out), background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), translate 320ms var(--ease-out); }

/* The masthead's bottom edge is the progress line; a small ball rolls along it. */
.progress { position: absolute; inset: auto 0 0; z-index: auto; height: 1px; background: var(--color-rule); pointer-events: none; }
.progress > #progress-bar { position: absolute; inset: -0.5px 0 auto; height: 2px; background: var(--tone-sage-deep); }
.progress .progress__ball { position: absolute; left: 0; bottom: -8px; width: 17px; height: 17px; border-radius: var(--radius-pill); background: var(--progress-ball, var(--tone-clay-ink)) center / cover no-repeat; filter: drop-shadow(0 1px 1px oklch(20% 0.02 60 / 0.35)); transform: translate3d(0, 0, 0); will-change: transform; }

/* Sticky things sit under the masthead */
.desk__card { top: calc(var(--nav-h) + var(--space-md)); }
@media (min-width: 60.0625rem) { .card { max-height: calc(100dvh - var(--nav-h) - 2 * var(--space-md)); } }
.story__stage { top: calc(var(--nav-h) + var(--space-md)); height: calc(100svh - var(--nav-h) - 2 * var(--space-md)); }
@media (max-width: 60rem) { .story__stage { top: var(--nav-h); height: auto; } }

/* ---------- The equipment: studio renders. A round ball's base spins under fixed light ---------- */
.orb { --size: 80px; position: relative; display: grid; place-items: center; flex-shrink: 0; width: var(--size); aspect-ratio: 1; }
.orb__ball { position: relative; display: block; width: 100%; height: 100%; }
.orb__base { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; user-select: none; -webkit-user-drag: none; rotate: calc(var(--spin, 0deg) + var(--i, 0) * 40deg); }
/* Equipment that is not a ball does not roll; it only tips a little with the motion */
.orb__ball[data-shape="item"] .orb__base { rotate: calc(var(--spin, 0deg) * 0.03); }
/* Spinning balls get their own layer, so turning them is a GPU job rather than a repaint */
.motion :is(.hero__ball, .finale__orb) .orb__base { will-change: rotate; }
.orb__light { position: absolute; inset: 0; border-radius: 50%; background: var(--img-spec, none) center / 100% 100% no-repeat, var(--img-shade) center / 100% 100% no-repeat; pointer-events: none; }
.orb__ball[data-mat="satin"] { --img-spec: var(--img-spec-satin); }
.orb__ball[data-mat="matte"] { --img-spec: var(--img-spec-matte); }
.orb__ball[data-mat="gloss"] { --img-spec: var(--img-spec-gloss); }
.orb__ball[data-mat="soft"] { --img-spec: var(--img-spec-soft); }
/* A soft contact shadow under balls that rest on something */
.orb--grounded .orb__ball[data-shape="round"]::after { content: ""; position: absolute; z-index: -1; left: 10%; right: 10%; bottom: -9%; height: 16%; border-radius: 50%; background: radial-gradient(closest-side, oklch(20% 0.02 60 / 0.42), oklch(20% 0.02 60 / 0)); }

/* The hero ball is the same studio ball */
.hero__ball-body { background: none; }
.hero__ball-body .orb__ball { width: 100%; height: 100%; }
.hero__ball-body.is-swapping .orb__ball { animation: swap 560ms var(--ease-out) both; }
@keyframes swap { 0% { opacity: 0; scale: 0.6; } 60% { opacity: 1; scale: 1.08; } 100% { opacity: 1; scale: 1; } }

/* ---------- Hero: pinned on wide screens while the pitch zooms out and the ball rolls in ---------- */
.hero__sticky { position: relative; }
.hero__cue { display: none; }
@media (min-width: 60.0625rem) {
  .motion .hero { height: 230svh; padding-block: 0; }
  .motion .hero__sticky { position: sticky; top: var(--nav-h); display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; height: calc(100svh - var(--nav-h)); min-height: 600px; padding-block: var(--space-xl) var(--space-3xl); overflow: clip; }
  .motion .hero__field { transform: scale(2.3); opacity: 0.3; transform-origin: 50% 50%; will-change: transform, opacity; }
  .motion .hero__field .draw .ln { transition: none; stroke-dashoffset: calc(1 - var(--draw, 0)); }
  .motion .hero__field .draw .dot { transition: none; opacity: clamp(0, (var(--draw, 0) - 0.8) * 5, 1); }
  .motion .hero__field .draw .cell { transition: none; opacity: clamp(0, (var(--draw, 0) - 0.8) * 0.8, 0.16); }
  .motion .hero .scoreboard, .motion .hero .scoreboard__cell { opacity: 0; will-change: transform, opacity; }
  .motion .hero__ball { will-change: transform; }
  .motion .hero__cue { position: absolute; left: 50%; bottom: var(--space-lg); display: flex; align-items: center; gap: var(--space-sm); translate: -50% 0; color: var(--color-ink-2); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; }
  .hero__cue-ball { width: 12px; height: 12px; border-radius: var(--radius-pill); background: var(--tone-sage-deep); animation: cue 1.3s var(--ease-in-out) infinite; }
}
@keyframes cue { 0%, 100% { transform: translateY(0) scaleY(0.9); } 50% { transform: translateY(-9px) scaleY(1.05); } }

/* ---------- Statement: the season in one sentence, lit word by word ---------- */
.statement { position: relative; background: var(--color-paper); }
.statement__sticky { position: relative; overflow: clip; padding-block: var(--section-gap); }
.statement__inner { position: relative; z-index: 1; }
.statement__eyebrow { margin-bottom: var(--space-lg); color: var(--color-ink-2); font-size: var(--text-sm); font-weight: 600; }
.statement__text { max-width: 21ch; font-family: var(--font-display); font-size: clamp(2rem, 4.2vw + 0.6rem, 5.25rem); font-weight: 700; line-height: 1.02; letter-spacing: -0.035em; text-wrap: balance; }
.motion .statement { height: 230svh; }
.motion .statement__sticky { position: sticky; top: 0; display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; height: 100svh; padding-block: var(--nav-h) 0; }
.motion .statement__text .w { opacity: calc(0.14 + 0.86 * var(--a, 0)); }
.statement__floats { position: absolute; inset: 0; pointer-events: none; }
.statement__float { position: absolute; --size: clamp(48px, 6vw, 96px); will-change: transform; }
.statement__float:nth-child(1) { right: 6%; top: 12%; --size: clamp(64px, 9vw, 140px); }
.statement__float:nth-child(2) { right: 26%; top: 60%; --size: clamp(44px, 5vw, 80px); }
.statement__float:nth-child(3) { right: 30%; top: 16%; --size: clamp(36px, 4vw, 64px); }
.statement__float:nth-child(4) { right: 5%; bottom: 10%; --size: clamp(46px, 5.6vw, 92px); }
.statement__float:nth-child(5) { right: 18%; top: 38%; --size: clamp(32px, 3.6vw, 56px); }
.statement__float:nth-child(6) { right: 2%; top: 50%; --size: clamp(34px, 3.4vw, 56px); }
.statement__float:nth-child(7) { right: 37%; bottom: 7%; --size: clamp(40px, 4.4vw, 72px); }
.statement__float:nth-child(8) { right: 43%; top: 7%; --size: clamp(34px, 3.8vw, 60px); }
.statement__float:nth-child(9) { right: 44%; top: 42%; --size: clamp(36px, 3.8vw, 62px); }
/* a piece of equipment: its studio render, a little larger than a ball (it has room round it) */
.statement__float.kit img { display: block; width: calc(var(--size) * 1.75); height: auto; pointer-events: none; user-select: none; }
@media (max-width: 60rem) {
  .statement__float { opacity: 0.55; }
  .statement__float:nth-child(n + 5) { display: none; }
  .statement__float:nth-child(1) { right: 4%; top: 8%; }
  .statement__float:nth-child(2) { right: auto; left: 6%; top: auto; bottom: 6%; }
  .statement__float:nth-child(3) { right: 30%; top: 4%; }
  .statement__float:nth-child(4) { right: 8%; bottom: 3%; }
}

/* ---------- Line-up: one card per sport. Wide screens scroll it sideways, phones swipe ---------- */
.lineup { position: relative; padding-block: var(--section-gap-s); background: var(--color-paper-2); }
.lineup__head { margin-bottom: var(--space-xl); }
.lineup__view { min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none; }
.lineup__view::-webkit-scrollbar { display: none; }
.lineup__track { display: flex; gap: var(--space-lg); width: max-content; margin: 0; padding: var(--space-md) var(--gutter) var(--space-xl); list-style: none; }
.lineup__foot { display: none; }
.sport-card { position: relative; display: grid; grid-template-rows: auto 1fr auto auto auto; gap: var(--space-xs); width: clamp(260px, 24vw, 340px); min-height: clamp(380px, 34vw, 470px); padding: var(--space-xl); border-radius: var(--radius-card); background: color-mix(in oklab, var(--sp) 62%, var(--color-card)); scroll-snap-align: start; box-shadow: var(--shadow-card); }
.sport-card__orb { --size: clamp(120px, 11vw, 168px); margin-bottom: var(--space-lg); }
.sport-card__index { position: absolute; top: var(--space-lg); right: var(--space-lg); color: var(--sp-deep); font-size: var(--text-figure-s); line-height: 0.9; }
.sport-card__name { align-self: end; font-family: var(--font-display); font-size: clamp(1.75rem, 1.6vw + 1rem, 2.5rem); font-weight: 800; line-height: 0.95; letter-spacing: -0.035em; }
.sport-card__meta { color: var(--color-ink-2); font-size: var(--text-sm); }
.sport-card__price { color: var(--color-ink); font-weight: 600; }
.sport-card__when { color: var(--color-ink-2); font-size: var(--text-sm); }
.sport-card__go { justify-self: start; margin-top: var(--space-md); border-color: var(--sp-deep); background: var(--color-card); color: var(--color-ink); transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), translate 320ms var(--ease-out); }
@media (hover: hover) { .sport-card__go:hover { background: var(--sp-deep); color: var(--color-paper); } }
.sport-card__go:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

@media (min-width: 60.0625rem) {
  .motion .lineup { padding-block: 0; }
  .motion .lineup__sticky { position: sticky; top: 0; display: grid; grid-template-columns: minmax(0, 1fr); align-content: center; height: 100svh; padding-top: var(--nav-h); overflow: clip; }
  .motion .lineup__view { overflow: visible; scroll-snap-type: none; }
  .motion .lineup__track { padding-inline: max(var(--gutter), (100vw - var(--container)) / 2 + var(--gutter)); will-change: transform; }
  .motion .lineup__track { gap: var(--space-xl); }
  .motion .sport-card { translate: 0 calc(var(--d, 0) * var(--d, 0) * 60px); rotate: calc(var(--d, 0) * 2.5deg); scale: calc(1 - var(--d, 0) * var(--d, 0) * 0.06); }
  .motion .sport-card__orb { translate: calc(var(--d, 0) * -28px) 0; }
  .motion .lineup__foot { display: block; margin-top: var(--space-md); }
  .lineup__bar { display: block; height: 3px; overflow: hidden; border-radius: var(--radius-pill); background: var(--color-rule); }
  .lineup__bar > span { display: block; height: 100%; background: var(--color-ink); transform: scaleX(0); transform-origin: 0 50%; }
}

/* ---------- Story: cards come into focus while a ball plays a move on the court ---------- */
.play { opacity: 0; transition: opacity var(--dur-short) var(--ease-out); }
.play__trail { fill: none; stroke: currentColor; stroke-width: calc(1.4 * var(--sw, 1)); stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0.5; }
.play__shadow { fill: currentColor; opacity: 0.16; }
.play__ball { overflow: visible; }
@media (min-width: 60.0625rem) { .motion .story .step { will-change: opacity, transform; } }

/* ---------- Ribbon: driven by motion.js so it can speed up and lean with the scroll ---------- */
.motion .ribbon[data-loop].is-running .ribbon__track { animation: none; }
.motion .ribbon__track { will-change: transform; }

/* ---------- Reveals ---------- */
.rw { display: inline-block; overflow: clip; padding-bottom: 0.12em; margin-bottom: -0.12em; vertical-align: bottom; }
.rw__i { display: inline-block; }
.motion [data-reveal-words] .rw__i { translate: 0 110%; transition: translate 900ms var(--ease-out); transition-delay: calc(var(--i, 0) * 70ms); }
.motion [data-reveal-words].is-in .rw__i { translate: none; }

.motion .hub__list[data-reveal-group] > li { opacity: 0; }
.motion .hub__list.is-in > li { animation: drop 1000ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 80ms); }
@keyframes drop {
  0% { opacity: 0; transform: translateY(-80px); }
  40% { opacity: 1; transform: translateY(0) scale(1.06, 0.9); }
  58% { transform: translateY(-18px) scale(0.98, 1.03); }
  74% { transform: translateY(0) scale(1.02, 0.97); }
  86% { transform: translateY(-5px); }
  100% { opacity: 1; transform: none; }
}

.motion .schools__grid[data-reveal-group] > li { opacity: 0; translate: 0 28px; }
.motion .schools__grid.is-in > li { opacity: 1; translate: none; transition: opacity 600ms var(--ease-out), translate 800ms var(--ease-out), transform var(--dur-short) var(--ease-out); transition-delay: calc(var(--i, 0) * 70ms); }
.motion .schools__grid.is-in .school__crest { animation: pop 700ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 70ms + 180ms); }
@keyframes pop { 0% { transform: scale(0.4) rotate(-40deg); } 60% { transform: scale(1.12) rotate(6deg); } 100% { transform: none; } }


/* ---------- Finale: a ball rolls onto the centre spot, then the last call ---------- */
.finale { overflow: clip; padding-block: var(--section-gap); background: var(--color-paper); text-align: center; }
.finale__inner { display: grid; justify-items: center; gap: var(--space-lg); }
.finale__pitch { position: relative; width: min(100%, 760px); height: clamp(96px, 10vw, 140px); }
.finale__line { position: absolute; inset: auto 0 0; height: 2px; border-radius: var(--radius-pill); background: var(--color-ink); transform-origin: 0 50%; }
.finale__line::after { content: ""; position: absolute; left: 50%; bottom: -5px; width: 2px; height: 12px; translate: -50% 0; background: var(--color-ink); }
.finale__orb { --size: clamp(84px, 9vw, 128px); position: absolute; left: 50%; bottom: 2px; margin-left: calc(var(--size) / -2); will-change: transform; }
.finale h2 { max-width: 14ch; font-size: clamp(2.6rem, 6vw + 0.5rem, 6.5rem); font-weight: 800; line-height: 0.95; letter-spacing: -0.045em; }
.finale__text { max-width: 38ch; color: var(--color-ink-2); font-size: var(--text-lead); }
.motion .finale__line { transform: scaleX(0); }
.motion .finale__orb { transform: translateX(-55vw); }

/* ---------- Reduced motion and print: everything in its finished place ---------- */
@media (prefers-reduced-motion: reduce) {
  .progress .progress__ball { display: none; }
  .hero__ball-body.is-swapping .orb__ball { animation: none; }
}
@media print {
  .masthead { position: static; }
  .rw__i { translate: none !important; }
  .motion .hub__list > li, .motion .schools__grid > li { opacity: 1 !important; }
}
