/* ==========================================================================
   TK Sports Media — site styles
   The hero is one pinned screen of four quarter-tiles, two by two. Every
   section after it is a twelve-column grid of hard-edged tiles split by
   hairline rules. A grotesk for everything you read, a mono for labels, and
   three colours (white, charcoal, navy) plus one pale grey for quiet tiles.
   No rounded corners, no shadows.
   ========================================================================== */

:root {
  --white: #ffffff;
  --paper: #eef0f3;
  --char: #1d1f22;
  --navy: #0c1f4a;
  --navy-lit: #17337a;
  --rule: #d6d9de;
  --dim: #5d616a;

  --sans: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  --head: 64px;
  --stage: calc(100svh - var(--head));   /* one screen: the space under the header */
  --pad: clamp(16px, 1.6vw, 28px);
  --ease: cubic-bezier(0.2, 0.7, 0.1, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: var(--head); }

body {
  margin: 0;
  background: var(--white);
  color: var(--char);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
h1, h2, h3, p, blockquote, ol, ul { margin: 0; }
:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px; }

.mono {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.5;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  padding: 10px 14px;
  background: var(--navy);
  color: #fff;
}
.skip:focus { top: 12px; }

.arrow {
  width: 18px;
  height: 18px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: square;
  transform: translate(var(--mx, 0px), var(--my, 0px));
  transition: transform 0.35s var(--ease-out);
}

/* ---------- The hero's scene ----------
   The hero is a scene: as tall as the scrolling it takes (script sets
   --len, in screens). Its stage sticks under the header for all of that,
   then lets go and the page scrolls on. Its one screen is four quarters. */
.scene {
  position: relative;
  height: calc(var(--stage) * var(--len, 1));
}

.stage {
  position: sticky;
  top: var(--head);
  height: var(--stage);
  overflow: hidden;
  background: var(--rule);
  border-bottom: 1px solid var(--rule);
}

.track { will-change: transform; }

.screen {
  position: relative;
  height: var(--stage);
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 1px;
  background: var(--rule);
}

/* The sections after the hero: twelve columns. The rules between tiles are
   the grid's own background showing through one-pixel gaps, so every edge
   is exactly one hairline however the tiles are arranged. */
.grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border-bottom: 1px solid var(--rule);
}

.tile {
  position: relative;
  min-width: 0;
  min-height: 0;
  padding: var(--pad);
  background: var(--white);
  overflow: hidden;
}

.tile-paper { background: var(--paper); }
.tile-char  { background: var(--char); color: var(--white); }
.tile-navy  { background: var(--navy); color: var(--white); }
.tile-char .label, .tile-navy .label { color: rgba(255, 255, 255, 0.6); }

.label { color: var(--dim); }

.tile-cap {
  position: absolute;
  left: var(--pad);
  bottom: var(--pad);
  z-index: 1;
  padding: 3px 6px;
  background: var(--white);
  color: var(--char);
}

/* Halftone canvases fill their tile. */
.ht {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.tile-link {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

/* ---------- Type scale ---------- */
.h-giant {
  font-weight: 500;
  font-size: clamp(5rem, 14.5vw, 15rem);
  line-height: 0.8;
  letter-spacing: -0.065em;
}
.h-xl {
  font-weight: 400;
  font-size: clamp(2.2rem, 4.4vw, 4.4rem);
  line-height: 1;
  letter-spacing: -0.04em;
}
.lead {
  font-size: clamp(1.05rem, 1.35vw, 1.35rem);
  line-height: 1.42;
  letter-spacing: -0.012em;
  max-width: 34em;
}

/* ---------- Header ---------- */
.head {
  position: sticky;
  top: 0;
  z-index: 50;
  display: grid;
  grid-template-columns: var(--head) auto 1fr auto;
  align-items: stretch;
  height: var(--head);
  background: var(--white);
  border-bottom: 1px solid var(--rule);
}

.head-mark { display: grid; place-items: center; background: var(--navy); transition: background 0.3s var(--ease); }
.head-mark:hover { background: var(--navy-lit); }
.head-mark img { width: 28px; height: 28px; }

.head-tag { align-self: center; padding: 0 var(--pad); color: var(--char); }
.head-tag span { color: var(--dim); padding: 0 4px; }

.head-nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(16px, 2.2vw, 34px);
  padding: 0 clamp(18px, 2.4vw, 36px);
  font-size: 15px;
  letter-spacing: -0.01em;
}
.head-nav a { position: relative; padding: 4px 0; }
.head-nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.4s var(--ease-out);
}
.head-nav a:hover::after,
.head-nav a.is-here::after { transform: scaleX(1); transform-origin: left; }

.head-cta {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 clamp(18px, 2vw, 30px);
  background: var(--navy);
  color: var(--white);
  font-size: 15px;
  letter-spacing: -0.01em;
  transition: background 0.3s var(--ease);
}
.head-cta:hover { background: var(--navy-lit); }

/* ---------- Hero ----------
   One halftone picture behind the whole screen (the canvas), with the TK
   mark carved out of its dots and turning. The two open quarters show it;
   the wordmark tile and the split quarter are solid, laid over it. */
.hero-screen { background: var(--white); }
.hero-screen > .q { z-index: 1; }

/* An open quarter: no fill of its own, just its edge. */
.q-open {
  position: relative;
  min-height: 0;
  box-shadow: inset 0 0 0 0.5px var(--rule);
}
.q-open .tile-cap { left: var(--pad); bottom: var(--pad); }
.q-open > .ht { z-index: 0; }

.hero-word { display: flex; flex-direction: column; justify-content: space-between; perspective: 1100px; }
.hero-wordmark {
  font-weight: 500;
  font-size: min(9.4vw, 20svh);
  line-height: 0.78;
  letter-spacing: -0.065em;
  margin: 0 0 -0.06em -0.04em;
  white-space: nowrap;
}

/* The plain hero tiles pick up a faint trail too, under their words. */
.hero-word, .hero-say { isolation: isolate; }
.hero-word > .ht, .hero-say > .ht { z-index: -1; opacity: 0.75; }

/* Each letter moves on its own as the wordmark lifts away (site.js). */
.wm-ch { display: inline-block; will-change: transform; }

.hero-say { display: flex; flex-direction: column; justify-content: space-between; gap: 22px; }
.hero-statement {
  max-width: 17em;
  font-size: clamp(1.3rem, 2.3vw, 2.4rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}
.hero-say .tile-link { color: var(--white); }

/* The TK mark in the corner, one turn every ten seconds: it lingers
   while it faces you (and again when it faces away), then whips through
   the edge-on moments. Each quarter turn eases in towards edge-on and
   out of it; the two curves meet at the same speed, so it never jolts. */
.hero-mark {
  position: absolute;
  right: var(--pad);
  bottom: var(--pad);
  width: clamp(54px, 5.6vw, 92px);
  color: #dcdee1;
}
.hero-mark svg { display: block; width: 100%; height: auto; animation: mark-turn 10s infinite; }
@keyframes mark-turn {
  0%   { transform: rotateY(0deg);   animation-timing-function: cubic-bezier(0.5, 0, 0.75, 0); }
  25%  { transform: rotateY(90deg);  animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1); }
  50%  { transform: rotateY(180deg); animation-timing-function: cubic-bezier(0.5, 0, 0.75, 0); }
  75%  { transform: rotateY(270deg); animation-timing-function: cubic-bezier(0.25, 1, 0.5, 1); }
  100% { transform: rotateY(360deg); }
}

/* The hero's arrivals wait for the opening to lift. */
.hero [data-reveal] { --boot: 1.15s; }

/* ---------- The opening ----------
   The TK mark turns once on a charcoal screen, then the screen lifts away.
   CSS only; out of the way after a second and a half. */
.loader {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: grid;
  place-items: center;
  background: var(--char);
  color: var(--white);
  perspective: 900px;
  pointer-events: none;
  animation: loader-lift 0.75s cubic-bezier(0.7, 0, 0.2, 1) 1.1s forwards;
}
.loader svg {
  width: clamp(90px, 11vw, 150px);
  height: auto;
  animation: loader-spin 1.1s cubic-bezier(0.45, 0, 0.2, 1) both;
}
/* One full turn that lands facing forward, so the TK reads the right way
   round as the screen lifts. */
@keyframes loader-spin {
  from { transform: rotateY(-360deg) scale(0.85); opacity: 0; }
  30%  { opacity: 1; }
  to   { transform: rotateY(0deg) scale(1); opacity: 1; }
}
@keyframes loader-lift {
  to { transform: translateY(-100%); visibility: hidden; }
}

/* ---------- Ticker ---------- */
.ticker {
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
  font-size: 12.5px;
  white-space: nowrap;
}
.ticker-track { display: inline-flex; animation: ticker 36s linear infinite; }
.ticker-track span { padding: 15px 0; }
.ticker-track span::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin: 0 30px 1px;
  background: var(--navy);
}
@keyframes ticker { to { transform: translateX(-50%); } }

/* ---------- Numbers ----------
   Three lanes, mostly white space. In each, a stat tile sits some way
   down (--at, in screens) inside a hold (--len screens tall). As you
   scroll it catches under the header and stays there until the bottom of
   its hold pushes it on, so the tiles stack up one by one and then get
   shoved out, a lane at a time. */
.drop {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border-bottom: 1px solid var(--rule);
}
.lane {
  position: relative;
  background: var(--white);
  padding-top: calc(var(--stage) * var(--at));
}
.lane-a { grid-column: 1 / 7; }
.lane-b { grid-column: 7 / 10; }
.lane-c { grid-column: 10 / 13; }
.hold { height: calc(var(--stage) * var(--len)); }
.hold > .tile {
  position: sticky;
  top: var(--head);
  height: calc(var(--stage) * var(--h));
}

/* The heading and the picture sit at the tops of their lanes and scroll
   away normally. */
.numbers-head {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: calc(var(--stage) * 0.62);
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.numbers-art {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: calc(var(--stage) * 0.8);
  overflow: hidden;
}

.stat {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
}
.stat-num {
  font-size: clamp(5rem, 11vw, 11.5rem);
  font-weight: 400;
  line-height: 0.85;
  letter-spacing: -0.06em;
  font-variant-numeric: tabular-nums;
}
.lane-a .stat-num { font-size: clamp(6rem, 15vw, 15rem); }
.stat-cap { font-size: clamp(1rem, 1.3vw, 1.3rem); letter-spacing: -0.01em; }
.lane-a .stat-cap { align-self: flex-end; }

/* Behind each stat, a faint dotted match photo that parts for the
   pointer; over it, a thin line drawing that keeps moving. The words sit
   on top of both. */
.stat > p { position: relative; z-index: 1; }
.stat .ht { opacity: 0.22; }
.stat-art {
  position: absolute;
  right: var(--pad);
  bottom: var(--pad);
  z-index: 1;
  width: clamp(92px, 9vw, 150px);
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  overflow: visible;
  pointer-events: none;
}
.stat-art * { vector-effect: non-scaling-stroke; transform-box: view-box; transform-origin: 50% 50%; }
.lane-a .stat-art { top: 50%; bottom: auto; right: calc(var(--pad) * 2); width: clamp(150px, 15vw, 250px); transform: translateY(-50%); }

/* 100+: a stack of posters, the front one dealt off and sent to the back. */
.art-cards .card {
  animation: deal 8s var(--ease) infinite;
  animation-delay: calc(var(--k) * -2s);
}
@keyframes deal {
  0%, 20%  { transform: translate(0, 0); opacity: 1; }
  25%      { transform: translate(-26px, 18px) rotate(-8deg); opacity: 0; }
  25.01%   { transform: translate(24px, -24px); opacity: 0; }
  30%, 45% { transform: translate(24px, -24px); opacity: 0.3; }
  50%, 70% { transform: translate(16px, -16px); opacity: 0.5; }
  75%, 95% { transform: translate(8px, -8px); opacity: 0.75; }
  100%     { transform: translate(0, 0); opacity: 1; }
}

/* 40+: forty dots round a ring, a wave of them lighting up in turn. */
.art-ring .spin { animation: spin 24s linear infinite; }
.art-ring .d {
  fill: currentColor;
  stroke: none;
  transform-box: fill-box;
  transform-origin: center;
  animation: roll-call 3s ease-in-out infinite;
  animation-delay: calc(var(--k) * 0.075s);
}
@keyframes roll-call {
  0%, 30%, 100% { transform: scale(1); opacity: 0.35; }
  12%           { transform: scale(2.1); opacity: 1; }
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Years: a ring for each season, each with its own dot going round. */
.art-orbit .core { fill: currentColor; stroke: none; }
.art-orbit .orb > circle:first-child { opacity: 0.45; }
.art-orbit .sat { fill: currentColor; stroke: none; }
.art-orbit .orb { animation: spin calc(5s + var(--k) * 3s) linear infinite; }
.art-orbit .orb:nth-child(odd) { animation-direction: reverse; }

/* ---------- Services ----------
   The statement on the left sticks under the header for the whole
   section; the six services scroll up past it on the right. */
.services {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule);
  border-bottom: 1px solid var(--rule);
}
.services-pin {
  grid-column: 1 / 7;
  position: sticky;
  top: var(--head);
  height: var(--stage);
  padding: var(--pad);
  display: flex;
  flex-direction: column;
}
.services-say {
  display: flex;
  flex-direction: column;
  margin-top: 10px;
  font-weight: 500;
  font-size: clamp(3.2rem, 7.6vw, 8.4rem);
  line-height: 0.86;
  letter-spacing: -0.055em;
  text-transform: uppercase;
}
.services-say .r { align-self: flex-end; }
.services-foot {
  margin-top: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--pad);
  align-items: end;
}
.services-foot .lead { grid-column: 2; font-size: clamp(1rem, 1.25vw, 1.25rem); }
.services-foot .btn { grid-column: 2; justify-self: start; }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 40px;
  padding: 16px 20px;
  background: var(--navy);
  color: var(--white);
  font-size: 12.5px;
  transition: background 0.3s var(--ease);
}
.btn:hover { background: var(--navy-lit); }

.svc-list {
  grid-column: 7 / 13;
  list-style: none;
  padding: 0;
  background: var(--white);
  color: var(--char);
}

.svc {
  display: grid;
  grid-template-columns: 3.2em minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  column-gap: var(--pad);
  row-gap: 32px;
  min-height: calc(var(--stage) * 0.82);
  padding: calc(var(--pad) * 2) var(--pad);
  border-top: 1px solid var(--rule);
  transition: background 0.45s var(--ease);
}
.svc:first-child { border-top: 0; }
/* A faint dotted match photo behind each service, as in the stats. */
.svc { position: relative; overflow: hidden; }
.svc > :not(.ht) { position: relative; z-index: 1; }
.svc > .ht { opacity: 0.16; transition: opacity 0.45s var(--ease); }
.svc:hover > .ht { opacity: 0.26; }
.svc:hover { background: var(--paper); }
/* Rows alternate white and navy down the column; the navy ones turn
   their words, icon and dots white. */
.svc:nth-child(even) { background: var(--navy); color: var(--white); border-top-color: var(--navy); }
.svc:nth-child(even):hover { background: #12295e; }
.svc:nth-child(even) + .svc { border-top-color: var(--navy); }

.svc-no { grid-column: 1; grid-row: 1; padding-top: 0.55em; color: var(--dim); }
.svc:nth-child(even) .svc-no { color: rgba(255, 255, 255, 0.5); }

.svc-name {
  grid-column: 2;
  grid-row: 1;
  font-weight: 400;
  font-size: clamp(1.8rem, 3vw, 3.2rem);
  line-height: 1.02;
  letter-spacing: -0.04em;
  transition: transform 0.6s var(--ease-out);
}
.svc:hover .svc-name { transform: translateX(10px); }

.svc-copy {
  grid-column: 3;
  grid-row: 1;
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.45;
  color: #3c4048;
}
.svc:nth-child(even) .svc-copy { color: rgba(255, 255, 255, 0.86); }

/* Small examples; each opens full size. */
.svc-shots {
  grid-column: 2 / 4;
  grid-row: 2;
  align-self: center;
  display: flex;
  gap: 12px;
}
.shot {
  width: clamp(74px, 6.6vw, 108px);
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--paper);
  cursor: zoom-in;
  transition: transform 0.6s var(--ease-out), opacity 0.4s var(--ease);
}
.shot img { width: 100%; height: 100%; object-fit: cover; }
.svc-shots:hover .shot { opacity: 0.45; }
.svc-shots .shot:hover { opacity: 1; transform: translateY(-6px); }

.svc-tags {
  grid-column: 3;
  grid-row: 3;
  align-self: end;
  list-style: none;
  padding: 0;
  display: grid;
  gap: 8px;
  font-size: 12.5px;
}
.svc-tags li { display: flex; align-items: center; gap: 12px; }
.svc-tags li::before { content: ''; width: 8px; height: 8px; background: var(--navy); flex: none; }
.svc:nth-child(even) .svc-tags li::before { background: #5b82ff; }

.svc-icon {
  grid-column: 2;
  grid-row: 3;
  align-self: end;
  width: clamp(76px, 7vw, 110px);
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  overflow: visible;
}
.svc-icon * { vector-effect: non-scaling-stroke; transform-box: fill-box; transform-origin: center; }

/* Each icon has its own movement, parked until the row is hovered. */
.svc-icon .m, .svc-icon .c, .svc-icon .l, .svc-icon .r, .svc-icon .ring,
.svc-icon .b, .svc-icon .n { animation-play-state: paused; }
.svc:hover .svc-icon * { animation-play-state: running; }

.icon-globe .m { animation: meridian 3.6s linear infinite; }
.icon-globe .m2 { animation-delay: -0.9s; }
.icon-globe .m3 { animation-delay: -1.8s; }
.icon-globe .m4 { animation-delay: -2.7s; }
@keyframes meridian {
  0%   { transform: scaleX(1); }
  25%  { transform: scaleX(0); }
  50%  { transform: scaleX(-1); }
  75%  { transform: scaleX(0); }
  100% { transform: scaleX(1); }
}
.icon-grid .c { animation: cell 2.4s var(--ease) infinite; }
.icon-grid .c2, .icon-grid .c4 { animation-delay: 0.15s; }
.icon-grid .c3, .icon-grid .c5, .icon-grid .c7 { animation-delay: 0.3s; }
.icon-grid .c6, .icon-grid .c8 { animation-delay: 0.45s; }
.icon-grid .c9 { animation-delay: 0.6s; }
@keyframes cell { 0%, 60%, 100% { transform: scale(1); } 30% { transform: scale(0.35); } }
.icon-pair .l { animation: pair-l 2.2s var(--ease) infinite alternate; }
.icon-pair .r { animation: pair-r 2.2s var(--ease) infinite alternate; }
@keyframes pair-l { to { transform: translateX(12px); } }
@keyframes pair-r { to { transform: translateX(-12px); } }
.icon-rings .ring { animation: ring 2.4s var(--ease) infinite; }
.icon-rings .r2 { animation-delay: 0.2s; }
.icon-rings .r3 { animation-delay: 0.4s; }
.icon-rings .dotc { fill: currentColor; stroke: none; }
@keyframes ring { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(0.55); opacity: 0.4; } }
.icon-lines .b { transform-origin: left center; animation: bar 2.6s var(--ease) infinite; }
.icon-lines .b2 { animation-delay: 0.12s; }
.icon-lines .b3 { animation-delay: 0.24s; }
.icon-lines .b4 { animation-delay: 0.36s; }
.icon-lines .b5 { animation-delay: 0.48s; }
@keyframes bar { 0%, 100% { transform: scaleX(1); } 45% { transform: scaleX(0.3); } }
.icon-nest .n { animation: nest 3s var(--ease) infinite; }
.icon-nest .n2 { animation-delay: 0.15s; }
.icon-nest .n3 { animation-delay: 0.3s; }
@keyframes nest { 0%, 20% { transform: rotate(0); } 60%, 100% { transform: rotate(90deg); } }

/* ---------- Work ---------- */
.work-head {
  grid-column: 1 / 9;
  min-height: 42vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.work-head .h-giant { margin-bottom: -0.1em; }
.work-intro {
  grid-column: 9 / 13;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 18px;
}
.work-count { color: var(--dim); }

.work-pair { align-items: start; }
.work-list {
  grid-column: 1 / 8;
  align-self: stretch;
  list-style: none;
  padding: 0;
}
/* Tall rows, so the list takes a while to pass the pinned preview. */
.work-row {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  width: 100%;
  min-height: calc(var(--stage) * 0.2);
  padding: 17px var(--pad);
  border-bottom: 1px solid var(--rule);
  text-align: left;
  transition: background 0.35s var(--ease), color 0.35s var(--ease);
}
.work-list li:last-child .work-row { border-bottom: 0; }
.work-row .t {
  font-size: clamp(1.4rem, 2.4vw, 2.5rem);
  letter-spacing: -0.025em;
  line-height: 1.2;
  transition: transform 0.5s var(--ease-out);
}
.work-row .mono { color: var(--dim); transition: color 0.35s var(--ease); }
.work-row:hover .t, .work-row.is-on .t { transform: translateX(10px); }
.work-row.is-on .n::before { content: "■ "; }

/* The picked row: a live dotted picture in the site's blue (site.js),
   strong at the left and thinning out to the right, shimmering and
   answering the pointer like the others. It blinks in behind the row and
   out again when you move on, a very quick fade. */
.work-row { position: relative; isolation: isolate; }
.work-row > .ht {
  z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s linear;
}
.work-row.is-on > .ht { opacity: 0.2; }
/* The number sits on a small white pill so it reads over the dots. */
.work-row .n {
  justify-self: start;
  padding: 3px 8px;
  margin-left: -8px;
  border-radius: 999px;
  background: transparent;
  transition: color 0.35s var(--ease), background 0.12s linear;
}
.work-row.is-on .n { background: var(--white); }
.work-row.is-on .n { color: var(--navy); }

.work-preview {
  grid-column: 8 / 13;
  position: sticky;
  top: var(--head);
  height: var(--stage);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(28px, 3.5vw, 56px);
}
.work-frame {
  position: relative;
  height: min(100%, 72vh);
  max-width: 100%;
  aspect-ratio: 4 / 5;
}
.work-frame img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.03);
  transition: opacity 0.5s var(--ease), transform 0.9s var(--ease-out);
}
.work-frame img.is-on { opacity: 1; transform: none; }
/* White, over a faint dotted match photo; the graphic sits on top. */
.work-frame { z-index: 1; }
.work-preview > .ht { opacity: 0.2; }

/* ---------- Athletes ----------
   Built like the numbers. The poster pins on the left for the whole
   section. On the right the copy scrolls away, then 1, 2 and 3 drop down three lanes, catch under
   the header like the stats (a step taller each), tick themselves off on
   the poster, and get pushed out in turn before the button. */
.athletes { grid-template-rows: auto auto auto; }
.ath-pin { grid-column: 1 / 7; grid-row: 1 / 5; background: var(--white); }
.athletes-art {
  position: sticky;
  top: var(--head);
  height: var(--stage);
  padding: 0;
}

/* The checklist in the poster's corner: each point lights up as it lands. */
.ath-spec {
  position: absolute;
  top: var(--pad);
  right: var(--pad);
  z-index: 3;
  margin: 0;
  padding: 10px 12px;
  list-style: none;
  background: var(--white);
  color: var(--dim);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.9;
}
.ath-spec li::after {
  content: "";
  display: inline-block;
  width: 7px; height: 7px;
  margin-left: 14px;
  vertical-align: 1px;
  border: 1px solid currentColor;
  transition: background 0.25s var(--ease), border-color 0.25s var(--ease);
}
.ath-spec li { display: flex; justify-content: space-between; align-items: center; transition: color 0.25s var(--ease); }
.ath-spec li.is-on { color: var(--navy); }
.ath-spec li.is-on::after { background: #1f5bff; border-color: #1f5bff; }

/* The heading locks under the header too (its height, measured by the
   script, is --copy), and the cards catch just beneath it instead of
   under the header, so heading, poster and all three cards share one
   screen. The cards are sized to fill what's left of it, a step taller
   each, with C reaching the bottom. */
.athletes { --copy: 42svh; grid-template-rows: var(--copy) auto var(--stage) calc(var(--stage) * 0.7); }
/* The heading's wrapper runs down to where the button starts, so once
   the button reaches it, the heading goes up with it. */
.ath-head {
  grid-column: 7 / 13;
  grid-row: 1 / 3;
  position: relative;
  z-index: 2;
  pointer-events: none;
}
.athletes-copy {
  pointer-events: auto;
  position: sticky;
  top: var(--head);
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 22px;
  box-shadow: 0 1px 0 var(--rule);
}
.athletes-copy .label { margin-bottom: 14px; }

.ath-lane { grid-row: 2; }
.ath-a { grid-column: 7 / 9; }
.ath-b { grid-column: 9 / 11; }
.ath-c { grid-column: 11 / 13; }
.ath-lane .hold > .tile {
  top: calc(var(--head) + var(--copy));
  height: calc((var(--stage) - var(--copy)) * var(--h));
}

.point {
  display: flex;
  flex-direction: column;
  gap: 10px;
  isolation: isolate;
}
.point > .ht { z-index: -1; opacity: 0.3; }
.ath-lane .point { transform-origin: 50% 0; will-change: transform; }
.point-no {
  font-size: clamp(4rem, 7vw, 7.5rem);
  line-height: 0.8;
  letter-spacing: -0.06em;
  margin-bottom: auto;
}
.point h3 { font-size: 1.15rem; font-weight: 500; letter-spacing: -0.02em; line-height: 1.2; }
.point p { font-size: 14.5px; color: var(--dim); line-height: 1.5; }
.point.tile-navy p, .point.tile-char p { color: rgba(255, 255, 255, 0.72); }

/* The button comes up as a full-height navy panel. It meets the heading,
   shoves it off the top, then locks in beside the poster for a while as
   its own section before the page moves on. */
.athletes-cta {
  grid-column: 7 / 13;
  grid-row: 3 / 5;
  align-self: start;
  position: sticky;
  top: var(--head);
  height: var(--stage);
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto;
  align-content: end;
  gap: 14px 20px;
  transition: background 0.3s var(--ease);
}
.athletes-cta:hover { background: var(--navy-lit); }
.athletes-cta .mono { grid-column: 1; color: rgba(255, 255, 255, 0.65); }
.athletes-cta .cta-big {
  grid-column: 1;
  font-size: clamp(2.6rem, 5vw, 5.6rem);
  letter-spacing: -0.035em;
  line-height: 1.05;
}
.athletes-cta .arrow { grid-column: 2; grid-row: 1 / 3; align-self: end; width: clamp(34px, 3.4vw, 56px); height: clamp(34px, 3.4vw, 56px); }

/* ---------- Pricing ---------- */
.pricing-head { grid-column: 1 / 13; min-height: 34vh; display: flex; flex-direction: column; justify-content: space-between; gap: 36px; }

.tier {
  grid-column: span 3;
  min-height: 58vh;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.tier-name em {
  display: block;
  margin-top: 6px;
  font-style: normal;
  opacity: 0.65;
}
.tier-price {
  margin-top: auto;
  font-size: clamp(3rem, 5.2vw, 5rem);
  font-weight: 400;
  letter-spacing: -0.055em;
  line-height: 0.9;
}
.tier-price span {
  margin-left: 6px;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.65;
}
.tier-note { opacity: 0.72; font-size: 15px; }
.tier ul {
  list-style: none;
  padding: 0;
  font-size: 14.5px;
  border-top: 1px solid rgba(128, 132, 140, 0.35);
}
.tier li { position: relative; padding: 9px 0; }
.tier li::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: rgba(128, 132, 140, 0.35);
  transform-origin: 0 50%;
}
.tier-price b { font-weight: inherit; font-variant-numeric: tabular-nums; }
.tier { isolation: isolate; }
.tier > .ht { z-index: -1; opacity: 0.8; }

/* The boxes grow up from the bottom one after another, like the bars of
   a chart, then the rows of each list draw in, a line at a time. The
   prices count up as they come into view. The script sets is-in on all
   four once their row reaches the screen (a box clipped to nothing never
   counts as on screen itself). */
.js .tier:not(.is-in) { clip-path: inset(100% 0 0 0); }
.js .tier.is-in {
  animation: tier-rise 1.1s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 130ms);
}
@keyframes tier-rise {
  from { clip-path: inset(100% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
.js .tier li { opacity: 0; }
.js .tier.is-in li {
  animation: tier-row 0.6s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 130ms + 550ms + var(--r, 0) * 90ms);
}
.js .tier.is-in li::after {
  animation: tier-line 0.8s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 130ms + 500ms + var(--r, 0) * 90ms);
}
.tier li:nth-child(2) { --r: 1; }
.tier li:nth-child(3) { --r: 2; }
.tier li:nth-child(4) { --r: 3; }
@keyframes tier-row {
  from { opacity: 0; translate: -10px 0; }
  to   { opacity: 1; translate: 0 0; }
}
@keyframes tier-line {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* A small pulsing square beside "Most clubs start here". */
.tier-pulse {
  display: inline-block;
  width: 7px; height: 7px;
  margin-right: 8px;
  vertical-align: 1px;
  background: #5b82ff;
  animation: tier-pulse 1.8s var(--ease) infinite;
}
@keyframes tier-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}
.tier .tile-link { margin-top: 8px; }

.pricing-foot {
  padding: 18px var(--pad);
  border-bottom: 1px solid var(--rule);
  color: var(--dim);
  text-transform: none;
  letter-spacing: 0;
  font-size: 12.5px;
}

/* ---------- Kind words ---------- */
.words-art {
  grid-column: 1 / 5;
  min-height: 72vh;
  padding: 0;
  /* The studio backdrop's own grey, a touch lighter to the right as it is
     in the photo, so the space above the photo reads as more backdrop. */
  background: linear-gradient(90deg, rgb(177, 177, 177), rgb(186, 186, 186));
}
/* The photo in grayscale, set a little lower than the tile's top so there's
   room above the head, its top edge feathered into the backdrop grey. */
.words-photo {
  position: absolute;
  left: 0;
  right: 0;
  top: 7%;
  width: 100%;
  height: 93%;
  object-fit: cover;
  object-position: 50% 0%;
  filter: grayscale(1);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 7%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 7%);
}
.words-quote {
  grid-column: 5 / 13;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
}
.quote {
  font-size: clamp(2rem, 3.6vw, 3.6rem);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.04em;
  max-width: 17em;
  text-indent: -0.42em;
}
.words-quote blockquote footer { margin-top: 26px; color: var(--dim); }
.words-count { align-self: flex-end; color: var(--dim); }
/* On charcoal, over a faint dotted match photo like the services. */
.words-quote > :not(.ht) { position: relative; z-index: 1; }
.words-quote > .ht { opacity: 0.2; }
.words-quote.tile-char blockquote footer,
.words-quote.tile-char .words-count { color: rgba(255, 255, 255, 0.6); }

/* ---------- Contact ---------- */
.contact-hero {
  position: relative;
  min-height: 72vh;
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
  border-bottom: 1px solid var(--rule);
}
.contact-hero .label, .contact-hero .h-giant { position: relative; z-index: 1; }
.contact-hero .h-giant { font-size: clamp(4.2rem, 11vw, 11.5rem); line-height: 0.84; }
.ht-back { opacity: 0.22; }

.contact-info {
  grid-column: 1 / 5;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 40px;
}
.contact-line a { border-bottom: 1px solid currentColor; }

.contact-form {
  grid-column: 5 / 13;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px var(--pad);
  padding-top: calc(var(--pad) * 1.6);
  padding-bottom: calc(var(--pad) * 1.6);
}
.field { display: flex; flex-direction: column; gap: 8px; }
.field-wide { grid-column: 1 / -1; }
.field .mono { color: var(--dim); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 10px 0;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  background: transparent;
  color: var(--char);
  font: inherit;
  font-size: 18px;
  letter-spacing: -0.015em;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.3s var(--ease);
}
.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--char) 50%), linear-gradient(135deg, var(--char) 50%, transparent 50%);
  background-position: calc(100% - 12px) 55%, calc(100% - 7px) 55%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
}
.field textarea { resize: vertical; min-height: 120px; line-height: 1.45; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-bottom-color: var(--navy); }

.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-foot { grid-column: 1 / -1; display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.send {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  padding: 18px 26px;
  background: var(--navy);
  color: var(--white);
  font-size: 16px;
  letter-spacing: -0.01em;
  transition: background 0.3s var(--ease);
}
.send:hover { background: var(--navy-lit); }
.form-status { color: var(--dim); text-transform: none; letter-spacing: 0; font-size: 13px; }

/* ---------- Footer ---------- */
.foot-word { grid-column: 1 / 7; background: var(--navy); color: var(--white); min-height: 40vh; display: flex; align-items: flex-end; }
.foot-big {
  font-size: clamp(3rem, 7vw, 7rem);
  font-weight: 500;
  line-height: 0.86;
  letter-spacing: -0.06em;
}
.foot-links {
  grid-column: 7 / 10;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 18px;
  letter-spacing: -0.02em;
}
.foot-links a { width: max-content; }
.foot-links a:hover { color: var(--navy-lit); }
.foot-meta {
  grid-column: 10 / 13;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
}
.foot-legal { padding: 18px var(--pad); color: var(--dim); }

/* ---------- Zoom ----------
   A picture lifted out of the page. site.js flies the figure in from the
   thumbnail and raises the charcoal shutter behind it. */
.zoom {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: none;
  color: var(--white);
  cursor: zoom-out;
}
.zoom.is-open { display: block; }
.zoom-bg { position: absolute; inset: 0; background: var(--char); }
.zoom-fig {
  position: fixed;
  margin: 0;
  transform-origin: 0 0;
  will-change: transform;
}
.zoom-img { width: 100%; height: 100%; object-fit: cover; }
.zoom-cap {
  position: absolute;
  left: var(--pad);
  bottom: var(--pad);
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 22em;
  font-size: clamp(1.1rem, 1.5vw, 1.5rem);
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.zoom-cat { color: rgba(255, 255, 255, 0.55); }
.zoom-close {
  position: absolute;
  top: var(--pad);
  right: var(--pad);
  display: flex;
  gap: 10px;
  color: var(--white);
}

/* ---------- Arrivals ----------
   The tile itself stays put, so its colour and the rules around it are
   there from the start; what arrives is its content, rising into place.
   It runs as an animation on the separate translate property, so it never
   fights the hover and pointer movement that the same elements do with
   transform. Hidden only once script is running, so nothing is lost
   without it. */
.js [data-reveal]:not(.is-in) > :not(.ht) { opacity: 0; }
.js [data-reveal].is-in > :not(.ht) {
  animation: arrive 1s var(--ease-out) both;
  animation-delay: calc(var(--boot, 0s) + var(--i, 0) * 80ms + var(--c, 0) * 70ms);
}
.js [data-reveal] > :nth-child(2) { --c: 1; }
.js [data-reveal] > :nth-child(3) { --c: 2; }
.js [data-reveal] > :nth-child(4) { --c: 3; }
.js [data-reveal] > :nth-child(5) { --c: 4; }
@keyframes arrive {
  from { opacity: 0; translate: 0 24px; }
  to   { opacity: 1; translate: 0 0; }
}

/* ---------- Narrow or very short screens: no pinning ----------
   Quarters of a phone screen are too small to read, so there the scenes
   become an ordinary scrolling page, one tile after another. script.js
   leaves the track alone at the same sizes. A laptop window with a short
   browser still counts as a laptop. */
@media (max-width: 900px), (max-height: 420px) {
  .head { grid-template-columns: var(--head) 1fr auto; }
  .head-tag, .head-nav { display: none; }

  .scene { height: auto !important; }
  .stage { position: static; height: auto; overflow: visible; }
  .track { transform: none !important; }
  .screen { height: auto; grid-template-columns: 1fr; grid-template-rows: none; }
  .screen > * { min-height: 50svh; }
  .hero-wordmark { font-size: 20vw; }

  .grid > * { grid-column: 1 / -1 !important; grid-row: auto !important; }
  .lane, .hold { padding-top: 0; height: auto; grid-column: 1 / -1; }
  .hold > .tile, .services-pin, .work-preview { position: static; height: auto; min-height: 40svh; }
  .work-row { min-height: 0; }
  .work-frame { height: auto; width: min(100%, 420px); }
  .numbers-head, .numbers-art { position: relative; height: 40svh; }
  .services-pin, .svc-list { grid-column: 1 / -1; }
  .svc { grid-template-columns: 1fr auto; min-height: 0; }
  .svc > * { grid-column: 1 !important; grid-row: auto !important; }
  .svc-icon { grid-column: 2 !important; grid-row: 1 !important; width: 56px; }
  .athletes-art, .words-art { min-height: 60svh; }
  .athletes { grid-template-rows: none; }
  .athletes-copy, .athletes-cta { position: relative; top: auto; }
  .athletes-cta { height: auto; min-height: 30svh; }
  .ath-pin, .ath-head, .ath-lane, .athletes-cta { grid-column: 1 / -1 !important; grid-row: auto !important; }
  .ath-lane .hold > .tile { height: auto; }
  .athletes-art { position: relative; height: 60svh; }
  .contact-form { grid-template-columns: 1fr; }
  .tier { min-height: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker-track { animation: none; }
  .svc-icon * { animation: none !important; }
  .stat-art * { animation: none !important; }
  .hero-mark svg { animation: none; }
  .tier, .tier li, .tier li::after, .tier-pulse { animation: none !important; clip-path: none !important; opacity: 1 !important; }
  .loader { display: none; }
  .js [data-reveal] > * { opacity: 1 !important; animation: none !important; }
}
