/*
  Definitive KLS direction, August 2026.
  The old stylesheet still owns the project and film viewers. Everything
  visible on the homepage is scoped here so the review build stays isolated.
*/

.definitive-site {
  --def-bg: #06070a;
  --def-bg-raised: #0a0b0f;
  --def-paper: #f4f1eb;
  --def-muted: rgba(244, 241, 235, 0.62);
  --def-dim: rgba(244, 241, 235, 0.34);
  --def-line: rgba(244, 241, 235, 0.14);
  --def-pad: clamp(1.25rem, 4.45vw, 4rem);
  --def-display: "Playfair Display", Georgia, serif;
  --def-body: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --def-ease: cubic-bezier(0.16, 1, 0.3, 1);
  /* r89: the accent is Opus orange (Kyle at 07:05 — "this opus orange
     actually would be a pretty good reference"). One value, swept
     everywhere the r88 gold lived. Stars stay star-gold. */
  --kls-accent: #fb5607;
  --kls-accent-rgb: 251 86 7;
  margin: 0;
  background: var(--def-bg);
  color: var(--def-paper);
  font-family: var(--def-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

.definitive-site::before {
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  content: "";
  opacity: 0.055;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.7'/%3E%3C/svg%3E");
}

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

.definitive-site img,
.definitive-site video,
.definitive-site iframe,
.definitive-site svg,
.definitive-site canvas {
  display: block;
  max-width: 100%;
}

.definitive-site a {
  color: inherit;
  text-decoration: none;
}

.definitive-site button {
  color: inherit;
  font: inherit;
}

.definitive-site h1,
.definitive-site h2,
.definitive-site h3 {
  margin: 0;
  font-family: var(--def-display);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 0.98;
  text-wrap: balance;
}

.definitive-site p {
  margin: 0;
}

.definitive-site :focus-visible {
  outline: 1px solid var(--def-paper);
  outline-offset: 5px;
}

.definitive-site .site-nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 80;
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) auto minmax(9rem, 1fr);
  align-items: center;
  /* One expression for the whole range. The phone override ramped to 74px and
     the base sat flat at 80px, so the bar still stepped 6px as the window
     crossed the breakpoint - the last discontinuity in the header. */
  min-height: clamp(4.5rem, 3.9rem + 1.6vw, 5rem);
  padding: 0 var(--def-pad);
  border: 0;
  background: linear-gradient(to bottom, rgba(6, 7, 10, 0.76), transparent);
  transform: none;
  transition: background 500ms var(--def-ease), backdrop-filter 500ms var(--def-ease);
}

.definitive-site .site-nav.is-solid {
  background: rgba(6, 7, 10, 0.86);
  backdrop-filter: blur(18px) saturate(120%);
  -webkit-backdrop-filter: blur(18px) saturate(120%);
}

.definitive-site .nav-brand {
  position: relative;
  z-index: 2;
  grid-column: 2;
  grid-row: 1;
  justify-self: center;
  /* ONE ramp, not three steps. This was 9.25rem here, 7rem under 1024 and
     7.8rem on phones - three rules written at different times and never
     reconciled, so the mark measured 125px on a phone, SHRANK to 112px at
     900px wide, then jumped to 148px past 1024. Dragging the window made it
     get smaller as the window got bigger. It is continuous now: it can only
     grow with the viewport, and the endpoints are the ones we already had. */
  width: clamp(7.4rem, 7.1rem + 2.4vw, 9.25rem);
}

/* Same collision geometry as the interior routes: on phones the centred
   wordmark would meet the MENU button. Left and smaller. */
@media (max-width: 1024px) {
  .definitive-site .nav-brand {
    grid-column: 1;
    justify-self: start;
  }
}

.definitive-site .nav-brand img {
  width: 100%;
  height: auto;
}

/* The header stays; only its mark steps aside. In the fold the centred mark is
   the brand, so the header's small one fades out - and fades back in as the
   fold leaves. Two marks never show at once, and nothing snaps. */
.definitive-site .nav-brand {
  transition: opacity 420ms var(--def-ease);
}

html.kls-in-hero .definitive-site .nav-brand {
  opacity: 0;
  pointer-events: none;
}

.definitive-site .nav-brand img {
  width: 100%;
  height: auto;
}

/* Redesign fix: the original mockup's header order — links LEFT, the docking
   mark dead-centre, CTA right. The links were living in the centre column,
   which is exactly where the logo docks. */
.definitive-site .desktop-nav {
  display: flex;
  grid-column: 1;
  grid-row: 1;
  align-items: center;
  justify-content: flex-start;
  justify-self: start;
  gap: clamp(1.4rem, 2.8vw, 2.8rem);
  min-width: 0;
}

.definitive-site .nav-cta {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
}

.definitive-site .desktop-nav > a,
.definitive-site .nav-group > a,
.definitive-site .nav-cta,
.definitive-site .menu-toggle {
  position: relative;
  padding: 0.8rem 0;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.15em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.definitive-site .desktop-nav > a::after,
.definitive-site .nav-group > a::after {
  position: absolute;
  right: 0;
  bottom: 0.45rem;
  left: 0;
  height: 1px;
  content: "";
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 320ms var(--def-ease);
}

.definitive-site .desktop-nav > a:hover::after,
.definitive-site .desktop-nav > a:focus-visible::after,
.definitive-site .nav-group:hover > a::after,
.definitive-site .nav-group:focus-within > a::after {
  transform: scaleX(1);
  transform-origin: left;
}

.definitive-site .nav-group {
  position: relative;
}

.definitive-site .nav-submenu {
  position: absolute;
  top: calc(100% - 0.2rem);
  left: -1.15rem;
  width: 12.5rem;
  padding: 0.75rem 1.15rem;
  border: 1px solid var(--def-line);
  background: rgba(8, 9, 13, 0.96);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-0.45rem);
  transition: opacity 220ms ease, transform 320ms var(--def-ease);
}

.definitive-site .nav-group:hover .nav-submenu,
.definitive-site .nav-group:focus-within .nav-submenu {
  opacity: 1;
  pointer-events: auto;
  transform: none;
}

.definitive-site .nav-submenu a {
  display: block;
  padding: 0.6rem 0;
  color: var(--def-muted);
  font-size: 0.77rem;
  transition: color 180ms ease, transform 260ms var(--def-ease);
}

.definitive-site .nav-submenu a:hover,
.definitive-site .nav-submenu a:focus-visible {
  color: var(--def-paper);
  transform: translateX(0.2rem);
}

.definitive-site .nav-cta {
  justify-self: end;
  display: flex;
  gap: 0.7rem;
  align-items: center;
  padding: 0.85rem 1.05rem;
  border: 1px solid var(--def-line);
  transition: background 220ms ease, color 220ms ease, transform 220ms var(--def-ease);
}

.definitive-site .nav-cta:hover,
.definitive-site .nav-cta:focus-visible {
  background: var(--def-paper);
  color: var(--def-bg);
  transform: translateY(-2px);
}

.definitive-site .menu-toggle,
.definitive-site .mobile-menu {
  display: none;
}

.definitive-site .def-hero {
  position: relative;
  height: 100dvh;
  min-height: 42rem;
  overflow: hidden;
  background: var(--def-bg);
}

.definitive-site .hero-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.definitive-site .hero-fallback,
.definitive-site .def-hero-reel {
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100vw, 177.78vh);
  height: max(100vh, 56.25vw);
  max-width: none;
  border: 0;
  object-fit: cover;
  transform: translate(-50%, -50%) scale(1.015);
}

.definitive-site .hero-fallback {
  z-index: 0;
}

.definitive-site .def-hero-reel {
  z-index: 1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 900ms ease;
}

/* The hand-off is a filmic cut, not a dissolve. The poster is the reel's
   title card and playback starts five seconds in, so crossfading one over
   the other double-exposed two unrelated frames - the "jump". Now: poster
   drops to the page's black first, THEN the moving footage fades up from
   that black. Mismatch reads as an edit instead of a glitch. */
.definitive-site .hero-media .hero-fallback {
  transition: opacity 240ms var(--def-ease);
}
.definitive-site .hero-media.is-reel-ready .hero-fallback {
  opacity: 0;
}
.definitive-site .hero-media .def-hero-reel {
  /* Was 520ms after a 260ms hold - a crossfade tuned to mask a video that
     mounted late. The reel mounts at parse time now and the poster is the
     same scene at the same timestamp, so the handoff is a short dissolve the
     moment real frames exist, not a scheduled reveal. */
  transition: opacity 240ms var(--def-ease);
}
.definitive-site .hero-media.is-reel-ready .def-hero-reel {
  opacity: 1;
}

.definitive-site .hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(to bottom, rgba(3, 4, 7, 0.36), transparent 24%),
    linear-gradient(to top, var(--def-bg), transparent 31%),
    linear-gradient(90deg, rgba(3, 4, 7, 0.18), transparent 50%);
}

.definitive-site .def-hero-meta {
  position: absolute;
  right: var(--def-pad);
  bottom: clamp(2rem, 5vw, 4rem);
  left: var(--def-pad);
  z-index: 4;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
}

.definitive-site .def-hero-meta > div {
  display: flex;
  align-items: baseline;
  gap: 0.65rem;
  font-family: var(--def-display);
  font-size: clamp(1.7rem, 2.4vw, 2.55rem);
  line-height: 1;
}

.definitive-site .def-hero-meta > div span {
  color: var(--def-paper);
}

.definitive-site .def-hero-meta > div strong {
  color: var(--def-muted);
  font-weight: 400;
}

.definitive-site .def-reel-action {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0;
  border: 0;
  background: transparent;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.definitive-site .def-play {
  display: grid;
  width: 2.4rem;
  height: 2.4rem;
  place-items: center;
  border: 1px solid rgba(244, 241, 235, 0.5);
  border-radius: 50%;
  font-size: 0.55rem;
  text-indent: 0.12em;
  transition: background 220ms ease, color 220ms ease, transform 300ms var(--def-ease);
}

.definitive-site .def-reel-action:hover .def-play,
.definitive-site .def-reel-action:focus-visible .def-play {
  background: var(--def-paper);
  color: var(--def-bg);
  transform: scale(1.08);
}

.definitive-site .def-galaxy {
  height: 215dvh;
  min-height: 86rem;
  margin-top: 0;
  background: var(--def-bg);
}

.definitive-site .galaxy-sticky {
  height: 100dvh;
  min-height: 40rem;
}

.definitive-site .galaxy-copy {
  font-family: var(--def-display);
  font-size: clamp(2.7rem, 6.4vw, 7.2rem);
  font-weight: 400;
  letter-spacing: -0.04em;
}

.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-process,
.definitive-site .def-reviews,
.definitive-site .def-instagram,
.definitive-site .def-client-proof,
.definitive-site .def-learn {
  padding-right: var(--def-pad);
  padding-left: var(--def-pad);
}

.definitive-site .def-work {
  padding-top: clamp(5rem, 10vw, 10rem);
  padding-bottom: clamp(7rem, 12vw, 12rem);
  background: var(--def-bg);
}

.definitive-site .def-section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 3rem;
  margin-bottom: clamp(2.8rem, 5vw, 5rem);
}

.definitive-site .def-section-head h2 {
  font-size: clamp(3.5rem, 8vw, 8.6rem);
}

.definitive-site .def-kicker {
  margin-bottom: 1rem;
  color: var(--def-muted);
  font-size: 0.69rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.definitive-site .def-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--def-line);
  font-size: 0.77rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: border-color 200ms ease, transform 280ms var(--def-ease);
}

.definitive-site .def-arrow-link:hover,
.definitive-site .def-arrow-link:focus-visible {
  border-color: var(--def-paper);
  transform: translateX(0.25rem);
}

.definitive-site .def-head-note {
  max-width: 24rem;
  color: var(--def-muted);
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  line-height: 1.45;
}

.definitive-site .def-featured-shell {
  position: relative;
  margin-right: calc(var(--def-pad) * -1);
  margin-left: calc(var(--def-pad) * -1);
  padding: clamp(4rem, 7vw, 7rem) 0 clamp(2rem, 4vw, 4rem);
  overflow: hidden;
}

.definitive-site .def-featured-backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--def-bg-raised);
}

.definitive-site .def-featured-backdrop::after {
  position: absolute;
  inset: 0;
  content: "";
  background: rgba(6, 7, 10, 0.8);
  backdrop-filter: blur(28px) saturate(78%);
  -webkit-backdrop-filter: blur(28px) saturate(78%);
}

.definitive-site .def-featured-backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.42;
  transform: scale(1.12);
  transition: opacity 240ms ease;
}

.definitive-site .def-featured-backdrop.is-switching img {
  opacity: 0;
}

.definitive-site .def-featured-grid {
  position: relative;
  z-index: 2;
  display: flex;
  gap: clamp(0.8rem, 1.6vw, 1.5rem);
  padding: 0 max(var(--def-pad), calc((100vw - min(68vw, 68rem)) / 2));
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.definitive-site .def-featured-grid::-webkit-scrollbar {
  display: none;
}

.definitive-site .def-work-source {
  display: contents;
}

.definitive-site .def-featured-grid .campaign-card {
  position: relative;
  display: block;
  flex: 0 0 min(68vw, 68rem);
  scroll-snap-align: center;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--def-paper);
  text-align: left;
  opacity: 1;
  transform: none;
}

.definitive-site .campaign-media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--def-bg-raised);
}

.definitive-site .campaign-still,
.definitive-site .campaign-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.definitive-site .campaign-still {
  transition: transform 900ms var(--def-ease), filter 500ms ease;
}

.definitive-site .campaign-video {
  position: absolute;
  inset: 0;
  border: 0;
  opacity: 0;
}

.definitive-site .campaign-card:hover .campaign-still,
.definitive-site .campaign-card:focus-visible .campaign-still {
  transform: scale(1.035);
}

.definitive-site .campaign-credit {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.2rem 1rem;
  padding: 0.9rem 0 1.7rem;
}

.definitive-site .campaign-client,
.definitive-site .campaign-meta {
  color: var(--def-muted);
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.definitive-site .campaign-title {
  grid-row: 1 / span 2;
  font-family: var(--def-display);
  font-size: clamp(1.35rem, 2vw, 2rem);
  font-weight: 400;
  line-height: 1.1;
}

.definitive-site .campaign-client + .campaign-title {
  grid-column: 1;
  grid-row: 2;
}

.definitive-site .campaign-meta {
  grid-column: 2;
  grid-row: 2;
  align-self: end;
}

.definitive-site .def-featured-controls {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1rem;
  font-size: 0.66rem;
  letter-spacing: 0.13em;
}

.definitive-site .def-featured-controls button {
  display: grid;
  width: 2.5rem;
  height: 2.5rem;
  place-items: center;
  border: 1px solid var(--def-line);
  border-radius: 50%;
  background: rgba(6, 7, 10, 0.28);
  transition: background 200ms ease, color 200ms ease, transform 260ms var(--def-ease);
}

.definitive-site .def-featured-controls button:hover,
.definitive-site .def-featured-controls button:focus-visible {
  background: var(--def-paper);
  color: var(--def-bg);
  transform: scale(1.06);
}

.definitive-site .def-work-paths {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin-top: clamp(3rem, 6vw, 6rem);
  border-top: 1px solid var(--def-line);
  border-bottom: 1px solid var(--def-line);
}

.definitive-site .def-work-paths a {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 8.5rem;
  padding: 1.1rem;
  border-right: 1px solid var(--def-line);
  font-family: var(--def-display);
  font-size: clamp(1rem, 1.45vw, 1.4rem);
  transition: background 250ms ease, color 250ms ease;
}

.definitive-site .def-work-paths a:last-child {
  border-right: 0;
}

.definitive-site .def-work-paths a:hover,
.definitive-site .def-work-paths a:focus-visible {
  background: var(--def-paper);
  color: var(--def-bg);
}

.definitive-site .def-work-paths span {
  font-family: var(--def-body);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
}

.definitive-site .def-proof {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: 0 var(--def-pad);
  border-top: 1px solid var(--def-line);
  border-bottom: 1px solid var(--def-line);
}

.definitive-site .def-proof-item {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: clamp(12rem, 19vw, 18rem);
  padding: clamp(1.5rem, 3vw, 2.8rem) clamp(1rem, 2vw, 2rem);
  border-right: 1px solid var(--def-line);
}

.definitive-site .def-proof-item:first-child {
  padding-left: 0;
}

.definitive-site .def-proof-item:last-child {
  border-right: 0;
}

.definitive-site .def-proof-item strong {
  font-family: var(--def-display);
  font-size: clamp(3rem, 6.5vw, 7rem);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 0.85;
}

.definitive-site .def-proof-item span {
  max-width: 11rem;
  color: var(--def-muted);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.definitive-site .def-expertise {
  padding-top: clamp(7rem, 14vw, 14rem);
  padding-bottom: clamp(7rem, 13vw, 13rem);
}

.definitive-site .def-expertise-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(19rem, 0.75fr);
  gap: clamp(2rem, 4vw, 5rem);
  align-items: end;
}

.definitive-site .def-expertise-media {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--def-bg-raised);
}

.definitive-site .def-expertise-media::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(to top, rgba(4, 5, 8, 0.7), transparent 54%);
}

.definitive-site .def-expertise-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 260ms ease, transform 800ms var(--def-ease);
}

.definitive-site .def-expertise-stage.is-switching img {
  opacity: 0;
  transform: scale(1.025);
}

.definitive-site .def-expertise-caption {
  position: absolute;
  right: 1.5rem;
  bottom: 1.3rem;
  left: 1.5rem;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 2rem;
}

.definitive-site .def-expertise-caption span {
  font-family: var(--def-display);
  font-size: 2.2rem;
}

.definitive-site .def-expertise-caption p {
  max-width: 25rem;
  text-align: right;
}

.definitive-site .def-expertise-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-expertise-list button {
  position: relative;
  width: 100%;
  padding: 1.15rem 2.4rem 1.15rem 0;
  border: 0;
  border-bottom: 1px solid var(--def-line);
  background: transparent;
  color: var(--def-dim);
  font-family: var(--def-display);
  font-size: clamp(1.55rem, 2.55vw, 2.9rem);
  text-align: left;
  transition: color 250ms ease, padding-left 360ms var(--def-ease);
}

.definitive-site .def-expertise-list button::after {
  position: absolute;
  top: 50%;
  right: 0;
  content: "↗";
  color: var(--def-paper);
  font-family: var(--def-body);
  font-size: 1rem;
  opacity: 0;
  transform: translate(-0.5rem, -50%);
  transition: opacity 250ms ease, transform 350ms var(--def-ease);
}

.definitive-site .def-expertise-list button:hover,
.definitive-site .def-expertise-list button:focus-visible,
.definitive-site .def-expertise-list button.is-active {
  padding-left: 0.6rem;
  color: var(--def-paper);
}

.definitive-site .def-expertise-list button.is-active::after {
  opacity: 1;
  transform: translate(0, -50%);
}

.definitive-site .def-process {
  padding-top: clamp(6rem, 11vw, 11rem);
  padding-bottom: clamp(7rem, 13vw, 13rem);
  background: #f0ece5;
  color: #0a0b0f;
}

.definitive-site .def-process .def-kicker,
.definitive-site .def-process .def-head-note,
.definitive-site .def-process .def-roadmap article p {
  color: rgba(10, 11, 15, 0.58);
}

.definitive-site .def-process .def-section-head h2 {
  max-width: 12ch;
  font-size: clamp(3.2rem, 7.3vw, 7.8rem);
}

.definitive-site .def-roadmap {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-top: 4rem;
}

.definitive-site .def-roadmap-line {
  position: absolute;
  top: 1.4rem;
  right: 0;
  left: 0;
  height: 1px;
  background: rgba(10, 11, 15, 0.18);
}

.definitive-site .def-roadmap-line span {
  display: block;
  width: var(--roadmap-progress, 0%);
  height: 100%;
  background: #0a0b0f;
  transition: width 120ms linear;
}

.definitive-site .def-roadmap article {
  position: relative;
}

.definitive-site .def-roadmap article::before {
  position: absolute;
  top: -2.85rem;
  left: 0;
  width: 0.72rem;
  height: 0.72rem;
  border: 1px solid #0a0b0f;
  border-radius: 50%;
  content: "";
  background: #f0ece5;
}

.definitive-site .def-roadmap article > span {
  display: block;
  margin-bottom: 4rem;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
}

.definitive-site .def-roadmap h3 {
  margin-bottom: 1rem;
  font-size: clamp(1.8rem, 3vw, 3rem);
}

.definitive-site .def-roadmap article p {
  max-width: 16.5rem;
  line-height: 1.55;
}

.definitive-site .def-photo-trace {
  display: grid;
  grid-template-columns: minmax(18rem, 0.72fr) minmax(0, 1.6fr);
  min-height: 38rem;
  overflow: hidden;
  border-bottom: 1px solid var(--def-line);
}

.definitive-site .def-photo-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(4rem, 8vw, 8rem) var(--def-pad);
}

.definitive-site .def-photo-copy h2 {
  max-width: 8ch;
  margin-bottom: 3rem;
  font-size: clamp(3rem, 5.6vw, 6.2rem);
}

.definitive-site .def-photo-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(12rem, 1fr));
  gap: 0.35rem;
  align-items: stretch;
  padding: 2rem 0;
  transform: rotate(-2.5deg) scale(1.05);
}

.definitive-site .def-photo-strip img {
  width: 100%;
  height: 100%;
  min-height: 32rem;
  object-fit: cover;
}

.definitive-site .def-photo-strip img:nth-child(even) {
  margin-top: 3rem;
  margin-bottom: -3rem;
}

.definitive-site .def-about {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(24rem, 0.92fr);
  min-height: 48rem;
  padding: clamp(7rem, 12vw, 12rem) var(--def-pad);
  gap: clamp(3rem, 7vw, 8rem);
  align-items: center;
  border: 0;
  background: var(--def-bg);
}

.definitive-site .def-about-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}

.definitive-site .def-about-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.definitive-site .def-about-media::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(to top, rgba(6, 7, 10, 0.44), transparent 55%);
}

.definitive-site .def-about .story-play {
  position: absolute;
  inset: 50% auto auto 50%;
  z-index: 2;
  display: grid;
  width: 4.5rem;
  height: 4.5rem;
  place-items: center;
  border: 1px solid rgba(244, 241, 235, 0.56);
  border-radius: 50%;
  background: rgba(6, 7, 10, 0.22);
  backdrop-filter: blur(10px);
  transform: translate(-50%, -50%);
  transition: background 220ms ease, color 220ms ease, transform 300ms var(--def-ease);
}

.definitive-site .def-about .story-play:hover,
.definitive-site .def-about .story-play:focus-visible {
  background: var(--def-paper);
  color: var(--def-bg);
  transform: translate(-50%, -50%) scale(1.06);
}

.definitive-site .def-about-copy h2 {
  margin-bottom: 1.75rem;
  font-size: clamp(4rem, 7.4vw, 8rem);
}

.definitive-site .def-about-lead {
  max-width: 26rem;
  margin-bottom: 1.7rem;
  font-family: var(--def-display);
  font-size: clamp(1.55rem, 2.5vw, 2.5rem);
  line-height: 1.2;
}

.definitive-site .def-about-copy > p:not(.def-kicker):not(.def-about-lead) {
  max-width: 37rem;
  margin-bottom: 2rem;
  color: var(--def-muted);
}

.definitive-site .def-reviews {
  padding-top: clamp(7rem, 12vw, 12rem);
  padding-bottom: clamp(7rem, 12vw, 12rem);
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-review-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 1rem;
}

.definitive-site .def-review-grid blockquote {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  min-height: 23rem;
  margin: 0;
  padding: clamp(1.5rem, 2.5vw, 2.5rem);
  border-top: 1px solid var(--def-line);
  background: var(--def-bg-raised);
}

.definitive-site .def-review-grid blockquote:nth-child(1) {
  grid-column: span 5;
}

.definitive-site .def-review-grid blockquote:nth-child(2) {
  grid-column: span 4;
}

.definitive-site .def-review-grid blockquote:nth-child(3) {
  grid-column: span 3;
}

.definitive-site .def-review-grid blockquote > p {
  font-family: var(--def-display);
  font-size: clamp(1.35rem, 2.15vw, 2.25rem);
  line-height: 1.24;
}

.definitive-site .def-review-grid footer {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  color: var(--def-muted);
  font-size: 0.73rem;
}

.definitive-site .def-review-grid footer strong {
  color: var(--def-paper);
  font-weight: 500;
}

.definitive-site .def-instagram {
  padding-bottom: clamp(7rem, 11vw, 11rem);
}

.definitive-site .def-instagram .instagram-heading {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.3rem;
  margin-bottom: 2rem;
  padding: 0;
  text-align: left;
}

.definitive-site .def-instagram .ig-avatar {
  width: 4.6rem;
  height: 4.6rem;
  padding: 0.18rem;
  border: 1px solid rgba(244, 241, 235, 0.45);
  border-radius: 50%;
}

.definitive-site .def-instagram .ig-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}

.definitive-site .def-instagram .def-kicker {
  margin-bottom: 0.35rem;
}

.definitive-site .def-instagram h2 {
  font-size: clamp(2rem, 4vw, 4.6rem);
}

.definitive-site .def-instagram .instagram-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.35rem;
}

.definitive-site .def-instagram .instagram-tile {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}

.definitive-site .def-instagram .instagram-tile:nth-child(n + 9) {
  display: none;
}

.definitive-site .def-instagram .instagram-tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--def-ease), filter 300ms ease;
}

.definitive-site .def-instagram .instagram-tile:hover img,
.definitive-site .def-instagram .instagram-tile:focus-visible img {
  filter: brightness(0.78);
  transform: scale(1.035);
}

.definitive-site .def-client-proof {
  position: relative;
  padding-top: clamp(4rem, 7vw, 7rem);
  padding-bottom: clamp(5rem, 9vw, 9rem);
  overflow: hidden;
  border-top: 1px solid var(--def-line);
  background:
    radial-gradient(circle at 50% 100%, rgba(70, 86, 125, 0.18), transparent 47%),
    var(--def-bg);
}

.definitive-site .def-client-proof > .def-kicker {
  text-align: center;
}

.definitive-site .def-logo-window {
  margin-top: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 10%, black 90%, transparent);
}

.definitive-site .def-logo-track {
  display: flex;
  width: max-content;
  align-items: center;
  gap: clamp(4rem, 8vw, 9rem);
  /* No CSS animation here: initLogoMarquee owns the motion (drift + drag +
     wheel + infinite wrap), and a running animation overrides the JS inline
     transform — which is why dragging used to do nothing. */
}

.definitive-site .def-logo-track img {
  width: clamp(6.5rem, 10vw, 10.5rem);
  max-height: 4.5rem;
  object-fit: contain;
  filter: grayscale(1) brightness(0) invert(1);
  opacity: 0.72;
}


.definitive-site .def-learn {
  display: grid;
  grid-template-columns: minmax(18rem, 0.7fr) minmax(0, 1.3fr);
  gap: clamp(3rem, 7vw, 8rem);
  padding-top: clamp(7rem, 12vw, 12rem);
  padding-bottom: clamp(7rem, 12vw, 12rem);
  align-items: start;
}

.definitive-site .def-learn h2 {
  max-width: 7ch;
  font-size: clamp(4rem, 7vw, 7.5rem);
}

.definitive-site .def-learn-links {
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-learn-links a {
  display: grid;
  grid-template-columns: 2rem 1fr auto;
  gap: 1rem;
  align-items: center;
  padding: 1.45rem 0;
  border-bottom: 1px solid var(--def-line);
  transition: padding-left 350ms var(--def-ease), color 200ms ease;
}

.definitive-site .def-learn-links a:hover,
.definitive-site .def-learn-links a:focus-visible {
  padding-left: 0.7rem;
}

.definitive-site .def-learn-links span,
.definitive-site .def-learn-links small {
  color: var(--def-muted);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.definitive-site .def-learn-links strong {
  font-family: var(--def-display);
  font-size: clamp(1.5rem, 2.6vw, 2.8rem);
  font-weight: 400;
}

.definitive-site .def-learn-links small {
  max-width: 14rem;
  text-align: right;
}

.definitive-site .def-close {
  position: relative;
  min-height: min(58rem, 92dvh);
  overflow: hidden;
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-close-media {
  position: absolute;
  inset: 0;
}

.definitive-site .def-close-media img {
  position: absolute;
  width: clamp(11rem, 20vw, 20rem);
  aspect-ratio: 16 / 10;
  object-fit: cover;
  opacity: 0.58;
  box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.32);
}

.definitive-site .def-close-media img:nth-child(1) { top: 10%; left: 4%; transform: rotate(-5deg); }
.definitive-site .def-close-media img:nth-child(2) { top: 7%; right: 5%; transform: rotate(4deg); }
.definitive-site .def-close-media img:nth-child(3) { bottom: 5%; left: 11%; transform: rotate(3deg); }
.definitive-site .def-close-media img:nth-child(4) { right: 10%; bottom: 3%; transform: rotate(-4deg); }

.definitive-site .def-close::after {
  position: absolute;
  inset: 0;
  content: "";
  background: radial-gradient(circle at center, rgba(6, 7, 10, 0.25), rgba(6, 7, 10, 0.91) 70%);
}

.definitive-site .def-close-copy {
  position: relative;
  z-index: 2;
  display: flex;
  min-height: inherit;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6rem var(--def-pad);
  text-align: center;
}

.definitive-site .def-close-copy h2 {
  font-size: clamp(4.8rem, 10vw, 11rem);
}

.definitive-site .def-close-copy > p:not(.def-kicker) {
  margin: 1.3rem 0 2.3rem;
  color: var(--def-muted);
  font-size: 1.2rem;
}

.definitive-site .def-close-copy > a {
  display: inline-flex;
  gap: 0.8rem;
  align-items: center;
  padding: 1rem 1.3rem;
  border: 1px solid var(--def-line);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: background 220ms ease, color 220ms ease, transform 300ms var(--def-ease);
}

.definitive-site .def-close-copy > a:hover,
.definitive-site .def-close-copy > a:focus-visible {
  background: var(--def-paper);
  color: var(--def-bg);
  transform: translateY(-2px);
}

.definitive-site .def-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3rem 5rem;
  padding: clamp(4rem, 8vw, 8rem) var(--def-pad) 2rem;
  border-top: 1px solid var(--def-line);
  background:
    radial-gradient(circle at 50% 0%, rgba(71, 83, 117, 0.15), transparent 45%),
    var(--def-bg);
  text-align: left;
}

.definitive-site .def-footer-logo {
  width: clamp(9rem, 15vw, 14rem);
}

.definitive-site .def-footer-logo img {
  width: 100%;
  height: auto;
}

.definitive-site .def-footer .footer-email {
  grid-column: 1 / -1;
  justify-self: start;
  font-family: var(--def-display);
  font-size: clamp(2rem, 5vw, 5.7rem);
  letter-spacing: -0.035em;
}

.definitive-site .def-footer .footer-nav {
  display: flex;
  gap: 1.4rem;
  grid-column: 1;
  grid-row: 3;
  justify-content: flex-start;
  font-size: 0.7rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.definitive-site .def-footer .footer-social {
  display: flex;
  gap: 1rem;
  grid-column: 2;
  grid-row: 3;
  align-items: center;
}

.definitive-site .def-footer .footer-social a {
  opacity: 0.64;
  transition: opacity 180ms ease, transform 220ms var(--def-ease);
}

.definitive-site .def-footer .footer-social a:hover,
.definitive-site .def-footer .footer-social a:focus-visible {
  opacity: 1;
  transform: translateY(-2px);
}

.definitive-site .def-footer .footer-social svg {
  width: 1.05rem;
  height: 1.05rem;
}

.definitive-site .def-footer .footer-bottom {
  display: flex;
  grid-column: 1 / -1;
  justify-content: space-between;
  padding-top: 1.5rem;
  border-top: 1px solid var(--def-line);
  color: var(--def-muted);
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.definitive-site [data-def-reveal] {
  opacity: 0;
  transform: translateY(2.4rem);
  /* r94 (Giovani): the entrances read too fast to notice. Slower rise, and
     on fine pointers a literal focus pull - sections arrive the way a lens
     racks onto a subject. Phones keep the cheaper fade (blur transitions
     cost frames there). */
  transition: opacity 1150ms ease, transform 1300ms var(--def-ease);
}

.definitive-site [data-def-reveal].is-visible {
  opacity: 1;
  transform: none;
}

@media (pointer: fine) {
  .definitive-site [data-def-reveal] {
    filter: blur(7px);
    transition: opacity 1150ms ease, transform 1300ms var(--def-ease), filter 1150ms ease;
  }
  .definitive-site [data-def-reveal].is-visible { filter: blur(0); }
}

.definitive-site .def-reel-dialog {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: var(--def-pad);
  border: 0;
  background: rgba(4, 5, 8, 0.98);
  color: var(--def-paper);
  opacity: 0;
  transform: scale(0.985);
  transition: opacity 260ms ease, transform 500ms var(--def-ease), display 260ms allow-discrete, overlay 260ms allow-discrete;
}

.definitive-site .def-reel-dialog[open] {
  display: grid;
  place-items: center;
  opacity: 1;
  transform: none;
}

.definitive-site .def-reel-dialog::backdrop {
  background: #040508;
}

.definitive-site .def-reel-dialog > button {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 2;
  padding: 0.7rem 0;
  border: 0;
  background: transparent;
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.definitive-site .def-reel-frame {
  width: min(92vw, 90rem);
  aspect-ratio: 16 / 9;
  background: #000;
}

.definitive-site .def-reel-frame iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

body.definitive-site.project-open .site-nav.site-nav {
  border-bottom-color: transparent;
  background: transparent;
  pointer-events: none;
}

body.definitive-site.project-open .menu-toggle {
  opacity: 0;
}

body.definitive-site.project-open .project-close {
  right: var(--def-pad);
  font-family: var(--def-body);
}

@media (max-width: 1024px) {
  .definitive-site .site-nav {
    grid-template-columns: 1fr auto;
  }

  .definitive-site .desktop-nav,
  .definitive-site .nav-cta {
    display: none;
  }

  .definitive-site .menu-toggle {
    display: block;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    border: 0;
    background: transparent;
  }

  .definitive-site .mobile-menu {
    position: fixed;
    inset: 0;
    z-index: 70;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: 0.55rem;
    padding: 7rem var(--def-pad) 3rem;
    background: rgba(6, 7, 10, 0.98);
  }

  .definitive-site .mobile-menu[hidden] {
    display: none;
  }

  .definitive-site .mobile-menu a {
    font-family: var(--def-display);
    font-size: clamp(2.5rem, 8vw, 4.5rem);
    line-height: 1.08;
  }

  .definitive-site .def-featured-grid .campaign-card {
    flex-basis: min(76vw, 56rem);
  }

  .definitive-site .def-expertise-stage {
    grid-template-columns: 1fr;
  }

  .definitive-site .def-expertise-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .definitive-site .def-expertise-list button:nth-child(odd) {
    border-right: 1px solid var(--def-line);
  }

  .definitive-site .def-roadmap {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 5rem 2rem;
  }

  .definitive-site .def-roadmap-line {
    display: none;
  }

  .definitive-site .def-roadmap article::before {
    display: none;
  }

  .definitive-site .def-roadmap article > span {
    margin-bottom: 2rem;
  }

  .definitive-site .def-photo-trace,
  .definitive-site .def-about,
  .definitive-site .def-learn {
    grid-template-columns: 1fr;
  }

  .definitive-site .def-photo-trace {
    min-height: 0;
  }

  .definitive-site .def-photo-strip {
    min-height: 32rem;
  }

  .definitive-site .def-about {
    min-height: 0;
  }

  .definitive-site .def-review-grid blockquote:nth-child(n) {
    grid-column: span 4;
  }
}

@media (max-width: 720px) {
  .definitive-site {
    /* The gutter stepped 20px -> 34px across this breakpoint and the header
       72px -> 80px with it, so the whole bar lurched as the window crossed
       768. Both ramp now and meet the desktop value exactly. */
    --def-pad: clamp(1.25rem, 4.45vw, 4rem);
  }





  .definitive-site .def-hero {
    min-height: 38rem;
  }

  .definitive-site .hero-fallback,
  .definitive-site .def-hero-reel {
    width: max(100vw, 75vh);
    height: max(100vh, 133.33vw);
  }

  .definitive-site .def-hero-meta {
    align-items: flex-start;
    flex-direction: column;
    gap: 1.2rem;
  }

  .definitive-site .def-hero-meta > div {
    font-size: 1.75rem;
  }

  .definitive-site .def-galaxy {
    height: 180dvh;
    min-height: 68rem;
  }

  .definitive-site .galaxy-copy {
    width: calc(100% - 2.5rem);
    font-size: clamp(2.65rem, 12vw, 4.6rem);
  }

  .definitive-site .def-section-head {
    align-items: flex-start;
    flex-direction: column;
    gap: 1.5rem;
  }

  .definitive-site .def-section-head h2,
  .definitive-site .def-process .def-section-head h2 {
    font-size: clamp(3.2rem, 17vw, 5.6rem);
  }

  .definitive-site .def-featured-grid {
    gap: 0.65rem;
    padding-right: 1.25rem;
    padding-left: 1.25rem;
    scroll-padding-inline: 1.25rem;
  }

  .definitive-site .def-featured-grid .campaign-card {
    flex-basis: calc(100vw - 2.9rem);
    scroll-snap-align: start;
  }

  .definitive-site .campaign-credit {
    padding-bottom: 2rem;
  }

  .definitive-site .def-work-paths {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .definitive-site .def-work-paths a {
    min-height: 6.5rem;
  }

  .definitive-site .def-work-paths a:nth-child(even) {
    border-right: 0;
  }

  .definitive-site .def-work-paths a:last-child {
    grid-column: 1 / -1;
    border-top: 1px solid var(--def-line);
  }

  .definitive-site .def-proof {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .definitive-site .def-proof-item {
    min-height: 11rem;
    padding: 1.4rem 1rem;
  }

  .definitive-site .def-proof-item:nth-child(2) {
    border-right: 0;
  }

  .definitive-site .def-proof-item:nth-child(-n + 2) {
    border-bottom: 1px solid var(--def-line);
  }

  .definitive-site .def-proof-item strong {
    font-size: clamp(3rem, 16vw, 4.6rem);
  }

  .definitive-site .def-expertise-media {
    aspect-ratio: 4 / 5;
  }

  .definitive-site .def-expertise-caption {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.8rem;
  }

  .definitive-site .def-expertise-caption p {
    text-align: left;
  }

  .definitive-site .def-expertise-list {
    grid-template-columns: 1fr;
  }

  .definitive-site .def-expertise-list button:nth-child(odd) {
    border-right: 0;
  }

  .definitive-site .def-roadmap {
    grid-template-columns: 1fr;
    gap: 4rem;
    padding-top: 0;
  }

  .definitive-site .def-roadmap article {
    padding-left: 3rem;
  }

  .definitive-site .def-roadmap article > span {
    position: absolute;
    top: 0.15rem;
    left: 0;
  }

  .definitive-site .def-photo-strip {
    grid-template-columns: repeat(4, 56vw);
    min-height: 25rem;
    overflow: hidden;
  }

  .definitive-site .def-photo-strip img {
    min-height: 24rem;
  }

  .definitive-site .def-about {
    padding-top: 6rem;
    padding-bottom: 7rem;
  }

  .definitive-site .def-about-copy h2 {
    font-size: clamp(4rem, 20vw, 6rem);
  }

  .definitive-site .def-review-grid {
    grid-template-columns: 1fr;
  }

  .definitive-site .def-review-grid blockquote:nth-child(n) {
    grid-column: 1;
    min-height: 19rem;
  }

  .definitive-site .def-instagram .instagram-heading {
    grid-template-columns: auto 1fr;
  }

  .definitive-site .def-instagram .instagram-heading > .def-arrow-link {
    grid-column: 1 / -1;
    justify-self: start;
  }

  .definitive-site .def-instagram .instagram-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .definitive-site .def-learn-links a {
    grid-template-columns: 1.6rem 1fr;
  }

  .definitive-site .def-learn-links small {
    display: none;
  }

  .definitive-site .def-close {
    min-height: 44rem;
  }

  .definitive-site .def-close-media img {
    width: 42vw;
  }

  .definitive-site .def-close-copy h2 {
    font-size: clamp(4.4rem, 19vw, 7rem);
  }

  .definitive-site .def-footer {
    grid-template-columns: 1fr;
    gap: 2.3rem;
  }

  .definitive-site .def-footer .footer-email,
  .definitive-site .def-footer .footer-nav,
  .definitive-site .def-footer .footer-social,
  .definitive-site .def-footer .footer-bottom {
    grid-column: 1;
    grid-row: auto;
  }

  .definitive-site .def-footer .footer-email {
    font-size: clamp(1.6rem, 8.6vw, 2.65rem);
    overflow-wrap: anywhere;
  }

  .definitive-site .def-footer .footer-nav {
    flex-wrap: wrap;
  }

  .definitive-site .def-footer .footer-social {
    justify-self: start;
  }

  .definitive-site .def-footer .footer-bottom {
    align-items: flex-start;
    flex-direction: column;
    gap: 0.4rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site [data-def-reveal] {
    opacity: 1;
    transform: none;
  }
}

/* ==========================================================================
   August review pass 02. Motion is continuous, media stays clean, and the
   page hands off through soft fields instead of hard section rules.
   ========================================================================== */

.definitive-site {
  --def-grain-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.065'/%3E%3C/svg%3E");
}

.definitive-site::before {
  display: none;
}

.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-photo-motion,
.definitive-site .def-about,
.definitive-site .def-instagram,
.definitive-site .def-client-proof,
.definitive-site .def-learn,
.definitive-site .def-close,
.definitive-site .def-footer {
  border: 0 !important;
}

.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-learn {
  background-color: var(--def-bg);
  background-image: var(--def-grain-image);
}

/* Galaxy */
.definitive-site .def-galaxy {
  height: 225dvh;
  min-height: 1500px;
  --mark-opacity: 0;
  --mark-scale: 0.36;
}

.definitive-site .galaxy-sticky {
  opacity: var(--galaxy-exit, 1);
  transform: scale(calc(0.992 + var(--galaxy-exit, 1) * 0.008));
  transform-origin: center bottom;
}

.definitive-site .galaxy-copy {
  z-index: 3;
  width: min(90vw, 76rem);
  font-family: var(--def-body);
  font-size: clamp(1.35rem, 3.4vw, 3.45rem);
  font-weight: 500;
  letter-spacing: 0.095em;
  line-height: 1.15;
  text-transform: uppercase;
}

.definitive-site .galaxy-copy span {
  margin-block: 0.14em;
}

.definitive-site .def-galaxy-marks a,
.definitive-site .def-galaxy-marks a:nth-child(2n) {
  width: clamp(5.2rem, 9vw, 9.5rem);
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  opacity: var(--mark-opacity, 0);
  transform: translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px))) scale(var(--mark-scale, 0.36));
  transition: filter 280ms ease, opacity 80ms linear, transform 80ms linear;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.definitive-site .def-galaxy-marks a:nth-child(3n) {
  width: clamp(4.4rem, 7.4vw, 7.8rem);
}

.definitive-site .def-galaxy-marks a:hover,
.definitive-site .def-galaxy-marks a:focus-visible {
  background: transparent;
  filter: drop-shadow(0 0 1.15rem rgba(183, 205, 255, 0.55));
}

.definitive-site .def-galaxy-marks img {
  width: 100%;
  max-height: 4.25rem;
  object-fit: contain;
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 0.8rem rgba(0, 0, 0, 0.62));
  opacity: 1;
  animation: def-mark-breathe 6.5s ease-in-out infinite alternate;
}

.definitive-site .def-galaxy-marks a:nth-child(2n) img { animation-delay: -2.7s; }
.definitive-site .def-galaxy-marks a:nth-child(3n) img { animation-delay: -4.1s; }

@keyframes def-mark-breathe {
  from { transform: translate3d(-2px, -3px, 0) rotate(-0.45deg); }
  to { transform: translate3d(3px, 4px, 0) rotate(0.55deg); }
}

.definitive-site .def-work {
  padding-top: clamp(5.5rem, 9vw, 9rem);
  background-image:
    linear-gradient(to bottom, rgba(5, 6, 10, 0), var(--def-bg) 10rem),
    var(--def-grain-image);
}

/* Film coverflow */
.definitive-site .def-film-roll {
  position: relative;
  isolation: isolate;
  min-height: clamp(48rem, 100dvh, 64rem);
  padding: clamp(6rem, 10vw, 9rem) 0 clamp(4rem, 8vw, 7rem);
  overflow: hidden;
  background: var(--def-bg);
}

.definitive-site .def-film-roll::before,
.definitive-site .def-film-roll::after {
  position: absolute;
  z-index: 1;
  right: 0;
  left: 0;
  height: 9rem;
  pointer-events: none;
  content: "";
}

.definitive-site .def-film-roll::before { top: 0; background: linear-gradient(to bottom, var(--def-bg), transparent); }
.definitive-site .def-film-roll::after { bottom: 0; background: linear-gradient(to top, var(--def-bg), transparent); }

.definitive-site .def-film-backdrop {
  position: absolute;
  z-index: -1;
  inset: -5rem;
  overflow: hidden;
  background: #090a0e;
}

.definitive-site .def-film-backdrop::after {
  position: absolute;
  inset: 0;
  content: "";
  background: rgba(5, 6, 10, 0.76);
  backdrop-filter: blur(38px) saturate(72%);
  -webkit-backdrop-filter: blur(38px) saturate(72%);
}

.definitive-site .def-film-backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.46;
  transform: scale(1.12);
  transition: opacity 320ms ease;
}

.definitive-site .def-film-roll.is-backdrop-switching .def-film-backdrop img { opacity: 0.12; }

.definitive-site .def-film-roll-head {
  position: relative;
  z-index: 3;
  padding-inline: var(--def-pad);
  text-align: center;
}

.definitive-site .def-film-roll-head h2 {
  margin-top: 0.5rem;
  font-size: clamp(3rem, 6.4vw, 7rem);
}

.definitive-site .def-film-stage {
  position: relative;
  z-index: 2;
  height: clamp(27rem, 53vw, 43rem);
  margin-top: clamp(1.5rem, 4vw, 3rem);
  perspective: 1500px;
}

.definitive-site .def-film-card {
  position: absolute;
  top: 50%;
  left: 50%;
  /* Round 19: the active film is now nearly the wall the reel band used to be.
     56vw -> 80vw is 43% more card, and the neighbours still show ~144px of
     sliver at 1440 / ~110px at 1280, so the rail still reads as swipeable.
     Capped at 84rem because the posters and the film loops are 1280w and
     anything past that is upscaling.
     Round 25 (D): 80vw was too much wall - Giovani asked for "a decent amount
     smaller, not as small as originally". 68vw sits between round 19's 80 and
     the original 56; the cap comes to 72rem with it. At 1440 the card is
     979px (was 1152) and the neighbours show ~230px of sliver each side, so
     the rail reads MORE swipeable, not less.
     LOCKED: .def-film-stage's height clamp is this clamp x 9/16. Change both.
     The stage rule that actually wins is the round-14 one further down the
     file (search "Exactly .def-film-card's width clamp"), not the one a few
     lines below here - that one is overridden. Change the winner.
     r89 (Kyle at 12:12): "the middle video needs to shrink a little bit" -
     68vw comes down to 56 (the original width), cap 72rem -> 60, and the
     neighbours breathe; the stage winner moved with it, same commit. */
  width: clamp(18rem, 56vw, 60rem);
  aspect-ratio: 16 / 9;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0.35rem;
  background: #0b0c0f;
  box-shadow: 0 2.5rem 7rem rgba(0, 0, 0, 0.48);
  cursor: pointer;
  opacity: var(--film-opacity, 0);
  /* --film-drop compensates the hover scale so the card's TOP edge never
     moves. A percentage translate resolves against the element's own height,
     so 1.4% is exactly half of the 2.8% the pop adds - the growth all goes
     downward. Without it the card climbed into "Watch the work." and clipped
     the type, and it did so at some widths and not others because the
     clearance and the card height scale differently. */
  transform: translate3d(calc(-50% + var(--film-x, 0px)), calc(-50% + var(--film-drop, 0%)), 0) rotateY(var(--film-turn, 0deg)) scale(calc(var(--film-scale, 1) * var(--film-hover, 1)));
  transform-origin: center;
  will-change: transform, opacity, filter;
}

.definitive-site .def-film-card::after {
  position: absolute;
  z-index: 2;
  inset: 0;
  content: "";
  background: linear-gradient(to top, rgba(4, 5, 7, 0.74), transparent 44%);
  pointer-events: none;
}

.definitive-site .def-film-card img,
.definitive-site .def-film-card iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}

/* Round 18 items 4+5. `object-fit: cover` is inert on an iframe - it only
   applies to replaced content - so the player letterboxed inside the card and
   the card's own background showed as a pale line top and bottom. Oversizing
   the frame and centring it pushes those bars outside the card's overflow.
   The crossfade is also gone from the OUTGOING film: a fading-out player over
   an incoming one is what made two films visible at once. Non-active cards
   drop their video instantly; the only fade left is the active card's poster
   handing over to its own footage. */
.definitive-site .def-film-card iframe {
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 106%;
  height: 106%;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(1.045);
  /* r94 (Giovani): the footage used to POP to the front at 200ms and drop
     dead instantly on the way out. It now settles in - a slow fade while
     the frame eases from a 4.5% overscale to rest - and leaves the same
     way, quickly enough that the next card's film never overlaps it. */
  transition: opacity 620ms ease, transform 1100ms cubic-bezier(0.22, 1, 0.36, 1);
}

.definitive-site .def-film-card.is-active.is-video-ready iframe {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.definitive-site .def-film-card:not(.is-active) iframe {
  opacity: 0;
  transition: opacity 300ms ease;
}

.definitive-site .def-film-card > span {
  position: absolute;
  z-index: 3;
  right: 1.4rem;
  bottom: 1.2rem;
  left: 1.4rem;
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 1rem;
  opacity: 0;
  transform: translateY(0.8rem);
  transition: opacity 320ms ease, transform 520ms var(--def-ease);
}

.definitive-site .def-film-card.is-active > span { opacity: 1; transform: none; }
.definitive-site .def-film-card small { font-size: 0.65rem; letter-spacing: 0.13em; text-transform: uppercase; }
.definitive-site .def-film-card strong { font-family: var(--def-display); font-size: clamp(1.2rem, 2vw, 2rem); font-weight: 400; }

.definitive-site .def-film-controls {
  position: relative;
  z-index: 4;
  display: grid;
  width: min(28rem, calc(100% - 2.5rem));
  grid-template-columns: 3rem 1fr 3rem;
  gap: 1rem;
  align-items: center;
  margin: -1.25rem auto 0;
}

.definitive-site .def-film-controls button {
  display: grid;
  width: 3rem;
  height: 3rem;
  padding: 0;
  place-items: center;
  border: 1px solid rgba(244, 241, 235, 0.28);
  border-radius: 50%;
  background: rgba(6, 7, 10, 0.45);
  cursor: pointer;
  transition: background 220ms ease, color 220ms ease, transform 320ms var(--def-ease);
}

.definitive-site .def-film-controls button:hover,
.definitive-site .def-film-controls button:focus-visible { background: var(--def-paper); color: var(--def-bg); transform: scale(1.06); }
.definitive-site .def-film-controls p { display: flex; flex-direction: column; align-items: center; text-align: center; }
.definitive-site .def-film-controls span { font-family: var(--def-display); font-size: 1.25rem; }
.definitive-site .def-film-controls small { color: var(--def-muted); font-size: 0.62rem; letter-spacing: 0.14em; }

/* Expertise cards */
.definitive-site .def-expertise {
  padding-top: clamp(7rem, 11vw, 11rem);
  padding-bottom: clamp(7rem, 11vw, 11rem);
}

/* ============================================================
   Round 18 item 6: the expertise cards.

   They were four overlay tiles on an asymmetric 12-column grid - one wide,
   one narrow, image behind and copy floated on top of it. Giovani wants the
   Ensotography service-card shape instead: four equal cards, picture on top,
   then headline, subheadline and an action, each card a real object rather
   than a caption over a photograph.
   ============================================================ */
.definitive-site .def-service-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1rem, 1.6vw, 1.6rem);
  margin-top: clamp(2.5rem, 5vw, 5rem);
}

.definitive-site .def-service-grid article {
  position: relative;
  display: flex;
  height: auto;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid rgba(244, 241, 235, 0.09);
  border-radius: 0.4rem;
  background: rgba(12, 14, 19, 0.72);
  transition: border-color 320ms ease, transform 420ms var(--def-ease), background 320ms ease;
}

.definitive-site .def-service-grid article:hover,
.definitive-site .def-service-grid article:focus-within {
  border-color: rgba(244, 241, 235, 0.2);
  background: rgba(16, 19, 25, 0.86);
  transform: translateY(-4px);
}

/* The picture is the top of the card now, not its background. */
.definitive-site .def-service-grid .def-service-media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  /* A frame, never a hole. These four photos were `loading="lazy"` and queued
     behind the self-hosted reel video, so scrolling to Expertise showed four
     empty black boxes until they arrived. They load with the document at low
     priority now, and this tint means even a slow frame reads as a panel. */
  background: rgb(244 241 235 / 0.045);
}

.definitive-site .def-service-grid img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 900ms var(--def-ease), filter 600ms ease;
}

/* The Jeremiah's storefront frame is the widest of the four, so it is held
   left of centre to keep the crew and seated talent inside the crop. */
.definitive-site .def-service-grid article:nth-child(2) img { object-position: 40% 50%; }

.definitive-site .def-service-grid article:hover img { filter: saturate(1.12); transform: scale(1.035); }

.definitive-site .def-service-grid article > div {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(1.25rem, 1.9vw, 1.85rem);
}

.definitive-site .def-service-grid span {
  color: var(--def-muted);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
}

.definitive-site .def-service-grid h3 {
  margin: 0.5rem 0 0.6rem;
  font-size: clamp(1.5rem, 1.9vw, 2.1rem);
  line-height: 1.08;
}

.definitive-site .def-service-grid p {
  max-width: none;
  margin: 0 0 1.5rem;
  color: rgba(244, 241, 235, 0.72);
  font-size: 0.92rem;
  line-height: 1.5;
}

/* Pushed to the bottom edge so the four actions line up across the row
   regardless of how long each description runs. */
.definitive-site .def-service-grid .def-service-cta {
  display: inline-flex;
  align-items: center;
  margin-top: auto;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid rgba(244, 241, 235, 0.28);
  color: var(--def-ink);
  font-size: 0.68rem;
  gap: 0.45rem;
  letter-spacing: 0.14em;
  text-decoration: none;
  text-transform: uppercase;
  transition: border-color 240ms ease, gap 240ms ease;
}

.definitive-site .def-service-grid .def-service-cta:hover,
.definitive-site .def-service-grid .def-service-cta:focus-visible {
  border-color: var(--def-ink);
  gap: 0.75rem;
}

@media (max-width: 1000px) {
  .definitive-site .def-service-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .definitive-site .def-service-grid { grid-template-columns: minmax(0, 1fr); }
  .definitive-site .def-service-grid article > div { align-items: center; text-align: center; }
}

/* Photography and Instagram */
.definitive-site .def-photo-motion .photo-intro {
  align-items: center;
}

.definitive-site .def-photo-motion .photo-intro > .def-kicker { margin: 0; }
.definitive-site .def-instagram .ig-avatar { transform: translateY(0.38rem); }

/* Education is a visual lane, never a stacked list. */
.definitive-site .def-learn {
  display: block;
  padding-top: clamp(7rem, 11vw, 11rem);
  padding-bottom: clamp(7rem, 11vw, 11rem);
}

.definitive-site .def-learn-intro {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 2rem;
}

.definitive-site .def-learn h2 { max-width: none; font-size: clamp(3.8rem, 7.2vw, 7.8rem); }

.definitive-site .def-learn-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.7rem);
  margin-top: clamp(3rem, 6vw, 5.5rem);
}

.definitive-site .def-learn-cards a {
  position: relative;
  display: grid;
  min-height: clamp(28rem, 42vw, 42rem);
  grid-template-rows: 1fr auto auto auto;
  padding: 1.2rem;
  overflow: hidden;
  background: #0b0c10;
}

.definitive-site .def-learn-cards a::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(to top, rgba(5, 6, 9, 0.98), transparent 67%);
  pointer-events: none;
}

.definitive-site .def-learn-cards img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.82);
  transition: filter 450ms ease, transform 850ms var(--def-ease);
}

.definitive-site .def-learn-cards a:hover img,
.definitive-site .def-learn-cards a:focus-visible img { filter: saturate(1.06); transform: scale(1.035); }
.definitive-site .def-learn-cards span,
.definitive-site .def-learn-cards strong,
.definitive-site .def-learn-cards small { position: relative; z-index: 2; }
.definitive-site .def-learn-cards span { align-self: end; margin-bottom: 0.65rem; color: var(--def-muted); font-size: 0.62rem; letter-spacing: 0.14em; }
.definitive-site .def-learn-cards strong { font-family: var(--def-display); font-size: clamp(1.8rem, 3vw, 3.15rem); font-weight: 400; line-height: 1; }
.definitive-site .def-learn-cards small { margin-top: 0.6rem; color: rgba(244, 241, 235, 0.68); font-size: 0.72rem; letter-spacing: 0.06em; text-transform: uppercase; }

/* Work-with-us postcard field */
.definitive-site .def-close {
  --close-px: 0;
  --close-py: 0;
  min-height: clamp(49rem, 100dvh, 62rem);
  background: var(--def-bg);
}

.definitive-site .def-close::before {
  position: absolute;
  z-index: 1;
  inset: 0;
  content: "";
  background: radial-gradient(circle at center, rgba(18, 21, 30, 0.34), transparent 58%);
  pointer-events: none;
}

.definitive-site .def-close::after {
  z-index: 2;
  background: radial-gradient(circle at center, rgba(6, 7, 10, 0.22), rgba(6, 7, 10, 0.72) 76%);
  pointer-events: none;
}

.definitive-site .def-close-media {
  z-index: 1;
  perspective: 1100px;
}

.definitive-site .def-close-media button {
  position: absolute;
  top: var(--y);
  left: var(--x);
  width: clamp(10.5rem, 17vw, 18rem);
  aspect-ratio: 16 / 10;
  padding: 0;
  overflow: hidden;
  border: 0;
  background: #111318;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.34);
  cursor: pointer;
  transform: translate3d(var(--shift-x, 0px), var(--shift-y, 0px), 0) rotate(var(--r));
  transition: transform 720ms var(--def-ease), box-shadow 350ms ease;
  will-change: transform;
}

.definitive-site .def-close-media button > img,
.definitive-site .def-close-media button > iframe {
  position: absolute !important;
  top: 0 !important;
  right: auto !important;
  bottom: auto !important;
  left: 0 !important;
  width: 100% !important;
  height: 100%;
  border: 0;
  object-fit: cover;
  opacity: 1;
  filter: saturate(1.12) contrast(1.02);
  transform: none !important;
  animation: none !important;
}

.definitive-site .def-close-media button > iframe {
  z-index: 1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 420ms ease;
}

.definitive-site .def-close-media button.is-video-ready > iframe { opacity: 1; }

.definitive-site .def-close-media button > span {
  position: absolute;
  z-index: 2;
  right: 0;
  bottom: 0;
  left: 0;
  /* The label sat directly on the frame, so a bright still (the Chilly Pop
     yellow, the white studio cyc) swallowed it. It now rides its own gradient
     scrim anchored to the bottom edge - a shadow alone cannot carry white
     type over white footage. */
  padding: 2.2rem 0.85rem 0.7rem;
  background: linear-gradient(to top, rgba(3, 4, 6, 0.92) 0%, rgba(3, 4, 6, 0.72) 38%, rgba(3, 4, 6, 0) 100%);
  color: #fff;
  font-size: 0.63rem;
  letter-spacing: 0.12em;
  opacity: 0;
  text-align: left;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
  text-transform: uppercase;
  transform: translateY(0.45rem);
  transition: opacity 250ms ease, transform 420ms var(--def-ease);
}

.definitive-site .def-close-media button:hover,
.definitive-site .def-close-media button:focus-visible {
  z-index: 5;
  box-shadow: 0 2.2rem 6rem rgba(0, 0, 0, 0.56);
  transform: translate3d(var(--shift-x, 0px), var(--shift-y, 0px), 3rem) rotate(var(--r)) scale(1.065);
}

.definitive-site .def-close-media button:hover > span,
.definitive-site .def-close-media button:focus-visible > span { opacity: 1; transform: none; }

.definitive-site .def-close-copy { z-index: 4; pointer-events: none; }
.definitive-site .def-close-copy > a { pointer-events: auto; }
.definitive-site .def-close-copy h2 { font-size: clamp(4.5rem, 9vw, 9.5rem); }
.definitive-site .def-close-copy > p:not(.def-kicker) { max-width: 31rem; }

/* Nightcall-referenced compact image footer, using Kyle's own frame. */
.definitive-site .def-footer {
  position: relative;
  isolation: isolate;
  display: block;
  min-height: 31rem;
  padding: 0;
  overflow: hidden;
  background: #12140f;
  text-align: left;
  animation: none;
}

.definitive-site .def-footer-backdrop {
  position: absolute;
  z-index: -2;
  inset: -3rem;
}

.definitive-site .def-footer-backdrop img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(5px) saturate(1.2);
  transform: scale(1.08);
}

.definitive-site .def-footer::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  background: linear-gradient(105deg, rgba(4, 8, 5, 0.8), rgba(8, 12, 8, 0.48) 48%, rgba(4, 7, 4, 0.74));
}

.definitive-site .def-footer-grid {
  display: grid;
  min-height: 31rem;
  grid-template-columns: 1.2fr 0.8fr 1.15fr 0.75fr;
  gap: clamp(2rem, 5vw, 6rem);
  align-items: start;
  padding: clamp(6rem, 10vw, 8rem) var(--def-pad) 2rem;
}

.definitive-site .def-footer-logo {
  width: clamp(12rem, 18vw, 18rem);
  align-self: start;
}

.definitive-site .def-footer-logo img { width: 100%; filter: drop-shadow(0 0 1rem rgba(0, 0, 0, 0.35)); }

.definitive-site .def-footer .footer-nav,
.definitive-site .def-footer .footer-contact,
.definitive-site .def-footer .footer-social {
  display: flex;
  grid-column: auto;
  grid-row: auto;
  flex-direction: column;
  gap: 0.8rem;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: none;
}

.definitive-site .def-footer .footer-nav { justify-content: flex-start; }
.definitive-site .def-footer .footer-contact span { color: rgba(255, 255, 255, 0.62); line-height: 1.45; }

.definitive-site .def-footer .footer-email {
  grid-column: auto;
  justify-self: auto;
  padding: 0;
  border: 0;
  font-family: var(--def-body);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}

.definitive-site .def-footer .footer-social { gap: 0.8rem; }
.definitive-site .def-footer .footer-social a { display: block; width: auto; height: auto; border: 0; opacity: 1; }

.definitive-site .def-footer .footer-nav a,
.definitive-site .def-footer .footer-contact a,
.definitive-site .def-footer .footer-social a { transition: opacity 180ms ease, transform 280ms var(--def-ease); }
.definitive-site .def-footer .footer-nav a:hover,
.definitive-site .def-footer .footer-contact a:hover,
.definitive-site .def-footer .footer-social a:hover { opacity: 0.65; transform: translateX(0.25rem); }

.definitive-site .def-footer .footer-bottom {
  position: static;
  display: flex;
  grid-column: 1 / -1;
  align-self: end;
  justify-content: space-between;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  color: rgba(255, 255, 255, 0.64);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

@media (max-width: 900px) {
  .definitive-site .def-footer-grid { grid-template-columns: 1.2fr 0.8fr 1fr; }
  .definitive-site .def-footer .footer-social { display: none; }
}

@media (max-width: 620px) {
  .definitive-site .def-galaxy {
    height: 205dvh;
    min-height: 1280px;
  }

  .definitive-site .galaxy-copy {
    width: calc(100% - 2.5rem);
    font-size: clamp(1.05rem, 5.3vw, 1.5rem);
    letter-spacing: 0.08em;
  }

  .definitive-site .def-galaxy-marks a,
  .definitive-site .def-galaxy-marks a:nth-child(2n),
  .definitive-site .def-galaxy-marks a:nth-child(3n) {
    display: grid;
    width: clamp(3.7rem, 17vw, 5rem);
  }

  .definitive-site .def-galaxy-marks a:nth-child(5),
  .definitive-site .def-galaxy-marks a:nth-child(7) { display: none; }

  .definitive-site .def-film-roll { min-height: 42rem; padding-top: 5.5rem; }
  .definitive-site .def-film-roll-head h2 { font-size: clamp(2.75rem, 12vw, 4rem); }
  .definitive-site .def-film-stage { height: 24rem; margin-top: 1rem; }
  .definitive-site .def-film-card { width: min(78vw, 27rem); }
  .definitive-site .def-film-card > span { right: 0.85rem; bottom: 0.75rem; left: 0.85rem; }
  .definitive-site .def-film-card small { display: none; }
  .definitive-site .def-film-controls { margin-top: -1rem; }

  .definitive-site .def-service-grid { grid-template-columns: 1fr; }

  .definitive-site .def-photo-motion .photo-intro {
    flex-direction: row;
    align-items: center;
    padding-inline: var(--def-pad);
  }

  .definitive-site .def-instagram .ig-avatar { transform: translateY(0.2rem); }

  .definitive-site .def-learn { overflow: hidden; }
  .definitive-site .def-learn h2 { font-size: clamp(3.5rem, 16vw, 5.4rem); }
  .definitive-site .def-learn-cards {
    width: calc(100vw - var(--def-pad));
    grid-auto-columns: min(80vw, 22rem);
    grid-template-columns: none;
    grid-auto-flow: column;
    gap: 1rem;
    margin-right: calc(var(--def-pad) * -1);
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    padding-right: var(--def-pad);
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .definitive-site .def-learn-cards::-webkit-scrollbar { display: none; }
  .definitive-site .def-learn-cards a { min-height: 34rem; scroll-snap-align: start; }

  .definitive-site .def-close {
    display: flex;
    min-height: 0;
    flex-direction: column;
    padding: 5rem var(--def-pad) 4rem;
  }
  .definitive-site .def-close-copy {
    order: 1;
    min-height: 34rem;
    padding: 4rem 0;
  }
  .definitive-site .def-close-copy h2 { font-size: clamp(4rem, 18vw, 6.6rem); }
  .definitive-site .def-close-media {
    position: relative;
    z-index: 4;
    display: grid;
    order: 2;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
  }
  .definitive-site .def-close-media button {
    /* Round 16 item 7: `transform: none !important` used to flatten this wall
       into a grid, and an !important here would beat the entrance and the
       drift both. The placement now lives at the end of this file. */
    display: block;
  }
  .definitive-site .def-close-media button > span { opacity: 1; transform: none; }

  .definitive-site .def-footer,
  .definitive-site .def-footer-grid { min-height: 35rem; }
  .definitive-site .def-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 3rem 1.5rem;
    padding-top: 5rem;
  }
  .definitive-site .def-footer-logo { grid-column: 1 / -1; width: min(15rem, 58vw); }
  .definitive-site .def-footer .footer-nav,
  .definitive-site .def-footer .footer-contact { display: flex; }
  .definitive-site .def-footer .footer-contact { align-items: flex-start; }
  .definitive-site .def-footer .footer-email { max-width: 9.5rem; overflow-wrap: anywhere; }
  .definitive-site .def-footer .footer-bottom { align-items: flex-start; flex-direction: column; gap: 0.45rem; }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks img,
  .definitive-site .def-film-card,
  .definitive-site .def-close-media button { animation: none; transition-duration: 0.01ms; }
}

/* ==========================================================================
   August feedback revision. Restores the strongest original systems while
   keeping the definitive shell and case-study layer intact.
   ========================================================================== */

.definitive-site .site-nav {
  overflow: visible !important;
}

.definitive-site .desktop-nav,
.definitive-site .nav-group {
  overflow: visible;
}

.definitive-site .nav-submenu {
  top: calc(100% + 0.35rem);
  z-index: 120;
  max-height: min(70vh, 30rem);
  overflow-y: auto;
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.45);
}

.definitive-site .def-hero-meta {
  justify-content: flex-end;
}

.definitive-site .def-galaxy {
  height: 300dvh;
  min-height: 2050px;
  --marks-opacity: 0;
  --marks-scale: 0.25;
}

.definitive-site .galaxy-sticky {
  background:
    radial-gradient(ellipse 58% 44% at 50% 48%, rgba(64, 88, 145, 0), transparent 72%),
    #05060a;
}

.definitive-site .galaxy-vignette {
  background:
    radial-gradient(ellipse 72% 60% at 50% 48%, transparent 28%, rgba(5, 6, 10, 0.2) 58%, rgba(5, 6, 10, 0.88) 100%),
    linear-gradient(to bottom, rgba(5, 6, 10, 0.35), transparent 25%, transparent 72%, rgba(5, 6, 10, 0.72));
  box-shadow: none;
}

.definitive-site .galaxy-copy {
  z-index: 3;
  font-size: clamp(2.65rem, 7.15vw, 7.6rem);
  line-height: 1.02;
  letter-spacing: -0.032em;
}

.definitive-site .def-galaxy-marks {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.definitive-site .def-galaxy-marks a {
  position: absolute;
  top: var(--mark-y);
  left: var(--mark-x);
  display: grid;
  width: clamp(4.6rem, 8vw, 8.5rem);
  min-height: 3.5rem;
  padding: 0.65rem;
  place-items: center;
  border: 1px solid rgba(244, 241, 235, 0.1);
  background: rgba(8, 10, 16, 0.28);
  opacity: var(--marks-opacity);
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(calc(var(--marks-scale) + (var(--mark-delay) * 0.01)));
  transition:
    border-color 260ms ease,
    background 260ms ease,
    filter 260ms ease,
    opacity 90ms linear,
    transform 110ms linear;
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.definitive-site .def-galaxy-marks a:nth-child(2n) {
  width: clamp(5.4rem, 9.5vw, 10rem);
}

.definitive-site .def-galaxy-marks a:hover,
.definitive-site .def-galaxy-marks a:focus-visible {
  z-index: 4;
  border-color: rgba(244, 241, 235, 0.6);
  background: rgba(18, 23, 36, 0.72);
  filter: drop-shadow(0 0 1.2rem rgba(168, 192, 255, 0.48));
}

.definitive-site .def-galaxy-marks img {
  width: 100%;
  max-height: 3.7rem;
  object-fit: contain;
  filter: grayscale(1) brightness(0) invert(1);
  opacity: 0.76;
}

.definitive-site .def-work {
  position: relative;
  z-index: 3;
  padding-top: clamp(6rem, 11vw, 11rem);
  background: linear-gradient(to bottom, rgba(6, 7, 10, 0.95), var(--def-bg) 13rem);
}

.definitive-site .def-work-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.1rem;
}

.definitive-site .def-work-grid .campaign-card {
  position: relative;
  display: block;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--def-paper);
  opacity: 0;
  clip-path: inset(0 0 10% 0);
  text-align: left;
  transform: translateY(42px) scale(0.992);
  transition:
    clip-path 780ms var(--def-ease) calc(var(--reveal-index, 0) * 55ms),
    opacity 700ms var(--def-ease) calc(var(--reveal-index, 0) * 55ms),
    transform 780ms var(--def-ease) calc(var(--reveal-index, 0) * 55ms);
}

.definitive-site .def-work-grid .campaign-card.is-revealed {
  opacity: 1;
  clip-path: inset(0);
  transform: none;
}

.definitive-site .def-work-grid .campaign-media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--def-bg-raised);
  transition: transform 520ms var(--def-ease);
}

.definitive-site .def-work-grid .campaign-media::after {
  position: absolute;
  inset: 0;
  z-index: 1;
  content: "";
  background: linear-gradient(to top, rgba(5, 6, 10, 0.82), transparent 54%);
  pointer-events: none;
}

.definitive-site .def-work-grid .campaign-still,
.definitive-site .def-work-grid .campaign-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.definitive-site .def-work-grid .campaign-credit {
  position: absolute;
  right: 1.1rem;
  bottom: 1rem;
  left: 1.1rem;
  z-index: 2;
  display: block;
  padding: 0;
}

.definitive-site .def-work-grid .campaign-title {
  display: block;
  font-family: var(--def-display);
  font-size: clamp(1.3rem, 2vw, 2rem);
  font-weight: 400;
  line-height: 1.05;
  text-transform: none;
}

.definitive-site .def-work-grid .campaign-client {
  display: block;
  margin-bottom: 0.25rem;
  font-family: var(--def-body);
  font-size: 0.64rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

@media (hover: hover) and (pointer: fine) {
  .definitive-site .def-work-grid:has(.campaign-card.is-previewing) .campaign-card:not(.is-previewing) {
    opacity: 0.38;
    transform: scale(0.986);
  }
}

.definitive-site .def-expertise {
  padding-top: clamp(7rem, 12vw, 12rem);
  padding-bottom: clamp(7rem, 12vw, 12rem);
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-service-list {
  border-top: 1px solid var(--def-line);
}

.definitive-site .def-service-list article {
  display: grid;
  grid-template-columns: clamp(3.2rem, 5vw, 5rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  padding: clamp(1.5rem, 3vw, 2.6rem) 0;
  border-bottom: 1px solid var(--def-line);
}

.definitive-site .def-service-list svg {
  width: clamp(2.4rem, 4vw, 4rem);
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1;
  opacity: 0.55;
}

.definitive-site .def-service-list h3 {
  margin-bottom: 0.45rem;
  font-size: clamp(1.8rem, 3.6vw, 3.6rem);
  line-height: 1.05;
}

.definitive-site .def-service-list p {
  max-width: 42rem;
  color: var(--def-muted);
}

.definitive-site .def-photo-motion {
  padding-top: clamp(6rem, 10vw, 10rem);
  padding-bottom: clamp(7rem, 12vw, 12rem);
  border-top: 1px solid var(--def-line);
  background: var(--def-bg);
}

.definitive-site .def-photo-motion .photo-intro h2 {
  max-width: 10ch;
  font-family: var(--def-display);
  font-size: clamp(3.5rem, 7vw, 7.4rem);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 0.98;
  text-transform: none;
}

.definitive-site .def-photo-motion .photo-frame {
  background: var(--def-bg-raised);
}

.definitive-site .def-instagram {
  padding-top: clamp(7rem, 11vw, 11rem);
}

.definitive-site .def-instagram .instagram-heading {
  gap: 0.8rem;
}

.definitive-site .def-instagram .instagram-heading > div {
  justify-self: start;
}

.definitive-site .def-instagram .ig-avatar {
  position: relative;
  width: 6rem;
  height: 6rem;
  padding: 0.22rem;
  border: 0;
  background: linear-gradient(145deg, #feda75, #d62976 52%, #4f5bd5);
}

.definitive-site .def-instagram .ig-avatar::after {
  position: absolute;
  inset: 0.22rem;
  border: 3px solid var(--def-bg);
  border-radius: 50%;
  content: "";
  pointer-events: none;
}

.definitive-site .def-logo-track a {
  display: grid;
  min-width: clamp(6.5rem, 10vw, 10.5rem);
  min-height: 5rem;
  place-items: center;
  opacity: 0.72;
  transition: opacity 220ms ease, filter 260ms ease, transform 320ms var(--def-ease);
}

.definitive-site .def-logo-track a:hover,
.definitive-site .def-logo-track a:focus-visible {
  opacity: 1;
  transform: translateY(-0.25rem);
}

.definitive-site .def-logo-track img {
  width: 100%;
}

.definitive-site .def-close {
  min-height: min(62rem, 100dvh);
}

.definitive-site .def-close-media {
  perspective: 1000px;
}

/* A frame, never a hole — same rule as the expertise cards. The closing wall
   is eleven lazy images at the very bottom of the page; behind 48MB of
   self-hosted video they arrived so late the finale rendered as eleven empty
   rectangles. They load with the document at low priority now (668KB against
   that 48MB), and this tint means an in-flight frame still reads as a frame. */
.definitive-site .def-close-media button {
  background: rgb(244 241 235 / 0.045);
}

/* Round 16 item 1. This rule dates from when the closing wall WAS a set of
   bare <img>s. The wall is buttons now, and every visible transform lives on
   the button - so the breathe and the will-change here were animating and
   permanently compositing eleven images that nothing looks at. They were not
   free: eleven always-on compositor layers each running an infinite transform
   keyframe. Measured on a 6x-throttled 390x844 phone, dropping just these two
   declarations moved a scripted full-page scroll from 31.9fps to 45.9fps and
   cut the share of frames over 50ms from 25.8% to 18.2%.
   The layout properties stay: `button > img` overrides them, but they are the
   fallback if the markup ever loses its buttons again. */
.definitive-site .def-close-media img {
  width: clamp(9rem, 16vw, 17rem);
  opacity: 0.82;
  filter: saturate(0.85) contrast(1.08);
  transition: filter 300ms ease, opacity 300ms ease;
}

.definitive-site .def-close-media img:nth-child(1) { top: 8%; left: 2%; --base-rot: -7deg; animation-delay: -1s; }
.definitive-site .def-close-media img:nth-child(2) { top: 5%; right: 3%; --base-rot: 5deg; animation-delay: -5s; }
.definitive-site .def-close-media img:nth-child(3) { top: 37%; left: 8%; --base-rot: 3deg; animation-delay: -3s; }
.definitive-site .def-close-media img:nth-child(4) { top: 38%; right: 7%; --base-rot: -4deg; animation-delay: -7s; }
.definitive-site .def-close-media img:nth-child(5) { bottom: 3%; left: 1%; --base-rot: 6deg; animation-delay: -2s; }
.definitive-site .def-close-media img:nth-child(6) { bottom: 5%; right: 2%; --base-rot: -5deg; animation-delay: -6s; }
.definitive-site .def-close-media img:nth-child(7) { bottom: 0; left: 26%; --base-rot: -2deg; animation-delay: -4s; }
.definitive-site .def-close-media img:nth-child(8) { bottom: -1%; right: 25%; --base-rot: 3deg; animation-delay: -8s; }

@keyframes def-postcard-breathe {
  from { transform: translate3d(0, -8px, 0) rotate(var(--base-rot)) scale(0.98); }
  to { transform: translate3d(0, 11px, 22px) rotate(calc(var(--base-rot) + 1.5deg)) scale(1.025); }
}

.definitive-site .def-close::after {
  background: radial-gradient(circle at center, rgba(6, 7, 10, 0.12), rgba(6, 7, 10, 0.88) 72%);
}

.definitive-site .def-close-copy h2 {
  font-size: clamp(4.5rem, 9vw, 10rem);
}

.definitive-site .def-footer {
  position: relative;
  isolation: isolate;
  display: flex;
  min-height: clamp(25rem, 54svh, 36rem);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  padding: clamp(4rem, 8vh, 6rem) var(--def-pad) 2rem;
  overflow: hidden;
  background:
    radial-gradient(circle at 20% 22%, rgba(199, 218, 255, 0.5) 0 1px, transparent 1.5px),
    radial-gradient(circle at 76% 34%, rgba(247, 234, 210, 0.42) 0 1px, transparent 1.7px),
    radial-gradient(circle at 48% 75%, rgba(199, 218, 255, 0.34) 0 1px, transparent 1.6px),
    radial-gradient(ellipse 60% 50% at 50% 55%, rgba(62, 83, 130, 0), transparent 72%),
    var(--def-bg);
  background-size: 170px 170px, 230px 230px, 290px 290px, auto, auto;
  text-align: center;
  animation: def-footer-sky 36s linear infinite;
}

@keyframes def-footer-sky {
  to { background-position: 22px 44px, -31px 19px, 17px -36px, 0 0, 0 0; }
}

.definitive-site .def-footer-logo {
  width: clamp(7.5rem, 12vw, 11rem);
}

.definitive-site .def-footer .footer-email {
  grid-column: auto;
  justify-self: auto;
  padding-bottom: 0.2rem;
  border-bottom: 1px solid var(--def-line);
  font-size: clamp(1.15rem, 2.8vw, 2.2rem);
  letter-spacing: -0.015em;
}

.definitive-site .def-footer .footer-social {
  display: flex;
  grid-column: auto;
  grid-row: auto;
  gap: 0.5rem;
}

.definitive-site .def-footer .footer-social a {
  display: grid;
  width: 3.1rem;
  height: 3.1rem;
  place-items: center;
  border: 1px solid var(--def-line);
  opacity: 0.75;
}

.definitive-site .def-footer .footer-social svg {
  width: 1.75rem;
  height: 1.75rem;
}

.definitive-site .def-footer .footer-bottom {
  position: absolute;
  right: var(--def-pad);
  bottom: 1.4rem;
  left: var(--def-pad);
  display: flex;
  grid-column: auto;
  justify-content: space-between;
  padding-top: 1rem;
}

@media (max-width: 900px) {
  .definitive-site .def-galaxy-marks a {
    width: clamp(4rem, 13vw, 6rem);
  }

  .definitive-site .def-work-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .definitive-site .def-close-media img {
    width: clamp(8rem, 23vw, 13rem);
  }
}

@media (max-width: 720px) {
  .definitive-site .hero-fallback,
  .definitive-site .def-hero-reel {
    width: max(100vw, 177.78vh);
    height: max(100vh, 56.25vw);
    max-width: none;
  }
}

@media (max-width: 620px) {
  .definitive-site .def-hero-meta {
    align-items: flex-end;
  }

  .definitive-site .hero-fallback,
  .definitive-site .def-hero-reel {
    width: max(100vw, 177.78vh);
    height: max(100vh, 56.25vw);
    max-width: none;
  }

  .definitive-site .def-galaxy {
    height: 250dvh;
    min-height: 1650px;
  }

  .definitive-site .galaxy-copy {
    width: calc(100% - 2.5rem);
    font-size: clamp(2rem, 8.4vw, 2.8rem);
  }

  .definitive-site .def-galaxy-marks a {
    width: clamp(3.6rem, 18vw, 5rem);
    min-height: 2.7rem;
    padding: 0.45rem;
  }

  .definitive-site .def-galaxy-marks a:nth-child(2n) {
    width: clamp(4rem, 20vw, 5.5rem);
  }

  .definitive-site .def-galaxy-marks a:nth-child(5),
  .definitive-site .def-galaxy-marks a:nth-child(7) {
    display: none;
  }

  .definitive-site .def-work-grid {
    grid-template-columns: 1fr;
    gap: 0.7rem;
  }

  .definitive-site .def-service-list article {
    grid-template-columns: 2.8rem minmax(0, 1fr);
    gap: 1rem;
  }

  .definitive-site .def-photo-motion .photo-intro {
    align-items: flex-start;
    flex-direction: column;
    padding-inline: var(--def-pad);
  }

  .definitive-site .def-instagram .ig-avatar {
    width: 5rem;
    height: 5rem;
  }

  .definitive-site .def-close {
    min-height: 48rem;
  }

  .definitive-site .def-close-media img {
    width: 35vw;
  }

  .definitive-site .def-close-media img:nth-child(3),
  .definitive-site .def-close-media img:nth-child(4) {
    top: 58%;
  }

  .definitive-site .def-close-media img:nth-child(7),
  .definitive-site .def-close-media img:nth-child(8) {
    display: none;
  }

  .definitive-site .def-footer {
    gap: 1.2rem;
  }

  .definitive-site .def-footer .footer-email {
    font-size: clamp(1.05rem, 6vw, 1.65rem);
  }

  .definitive-site .def-footer .footer-bottom {
    align-items: center;
    flex-direction: column;
    gap: 0.35rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks a {
    opacity: 0.8;
    transform: translate(-50%, -50%) scale(1);
  }

  .definitive-site .def-close-media img,
  .definitive-site .def-footer {
    animation: none;
  }
}

/* Review pass 02 must remain last in the cascade. */
.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-photo-motion,
.definitive-site .def-about,
.definitive-site .def-instagram,
.definitive-site .def-client-proof,
.definitive-site .def-learn,
.definitive-site .def-close,
.definitive-site .def-footer { border: 0 !important; }

.definitive-site .def-galaxy {
  height: 225dvh;
  min-height: 1500px;
}

.definitive-site .galaxy-copy {
  width: min(90vw, 76rem);
  font-family: var(--def-body);
  font-size: clamp(1.35rem, 3.4vw, 3.45rem);
  font-weight: 500;
  letter-spacing: 0.095em;
  line-height: 1.15;
  text-transform: uppercase;
}

.definitive-site .def-galaxy-marks a,
.definitive-site .def-galaxy-marks a:nth-child(2n) {
  width: clamp(5.2rem, 9vw, 9.5rem);
  min-height: 0;
  padding: 0;
  border: 0;
  background: transparent;
  opacity: var(--mark-opacity, 0);
  transform: translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px))) scale(var(--mark-scale, 0.36));
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.definitive-site .def-galaxy-marks a:nth-child(3n) { width: clamp(4.4rem, 7.4vw, 7.8rem); }
.definitive-site .def-galaxy-marks img {
  width: 100%;
  max-height: 4.25rem;
  object-fit: contain;
  filter: drop-shadow(0 0 1px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 0.8rem rgba(0, 0, 0, 0.62));
  opacity: 1;
}

.definitive-site .def-photo-motion .photo-intro { align-items: center; }
.definitive-site .def-instagram .ig-avatar { transform: translateY(0.38rem); }

.definitive-site .def-close {
  min-height: clamp(49rem, 100dvh, 62rem);
  background: var(--def-bg);
}

.definitive-site .def-close-media button > img,
.definitive-site .def-close-media button > iframe {
  position: absolute !important;
  top: 0 !important;
  right: auto !important;
  bottom: auto !important;
  left: 0 !important;
  width: 100% !important;
  height: 100%;
  opacity: 1;
  transform: none !important;
  animation: none !important;
}

.definitive-site .def-close-media button > img { filter: saturate(1.12) contrast(1.02); }
.definitive-site .def-close-media button > iframe { opacity: 0; }
.definitive-site .def-close-media button.is-video-ready > iframe { opacity: 1; }
.definitive-site .def-close::after { background: radial-gradient(circle at center, rgba(6, 7, 10, 0.22), rgba(6, 7, 10, 0.72) 76%); }

.definitive-site .def-footer {
  position: relative;
  isolation: isolate;
  display: block;
  min-height: 31rem;
  padding: 0;
  overflow: hidden;
  background: #12140f;
  text-align: left;
  animation: none;
}

.definitive-site .def-footer-grid {
  display: grid;
  min-height: 31rem;
  grid-template-columns: 1.2fr 0.8fr 1.15fr 0.75fr;
  gap: clamp(2rem, 5vw, 6rem);
  align-items: start;
  padding: clamp(6rem, 10vw, 8rem) var(--def-pad) 2rem;
}

.definitive-site .def-footer-logo { width: clamp(12rem, 18vw, 18rem); }
.definitive-site .def-footer .footer-nav,
.definitive-site .def-footer .footer-contact,
.definitive-site .def-footer .footer-social {
  display: flex;
  grid-column: auto;
  grid-row: auto;
  flex-direction: column;
  gap: 0.8rem;
}
.definitive-site .def-footer .footer-email {
  grid-column: auto;
  justify-self: auto;
  padding: 0;
  border: 0;
  font-family: var(--def-body);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
}
.definitive-site .def-footer .footer-social a { display: block; width: auto; height: auto; border: 0; }
.definitive-site .def-footer .footer-bottom {
  position: static;
  right: auto;
  bottom: auto;
  left: auto;
  display: flex;
  grid-column: 1 / -1;
  align-self: end;
  justify-content: space-between;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
}

@media (max-width: 900px) {
  .definitive-site .def-footer-grid { grid-template-columns: 1.2fr 0.8fr 1fr; }
  .definitive-site .def-footer .footer-social { display: none; }
}

@media (max-width: 620px) {
  .definitive-site .def-galaxy { height: 205dvh; min-height: 1280px; }
  .definitive-site .galaxy-copy {
    width: calc(100% - 2.5rem);
    font-size: clamp(1.05rem, 5.3vw, 1.5rem);
    letter-spacing: 0.08em;
  }
  .definitive-site .def-galaxy-marks a,
  .definitive-site .def-galaxy-marks a:nth-child(2n),
  .definitive-site .def-galaxy-marks a:nth-child(3n) {
    display: grid;
    width: clamp(3.7rem, 17vw, 5rem);
    min-height: 0;
    padding: 0;
  }
  .definitive-site .def-galaxy-marks a:nth-child(5),
  .definitive-site .def-galaxy-marks a:nth-child(7) { display: none; }
  .definitive-site .def-photo-motion .photo-intro { align-items: center; flex-direction: row; }
  .definitive-site .def-instagram .ig-avatar { transform: translateY(0.2rem); }
  .definitive-site .def-close { display: flex; min-height: 0; }
  .definitive-site .def-close-media button > img,
  .definitive-site .def-close-media button > iframe { width: 100% !important; }
  .definitive-site .def-footer,
  .definitive-site .def-footer-grid { min-height: 35rem; }
  .definitive-site .def-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 3rem 1.5rem;
    padding-top: 5rem;
  }
  .definitive-site .def-footer-logo { grid-column: 1 / -1; width: min(15rem, 58vw); }
  .definitive-site .def-footer .footer-nav,
  .definitive-site .def-footer .footer-contact { display: flex; }
  .definitive-site .def-footer .footer-bottom { align-items: flex-start; flex-direction: column; gap: 0.45rem; }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks a {
    opacity: 0.9;
    transform: translate(-50%, -50%) scale(1);
  }
}

/* August review pass 03: first paint, tighter Galaxy, responsive film rail. */
/* Split on purpose: an unsupported :has() in a selector LIST drops the
   whole rule in older Safari - taking the body fallback down with it. */
html:has(body.definitive-site) { background: #06070a; color-scheme: dark; }
body.definitive-site { background: #06070a; color-scheme: dark; }

.definitive-site .hero-media {
  clip-path: none !important;
  opacity: 1;
  transform: scale(1);
}
.definitive-site .hero-fallback {
  animation: none !important;
  transform: translate(-50%, -50%) scale(1.015) !important;
}

@media (prefers-reduced-motion: no-preference) {
  .definitive-site.motion-ready:not(.is-page-ready) .hero-media {
    clip-path: none !important;
    opacity: 0.88;
    transform: scale(1.012);
  }
  .definitive-site.motion-ready.is-page-ready .hero-media {
    clip-path: none !important;
    opacity: 1;
    transform: scale(1);
    transition: opacity 720ms ease, transform 1400ms var(--def-ease);
  }
  .definitive-site.motion-ready:not(.is-page-ready) .site-nav { transform: translateY(-8px); }
}

.definitive-site .nav-group::after {
  position: absolute;
  top: 100%;
  right: -1rem;
  left: -1rem;
  height: 0.8rem;
  content: "";
}
.definitive-site .nav-submenu { top: calc(100% + 0.68rem); overflow: visible; }
.definitive-site .nav-cta { padding: 0.85rem 1.15rem; }

.definitive-site .def-galaxy {
  height: 178dvh;
  min-height: 1120px;
  --galaxy-copy-opacity: 0;
  --galaxy-copy-scale: 0.985;
}
.definitive-site .def-work { padding-top: clamp(3.75rem, 6vw, 6rem); }
.definitive-site .galaxy-copy { opacity: var(--galaxy-copy-opacity, 0); }
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  position: absolute;
  top: var(--mark-y);
  left: var(--mark-x);
  display: grid;
  width: clamp(5rem, 8vw, 8.6rem);
  min-height: 0;
  padding: 0;
  place-items: center;
  border: 0;
  background: transparent;
  opacity: var(--mark-opacity, 0);
  pointer-events: none;
  transform: translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px))) scale(var(--mark-scale, 0.36));
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n) { width: clamp(4.4rem, 7vw, 7.5rem); }
.definitive-site .def-galaxy-marks [data-galaxy-mark] img {
  width: 100%;
  max-height: 3.9rem;
  object-fit: contain;
  filter: grayscale(1) brightness(0) invert(1) drop-shadow(0 0 0.7rem rgba(133, 162, 220, 0.22));
  opacity: 0.92;
}

.definitive-site .def-film-stage { touch-action: pan-y; cursor: grab; }
.definitive-site .def-film-stage.is-dragging { cursor: grabbing; }
.definitive-site .def-film-card { transition: visibility 0s linear 180ms; }
.definitive-site .def-film-card.is-near { transition-delay: 0s; }
.definitive-site .def-film-card > span { right: auto; }
.definitive-site .def-film-card > span small { display: block; }
.definitive-site .def-film-backdrop iframe {
  position: absolute;
  z-index: 0;
  top: 50%;
  left: 50%;
  width: max(100%, 177.78vh);
  height: max(100%, 56.25vw);
  border: 0;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(1.1);
  transition: opacity 650ms ease;
}
.definitive-site .def-film-roll.is-ambient-ready .def-film-backdrop iframe { opacity: 0.42; }
.definitive-site .def-film-roll.is-ambient-ready .def-film-backdrop img { opacity: 0; }
.definitive-site .def-film-backdrop::after {
  z-index: 2;
  background: rgba(5, 6, 10, 0.7);
  backdrop-filter: blur(48px) saturate(110%);
  -webkit-backdrop-filter: blur(48px) saturate(110%);
}
.definitive-site .def-film-cursor {
  position: fixed;
  z-index: 60;
  top: 0;
  left: 0;
  display: grid;
  width: 4.6rem;
  height: 4.6rem;
  place-items: center;
  border-radius: 50%;
  /* Round 35: a play button, not the words "View film". Giovani is right that
     the glyph reads faster than a label at cursor size, and it survives the
     emoji-presentation problem that bit us on other routes because it is drawn
     in CSS rather than typed. */
  background: rgba(244, 241, 235, 0.94);
  color: #06070a;
  font-size: 0;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(calc(var(--cursor-x, -10rem) - 50%), calc(var(--cursor-y, -10rem) - 50%), 0) scale(0.75);
  transition: opacity 180ms ease, transform 280ms var(--def-ease);
}
.definitive-site .def-film-cursor::after {
  content: "";
  width: 1.05rem;
  height: 1.2rem;
  margin-left: 0.18rem;      /* a triangle's optical centre sits left of its box */
  background: #06070a;
  clip-path: polygon(0 0, 100% 50%, 0 100%);
}

.definitive-site .def-film-cursor.is-visible {
  opacity: 1;
  transform: translate3d(calc(var(--cursor-x, -10rem) - 50%), calc(var(--cursor-y, -10rem) - 50%), 0) scale(1);
}

.definitive-site .def-expertise,
.definitive-site .def-learn {
  background:
    radial-gradient(ellipse 70% 55% at 12% 20%, rgba(50, 69, 111, 0), transparent 68%),
    radial-gradient(ellipse 54% 48% at 86% 78%, rgba(92, 61, 55, 0), transparent 72%),
    linear-gradient(180deg, #06070a, #080910 55%, #06070a);
}
.definitive-site .def-photo-motion .photo-intro h2 {
  margin: 0;
  max-width: none;
  font-size: clamp(3.1rem, 7vw, 7rem);
  line-height: 0.95;
}
.definitive-site .instagram-tile-icon { display: none !important; }

.definitive-site .def-close-media button {
  aspect-ratio: 16 / 9;
  opacity: 1;
  transition: opacity 700ms var(--def-ease), transform 720ms var(--def-ease), box-shadow 350ms ease;
}
.definitive-site .def-close:not(.is-visible) .def-close-media button {
  opacity: 0;
  transform: translate3d(var(--shift-x, 0px), calc(var(--shift-y, 0px) + 34px), 0) rotate(var(--r)) scale(0.94);
}
.definitive-site .def-close.is-visible .def-close-media button:nth-child(2) { transition-delay: 70ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(3) { transition-delay: 130ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(4) { transition-delay: 190ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(5) { transition-delay: 250ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(6) { transition-delay: 310ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(7) { transition-delay: 370ms; }
.definitive-site .def-close.is-visible .def-close-media button:nth-child(8) { transition-delay: 430ms; }
.definitive-site .def-close-media button > img { filter: none; }
.definitive-site .def-close-media button > iframe { background: transparent; }

.definitive-site .def-footer {
  min-height: 24rem;
  background:
    radial-gradient(circle at 16% 28%, rgba(224, 232, 255, 0.55) 0 1px, transparent 1.4px),
    radial-gradient(circle at 76% 68%, rgba(247, 234, 210, 0.4) 0 1px, transparent 1.5px),
    radial-gradient(circle at 48% 44%, rgba(199, 218, 255, 0.34) 0 1px, transparent 1.4px),
    radial-gradient(ellipse 65% 80% at 50% 36%, rgba(48, 66, 106, 0), transparent 70%),
    #06070a;
  background-size: 190px 190px, 260px 260px, 330px 330px, auto, auto;
}
.definitive-site .def-footer::before {
  position: absolute;
  z-index: 0;
  top: 0;
  right: 0;
  left: 0;
  height: 8rem;
  content: "";
  background: linear-gradient(to bottom, #06070a, transparent);
  pointer-events: none;
}
.definitive-site .def-footer-grid {
  position: relative;
  z-index: 1;
  min-height: 24rem;
  grid-template-columns: 1.1fr 0.7fr 1fr 0.7fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding: clamp(4.5rem, 7vw, 6rem) var(--def-pad) 1.5rem;
}
.definitive-site .def-footer-logo { width: clamp(9rem, 14vw, 13rem); }

@media (max-width: 620px) {
  .definitive-site .hero-fallback {
    content: url("assets/images/proj-gatorade-hero.webp");
    width: 100vw;
    height: 100dvh;
    object-position: 50% 42%;
  }
  .definitive-site .def-galaxy { height: 170dvh; min-height: 1050px; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark] { width: clamp(3.2rem, 15vw, 4.5rem); }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(n + 9) { display: none; }
  .definitive-site .def-film-cursor { display: none; }
  .definitive-site .def-photo-motion .photo-intro {
    align-items: flex-start;
    flex-direction: column;
    gap: 1.4rem;
  }
  .definitive-site .def-instagram .instagram-heading {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
  .definitive-site .def-instagram h2 {
    font-size: clamp(1.35rem, 6.4vw, 1.75rem);
    overflow-wrap: normal;
    white-space: nowrap;
  }
  .definitive-site .def-close-media button { aspect-ratio: 16 / 9; }
  .definitive-site .def-footer,
  .definitive-site .def-footer-grid { min-height: 30rem; }
  .definitive-site .def-footer-grid {
    grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
    gap: 2rem 1.25rem;
    padding-top: 4rem;
  }
  .definitive-site .def-footer-logo { grid-column: 1 / -1; }
  .definitive-site .def-footer .footer-email {
    max-width: none;
    overflow-wrap: normal;
    white-space: nowrap;
  }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks [data-galaxy-mark] {
    opacity: 0.9;
    transform: translate(-50%, -50%) scale(1);
  }
  .definitive-site .def-close-media button { opacity: 1 !important; }
}

/* Review pass 03: manual film rail, brighter closing field, centered footer. */
.definitive-site .def-film-card iframe {
  transition: opacity 160ms ease;
}
.definitive-site .def-film-card.is-video-ready:not(.is-active) iframe {
  opacity: 0;
}
.definitive-site .def-film-backdrop img {
  opacity: 0.58;
  transition: none;
}
.definitive-site .def-film-backdrop::after {
  z-index: 1;
  background: rgba(5, 6, 10, 0.62);
  backdrop-filter: blur(42px) saturate(108%);
  -webkit-backdrop-filter: blur(42px) saturate(108%);
}
.definitive-site .def-film-roll.is-ambient-ready .def-film-backdrop iframe {
  opacity: 0.38;
}

.definitive-site .def-close::before {
  z-index: 0;
  background: linear-gradient(180deg, rgba(6, 7, 10, 0.2), rgba(6, 7, 10, 0.08) 48%, rgba(6, 7, 10, 0.28));
}
.definitive-site .def-close::after {
  z-index: 0;
  background: radial-gradient(circle at center, rgba(6, 7, 10, 0.62) 0 22%, rgba(6, 7, 10, 0.16) 50%, rgba(6, 7, 10, 0.3) 100%);
}
.definitive-site .def-close-media {
  z-index: 1;
}
.definitive-site .def-close-media button > img,
.definitive-site .def-close-media button > iframe {
  filter: saturate(1.18) contrast(1.06) brightness(1.08);
}
.definitive-site .def-close:not(.is-visible) .def-close-media button {
  opacity: 1;
}

.definitive-site .def-footer,
.definitive-site .def-footer-grid {
  min-height: 28rem;
}
.definitive-site .def-footer-grid {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.45rem;
  padding: clamp(4rem, 7vw, 5.5rem) var(--def-pad) 1.4rem;
  text-align: center;
}
.definitive-site .def-footer-logo {
  width: clamp(10rem, 14vw, 12.5rem);
  align-self: center;
  margin-bottom: 0.5rem;
}
.definitive-site .def-footer .footer-nav,
.definitive-site .def-footer .footer-contact,
.definitive-site .def-footer .footer-social {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.7rem 1.35rem;
  text-align: center;
}
.definitive-site .def-footer .footer-contact {
  gap: 0.65rem 1rem;
}
.definitive-site .def-footer .footer-social {
  gap: 1.15rem;
}
.definitive-site .def-footer .footer-nav a:hover,
.definitive-site .def-footer .footer-contact a:hover,
.definitive-site .def-footer .footer-social a:hover {
  transform: translateY(-0.15rem);
}
.definitive-site .def-footer .footer-bottom {
  width: 100%;
  margin-top: auto;
}

@media (max-width: 620px) {
  .definitive-site .def-footer,
  .definitive-site .def-footer-grid {
    min-height: 32rem;
  }
  .definitive-site .def-footer-grid {
    gap: 1.25rem;
    padding-top: 3.75rem;
  }
  .definitive-site .def-footer-logo {
    width: min(12rem, 58vw);
  }
  .definitive-site .def-footer .footer-nav {
    max-width: 18rem;
  }
  .definitive-site .def-footer .footer-contact {
    flex-direction: column;
    gap: 0.45rem;
  }
  .definitive-site .def-footer .footer-email {
    font-size: 0.82rem;
  }
}

/* ============================================================
   Round 11 - item 1 + 2: immediate playback and the film theater.
   ============================================================ */

/* Item 1. The poster and the player's first painted frame are the same
   picture now (poster cut at the timestamp playback starts from), so the
   hand-off is a short cross-fade rather than a held reveal. */
.definitive-site .def-film-card iframe {
  transition: opacity 180ms ease;
}
.definitive-site .def-close-media button > iframe {
  transition: opacity 200ms ease;
}

/* Item 2. Theater. The card itself is promoted to a fixed 16:9 rect, so the
   live player travels with it and never reloads. */
.definitive-site .def-film-stage .def-film-card.is-expanded {
  position: fixed;
  z-index: 90;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: 0 4rem 12rem rgba(0, 0, 0, 0.72);
  opacity: 1;
  cursor: default;
  transform: none;
  transform-origin: center;
  transition: transform 620ms var(--def-ease), border-radius 620ms var(--def-ease);
  will-change: transform;
}
.definitive-site .def-film-card.is-expanded::after,
.definitive-site .def-film-card.is-expanded > span {
  opacity: 0;
}
.definitive-site .def-film-card.is-expanded iframe {
  z-index: 2;
  pointer-events: auto;
}
/* Only once the player has actually painted - otherwise expanding covers a
   perfectly good poster with an empty player surface. */
.definitive-site .def-film-card.is-expanded.is-video-ready iframe { opacity: 1; }

.definitive-site .def-film-theater-scrim {
  position: fixed;
  z-index: 9000;
  inset: 0;
  background: rgba(4, 5, 7, 0.975);
  opacity: 0;
  pointer-events: none;
  transition: opacity 420ms var(--def-ease);
}
body.film-theater-open .def-film-theater-scrim {
  opacity: 1;
  pointer-events: auto;
}
/* The section has to out-rank the scrim as a whole - it isolates, so the
   card's own z-index is meaningless outside it. The rail's other cards stand
   down while the theater is open. */
.definitive-site .def-film-roll.is-theater-open { z-index: 9005; }
.definitive-site .def-film-roll.is-theater-open .def-film-stage { z-index: 5; }
/* The section rides above the scrim so the card can - which means the rail's
   own chrome has to recede, or it would sit on top of the scrim too. */
.definitive-site .def-film-roll.is-theater-open .def-film-roll-head,
.definitive-site .def-film-roll.is-theater-open .def-film-controls,
.definitive-site .def-film-roll.is-theater-open .def-film-backdrop,
.definitive-site .def-film-roll.is-theater-open::before,
.definitive-site .def-film-roll.is-theater-open::after {
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease;
}
.definitive-site .def-film-roll.is-theater-open .def-film-card:not(.is-expanded) {
  opacity: 0;
  transition: opacity 260ms ease;
}

.definitive-site .def-film-theater-chrome {
  position: fixed;
  z-index: 9010;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 320ms ease 120ms;
}
body.film-theater-open .def-film-theater-chrome { opacity: 1; }

.definitive-site .def-film-theater-close {
  position: absolute;
  top: clamp(1rem, 2.4vw, 2rem);
  right: clamp(1rem, 2.4vw, 2rem);
  display: grid;
  width: 2.9rem;
  height: 2.9rem;
  place-items: center;
  border: 1px solid var(--def-line);
  border-radius: 50%;
  background: rgba(6, 7, 10, 0.72);
  color: var(--def-paper);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
  transition: background-color 200ms ease, border-color 200ms ease;
}
.definitive-site .def-film-theater-close:hover,
.definitive-site .def-film-theater-close:focus-visible {
  border-color: rgba(244, 241, 235, 0.5);
  background: rgba(244, 241, 235, 0.12);
}

/* A floor under the control row so it reads over bright frames too. */
.definitive-site .def-film-theater-chrome::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: clamp(6rem, 14vh, 10rem);
  content: "";
  background: linear-gradient(to top, rgba(4, 5, 7, 0.78), transparent);
  pointer-events: none;
}

.definitive-site .def-film-theater-bar {
  position: absolute;
  z-index: 1;
  right: clamp(1rem, 4vw, 3.5rem);
  bottom: clamp(1rem, 3vw, 2.4rem);
  left: clamp(1rem, 4vw, 3.5rem);
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.6vw, 1.35rem);
  pointer-events: auto;
}
.definitive-site .def-film-theater-bar button {
  flex: none;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--def-line);
  border-radius: 999px;
  background: rgba(6, 7, 10, 0.72);
  color: var(--def-paper);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color 200ms ease, border-color 200ms ease;
}
.definitive-site .def-film-theater-bar button:hover,
.definitive-site .def-film-theater-bar button:focus-visible {
  border-color: rgba(244, 241, 235, 0.5);
  background: rgba(244, 241, 235, 0.12);
}
.definitive-site .def-film-theater-track {
  position: relative;
  flex: 1 1 auto;
  height: 2px;
  overflow: hidden;
  background: rgba(244, 241, 235, 0.2);
  cursor: pointer;
}
.definitive-site .def-film-theater-track::before {
  position: absolute;
  inset: -0.75rem 0;
  content: "";
}
.definitive-site .def-film-theater-track i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--def-paper);
  transform: scaleX(0);
  transform-origin: left center;
}
.definitive-site .def-film-theater-title {
  flex: none;
  margin: 0;
  color: var(--def-muted);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* The theater lives inside the film section's stacking context, so the fixed
   site chrome has to stand down while it is open. */
body.film-theater-open { overflow: hidden; }
body.film-theater-open .site-nav.site-nav,
body.film-theater-open .def-film-cursor {
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms ease;
}

@media (max-width: 620px) {
  .definitive-site .def-film-theater-title { display: none; }
  .definitive-site .def-film-theater-bar button { font-size: 0.56rem; padding: 0.45rem 0.7rem; }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-film-stage .def-film-card.is-expanded { transition: none; }
  .definitive-site .def-film-theater-scrim,
  .definitive-site .def-film-theater-chrome { transition: none; }
}

/* ============================================================
   Round 11 - item 3: the galaxy chapter.
   ============================================================ */

/* One set headline. The legacy sheet gave the third line font-size 1.32em and
   line-height 0.72, which is why "the galaxy." sat at a different size and
   crowded line two. All three lines now share one size, one line-height and
   one optical gap. */
.definitive-site .galaxy-copy {
  display: grid;
  justify-items: center;
  gap: 0.16em;
  line-height: 1.04;
}
.definitive-site .galaxy-copy span {
  display: block;
  line-height: inherit;
}
.definitive-site .galaxy-copy .galaxy-final-line {
  margin-top: 0;
  font-size: inherit;
  line-height: inherit;
}

/* Crisp marks. The white set is already pure white on transparent, so no
   filter pass is needed - and dropping it removes both the drop-shadow blur
   and the grayscale/invert rasterisation that was softening every edge. */
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  transform: translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px)))
    scale(var(--mark-scale, 0.94));
  transition: none;
}
.definitive-site .def-galaxy-marks [data-galaxy-mark].is-settled {
  /* At rest the mark carries no scale at all, so the SVG rasterises at its
     own layout size instead of being resampled. */
  transform: translate(-50%, -50%);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark] img {
  width: 100%;
  max-height: 3.9rem;
  object-fit: contain;
  filter: none;
  opacity: 1;
  animation: none;
  transform: none;
}

/* ============================================================
   Round 11 - item 4: the Selected Partners marquee is draggable.
   ============================================================ */
.definitive-site .def-logo-window {
  cursor: grab;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}
.definitive-site .def-logo-window.is-dragging { cursor: grabbing; }
.definitive-site .def-logo-track {
  /* The drift is driven by rAF now so it can be paused, thrown and resumed. */
  animation: none;
  will-change: transform;
}
/* Round 18 item 8: Selected Partners gets the galaxy's treatment. The marks
   are the colour set, they rest at one brightness like the ring does, and
   nothing paints behind or on them - the drop-shadow that used to fire on
   hover was the "square box" showing up around each logo, the same ink-on-
   alpha-art mistake Round 14 removed from the galaxy. Hover is opacity and
   lift only. */
.definitive-site .def-logo-track img {
  filter: none;
  opacity: 1;
}
.definitive-site .def-logo-track a { opacity: 0.82; }
.definitive-site .def-logo-track a:hover img,
.definitive-site .def-logo-track a:focus-visible img { filter: none; }
.definitive-site .def-logo-window.is-dragging .def-logo-track a { transition: none; }

/* ============================================================
   Round 11 - item 5: the "Work with us" wall.
   ============================================================ */

/* Entrance. Round 3 had pinned these to opacity 1 in every state, which
   cancelled the reveal entirely - the wall was simply there. It now rises and
   settles on a scroll-keyed stagger, like frames from his career landing on a
   wall, and the per-card delay is dropped once the wall has settled so hover
   stays instant. */
.definitive-site .def-close:not(.is-visible) .def-close-media button {
  opacity: 0;
  /* Each print arrives from slightly above, a touch large and over-rotated,
     then settles down into its final tilt - set onto the wall, not faded in.
     The oversized soft shadow tightens as it lands. */
  transform: translate3d(var(--shift-x, 0px), calc(var(--shift-y, 0px) - 26px), 0) rotate(calc(var(--r, 0deg) * 2.2)) scale(1.05);
  box-shadow: 0 2.75rem 5.5rem rgba(0, 0, 0, 0.52);
}
/* :nth-child(n) only to out-specify the round-3 per-child delay chain.
   Scoped to :not(.is-settled) so the settle-past easing applies to the
   entrance only - once the wall has landed, hover drift falls back to the
   base 720ms ease and stays calm. */
.definitive-site .def-close.is-visible:not(.is-settled) .def-close-media button:nth-child(n) {
  transition: transform 760ms cubic-bezier(0.3, 0.9, 0.32, 1.04), opacity 480ms ease-out, box-shadow 760ms var(--def-ease);
  transition-delay: calc(var(--i, 0) * 62ms);
}
.definitive-site .def-close.is-settled .def-close-media button:nth-child(n) {
  transition-delay: 0ms;
}

/* The copy zone is sacred: the two mid-band frames are pinned to the outer
   edges, and below 900px - where the headline eats most of the width - they
   step out of the composition entirely rather than crowd it. */
@media (max-width: 900px) and (min-width: 621px) {
  .definitive-site .def-close-media button[data-close-edge] { display: none; }
}

@media (max-width: 620px) {
  .definitive-site .def-close-media button { --i: 0 !important; }
}

/* ============================================================
   Round 11 - item 5b/6: closing wall clipping, and the footer.
   ============================================================ */
.definitive-site .def-close { overflow: hidden; }

/* The logo was floating a long way off the block it belongs to. Smaller, and
   sitting on the same rhythm as the rest of the column. */
.definitive-site .def-footer-logo {
  width: clamp(7.5rem, 10vw, 9.5rem);
  margin-bottom: 0;
}
.definitive-site .def-footer-grid {
  gap: 1.15rem;
}
.definitive-site .def-footer .footer-nav {
  margin-top: 0.55rem;
}

/* Location line and email share one centred axis and one rhythm. */
.definitive-site .def-footer .footer-contact {
  flex-direction: column;
  gap: 0.4rem;
  text-align: center;
}
.definitive-site .def-footer .footer-contact span,
.definitive-site .def-footer .footer-email {
  display: block;
  width: 100%;
  /* The legacy sheet gave the email a 52px top margin, which is what broke the
     two lines off each other's rhythm. */
  margin: 0;
  font-size: 0.86rem;
  letter-spacing: 0.01em;
  line-height: 1.5;
  text-align: center;
}
.definitive-site .def-footer .footer-contact span { color: var(--def-muted); }

/* Social marks, not words. */
.definitive-site .def-footer .footer-social {
  gap: 1.4rem;
  margin-top: 0.35rem;
}
.definitive-site .def-footer .footer-social a {
  display: grid;
  width: 1.35rem;
  height: 1.35rem;
  place-items: center;
  color: var(--def-muted);
  transition: color 200ms ease, transform 280ms var(--def-ease);
}
.definitive-site .def-footer .footer-social a svg {
  width: 100%;
  height: 100%;
}
.definitive-site .def-footer .footer-social a:hover,
.definitive-site .def-footer .footer-social a:focus-visible {
  color: var(--def-paper);
  opacity: 1;
  transform: translateY(-0.15rem);
}

@media (max-width: 620px) {
  .definitive-site .def-footer .footer-contact { gap: 0.35rem; }
  .definitive-site .def-footer .footer-contact span,
  .definitive-site .def-footer .footer-email { font-size: 0.8rem; }
}

/* ============================================================
   Round 11 - item 7: one type scale, one rhythm.

   Before this block the homepage carried seven different section-H2 sizes
   (115.2 / 92.2 / 115.2 / 100.8 / 106.6 / 57.6 / 103.7px at 1440), eight
   different section padding values, and two competing label treatments -
   Helvetica caps for kickers, IBM Plex Mono caps for the nav and footer.
   Everything below consumes tokens instead.
   ============================================================ */

.definitive-site {
  /* Type scale */
  --t-display: clamp(3.4rem, 7vw, 7rem);
  --t-h2: clamp(2.6rem, 5.4vw, 5.4rem);
  --t-h2-sm: clamp(1.9rem, 3.7vw, 3.7rem);
  --t-h3: clamp(1.35rem, 2.1vw, 2.1rem);
  --t-lead: clamp(1.02rem, 1.35vw, 1.3rem);
  --t-body: 1rem;
  --t-kicker: 0.69rem;
  --t-label: 0.63rem;
  --tracking-label: 0.18em;
  --leading-display: 0.98;

  /* Rhythm */
  --sec-pad-y: clamp(5.5rem, 9vw, 9rem);
  --sec-measure: 78rem;
  --card-radius: 0.35rem;
  --card-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.34);
}

/* --- One display family, one section-heading size ------------------------ */
.definitive-site .def-work .def-section-head h2,
.definitive-site .def-expertise .def-section-head h2,
.definitive-site .def-film-roll-head h2,
.definitive-site .def-photo-motion .photo-intro h2,
/* Round 18 item 7. This rule reset `margin: 0`, which silently dropped the
   1.75rem the headline used to carry - so "Kyle Loftus" sat straight on top of
   the line beneath it with nothing between them. The block gets a stated
   rhythm instead of inheriting whatever the last rule left behind: kicker,
   air, headline, more air, subline. */
.definitive-site .def-about-copy h2,
.definitive-site .def-learn-intro h2 {
  margin: 0 0 clamp(1.15rem, 1.7vw, 1.65rem);
  font-family: var(--def-display);
  font-size: var(--t-h2);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: var(--leading-display);
  text-transform: none;
}

.definitive-site .def-about-copy > .def-kicker,
.definitive-site .def-learn-intro > .def-kicker {
  margin: 0 0 clamp(0.9rem, 1.3vw, 1.25rem);
}

.definitive-site .def-about-lead {
  margin-top: 0;
  margin-bottom: clamp(1.4rem, 2.1vw, 2rem);
}
.definitive-site .def-instagram .instagram-heading h2 {
  margin: 0;
  font-size: var(--t-h2-sm);
  letter-spacing: -0.02em;
  line-height: var(--leading-display);
}
.definitive-site .def-close-copy h2 {
  font-size: var(--t-display);
  letter-spacing: -0.028em;
  line-height: var(--leading-display);
}
.definitive-site .def-service-grid h3,
.definitive-site .def-learn-cards strong {
  font-size: var(--t-h3);
  letter-spacing: -0.015em;
  line-height: 1.05;
}

/* --- One label treatment ------------------------------------------------- */
.definitive-site .def-kicker {
  margin: 0 0 0.9rem;
  color: var(--def-muted);
  font-family: var(--def-body);
  font-size: var(--t-kicker);
  font-weight: 400;
  letter-spacing: var(--tracking-label);
  line-height: 1.4;
  text-transform: uppercase;
}
.definitive-site .def-instagram .def-kicker { margin: 0 0 0.35rem; }
.definitive-site .def-client-proof > .def-kicker { margin: 0 0 0.9rem; }

/* The nav and footer chrome were the site's third typeface (IBM Plex Mono).
   Playfair Display + Helvetica only, per the brief's hard constraint, so the
   labels now share the kicker's treatment. */
.definitive-site .desktop-nav,
.definitive-site .nav-cta,
.definitive-site .menu-toggle,
.definitive-site .mobile-menu a,
.definitive-site .def-footer .footer-nav,
.definitive-site .def-footer .footer-bottom,
.definitive-site .def-film-controls,
.definitive-site .def-arrow-link {
  font-family: var(--def-body);
}
.definitive-site .desktop-nav,
.definitive-site .menu-toggle {
  font-size: var(--t-label);
  letter-spacing: var(--tracking-label);
}
.definitive-site .nav-cta {
  font-size: var(--t-label);
  font-weight: 400;
  letter-spacing: var(--tracking-label);
}
.definitive-site .def-footer .footer-nav,
.definitive-site .def-footer .footer-bottom {
  font-size: var(--t-label);
  letter-spacing: var(--tracking-label);
}
.definitive-site .mobile-menu a {
  font-family: var(--def-display);
  font-weight: 400;
  letter-spacing: -0.02em;
  text-transform: none;
}

/* --- One section rhythm -------------------------------------------------- */
.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-photo-motion,
.definitive-site .def-about,
.definitive-site .def-instagram,
.definitive-site .def-client-proof,
.definitive-site .def-learn {
  padding-block: var(--sec-pad-y);
}
.definitive-site .def-film-roll {
  padding-block: var(--sec-pad-y) calc(var(--sec-pad-y) * 0.72);
}

/* --- One card language --------------------------------------------------- */
.definitive-site .campaign-card,
.definitive-site .def-service-grid article,
.definitive-site .def-learn-cards a,
.definitive-site .def-close-media button,
.definitive-site .instagram-tile {
  border-radius: var(--card-radius);
  overflow: hidden;
}
.definitive-site .def-close-media button {
  box-shadow: var(--card-shadow);
}

/* ============================================================
   Round 11 - item 7 (cont.): 390px sweep fixes.
   ============================================================ */
@media (max-width: 620px) {
  /* The stacked wall shows its labels permanently, and several of these
     frames are bright - the labels need a floor to sit on. */
  .definitive-site .def-close-media button::after {
    position: absolute;
    z-index: 1;
    right: 0;
    bottom: 0;
    left: 0;
    height: 55%;
    content: "";
    background: linear-gradient(to top, rgba(4, 5, 7, 0.82), transparent);
    pointer-events: none;
  }
  .definitive-site .def-close-media button > span {
    z-index: 2;
    font-size: 0.58rem;
    letter-spacing: var(--tracking-label);
  }

  /* The footer was centred all the way down and then dropped a left-aligned
     bottom row after 170px of nothing. One axis, one rhythm. */
  .definitive-site .def-footer,
  .definitive-site .def-footer-grid {
    min-height: 0;
  }
  .definitive-site .def-footer-grid {
    padding-bottom: 2rem;
  }
  .definitive-site .def-footer .footer-bottom {
    align-items: center;
    flex-direction: column;
    gap: 0.6rem;
    margin-top: 1.6rem;
    padding-top: 1.6rem;
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* No opacity dampening on the marks in any path (item 3). */
  .definitive-site .def-galaxy-marks [data-galaxy-mark] { opacity: 1; }
  .definitive-site .def-logo-track { animation: none; }
}

/* Learn: the kicker was pinned to the far left with the headline pushed to the
   far right, the only section on the page that split them. Kicker above
   headline, left aligned, like every other section. */
.definitive-site .def-learn-intro {
  display: block;
  text-align: left;
}
.definitive-site .def-learn-intro h2 {
  text-align: left;
}

/* ============================================================
   Round 12 - item 7: nav/header uniformity.
   ============================================================ */

/* Nothing on the page may trap the header. The homepage nav already resolves
   to overflow:visible, but state it, because legacy-bridge.css ships an
   overflow:hidden `.site-nav` that any future ordering change would re-apply. */
.definitive-site .site-nav {
  overflow: visible;
}

/* Round 11's dropdown was rgba(8,9,13,0.96) with no blur: over the film rail
   the athlete's face read straight through the menu, which is what "clipped
   over video" looked like. It is a surface now. */
.definitive-site .nav-submenu {
  z-index: 2;
  background: rgba(8, 9, 13, 0.985);
  backdrop-filter: blur(20px) saturate(120%);
  -webkit-backdrop-filter: blur(20px) saturate(120%);
  box-shadow: 0 1.4rem 3rem rgba(0, 0, 0, 0.55);
}

/* ============================================================
   Round 12 - item 2: the hero -> galaxy seam.

   Round 11 ended the hero on an opaque floor (the scrim's bottom stop was a
   solid var(--def-bg)) and started the galaxy immediately below it, so however
   well the two colours were matched there was always a rule across the page at
   exactly 100dvh - and #06070a meeting the galaxy's blue-tinted #05060a made
   sure you could find it.

   There is no floor now. The hero's media is masked out over its bottom 28vh
   and the galaxy is tucked 18vh up underneath it, so the fold does not end on a
   colour - it dissolves, and the stars behind it are already showing through
   before the hero has left. One continuous space, no edge to align.
   ============================================================ */

.definitive-site .def-hero {
  position: relative;
  z-index: 2;
  background: transparent;
}

.definitive-site .def-galaxy {
  position: relative;
  z-index: 1;
  margin-top: -18vh;
  background: transparent;
}

/* Five stops, not two: a two-stop ramp of this length shows its own start as a
   faint band on a dark gradient. */
/* Round 22b: the fold has depth. Its media drifts at a fraction of the scroll
   (--hero-shift, written by initHeroParallax) while the mark travels at the
   page's own rate, so the fold separates into planes as you leave it. */
.definitive-site .hero-fallback,
.definitive-site .def-hero-reel {
  /* The independent `translate` property, NOT `transform`. These elements are
     centred with transform: translate(-50%,-50%) against top/left 50%, and a
     `transform` here replaced that centring outright - which is why the fold
     landed as a small rectangle offset into the corner. `translate` composes
     with transform instead of overwriting it. */
  translate: 0 var(--hero-shift, 0px);
  will-change: translate;
}

.definitive-site .hero-media {
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0,
    #000 calc(100% - 28vh),
    rgba(0, 0, 0, 0.94) calc(100% - 22vh),
    rgba(0, 0, 0, 0.74) calc(100% - 15vh),
    rgba(0, 0, 0, 0.4) calc(100% - 8.5vh),
    rgba(0, 0, 0, 0.14) calc(100% - 3.5vh),
    rgba(0, 0, 0, 0) 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 0,
    #000 calc(100% - 28vh),
    rgba(0, 0, 0, 0.94) calc(100% - 22vh),
    rgba(0, 0, 0, 0.74) calc(100% - 15vh),
    rgba(0, 0, 0, 0.4) calc(100% - 8.5vh),
    rgba(0, 0, 0, 0.14) calc(100% - 3.5vh),
    rgba(0, 0, 0, 0) 100%
  );
}

/* The scrim rides inside the masked media, so its bottom stop only has to
   settle the footage's contrast, not close the section off. */
.definitive-site .hero-scrim {
  background:
    linear-gradient(to bottom, rgba(3, 4, 7, 0.36), transparent 24%),
    linear-gradient(to top, rgba(5, 6, 10, 0.9), rgba(5, 6, 10, 0.34) 16%, transparent 38%),
    linear-gradient(90deg, rgba(3, 4, 7, 0.18), transparent 50%);
}

/* The chapter's own top vignette was a second horizontal ramp landing a few
   pixels from the first. One feather only. */
.definitive-site .galaxy-vignette {
  background:
    radial-gradient(ellipse 72% 60% at 50% 48%, transparent 30%, rgba(5, 6, 10, 0.18) 60%, rgba(5, 6, 10, 0.86) 100%),
    linear-gradient(to bottom, transparent 0, transparent 62%, rgba(5, 6, 10, 0.55) 100%);
}

/* The section below has to arrive out of the same space, not off a step. */
.definitive-site .def-work {
  background: linear-gradient(to bottom, rgba(5, 6, 10, 0) 0, rgba(6, 7, 10, 0.72) 6rem, var(--def-bg) 15rem);
}

@media (max-width: 620px) {
  .definitive-site .def-galaxy { margin-top: -14vh; }
  .definitive-site .hero-media {
    -webkit-mask-image: linear-gradient(
      to bottom, #000 0, #000 calc(100% - 22vh),
      rgba(0, 0, 0, 0.92) calc(100% - 17vh), rgba(0, 0, 0, 0.68) calc(100% - 11vh),
      rgba(0, 0, 0, 0.34) calc(100% - 6vh), rgba(0, 0, 0, 0) 100%);
    mask-image: linear-gradient(
      to bottom, #000 0, #000 calc(100% - 22vh),
      rgba(0, 0, 0, 0.92) calc(100% - 17vh), rgba(0, 0, 0, 0.68) calc(100% - 11vh),
      rgba(0, 0, 0, 0.34) calc(100% - 6vh), rgba(0, 0, 0, 0) 100%);
  }
}

/* ============================================================
   Round 12 - item 3: galaxy motion, timing and marks.
   ============================================================ */

/* Shorter chapter. 178dvh with the old lead/trail held the composition well
   past the point it had said everything; the release to Selected work now
   arrives while the field is still interesting. The -18vh tuck means the real
   added scroll is ~112vh. */
.definitive-site .def-galaxy {
  height: 130dvh;
  min-height: 880px;
}

@media (max-width: 620px) {
  .definitive-site .def-galaxy { height: 124dvh; min-height: 760px; }
}

/* Marks: +30% across the ring. */
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  width: clamp(6.5rem, 10.4vw, 11.2rem);
  /* --mark-drift-* is the per-layer idle parallax (the `translate` property is
     separate from `transform`, so it composes with the entrance transform
     without either one having to know about the other). */
  translate: var(--mark-drift-x, 0px) var(--mark-drift-y, 0px);
  animation: def-mark-drift calc(19s / (0.45 + var(--mark-layer, 0.6))) ease-in-out infinite;
  animation-delay: calc(var(--mark-delay, 0) * -1.7s);
  --mark-drift-span: calc(var(--mark-layer, 0.6) * 9px);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n) {
  width: clamp(5.7rem, 9.1vw, 9.8rem);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark] img {
  max-height: 5.1rem;
}

@keyframes def-mark-drift {
  0% { translate: 0 0; }
  33% { translate: var(--mark-drift-span) calc(var(--mark-drift-span) * -0.7); }
  66% { translate: calc(var(--mark-drift-span) * -0.8) calc(var(--mark-drift-span) * 0.5); }
  100% { translate: 0 0; }
}

/* Depth, not relief. A faint backlight sits behind the mark so it reads as
   lit from within the field. No bevel, no emboss, no 3D. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]::before {
  position: absolute;
  z-index: -1;
  inset: -70%;
  content: "";
  /* A round halo, not an ellipse sized to the logo box - an ellipse that
     follows the box reads as a plate behind the mark, which is the panel look
     the brief rules out. */
  background: radial-gradient(
    circle at 50% 50%,
    rgba(154, 180, 236, calc(0.045 + var(--mark-layer, 0.6) * 0.038)) 0%,
    rgba(120, 150, 210, 0.022) 34%,
    transparent 62%
  );
  opacity: 0.85;
  pointer-events: none;
  transition: opacity 260ms var(--def-ease), transform 260ms var(--def-ease);
}

/* Round 11 dropped the shift transform entirely at rest so the SVG rasterised
   at its layout size. Keep that, but the scroll-keyed parallax has to survive
   it or the ring goes flat the moment it settles. */
.definitive-site .def-galaxy-marks [data-galaxy-mark].is-settled {
  transform: translate(-50%, calc(-50% + var(--mark-shift-y, 0px)));
}

/* Only marks with a real case study behave like they are clickable, and the
   ring reads its own hierarchy at rest: a client you can open sits brighter
   than one you cannot. */
.definitive-site .def-galaxy-marks a[data-galaxy-mark] {
  pointer-events: auto;
  cursor: pointer;
  transition: filter 260ms var(--def-ease), opacity 80ms linear;
}
.definitive-site .def-galaxy-marks a[data-galaxy-mark] img {
  transition: opacity 260ms var(--def-ease), scale 260ms var(--def-ease);
  /* Matches the base resting value so a linked mark and an unlinked one are
     the same brightness. Anything else reads as one brand being worth less
     than another. */
  opacity: 0.94;
}
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover img,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible img {
  opacity: 1;
  scale: 1.07;
}
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible {
  z-index: 4;
  filter: drop-shadow(0 0 1.1rem rgba(168, 192, 255, 0.42));
}
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover::before,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible::before {
  opacity: 1;
  transform: scale(1.18);
}
/* Anything without a case study keeps the old inert treatment. */
.definitive-site .def-galaxy-marks span[data-galaxy-mark] {
  pointer-events: none;
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks [data-galaxy-mark] {
    animation: none;
    translate: none;
  }
}

/* The +30% is a desktop figure. Below 620px the ring is already tight against
   the copy, so it scales from the phone's own base instead of the desktop's. */
@media (max-width: 620px) {
  .definitive-site .def-galaxy-marks [data-galaxy-mark],
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n) {
    width: clamp(4.2rem, 19vw, 5.9rem);
  }
  .definitive-site .def-galaxy-marks [data-galaxy-mark] img { max-height: 3.4rem; }
}

/* ============================================================
   Round 13 - item 4: the opening, boring on purpose.

   Round 12 authored a wordmark sequence: the brand resolved at the centre of a
   black frame, held ~450ms, then travelled up into the nav while the poster,
   the reel control, the nav links and the header background each arrived on
   their own delay. It was 1.5s of choreography in front of a director's reel,
   and it read as the site introducing itself instead of showing the work.

   All of it is deleted. What is left is one beat: the hero settles out of a
   1.04 push as it fades up. Nothing else animates on load - the nav, the
   wordmark and the reel control are simply there. Reduced motion gets the same
   fade with no scale.

   Still pure CSS keyed off a class set before first paint, still paint-only:
   nothing is display:none and nothing loses pointer-events, so scrolling and
   clicking work from the first frame.
   ============================================================ */

/* The hero does not wait fully lit behind the curtain - it rises FROM the
   black while the overlay dissolves over it, so the reveal is one continuous
   brightness curve: drum, black, image developing. This is the seam Giovani
   kept feeling; the settle and the dissolve now overlap. */
.kls-opening .definitive-site .hero-media {
/* Starts BEFORE the bloom clears - the settle is already in motion when the
   light thins, so the drum's push-in and the hero's arrival read as one
   continuous camera move. */
/* Starts while the drum is still pushing, so the two zooms are one gesture:
     the hero is already growing behind the light, not after it. */
  animation: kls-open-hero 1500ms cubic-bezier(0.18, 0.72, 0.24, 1) 1180ms both;
  will-change: transform, opacity;
}

/* The landing: a focus pull. The rush exits at ~6px of smear and the bloom
   flashes - so the image develops out of the light SOFT and a touch hot, then
   resolves sharp as it settles. Blur decays continuously across the whole
   hand-off instead of snapping to sharp, which was the last visible seam. */
/* The blur is the expensive half of this - a full-viewport gaussian, per
   frame. It is shorter and shallower now, and it is GONE by 45% so the long
   tail of the zoom is pure transform+opacity on the compositor. */
@keyframes kls-open-hero {
  0%   { opacity: 0; transform: scale(1.10); filter: blur(8px) brightness(1.4); }
  20%  { opacity: 1; transform: scale(1.07); filter: blur(4px) brightness(1.22); }
  45%  { opacity: 1; transform: scale(1.035); filter: blur(0px) brightness(1.06); }
  100% { opacity: 1; transform: scale(1); filter: blur(0px) brightness(1); }
}

/* The opening, staged. Three beats on one easing: the footage settles first,
   the mark rises into it, then the frame's chrome (nav, reel action) arrives
   last. `both` holds each element at its 0% state from the very first paint,
   so nothing can flash in a wrong position while scripts are still parsing —
   the choreography doubles as the loading state. */

/* Giovani: the mark should fit INSIDE the film roll at the start and grow,
   subtly, to its full size as the fold lands. `scale` is the independent
   property so it composes with the centring transform rather than replacing
   it - the same trap the parallax fell into above. */
/* Round 26. THE ROLL IS FIRST; the mark arrives into it and never stops
   growing. Round 24's logo-first order is reverted: the film roll owns frame
   one (kls-intro-scene-life, delay 0), and the mark fades in over the drum -
   pure opacity, no travel, the way film-roll.framer.website floats its
   captions in over the spinning drum.

   ROUND 27, item 3. Giovani: it appeared halfway through the opening; it has
   to be there a FIFTH of the way through. The opening is 2700ms, so a fifth is
   540ms, and 540ms is now the frame the mark is FULLY opaque: `kls-mark-in` is
   360ms from a 180ms delay. Round 26 had it starting at 650 and finishing at
   1250 - just under half of 2700, exactly what he read.

   Growth is ONE CONTINUOUS RAMP across the whole roll -> homepage junction and
   it starts WITH the fade, not after it: 2520ms from the same 180ms delay,
   coming to a dead rest at 2700ms, the same frame `kls-open-hero` finishes
   resolving the fold (1180 + 1500 = 2680). One delay and one end for both
   animations, so the mark cannot grow before it is visible or keep moving
   after the fold has landed. The old shape - hold small, then a 900ms "zoom
   forward" after the roll was already gone - stays deleted; there is no second
   gesture to read as a zoom.
   Because the growth animation fills BACKWARDS, its 0% frame is held from the
   very first paint, so the mark is BORN at its caption size and has no other
   size before its delay elapses.

   ROUND 28. Giovani: during the roll the mark is WIDER THAN THE DRUM, so the
   opening reads as a billboard with a small spinning object behind it instead
   of the reference's caption-inside-the-scene. Measured at 1440x900 on the
   frozen clock, he is right about the effect even though the boxes do not
   quite overlap: the drum's silhouette (union of the visible slice rects) is
   490.8px at t=400 and 611.1px at t=700, but its flat READABLE FACE - the
   near-planar picture area between the curvature breaks - is only about 465px
   at t=700, and the wordmark's glyphs, 460px of the mark's 474.8px box, spanned
   the whole of it. The type was exactly as wide as the picture it sat on.

   The window did not move and the ramp is still ONE strictly-increasing
   gesture. Its SHAPE did. cubic-bezier(0.16, 0.7, 0.2, 1) front-loads: it had
   already spent 40% of the growth by 400ms and 68% by 700ms, so the very first
   frame the mark was legible (540ms - round 27's fifth-of-the-way rule) it was
   already 437.8px. `kls-mark-grow` is now a 21-point sampled track that holds
   caption size while the roll plays and spends 82% of its travel in the
   hand-off, t = 1600 -> 2700:

     313.6px at 0-180ms   318.0 at 400   320.2 at 540   322.4 at 700
     326.9 at 1000        336.2 at 1300  358.0 at 1600  419.8 at 2000
     514.1 at 2400        560.0 at 2700, then flat

   322.4px at t=700 is 53% of the drum's silhouette, 56% of its lit core and
   69% of its readable face - inside the band with air on both sides, which is
   the whole point. `linear` timing is REQUIRED: the sampled curve is the
   easing, the same contract as `kls-intro-spin-total`, and any bezier here
   would ease each of the twenty segments separately and kink the ramp.

   The track is GENERATED, never hand-written - `scripts/gen_mark_grow.py`:
     scale(tau) = 0.56 + 0.44 * g(tau),   tau = (t - 180) / 2520
     g = normalised integral of  tau^4.5 (1-tau)^0.9 + 0.008 (1-tau)^3
   Integrating a strictly positive velocity makes monotonicity structural, and
   both terms vanish at tau = 1, so VELOCITY as well as position reaches zero
   at 2700: the last 100ms of the ramp is 7.2px, the mark settles rather than
   stopping. The 21 emitted points sit within 2.3px of the continuous curve.

   The `scale` property, never `transform`: this rule targets the IMG, but the
   anchor above it is centred with `transform: translate(-50%, -50%)` and the
   one time scale was animated on the anchor it replaced the centring and threw
   the mark off-centre. Keeping size on the child, and on the independent
   property, means neither can ever compose into the other. */
/* Round 30. The mark is back where Giovani wants it - centred in the fold,
   handing off to the header on scroll - but it no longer opens the film. It
   used to fade up at 180ms and grow for 2520ms, which made it a billboard the
   roll happened behind. It now arrives as the roll is ENDING: the fade starts
   at 1500ms, just before the overlay begins to dissolve at 1620, so the mark
   emerges over the tail of the spin and is fully present as the fold lands.

   The growth is deliberately almost nothing - 0.94 to 1 - and it comes to rest
   at 2700ms, the same frame the spin, the hero settle and the chrome all stop.
   Giovani's standing note on this element is that it must not travel and must
   not restate itself once the hero lands, so: position is fixed by the
   wrapper's translate, size is the independent `scale` property on the child,
   and neither can ever compose into the other. */
.kls-opening .definitive-site .floating-logo img {
  animation: kls-mark-in 820ms var(--def-ease) 1500ms both,
             kls-mark-rest 1200ms cubic-bezier(0.16, 0.78, 0.22, 1) 1500ms both;
}

@keyframes kls-mark-in {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

@keyframes kls-mark-rest {
  0% { scale: 0.94; }
  100% { scale: 1; }
}

/* The mark has to read OVER the roll for the last half second, and the overlay
   sits at 200. Lifting it needs both halves: the hero must stop being a
   stacking context or its child can never out-paint the overlay, and the mark
   itself carries the raised index. Scoped to kls-intro-live, never to
   kls-opening - kls-opening persists for the whole session, and scoping the
   lift to it once left the fold stacked over every section below it. */
html.kls-intro-live .definitive-site .def-hero {
  z-index: auto;
}

html.kls-intro-live .definitive-site .floating-logo {
  z-index: 220;
}

html.kls-intro-live .definitive-site .def-galaxy {
  z-index: -1;
}

/* Round 25 (C) put the chrome on the fold's own clock instead of leaving it
   until 3350ms. Round 27, item 4, finishes the job: Giovani still read the nav
   and "Watch the full reel" as arriving abruptly, and the diagnosis is in the
   z-order block above - the nav's 800ms fade was running BEHIND the lifted
   fold and could not be seen at all, then appeared whole at 2700ms. With the
   fold no longer stacked over it the fade is actually on screen, and it is
   slowed and pushed to land just after the fold instead of well before it:
   1000ms from 1900ms, completing at 2900 - 220ms after `kls-open-hero`
   resolves the fold at 2680, comfortably inside the one second Giovani asked
   for. The entrance keeps the house's grammar (a few pixels of travel with the
   fade) instead of a bare opacity ramp: the nav settles down from -8px, the
   reel meta lifts from 8px.

   The travel is on `translate`, NOT `transform`, and that is load-bearing. The
   header's auto-hide in site-shell.js writes `header.style.transform =
   translateY(-102%)`, and a filling animation beats an inline style - holding
   `transform` here would silently disable the hide for the life of the page.
   `translate` is its own property, so the two compose and the shell keeps its
   transform to itself. */
.kls-opening .definitive-site .site-nav {
  animation: kls-open-nav 1000ms var(--def-ease) 1900ms both;
}

.kls-opening .definitive-site .def-hero-meta {
  animation: kls-open-meta 1000ms var(--def-ease) 1900ms both;
}

@keyframes kls-open-nav {
  0% { opacity: 0; translate: 0 -8px; }
  100% { opacity: 1; translate: 0 0; }
}

@keyframes kls-open-meta {
  0% { opacity: 0; translate: 0 8px; }
  100% { opacity: 1; translate: 0 0; }
}

/* ==========================================================================
   THE FILM-ROLL OPENING
   A strip of the studio's frames accelerates down the screen while the hero
   reel loads behind it, lands on the reel's own first frame, grows to full
   screen, and dissolves into the live video. Entirely time-driven — one CSS
   timeline, `both` fills, no scroll dependence, no JS in the visual path —
   so a dead script can delay nothing and break nothing. Timeline (round 27 —
   no loader, the mark lands a fifth of the way in, the spin finishes hard, and
   the overlay dissolves OVER the fold instead of behind it):
     0ms          the roll is already there, spinning (it fades up over ~350ms)
     150ms        the approach starts
     180-540ms    the mark fades in over the drum — fully there at 540, which
                  is 2700 x 0.2, and it starts growing on the same frame
     1000ms       the spin's eased ramp joins the base rotation
     1100-1650ms  the rush: the frames smear and melt into light
     1500-1740ms  the bloom
     1620-2100ms  the overlay dissolves into the live hero
     1180-2680ms  the fold resolves out of the light (focus pull)
     1900-2900ms  the chrome arrives, landing 220ms after the fold
     2700ms       the mark reaches full size and rests; the drum has turned
                  3883.6deg; the opening is over
   ========================================================================== */
.kls-intro {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  overflow: hidden;
  /* The reference's own background: warm near-black, not the page ground.
     Every number in this block is read from the component's source
     (film-roll.framer.website bundle): background #0a0705, sepia .25,
     contrast 1.12, saturation .9, darkness .25, grain .12, vignette .45,
     light leak on, radius 2.5 vs height 2.4, camera path "push". */
  background: #0a0705;
  pointer-events: none;
}

/* The light leak: a warm drifting glow, low in the frame - the reference
   keeps one burning softly at the edge the whole time. */
.kls-intro::before {
  position: absolute;
  inset: -20%;
  z-index: 1;
  content: "";
  background:
    radial-gradient(ellipse 42% 34% at 78% 74%, rgb(122 74 34 / 0.34), transparent 70%),
    radial-gradient(ellipse 30% 26% at 12% 18%, rgb(84 52 26 / 0.18), transparent 70%);
  animation: kls-intro-leak 6s ease-in-out infinite alternate;
}

@keyframes kls-intro-leak {
  0% { transform: translate(0, 0); }
  100% { transform: translate(3%, -2%); }
}

/* Vignette above the scene, grain above everything. The grain is an SVG
   turbulence tile re-jittered in steps - the reference regenerates its noise
   every frame; steps(6) at 90ms reads the same at a fraction of the cost. */
.kls-intro::after {
  position: absolute;
  inset: 0;
  z-index: 4;
  content: "";
  background:
    radial-gradient(ellipse 88% 78% at 50% 50%, transparent 42%, rgb(2 1 0 / 0.45) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.09 0'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: cover, 240px 240px;
  mix-blend-mode: normal;
  opacity: 1;
  animation: kls-intro-grain 540ms steps(6) infinite;
}

@keyframes kls-intro-grain {
  0% { background-position: 0 0, 0 0; }
  100% { background-position: 0 0, 240px 240px; }
}

.kls-opening .kls-intro {
  display: block;
  animation: kls-intro-out 480ms var(--def-ease) 1620ms both;
}

@keyframes kls-intro-out {
  0% { opacity: 1; visibility: visible; }
  100% { opacity: 0; visibility: hidden; }
}

/* Phase A: the drum. Ten panels arranged as a CSS-3D cylinder; the chord
   maths lock panel width to radius (r = w / (2 tan 18deg) = 1.539 w for ten
   panels), so the vars below are the only tuning surface. The spin is LINEAR
   and INFINITE - one speed, start to finish, exactly as directed; the ONLY
   thing that changes is the approach. */
.kls-intro-scene {
  /* The component's own geometry: cylinderRadius 2.5 vs cylinderHeight 2.4 -
     a TIGHT drum, radius roughly equal to height. Twelve frames around the
     ring, each split into three 10-degree slices, so the surface reads as a
     smooth curve instead of a faceted box (chord error at 10deg is invisible).
     Slice chord = 2 r sin(5deg). */
  --drum-h: 26vh;
  --drum-r: calc(var(--drum-h) * 1.042);
  --slice-w: calc(var(--drum-r) * 0.1743 + 0.5px);
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  perspective: 95vh;
  /* The reference's post pass, as close as CSS filters come: sepia .25,
     contrast 1.12, saturation .9, darkness .25 - plus the soft projection
     blur its minified textures produce. */
  /* Crisp at rest - Giovani read the resting blur as a dirty filter over the
     footage. The grade stays; the softness now comes only from SPEED: the
     ghost trail below and the rush blur in the final quarter. */
  filter: sepia(0.18) contrast(1.1) saturate(0.92) brightness(0.86);
  /* ONE animation owns the scene's opacity for its whole life. Splitting it
     into an -in and a -die pair broke the first second: both fill both ways,
     and the die's backwards fill (opacity 1) sat later in the list, overriding
     the in's pre-delay hold (opacity 0). Merged, there is nothing to fight:
     it runs from 0ms (round 26 - the roll is the first thing seen), its own
     16.3% ramp fades it up over the first ~350ms, and it is gone under the
     bloom at the end. */
  animation: kls-intro-scene-life 2150ms linear 0ms both,
             kls-intro-approach 1500ms linear 150ms both,
             kls-intro-rush 550ms linear 1100ms both;
}

/* Motion blur for the last beat of the push - the flick-scroll smear the
   reference shows when driven hard. */
/* The frames MELT into light before the bloom arrives - by flash time the
   content is already mostly brightness, so the bloom completes a morph
   instead of cutting to cream. */
@keyframes kls-intro-rush {
  0% { filter: sepia(0.18) contrast(1.1) saturate(0.92) brightness(0.86) blur(0px); }
  100% { filter: sepia(0.14) contrast(1.06) saturate(0.98) brightness(1.55) blur(10px); }
}

/* The base spin: constant, visible from the very first painted frame. The
   accelerating ramp on the drum ADDS to this - two rotations about one axis
   compose - so the ring is never still and the ramp stays one smooth curve. */
/* One smooth speed ramp (Giovani, round 21): slow enough at first to make out
   the frames, accelerating continuously with proximity. A single finite
   eased rotation IS a continuous acceleration - five extra revolutions over
   the approach on top of the base spin. The trails fade in on the same curve
   via their own opacity animations, so readable frames stay clean and only
   speed smears. */
/* ONE rotating element, ONE animation. Base spin and ramp used to live on two
   nested layers - two independently animated 3D transforms - and the browser's
   slice depth-sorting fell apart into interleaved slivers. The sum of the two
   curves is precomputed here as a 28-point sampled track: spinning from the
   first visible frame, accelerating continuously, one transform to sort.

   The track is GENERATED, never hand-written:
     angle(t) = 360 * t / 1100                                (base, constant)
              + RAMP * bezierY(bezierX^-1((t - 1000) / 1700))  (the ramp)
     bezier(0.72, 0, 0.94, 0.38), sampled at i/27 across 2700ms, i = 0..27.
   `linear` timing is required - the sampled curve IS the easing.

   Round 27, item 5: Giovani likes the start speed and wants a much faster
   finish, "it went faster in a previous version". Only RAMP moved, 1800 ->
   3000deg. Everything through 37.0% (t = 1000ms, where the ramp joins) is
   byte-identical to round 26, so the opening speed is untouched; the last
   quarter is where it all goes. Totals: 2683.6deg (7.45 rev) -> 3883.6deg
   (10.79 rev), and the closing 100ms alone now turns 1069deg instead of
   655deg. */
.kls-intro-drum {
  position: relative;
  width: var(--slice-w);
  height: var(--drum-h);
  transform-style: preserve-3d;
  animation: kls-intro-spin-total 2150ms linear both;
  will-change: transform;
}

@keyframes kls-intro-spin-total {
  0% { transform: rotateY(-0.0deg); }
  0.5556% { transform: rotateY(-3.8deg); }
  1.111% { transform: rotateY(-7.7deg); }
  1.667% { transform: rotateY(-11.6deg); }
  2.222% { transform: rotateY(-15.5deg); }
  2.778% { transform: rotateY(-19.5deg); }
  3.333% { transform: rotateY(-23.4deg); }
  3.889% { transform: rotateY(-27.3deg); }
  4.444% { transform: rotateY(-31.3deg); }
  5% { transform: rotateY(-35.2deg); }
  5.556% { transform: rotateY(-38.9deg); }
  6.111% { transform: rotateY(-42.9deg); }
  6.667% { transform: rotateY(-46.8deg); }
  7.222% { transform: rotateY(-50.7deg); }
  7.778% { transform: rotateY(-54.7deg); }
  8.333% { transform: rotateY(-58.6deg); }
  8.889% { transform: rotateY(-62.5deg); }
  9.444% { transform: rotateY(-66.4deg); }
  10% { transform: rotateY(-70.4deg); }
  10.56% { transform: rotateY(-74.1deg); }
  11.11% { transform: rotateY(-78.1deg); }
  11.67% { transform: rotateY(-82.0deg); }
  12.22% { transform: rotateY(-85.9deg); }
  12.78% { transform: rotateY(-89.8deg); }
  13.33% { transform: rotateY(-93.8deg); }
  13.89% { transform: rotateY(-97.7deg); }
  14.44% { transform: rotateY(-101.6deg); }
  15% { transform: rotateY(-105.5deg); }
  15.56% { transform: rotateY(-109.3deg); }
  16.11% { transform: rotateY(-113.2deg); }
  16.67% { transform: rotateY(-117.2deg); }
  17.22% { transform: rotateY(-121.1deg); }
  17.78% { transform: rotateY(-125.0deg); }
  18.33% { transform: rotateY(-128.9deg); }
  18.89% { transform: rotateY(-132.9deg); }
  19.44% { transform: rotateY(-136.8deg); }
  20% { transform: rotateY(-140.7deg); }
  20.56% { transform: rotateY(-144.5deg); }
  21.11% { transform: rotateY(-148.4deg); }
  21.67% { transform: rotateY(-152.3deg); }
  22.22% { transform: rotateY(-156.3deg); }
  22.78% { transform: rotateY(-160.2deg); }
  23.33% { transform: rotateY(-164.1deg); }
  23.89% { transform: rotateY(-168.1deg); }
  24.44% { transform: rotateY(-172.0deg); }
  25% { transform: rotateY(-175.9deg); }
  25.56% { transform: rotateY(-179.7deg); }
  26.11% { transform: rotateY(-183.6deg); }
  26.67% { transform: rotateY(-187.5deg); }
  27.22% { transform: rotateY(-191.5deg); }
  27.78% { transform: rotateY(-195.4deg); }
  28.33% { transform: rotateY(-199.3deg); }
  28.89% { transform: rotateY(-203.2deg); }
  29.44% { transform: rotateY(-207.2deg); }
  30% { transform: rotateY(-211.1deg); }
  30.56% { transform: rotateY(-214.9deg); }
  31.11% { transform: rotateY(-218.8deg); }
  31.67% { transform: rotateY(-222.7deg); }
  32.22% { transform: rotateY(-226.6deg); }
  32.78% { transform: rotateY(-230.6deg); }
  33.33% { transform: rotateY(-234.5deg); }
  33.89% { transform: rotateY(-238.4deg); }
  34.44% { transform: rotateY(-242.3deg); }
  35% { transform: rotateY(-246.3deg); }
  35.56% { transform: rotateY(-250.0deg); }
  36.11% { transform: rotateY(-254.0deg); }
  36.67% { transform: rotateY(-257.9deg); }
  37.22% { transform: rotateY(-261.8deg); }
  37.78% { transform: rotateY(-265.7deg); }
  38.33% { transform: rotateY(-269.7deg); }
  38.89% { transform: rotateY(-273.6deg); }
  39.44% { transform: rotateY(-277.5deg); }
  40% { transform: rotateY(-281.5deg); }
  40.56% { transform: rotateY(-285.2deg); }
  41.11% { transform: rotateY(-289.1deg); }
  41.67% { transform: rotateY(-293.1deg); }
  42.22% { transform: rotateY(-297.0deg); }
  42.78% { transform: rotateY(-300.9deg); }
  43.33% { transform: rotateY(-304.9deg); }
  43.89% { transform: rotateY(-308.8deg); }
  44.44% { transform: rotateY(-312.7deg); }
  45% { transform: rotateY(-316.6deg); }
  45.56% { transform: rotateY(-320.4deg); }
  46.11% { transform: rotateY(-324.3deg); }
  46.67% { transform: rotateY(-328.3deg); }
  47.22% { transform: rotateY(-332.2deg); }
  47.78% { transform: rotateY(-336.3deg); }
  48.33% { transform: rotateY(-340.6deg); }
  48.89% { transform: rotateY(-345.2deg); }
  49.44% { transform: rotateY(-350.2deg); }
  50% { transform: rotateY(-355.6deg); }
  50.56% { transform: rotateY(-361.4deg); }
  51.11% { transform: rotateY(-368.0deg); }
  51.67% { transform: rotateY(-375.3deg); }
  52.22% { transform: rotateY(-383.4deg); }
  52.78% { transform: rotateY(-392.3deg); }
  53.33% { transform: rotateY(-402.1deg); }
  53.89% { transform: rotateY(-412.8deg); }
  54.44% { transform: rotateY(-424.6deg); }
  55% { transform: rotateY(-437.4deg); }
  55.56% { transform: rotateY(-450.7deg); }
  56.11% { transform: rotateY(-465.8deg); }
  56.67% { transform: rotateY(-482.0deg); }
  57.22% { transform: rotateY(-499.5deg); }
  57.78% { transform: rotateY(-518.3deg); }
  58.33% { transform: rotateY(-538.3deg); }
  58.89% { transform: rotateY(-559.7deg); }
  59.44% { transform: rotateY(-582.5deg); }
  60% { transform: rotateY(-606.6deg); }
  60.56% { transform: rotateY(-631.0deg); }
  61.11% { transform: rotateY(-657.9deg); }
  61.67% { transform: rotateY(-686.2deg); }
  62.22% { transform: rotateY(-716.0deg); }
  62.78% { transform: rotateY(-747.1deg); }
  63.33% { transform: rotateY(-779.8deg); }
  63.89% { transform: rotateY(-813.8deg); }
  64.44% { transform: rotateY(-849.3deg); }
  65% { transform: rotateY(-886.2deg); }
  65.56% { transform: rotateY(-923.0deg); }
  66.11% { transform: rotateY(-962.6deg); }
  66.67% { transform: rotateY(-1003.7deg); }
  67.22% { transform: rotateY(-1046.1deg); }
  67.78% { transform: rotateY(-1089.9deg); }
  68.33% { transform: rotateY(-1135.0deg); }
  68.89% { transform: rotateY(-1181.3deg); }
  69.44% { transform: rotateY(-1228.9deg); }
  70% { transform: rotateY(-1277.7deg); }
  70.56% { transform: rotateY(-1325.5deg); }
  71.11% { transform: rotateY(-1376.5deg); }
  71.67% { transform: rotateY(-1428.6deg); }
  72.22% { transform: rotateY(-1481.7deg); }
  72.78% { transform: rotateY(-1535.7deg); }
  73.33% { transform: rotateY(-1590.7deg); }
  73.89% { transform: rotateY(-1646.5deg); }
  74.44% { transform: rotateY(-1703.0deg); }
  75% { transform: rotateY(-1760.3deg); }
  75.56% { transform: rotateY(-1815.8deg); }
  76.11% { transform: rotateY(-1874.2deg); }
  76.67% { transform: rotateY(-1933.1deg); }
  77.22% { transform: rotateY(-1992.4deg); }
  77.78% { transform: rotateY(-2052.0deg); }
  78.33% { transform: rotateY(-2111.9deg); }
  78.89% { transform: rotateY(-2171.8deg); }
  79.44% { transform: rotateY(-2231.8deg); }
  80% { transform: rotateY(-2291.8deg); }
  80.56% { transform: rotateY(-2349.3deg); }
  81.11% { transform: rotateY(-2409.3deg); }
  81.67% { transform: rotateY(-2469.3deg); }
  82.22% { transform: rotateY(-2529.3deg); }
  82.78% { transform: rotateY(-2589.3deg); }
  83.33% { transform: rotateY(-2649.3deg); }
  83.89% { transform: rotateY(-2709.3deg); }
  84.44% { transform: rotateY(-2769.3deg); }
  85% { transform: rotateY(-2829.3deg); }
  85.56% { transform: rotateY(-2886.8deg); }
  86.11% { transform: rotateY(-2946.8deg); }
  86.67% { transform: rotateY(-3006.8deg); }
  87.22% { transform: rotateY(-3066.8deg); }
  87.78% { transform: rotateY(-3126.8deg); }
  88.33% { transform: rotateY(-3186.8deg); }
  88.89% { transform: rotateY(-3246.8deg); }
  89.44% { transform: rotateY(-3306.8deg); }
  90% { transform: rotateY(-3366.8deg); }
  90.56% { transform: rotateY(-3424.3deg); }
  91.11% { transform: rotateY(-3484.3deg); }
  91.67% { transform: rotateY(-3544.3deg); }
  92.22% { transform: rotateY(-3604.3deg); }
  92.78% { transform: rotateY(-3664.3deg); }
  93.33% { transform: rotateY(-3724.3deg); }
  93.89% { transform: rotateY(-3784.3deg); }
  94.44% { transform: rotateY(-3844.3deg); }
  95% { transform: rotateY(-3904.3deg); }
  95.56% { transform: rotateY(-3961.8deg); }
  96.11% { transform: rotateY(-4021.8deg); }
  96.67% { transform: rotateY(-4081.8deg); }
  97.22% { transform: rotateY(-4141.8deg); }
  97.78% { transform: rotateY(-4201.8deg); }
  98.33% { transform: rotateY(-4261.8deg); }
  98.89% { transform: rotateY(-4321.8deg); }
  99.44% { transform: rotateY(-4381.8deg); }
  100% { transform: rotateY(-4441.8deg); }
}

@keyframes kls-intro-scene-life {
  0% { opacity: 0; }
  16.3% { opacity: 1; }
  79% { opacity: 1; }
  100% { opacity: 0; }
}

/* Camera path "push", compressed: prominent immediately, one breath, then
   through the wall and deeper inside. Easing lives in the keyframes. */
@keyframes kls-intro-approach {
  0% { transform: scale(0.8500); }
  0.8333% { transform: scale(0.8554); }
  1.667% { transform: scale(0.8604); }
  2.5% { transform: scale(0.8652); }
  3.333% { transform: scale(0.8697); }
  4.167% { transform: scale(0.8740); }
  5% { transform: scale(0.8780); }
  5.833% { transform: scale(0.8819); }
  6.667% { transform: scale(0.8856); }
  7.5% { transform: scale(0.8892); }
  8.333% { transform: scale(0.8927); }
  9.167% { transform: scale(0.8962); }
  10% { transform: scale(0.8996); }
  10.83% { transform: scale(0.9031); }
  11.67% { transform: scale(0.9065); }
  12.5% { transform: scale(0.9100); }
  13.33% { transform: scale(0.9136); }
  14.17% { transform: scale(0.9174); }
  15% { transform: scale(0.9213); }
  15.83% { transform: scale(0.9253); }
  16.67% { transform: scale(0.9296); }
  17.5% { transform: scale(0.9341); }
  18.33% { transform: scale(0.9388); }
  19.17% { transform: scale(0.9439); }
  20% { transform: scale(0.9493); }
  20.83% { transform: scale(0.9550); }
  21.67% { transform: scale(0.9611); }
  22.5% { transform: scale(0.9677); }
  23.33% { transform: scale(0.9746); }
  24.17% { transform: scale(0.9821); }
  25% { transform: scale(0.9900); }
  25.83% { transform: scale(0.9985); }
  26.67% { transform: scale(1.0076); }
  27.5% { transform: scale(1.0172); }
  28.33% { transform: scale(1.0275); }
  29.17% { transform: scale(1.0384); }
  30% { transform: scale(1.0500); }
  30.83% { transform: scale(1.0618); }
  31.67% { transform: scale(1.0733); }
  32.5% { transform: scale(1.0846); }
  33.33% { transform: scale(1.0958); }
  34.17% { transform: scale(1.1070); }
  35% { transform: scale(1.1182); }
  35.83% { transform: scale(1.1295); }
  36.67% { transform: scale(1.1410); }
  37.5% { transform: scale(1.1528); }
  38.33% { transform: scale(1.1649); }
  39.17% { transform: scale(1.1775); }
  40% { transform: scale(1.1905); }
  40.83% { transform: scale(1.2042); }
  41.67% { transform: scale(1.2185); }
  42.5% { transform: scale(1.2335); }
  43.33% { transform: scale(1.2494); }
  44.17% { transform: scale(1.2661); }
  45% { transform: scale(1.2838); }
  45.83% { transform: scale(1.3026); }
  46.67% { transform: scale(1.3224); }
  47.5% { transform: scale(1.3435); }
  48.33% { transform: scale(1.3659); }
  49.17% { transform: scale(1.3896); }
  50% { transform: scale(1.4147); }
  50.83% { transform: scale(1.4414); }
  51.67% { transform: scale(1.4696); }
  52.5% { transform: scale(1.4995); }
  53.33% { transform: scale(1.5312); }
  54.17% { transform: scale(1.5646); }
  55% { transform: scale(1.6000); }
  55.83% { transform: scale(1.6381); }
  56.67% { transform: scale(1.6796); }
  57.5% { transform: scale(1.7242); }
  58.33% { transform: scale(1.7716); }
  59.17% { transform: scale(1.8217); }
  60% { transform: scale(1.8741); }
  60.83% { transform: scale(1.9287); }
  61.67% { transform: scale(1.9850); }
  62.5% { transform: scale(2.0431); }
  63.33% { transform: scale(2.1024); }
  64.17% { transform: scale(2.1629); }
  65% { transform: scale(2.2242); }
  65.83% { transform: scale(2.2861); }
  66.67% { transform: scale(2.3484); }
  67.5% { transform: scale(2.4107); }
  68.33% { transform: scale(2.4729); }
  69.17% { transform: scale(2.5347); }
  70% { transform: scale(2.5959); }
  70.83% { transform: scale(2.6561); }
  71.67% { transform: scale(2.7152); }
  72.5% { transform: scale(2.7729); }
  73.33% { transform: scale(2.8289); }
  74.17% { transform: scale(2.8830); }
  75% { transform: scale(2.9349); }
  75.83% { transform: scale(2.9844); }
  76.67% { transform: scale(3.0312); }
  77.5% { transform: scale(3.0752); }
  78.33% { transform: scale(3.1160); }
  79.17% { transform: scale(3.1546); }
  80% { transform: scale(3.1912); }
  80.83% { transform: scale(3.2261); }
  81.67% { transform: scale(3.2592); }
  82.5% { transform: scale(3.2907); }
  83.33% { transform: scale(3.3208); }
  84.17% { transform: scale(3.3496); }
  85% { transform: scale(3.3771); }
  85.83% { transform: scale(3.4035); }
  86.67% { transform: scale(3.4289); }
  87.5% { transform: scale(3.4535); }
  88.33% { transform: scale(3.4773); }
  89.17% { transform: scale(3.5005); }
  90% { transform: scale(3.5232); }
  90.83% { transform: scale(3.5455); }
  91.67% { transform: scale(3.5676); }
  92.5% { transform: scale(3.5895); }
  93.33% { transform: scale(3.6114); }
  94.17% { transform: scale(3.6334); }
  95% { transform: scale(3.6556); }
  95.83% { transform: scale(3.6781); }
  96.67% { transform: scale(3.7011); }
  97.5% { transform: scale(3.7247); }
  98.33% { transform: scale(3.7489); }
  99.17% { transform: scale(3.7740); }
  100% { transform: scale(3.8000); }
}

/* A slice is one third of a frame: background-size 300% wide, positioned at
   0 / 50% / 100% so three neighbouring slices reassemble the full picture
   around the curve. */
.kls-intro-slice {
  position: absolute;
  inset: 0;
  /* Clip the trail ghosts to the slice. Un-clipped, each translated pseudo
     protrudes sideways out of its slice's PLANE and intersects the neighbours'
     planes - and plane intersections rasterise as exactly the interleaved
     sliver mosaic that kept appearing. Contained, the smear stays in-plane. */
  overflow: hidden;
  background-color: #0b0c0f;
  background-repeat: no-repeat;
  /* Four frames around the ring - the reference's own count - each spanning
     nine 10-degree slices: ~1.6:1 landscape on the drum. Twelve frames packed
     each into a 0.54:1 sliver, which read as weirdly compacted. */
  background-position: calc(var(--s) * 12.5%) 50%;
  background-size: 900% 100%;
  transform: rotateY(calc(var(--i) * 10deg)) translateZ(var(--drum-r));
  /* Backfaces VISIBLE, deliberately: once the camera pushes through the front
     wall, the ending is the INSIDE of the drum - the concave back wall
     sweeping past, mirrored like film seen through its base. Hiding backfaces
     left a black void for the whole final second. The reference's material is
     double-sided for exactly this. */
}

/* The motion blur: each slice drags two fading ghosts of itself against the
   spin direction. At 260ms/rev a 60fps frame advances the ring ~23deg - far
   past one slice - and without a trail that strobes; with it, each rendered
   frame carries its own smear, which is exactly what the reference's fast
   pass looks like. Pure pseudo-elements: no extra DOM, backgrounds inherit. */
.kls-intro-slice::before,
.kls-intro-slice::after {
  position: absolute;
  inset: 0;
  content: "";
  background: inherit;
  pointer-events: none;
}

.kls-intro-slice::before {
  opacity: 0;
  transform: translateX(-56%);
  animation: kls-intro-trail-a 1700ms cubic-bezier(0.72, 0, 0.94, 0.38) 1000ms both;
}

.kls-intro-slice::after {
  opacity: 0;
  transform: translateX(-115%);
  animation: kls-intro-trail-b 1700ms cubic-bezier(0.72, 0, 0.94, 0.38) 1000ms both;
}

@keyframes kls-intro-trail-a { 0% { opacity: 0; } 100% { opacity: 0.34; } }
@keyframes kls-intro-trail-b { 0% { opacity: 0; } 100% { opacity: 0.15; } }

/* Phase B: inside the strip. Full-screen frames sweeping past on the same
   clock - the track speed is tuned to read as the drum's own surface arriving
   at the camera - with the slightest continued approach. The dissolve to the
   live hero happens from here. */
/* The film bloom. At peak speed the frame catches light and blooms out -
   momentum ends INSIDE the flash instead of dying into black - and the hero
   develops out of it as the overlay dissolves. Warm, like film catching the
   lamp, not a camera strobe. */
/* Round 25 (B). THE BOTTOM-OF-SCREEN GLITCH, root-caused.
   The bloom grows: `kls-intro-flash-in` runs scale 0.72 -> 1.12. At `inset: 0`
   the element IS the viewport, so for the first half of that animation it was
   SMALLER than the screen - a cream rectangle with a hard edge inset from all
   four sides, painted at rising opacity over the hero's black bottom scrim.
   Measured on the frozen clock at 1440x900: a full-width step of 31 levels at
   row 852 (t=2570ms) and 57 levels at row 881 (t=2600ms) - the edge racing off
   the bottom of the screen in the last 90ms of the roll. That was the glitch;
   nothing was wrong with the timing or the hero.
   The fix is geometric, not temporal: the box is 1.5x the viewport now, so
   even the 0.72 frame covers it (0.72 x 1.5 = 1.08) and there is no edge to
   see at any point in the growth. The gradient is restated against the bigger
   box so the picture is pixel-identical - 120%/100% of the viewport becomes
   80%/66.7% of a 1.5x box, and the 48% centre becomes 48.7% because the
   viewport now occupies rows 16.7%-83.3% of the element. The far stop is fully
   opaque as well, so no partial-alpha tail can read as a band either.
   `.kls-intro` clips the overhang (overflow: hidden). */
.kls-intro-flash {
  position: absolute;
  inset: -25%;
  z-index: 5;
  /* r89: the flash warms toward the new Opus-orange accent family. */
  background: radial-gradient(ellipse 80% 66.7% at 50% 48.7%,
    #f8ecdf 0%, #f0cdad 46%, #cf7a48 100%);
  opacity: 0;
  animation: kls-intro-flash-in 240ms ease-out 1500ms both;
  pointer-events: none;
}

@keyframes kls-intro-flash-in {
  0% { opacity: 0; transform: scale(0.72); }
  100% { opacity: 1; transform: scale(1.12); }
}

/* ROUND 27, item 1: THE LOADING BAR IS GONE. `.kls-intro-progress` and its
   `@keyframes kls-intro-progress` are deleted, and so is the <span> in both
   index.html and intro.html. Giovani: "the motion is what tells you what to
   expect." Rounds 25 and 26 kept re-timing a loader that the roll itself
   already renders redundant - a 2px cream rule pinned to the bottom of the
   screen for the first 1.5s of a film. Nothing replaces it; the drum's
   acceleration is the progress indicator. */

/* Scroll stays parked while the roll runs; released by the inline script on
   the timeline's clock, 5s failsafe. */
html.kls-intro-live {
  overflow: hidden;
}

/* The zoom was janking because the overlay was still compositing while it ran:
   36 slices, 72 ghost pseudo-elements with background images, an animated
   grain tile and a drifting leak - all live behind a full-screen blur+scale on
   the hero. `visibility: hidden` keeps every one of those layers. Taking the
   overlay out of the box entirely hands the GPU back exactly when the fold
   needs it. */
html.kls-intro-done .kls-intro {
  display: none;
}

@media (max-width: 620px) {
  .kls-intro-scene {
    --drum-h: 19vh;
    perspective: 72vh;
  }
}

/* Round 3's page-motion entrance would run underneath this and fight it. */
.kls-opening .definitive-site.motion-ready:not(.is-page-ready) .site-nav,
.kls-opening .definitive-site.motion-ready.is-page-ready .site-nav,
.kls-opening .definitive-site.motion-ready:not(.is-page-ready) .hero-media,
.kls-opening .definitive-site.motion-ready.is-page-ready .hero-media {
  opacity: 1;
  transform: none;
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  /* The class is not set under reduced motion, but state it anyway: a plain
     fade, no scale. */
  .kls-opening .definitive-site .hero-media {
    animation: kls-open-fade 400ms linear both;
  }
}
@keyframes kls-open-fade {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

/* ============================================================
   Round 12 - item 5: the active card invites the click.
   ============================================================ */
/* Registered so the hover pop can be transitioned. A bare custom property
   snaps between values, and transitioning `transform` instead is not an
   option - the rail rewrites --film-x every frame, so an eased transform
   would put the drag a frame behind the cursor. */
@property --film-hover {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}
.definitive-site .def-film-card {
  transition:
    visibility 0s linear 180ms,
    box-shadow 260ms var(--def-ease),
    --film-hover 260ms var(--def-ease);
}
.definitive-site .def-film-card.is-near { transition-delay: 0s; }
/* The hover pop rides INSIDE the rail's own transform chain, via --film-hover.
   Using the individual `scale` property looked equivalent but composes BEFORE
   `transform`, so it scaled the card's own `-50%` centering offset too: the
   card crept up and to the left as it grew instead of coming straight at you.
   Folding it into the same scale() the rail writes keeps the growth centred on
   the card. No upward lift either - the headline sits directly above the rail
   now, and a card that rises into it reads as a collision. */
.definitive-site .def-film-stage:not(.is-dragging) .def-film-card.is-active:hover,
.definitive-site .def-film-card.is-active:focus-visible {
  --film-hover: 1.028;
  --film-drop: 1.4%;
  box-shadow: 0 3.4rem 9rem rgba(0, 0, 0, 0.62);
}
.definitive-site .def-film-card.is-expanded {
  --film-hover: 1;
  translate: none;
  scale: none;
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-film-card { transition: none; }
  .definitive-site .def-film-stage:not(.is-dragging) .def-film-card.is-active:hover {
    translate: none;
    scale: none;
  }
}

/* ============================================================
   Round 12 - item 6: Work with us + footer, one continuous space.
   ============================================================ */

/* ---- Edges --------------------------------------------------------------
   A single --x percentage cannot hold a 4vw inset on both sides, because the
   frame's own width is a much larger fraction of the viewport at 768 than at
   1440 - which is how one frame ended up 6px off the left edge and another 6px
   past the right one at 1440. The field is inset 4vw and frames on the right
   half anchor to the right (--rx), so 0% IS the 4vw line on either side. */
/* Scoped to the scattered composition only. Below 620px the wall is a plain
   two-column grid of relatively-positioned items, where a left/right offset
   does not place a frame - it displaces it out of its own cell, which pushed
   the page 30px wider than the viewport at 320. */
@media (min-width: 621px) {
  .definitive-site .def-close-media {
    /* +8px covers the rotated frame's bounding box, which reaches a few pixels
       past its own layout edge. */
    inset: 0 calc(4vw + 8px);
  }

  .definitive-site .def-close-media button {
    left: var(--x, auto);
    right: var(--rx, auto);
  }
}

@media (min-width: 621px) and (max-width: 899px) {
  .definitive-site .def-close-media { inset: 0 calc(3vw + 8px); }
}

@media (max-width: 620px) {
  .definitive-site .def-close-media button {
    top: auto;
    right: auto;
    left: auto;
  }
}

/* ---- Entrance -----------------------------------------------------------
   The wall used to drop in from above. It radiates now: every frame starts at
   the centre of the headline, small and dim, and flies out to its placement -
   centre first, edges last - so the composition reads as the work coming out
   of "Work with us". --from-x/--from-y are measured in JS; the release order
   is by distance from that centre. */
.definitive-site .def-close:not(.is-visible) .def-close-media button {
  opacity: 0;
  transform: translate3d(
      calc(var(--shift-x, 0px) + var(--from-x, 0px)),
      calc(var(--shift-y, 0px) + var(--from-y, 0px)),
      0
    )
    rotate(0deg) scale(0.34);
  box-shadow: 0 0.6rem 1.6rem rgba(0, 0, 0, 0.4);
}

/* :nth-child(n) only to out-specify round 3's per-child delay chain. The y2 of
   1.008 is the whole overshoot: the frame passes its mark by well under a
   percent and eases back. Anything more and it bounces. */
.definitive-site .def-close.is-visible:not(.is-settled) .def-close-media button:nth-child(n) {
  transition:
    transform 520ms cubic-bezier(0.2, 0.86, 0.28, 1.008),
    opacity 300ms ease-out,
    box-shadow 640ms var(--def-ease);
  transition-delay: calc(var(--burst-order, 0) * 52ms);
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-close:not(.is-visible) .def-close-media button {
    opacity: 1;
    transform: translate3d(var(--shift-x, 0px), var(--shift-y, 0px), 0) rotate(var(--r));
  }
}

/* ---- One sky ------------------------------------------------------------
   A background on each section is two fields meeting at an edge, and that edge
   is the seam. This is one layer sized across both, always drifting - about a
   third of the galaxy chapter's idle speed, tile-aligned so the loop is
   invisible. Both sections go transparent over it. */
.definitive-site .def-sky {
  position: absolute;
  z-index: 0;
  right: 0;
  left: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 20% 22%, rgba(199, 218, 255, 0.5) 0 1px, transparent 1.6px),
    radial-gradient(circle at 76% 34%, rgba(247, 234, 210, 0.4) 0 1px, transparent 1.8px),
    radial-gradient(circle at 48% 75%, rgba(199, 218, 255, 0.32) 0 1px, transparent 1.7px),
    radial-gradient(ellipse 74% 46% at 50% 30%, rgba(46, 62, 100, 0), transparent 76%),
    radial-gradient(ellipse 60% 40% at 50% 88%, rgba(38, 52, 86, 0), transparent 74%),
    var(--def-bg);
  background-size: 170px 170px, 230px 230px, 290px 290px, auto, auto, auto;
  animation: def-sky-drift 150s linear infinite;
}

/* Whole tiles only - a fractional offset would show the loop restart. */
@keyframes def-sky-drift {
  to { background-position: 170px 340px, -230px 230px, 290px -290px, 0 0, 0 0, 0 0; }
}

.definitive-site .def-close,
.definitive-site .def-footer {
  position: relative;
  z-index: 1;
  background: transparent;
  border-top: 0;
}

/* The footer's own field is retired into the shared one. What is left is a
   floor under the type so it stays legible over the stars. */
.definitive-site .def-footer {
  animation: none;
  background:
    linear-gradient(to bottom, rgba(6, 7, 10, 0) 0%, rgba(6, 7, 10, 0.45) 26%, rgba(6, 7, 10, 0.72) 100%);
}

/* The section's own vignettes tint the shared sky instead of covering it. */
.definitive-site .def-close::before {
  background: radial-gradient(ellipse 70% 56% at 50% 48%, rgba(26, 32, 48, 0.34), transparent 66%);
}
.definitive-site .def-close::after {
  background: radial-gradient(ellipse 78% 64% at 50% 50%, rgba(6, 7, 10, 0.1), rgba(6, 7, 10, 0.6) 78%);
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-sky { animation: none; }
}

/* ============================================================
   ROUND 13 - Workstream A. Homepage.
   ============================================================ */

/* ---- Item 1: the galaxy free-scrolls -------------------------------------
   Round 12's chapter was 130dvh of section wrapped around a 100dvh
   position:sticky pane, so the last 30dvh of it pinned the page: the wheel
   kept turning and the document did not move. That arrested beat is what
   Giovani felt. There is no pin now. The pane is relative, the chapter is one
   ordinary block that scrolls at page rate like every other section, and the
   whole animation keys to the block's transit across the viewport instead of
   to a scrubbed lock (see initGalaxy). Shorter, too: the -18vh tuck under the
   hero means the real added scroll is about one screen.

   The pane stays exactly one viewport tall and is centred in the block. The
   marks are placed as percentages of the pane, so a pane that is one screen
   tall is the only way the ring is ever the size of the screen: at the middle
   of the chapter's transit the pane aligns to the viewport and the whole
   composition is on it, then it carries on out. */
.definitive-site .def-galaxy {
  display: grid;
  height: 118dvh;
  min-height: 760px;
  align-content: center;
  justify-items: stretch;
}
.definitive-site .galaxy-sticky {
  position: relative;
  top: auto;
  height: 100dvh;
  min-height: 0;
}
@media (max-width: 620px) {
  .definitive-site .def-galaxy {
    height: 112dvh;
    min-height: 620px;
  }
}

/* ---- Item 5 + 6: one glow language ---------------------------------------
   The headline and the mark hover are lit by the same light: a hot white core,
   a cool-white bloom in the field's own blue, and a wide faint halo. Stated
   once here as a tint plus two ready-made shadow stacks (text-shadow for type,
   drop-shadow for the marks' alpha art) so the two can never drift apart. */
.definitive-site {
  --kls-glow-tint: 206, 224, 255;
  --kls-glow-core: 255, 255, 255;
  /* Type: em-based, so the bloom scales with the display size. */
  --kls-star-glow:
    0 0 0.04em rgba(var(--kls-glow-core), 0.5),
    0 0 0.2em rgba(var(--kls-glow-tint), 0.4),
    0 0 0.62em rgba(var(--kls-glow-tint), 0.24),
    0 0 1.5em rgba(var(--kls-glow-tint), 0.12);
  /* Art: the same three steps as a filter chain. */
  --kls-star-drop:
    drop-shadow(0 0 0.16rem rgba(var(--kls-glow-core), 0.4))
    drop-shadow(0 0 0.8rem rgba(var(--kls-glow-tint), 0.48))
    drop-shadow(0 0 2.1rem rgba(var(--kls-glow-tint), 0.26));
  /* At rest a mark is only just separated from the sky - enough to sit in
     front of the stars, not enough to read as lit. */
  --kls-star-drop-rest: drop-shadow(0 0 0.6rem rgba(var(--kls-glow-tint), 0.2));
}

.definitive-site .galaxy-copy {
  text-shadow: var(--kls-star-glow);
  /* The headline's box is 76rem wide and sits at z-index 3, a layer above the
     ring - so any mark whose placement overlapped that box was unhoverable,
     the h2 swallowed the pointer. It is display type; nothing in it is
     interactive. (This is why Barilla, at 8%/40%, never lit up.) */
  pointer-events: none;
}

/* ---- Item 6: all twelve marks hover, and nothing paints a box -------------
   The "weird square box" was literal: round 12's mark rule still carried the
   round-10 panel treatment - `background: rgba(18,23,36,.72)` plus a border on
   :hover - under a later rule that only zeroed the *resting* background. So
   hovering a logo painted a dark rectangle the full size of the mark's layout
   box behind transparent art. Every plate-ish property is zeroed here in both
   states, at a specificity that outranks the old `a:hover` rules.
   (The white PNG art was audited: alpha-lion, lasio and opus-genetics are all
   genuinely transparent, edge alpha 0 - the box was never in the pixels.) */
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  /* Marks without a case study hover too - they simply do not navigate and
     never show a pointer. */
  pointer-events: auto;
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition: filter 260ms var(--def-ease), opacity 80ms linear;
}
.definitive-site .def-galaxy-marks a[data-galaxy-mark] {
  pointer-events: auto;
  cursor: pointer;
}
/* Round 12 took the three case-study-less marks out of the hit test entirely,
   which is why they could not hover. They are in it now - they just have
   nowhere to go, and say so by never showing a pointer. */
.definitive-site .def-galaxy-marks span[data-galaxy-mark] {
  pointer-events: auto;
  cursor: default;
}

.definitive-site .def-galaxy-marks [data-galaxy-mark] img {
  /* Round 12 forced every mark white with grayscale/brightness/invert. The
     colour set (workstream B) has to survive, and the white set is already
     white, so the channel filters are gone and only the resting separation
     glow is left. */
  filter: var(--kls-star-drop-rest);
  opacity: 0.94;
  transition: opacity 260ms var(--def-ease), scale 260ms var(--def-ease);
}
/* Every mark rests at the same brightness. The three brands without a case
   study used to sit dimmer to signal they were not clickable, but a client
   logo that reads faint just looks like a broken asset - Opus Genetics was
   being dimmed twice, once in its artwork and again here. The cursor and the
   hover pop already carry the "this one opens" signal. */

.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible {
  z-index: 4;
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  filter: var(--kls-star-drop);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover img,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible img,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover img,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible img {
  /* Round 12 popped 1.07, which was inside the noise of the idle drift. */
  opacity: 1;
  scale: 1.12;
}
/* The round halo behind a mark brightens with it. It is a radial gradient that
   is fully transparent well before its own box, so it is depth, not a plate. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover::before,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible::before {
  opacity: 1;
  transform: scale(1.2);
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:hover img,
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible img {
    scale: 1.05;
  }
}

/* ---- Item 7: the rail sits under its headline -----------------------------
   The stage was clamp(27rem, 53vw, 43rem) tall while the card inside it is a
   16:9 crop of clamp(20rem, 56vw, 52rem) - about 29rem at 1440. The extra
   ~14rem was dead air, split above and below the rail, and it is what pushed
   "Watch the work." away from the work. The stage is the card's own height
   plus breathing room now, and the head's gap comes down with it. */
.definitive-site .def-film-roll {
  /* The section was floored at 100dvh, which put the reclaimed dead air back
     underneath the controls instead of above the rail. Its own padding is
     enough. */
  min-height: 0;
  padding-top: clamp(3.75rem, 6vw, 5.75rem);
}
.definitive-site .def-film-roll-head h2 {
  margin-top: 0.3rem;
}
.definitive-site .def-film-stage {
  height: calc(clamp(11.25rem, 31.5vw, 29.25rem) + 2.75rem);
  margin-top: clamp(0.5rem, 1.2vw, 1.25rem);
  /* Horizontal finger-drags belong to the rail; vertical ones stay with the
     page. Declared on the cards too - the card is the hit target, and the
     effective touch-action is the intersection up the ancestor chain. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}
.definitive-site .def-film-card {
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
/* Round 14 item 1. A poster is an <img>, and a mouse press-and-move on an
   <img> starts the browser's own drag-and-drop, which fires pointercancel and
   killed the rail drag after a single move. The markup carries
   draggable="false"; this is the WebKit belt to that braces. */
.definitive-site .def-film-card img,
.definitive-site .def-film-card iframe {
  -webkit-user-drag: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Hover on the active card: it lifts further out of the field. */
.definitive-site .def-film-stage:not(.is-dragging) .def-film-card.is-active:hover,
.definitive-site .def-film-card.is-active:focus-visible {
  translate: 0 -9px;
  scale: 1.032;
  box-shadow:
    0 4.5rem 12rem rgba(0, 0, 0, 0.8),
    0 1.4rem 3.5rem rgba(0, 0, 0, 0.55);
}

@media (max-width: 620px) {
  .definitive-site .def-film-roll {
    min-height: 34rem;
    padding-top: 3.75rem;
  }
  .definitive-site .def-film-stage {
    height: calc(min(43.9vw, 15.2rem) + 2rem);
    margin-top: 0.7rem;
  }
  .definitive-site .def-film-controls { margin-top: 0.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-film-stage:not(.is-dragging) .def-film-card.is-active:hover {
    translate: none;
    scale: none;
  }
}

/* ---- Item 9: the closing field runs the other way -------------------------
   The galaxy chapter's stars stream down and out past the viewer. The shared
   Work-with-us + footer sky was drifting the same way at 150s, which read as
   one continuous field rather than a second, closing one. It now flows against
   the galaxy and roughly twice as fast, so the wall visibly moves. Still whole
   tiles only - a fractional offset would show the loop restart. */
.definitive-site .def-sky {
  animation-duration: 76s;
}
@keyframes def-sky-drift {
  to { background-position: -170px -340px, 230px -230px, -290px 290px, 0 0, 0 0, 0 0; }
}

/* The other half of the square box. Round 12's backlight was `inset: -70%` on
   a rectangular pseudo-element carrying a `circle` (farthest-corner) gradient:
   on a 150x82 mark the halo's transparent stop lands 127px from centre while
   the box's own half-height is 98px, so the gradient was still painting when
   it ran out of element and got cut off flat along the top and bottom edges.
   That is the band you could see behind a hovered logo, and hover scaled it up
   and brightened it. The backlight is a real circle now - a square box, sized
   from the mark, with a closest-side gradient that is transparent well inside
   its own edges, so there is no edge left to see. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]::before {
  top: 50%;
  right: auto;
  bottom: auto;
  left: 50%;
  width: 210%;
  height: auto;
  aspect-ratio: 1;
  translate: -50% -50%;
  background: radial-gradient(
    circle closest-side,
    rgba(154, 180, 236, calc(0.05 + var(--mark-layer, 0.6) * 0.04)) 0%,
    rgba(120, 150, 210, 0.022) 38%,
    transparent 66%
  );
}

/* ============================================================
   ROUND 14 - Workstream A. Homepage.
   Seamless ground, crisp glow, controls clear of the film.
   ============================================================ */

/* ---- Item 2: the rail's controls come off the video ----------------------
   The row was pulled up 1.25rem into the stage, which put the arrows, the
   client name and the counter within two pixels of the poster's bottom edge -
   close enough, under the card's own shadow, to read as sitting ON the film.
   The stage is the card's height exactly now (the 2.75rem it used to carry was
   reserve for that overlap), and the row sits a real, token-sized gap below
   it. Nothing overlaps the film, arrows included. */
/* Exactly .def-film-card's width clamp x 9/16 (18->10.125, 56->31.5,
   60->33.75). The card is absolutely centred in here, so a mismatch bleeds it
   into the headline above or the arrows below.
   THIS is the stage rule that wins - the two earlier ones in this file are
   both overridden. Round 25 (D) brought the card down 80vw -> 68vw and this
   came with it, in the same commit, per the lock. r89 brought the card to
   56vw (Kyle: "the middle video needs to shrink") and this moved with it,
   same commit, per the lock. */
.definitive-site .def-film-stage {
  height: clamp(10.125rem, 31.5vw, 33.75rem);
}
.definitive-site .def-film-controls {
  margin: clamp(1.75rem, 2.6vw, 2.75rem) auto 0;
}
@media (max-width: 620px) {
  .definitive-site .def-film-stage { height: min(43.9vw, 15.2rem); }
  .definitive-site .def-film-controls { margin-top: clamp(1.25rem, 4.5vw, 1.75rem); }
}

/* ---- Item 3: the glow moves off the glyphs and behind the block ----------
   text-shadow paints INTO the letterforms: every stop of the old four-step
   stack softened the edge of the type it was meant to light. The headline is
   pure white with a hairline of separation now, and the light is a real
   backlight - a soft cool-white radial painted on a pseudo-element BEHIND the
   headline box. Same amount of glow in the picture, none of it on the type. */
.definitive-site .galaxy-copy {
  position: relative;
  color: #fff;
  /* A hairline, not a bloom: enough to hold the type off the field, far too
     tight to round an edge. */
  text-shadow: 0 0 0.012em rgba(255, 255, 255, 0.55);
}
.definitive-site .galaxy-copy::before {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  width: 128%;
  height: 210%;
  content: "";
  translate: -50% -50%;
  background: radial-gradient(
    ellipse 50% 42% at 50% 50%,
    rgba(214, 229, 255, 0.2) 0%,
    rgba(180, 203, 255, 0.1) 34%,
    rgba(150, 180, 240, 0.04) 58%,
    transparent 76%
  );
  filter: blur(28px);
  pointer-events: none;
}
@media (max-width: 620px) {
  .definitive-site .galaxy-copy::before { filter: blur(18px); }
}

/* ---- Item 4: no halo on mark art, at rest or on hover -------------------
   The "dirty white hue" around Alpha Lion and Opus was the resting drop-shadow
   chain - a white/blue glow painted around every alpha edge, which on art that
   is already light reads as grime rather than light. Rest is clean art on the
   sky, full stop. Hover does NOT add a filter either: a drop-shadow on the img
   is still ink on the artwork. The pop is scale plus the backlight circle
   behind it, so a hovered mark is CRISPER than a resting one, not softer. */
.definitive-site .def-galaxy-marks [data-galaxy-mark],
.definitive-site .def-galaxy-marks a[data-galaxy-mark],
.definitive-site .def-galaxy-marks span[data-galaxy-mark],
.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:hover,
.definitive-site .def-galaxy-marks a[data-galaxy-mark]:focus-visible {
  filter: none;
}
.definitive-site .def-galaxy-marks [data-galaxy-mark] img,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover img,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible img {
  filter: none;
}
/* The backlight carries the whole hover now, so it has further to travel. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]:hover::before,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:focus-visible::before {
  opacity: 1;
  transform: scale(1.32);
  background: radial-gradient(
    circle closest-side,
    rgba(196, 216, 255, calc(0.13 + var(--mark-layer, 0.6) * 0.05)) 0%,
    rgba(150, 180, 236, 0.05) 40%,
    transparent 68%
  );
}

/* ---- Item 5: Alpha Lion and Opus Genetics carry more weight -------------
   Keyed off the art's own alt text rather than a child index, so re-ordering
   the ring cannot silently move the nudge onto a different brand. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]:has(img[alt="Alpha Lion"]),
.definitive-site .def-galaxy-marks [data-galaxy-mark]:has(img[alt="Opus Genetics"]) {
  width: clamp(7.3rem, 11.6vw, 12.5rem);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:has(img[alt="Alpha Lion"]) img,
.definitive-site .def-galaxy-marks [data-galaxy-mark]:has(img[alt="Opus Genetics"]) img {
  max-height: 5.7rem;
}

/* ---- Item 6: one ground, no horizontal edges anywhere -------------------
   Every seam on this page came from the same thing: two opaque fields meeting
   at a box edge. The audit found four.
     1. The galaxy's sticky field is #05060a and the film rail's backdrop is a
        flat #090a0e box that starts 5rem ABOVE the section - so the "black line
        at the galaxy boundary" was literally those two rectangles butting up
        mid-chapter.
     2. The same backdrop overhangs 5rem BELOW the section, unfaded, which is
        the warm rail light cutting off into Selected work.
     3. Selected work paints opaque #06070a and Expertise paints a blue-tinted
        field: a step across the full width at their boundary. Same story at
        Selected partners -> Learn.
     4. Work with us dims itself to 0.6 alpha at its own bottom edge, and the
        footer starts at 0 - the hue step Giovani saw above the lockup.
   The fix is architectural, not cosmetic: ONE painted ground for the whole page
   below the galaxy (see initContinuousGround), and every section over it goes
   transparent. Tints that used to belong to a section are now broad ellipses
   measured as a percentage of the whole ground, so the light still changes down
   the page but no part of it has an edge to see. */
.definitive-site .def-ground {
  position: absolute;
  z-index: 0;
  right: 0;
  left: 0;
  overflow: hidden;
  pointer-events: none;
  background:
    /* Every ellipse is 7-12% of an ~8000px layer: 600-1000px of soft light, so
       the nearest thing to an edge is a gradient hundreds of pixels long. */
    radial-gradient(ellipse 80% 9% at 16% 14%, rgba(50, 69, 111, 0), transparent 72%),
    radial-gradient(ellipse 64% 7% at 86% 27%, rgba(92, 61, 55, 0), transparent 74%),
    radial-gradient(ellipse 96% 10% at 46% 46%, rgba(44, 60, 96, 0), transparent 76%),
    radial-gradient(ellipse 72% 8% at 20% 68%, rgba(50, 69, 111, 0), transparent 74%),
    radial-gradient(ellipse 88% 11% at 60% 86%, rgba(46, 62, 100, 0), transparent 74%),
    var(--def-grain-image),
    var(--def-bg);
  background-repeat: no-repeat, no-repeat, no-repeat, no-repeat, no-repeat, repeat, repeat;
  background-size: auto, auto, auto, auto, auto, 180px 180px, auto;
}
/* The stars. One layer, masked - never a second field. */
.definitive-site .def-ground i {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 20% 22%, rgba(199, 218, 255, 0.5) 0 1px, transparent 1.6px),
    radial-gradient(circle at 76% 34%, rgba(247, 234, 210, 0.4) 0 1px, transparent 1.8px),
    radial-gradient(circle at 48% 75%, rgba(199, 218, 255, 0.32) 0 1px, transparent 1.7px);
  background-size: 170px 170px, 230px 230px, 290px 290px;
  animation: def-ground-drift 150s linear infinite;
}
/* Whole tiles only - a fractional offset would show the loop restart. */
@keyframes def-ground-drift {
  to { background-position: 170px 340px, -230px 230px, 290px -290px; }
}
@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-ground i { animation: none; }
}

/* Everything from the rail to the copyright line rides ON the ground. */
.definitive-site .def-film-roll,
.definitive-site .def-work,
.definitive-site .def-expertise,
.definitive-site .def-about,
.definitive-site .def-instagram,
.definitive-site .def-client-proof,
.definitive-site .def-learn,
.definitive-site .def-close {
  position: relative;
  z-index: 1;
  background: transparent;
}
.definitive-site .def-footer {
  position: relative;
  z-index: 1;
  animation: none;
  /* All that is left of the footer's own field is a floor under the type so it
     stays legible over the stars - and it starts at zero, so the section above
     hands over to it with nothing to see. */
  background: linear-gradient(
    to bottom,
    rgba(6, 7, 10, 0) 0%,
    rgba(6, 7, 10, 0.4) 30%,
    rgba(6, 7, 10, 0.7) 100%
  );
}

/* Seam 2: the rail's warm light. It was a flat #090a0e rectangle - two levels
   lighter than the page - clipped hard to the section box, so its top and
   bottom were straight 1440px-wide lines: the "warm rail-light edges".
   It is now a light, not a panel. The section clips on x only (`overflow-x:
   clip` keeps the off-stage cards from widening the page while leaving y free -
   `hidden` cannot do one axis without forcing the other), the backdrop reaches
   11rem past the section on both ends, and it fades to nothing across that
   overhang. So the light genuinely arrives out of the galaxy above and dies out
   inside Selected work below, with no edge in either direction.
   The fade is on the backdrop's CHILDREN, not the backdrop: a mask on the
   parent breaks the ::after's backdrop-filter - the blur stops sampling the
   poster beneath it and the rail's soft light snaps into a sharp bright still.
   Masking each child keeps the blur intact. */
.definitive-site .def-film-backdrop {
  background: var(--def-bg);
}
/* The fade is on the section's own scrims, and it is long - 13rem at each end,
   easing rather than ramping. They can do this job now precisely because the
   ground beneath them is the same colour they paint: an opaque bar of #06070a
   over a #06070a ground is invisible, so all it does is take the warm light
   down to nothing before the section ends.
   (Tried and rejected: letting the backdrop overhang the section and masking
   it. A mask on the backdrop breaks the ::after's backdrop-filter, and masking
   the scrim instead means the blur is applied at partial strength through the
   fade - the picture comes back sharp exactly where it should be dissolving.
   The blur is worth more than the bleed.) */
.definitive-site .def-film-roll::before,
.definitive-site .def-film-roll::after {
  height: 13rem;
}
.definitive-site .def-film-roll::before {
  background: linear-gradient(to bottom, var(--def-bg) 0%, rgba(6, 7, 10, 0.72) 34%, transparent 100%);
}
.definitive-site .def-film-roll::after {
  background: linear-gradient(to top, var(--def-bg) 0%, rgba(6, 7, 10, 0.72) 34%, transparent 100%);
}
/* Seam 1, the black line at the galaxy boundary: the chapter's sticky field is
   #05060a and its vignette closes on rgba(5,6,10,.72), against a #06070a page.
   One level of hue and a straight edge 1440px wide is all it takes. Both are
   restated in the page's own colour, so the chapter now ends on the ground
   rather than against it. */
/* No flat colour layer. The canvas fills the ground colour wherever its mask
   is opaque and the page ground is the same colour, so painting it here was a
   visual no-op that nonetheless gave the chapter a hard rectangle edge. The
   chapter is a light now, not a painted box. */
/* Round 36. THE breaker Giovani kept pointing at, under the logos. The field
   is lit right up to the chapter's bottom edge and the page below it is flat,
   so the star field simply stopped in one row - measured 22.2 levels of
   luminance across a single row, where every other boundary on the page is
   under 1. Two halves to it: the ambient ellipse reached 92% of the chapter's
   height (centre 48% + radius 44%), and the canvas and vignette were not
   faded at all. The ellipse is pulled up and in so it is spent by 76%, and
   the field itself dissolves over the last third. */
.definitive-site .galaxy-sticky {
  background: radial-gradient(ellipse 58% 36% at 50% 40%, rgba(64, 88, 145, 0), transparent 72%);
}

.definitive-site .galaxy-canvas,
.definitive-site .galaxy-vignette {
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 58%, rgba(0, 0, 0, 0.45) 82%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 58%, rgba(0, 0, 0, 0.45) 82%, transparent 100%);
}
.definitive-site .galaxy-vignette {
  background:
    radial-gradient(ellipse 72% 60% at 50% 48%, transparent 28%, rgba(6, 7, 10, 0.2) 58%, rgba(6, 7, 10, 0.88) 100%),
    /* No top wash. It was 0.35 alpha of ground colour over the top quarter of
       the sticky - which, once the chapter became content-height, landed
       exactly on the seam row and darkened the very handover it should have
       hidden. The chapter now only closes at the bottom. */
    /* Round 25 (E). The close used to end on 0.72 alpha, so the chapter's last
       row was 72% of the way to the ground and the rail's first row was the
       ground - a step, full width. Same lesson as the hero scrim: land ON the
       colour, and get there over several stops so the ramp does not show its
       own start. Everything above 84% is within a couple of points of what it
       was, so the client logos (72-81%) are untouched; only the empty run
       between them and the rail closes harder, and it closes completely. */
    linear-gradient(
      to bottom,
      transparent 72%,
      rgba(6, 7, 10, 0.34) 84%,
      rgba(6, 7, 10, 0.72) 92%,
      rgba(6, 7, 10, 0.93) 96.5%,
      #06070a 100%
    );
}

/* Seam 4: Work with us was dimming itself to half-opacity at both its own top
   and bottom edges - a 4-level step down from Learn above it and back up into
   the footer below. The vignette now fades in and out inside its own section,
   so the closing field arrives and departs with nothing to see. */
.definitive-site .def-close::after {
  --def-close-fade: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(0, 0, 0, 0.5) 9%,
    #000 24%,
    #000 54%,
    transparent 100%
  );
  background: radial-gradient(
    ellipse 78% 64% at 50% 44%,
    rgba(6, 7, 10, 0.08),
    rgba(6, 7, 10, 0.5) 78%
  );
  -webkit-mask-image: var(--def-close-fade);
  mask-image: var(--def-close-fade);
}

/* Selected partners' own radial was a field with a boundary at the top of the
   section; the ground carries that light now. */
.definitive-site .def-client-proof {
  background: transparent;
}

/* Seam 4, properly. The line above the footer lockup and the hue step under it
   were one element: .def-footer::after, a near-opaque GREEN wash
   (rgba(4,8,5,.8) -> rgba(4,7,4,.74)) left over from the old photographic
   footer, sitting at z-index -1 across the whole footer and starting dead on
   its top edge. Beside it .def-footer::before painted an 8rem bar of opaque
   #06070a from the same edge. Both are retired: the footer is a window onto the
   one ground now, and the only thing it paints is the legibility floor above. */
.definitive-site .def-footer::after,
.definitive-site .def-footer::before {
  content: none;
}
.definitive-site .def-footer-backdrop {
  display: none;
}

/* The last hard horizontal line on the homepage is the footer's own rule above
   the copyright. It is structure, not a section breaker, so it stays - but it
   stops being a full-width edge: it fades to nothing at both ends. */
.definitive-site .def-footer .footer-bottom {
  position: relative;
  border-top: 0;
}
.definitive-site .def-footer .footer-bottom::before {
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 1px;
  content: "";
  background: linear-gradient(
    to right,
    transparent,
    rgba(255, 255, 255, 0.18) 22%,
    rgba(255, 255, 255, 0.18) 78%,
    transparent
  );
  pointer-events: none;
}

/* ---- Item 8: the case-study layer ends on the site's footer --------------
   The layer scrolls in its own container, so the page's one ground cannot
   reach it. The footer clone carries the same field with it - the same tiles,
   the same hue, the same drift - and it fades in from the More-work grid above
   so the layer closes the way the homepage does, with no edge. */
.definitive-site .project-layer [data-layer-footer],
.project-layer [data-layer-footer] {
  position: relative;
  z-index: 1;
  isolation: isolate;
  margin-top: clamp(4rem, 8vw, 8rem);
}
.definitive-site .project-layer [data-layer-footer]::before,
.project-layer [data-layer-footer]::before {
  /* Inset 0, not an overhang: .def-footer clips, so a layer that started above
     the footer's own top was cut off there at whatever alpha its mask happened
     to be - which put a soft band across the full width instead of a fade. The
     whole ramp lives inside the footer now.
     Stars only. A broad tint fading in over a few hundred pixels still reads as
     a band; individual points do not. */
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  background:
    radial-gradient(circle at 20% 22%, rgba(199, 218, 255, 0.5) 0 1px, transparent 1.6px),
    radial-gradient(circle at 76% 34%, rgba(247, 234, 210, 0.4) 0 1px, transparent 1.8px),
    radial-gradient(circle at 48% 75%, rgba(199, 218, 255, 0.32) 0 1px, transparent 1.7px);
  background-size: 170px 170px, 230px 230px, 290px 290px;
  animation: def-ground-drift 150s linear infinite;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 46%, #000 100%);
  mask-image: linear-gradient(to bottom, transparent 0%, #000 46%, #000 100%);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .project-layer [data-layer-footer]::before { animation: none; }
}

/* ==========================================================================
   ROUND 16 - ITEM 1: mobile scroll performance
   ==========================================================================
   Giovani's phone review: "very glitchy when I'm scrolling", "not smooth at
   all". Profiled with CDP at 390x844 / DPR 3 / CPU throttle 6x, driving a
   scripted 120-step wheel scroll of the whole page and reading back rAF frame
   intervals plus the Performance domain's main-thread counters. Script time
   was only ~198ms of a ~2900ms main-thread budget, so this was never a JS
   problem - it was rendering. Three costs, each measured in isolation against
   the same scenario:

     backdrop-filter off (mobile)      31.9 -> 42.4 fps, >50ms frames 25.8 -> 20.2%
     background-position anims off     31.9 -> 46.7 fps, >50ms frames 25.8 -> 17.8%
     dead postcard-breathe removed     31.9 -> 45.9 fps, >50ms frames 25.8 -> 18.2%

   `content-visibility: auto` on the offscreen sections was also tried and is
   deliberately NOT here: it measured WORSE (28.4fps, >50ms frames 30.6%),
   because this page's sections are cheap to lay out and the repeated
   skip/unskip churn costs more than it saves.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  /* Every backdrop-filter is a separate pass that re-samples whatever is
     behind it - on a fixed nav, that is the entire scrolling page, every
     frame. On a near-black site the blur is doing almost no visible work, so
     each one is replaced by the flat tint it was already sitting on, nudged
     opaque enough to hold the same separation. */
  .definitive-site .site-nav.is-solid {
    /* Flat to within 14px of its own bottom, then out. A solid band ends on a
       hard horizontal line across the full width - measured at 27 levels
       against the galaxy field - and the blur it used to carry never softened
       that edge either, it only blurred what was behind it. The tail costs
       nothing and the band stays legible everywhere the type sits. */
    background: linear-gradient(
      to bottom,
      rgba(6, 7, 10, 0.96) 0,
      rgba(6, 7, 10, 0.96) calc(100% - 14px),
      rgba(6, 7, 10, 0.78) calc(100% - 8px),
      rgba(6, 7, 10, 0.34) calc(100% - 3px),
      rgba(6, 7, 10, 0) 100%
    );
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .definitive-site .nav-submenu,
  .definitive-site .def-about .story-play {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* The film roll's field kept its diffuse look by blurring the live backdrop
     on every frame. The same look comes from blurring the SOURCE image once -
     a filter on a static <img> rasterises to a texture and is then just
     composited, instead of re-sampling the page beneath it 60 times a second.
     The scale hides the soft edge the blur leaves at the frame. */
  .definitive-site .def-film-backdrop::after {
    background: rgba(5, 6, 10, 0.72);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .definitive-site .def-film-backdrop img {
    filter: blur(22px);
    transform: scale(1.22);
  }

  /* `background-position` is not a compositor-animatable property: each of
     these repaints its tiled star gradients across the whole element on every
     frame, forever, whether or not anything is on screen. The drift they buy
     is 170px over 150s - about 1.1px per second, which no one has ever seen.
     Desktop keeps it; the phone does not pay for it. */
  .definitive-site .def-ground i,
  .definitive-site .def-sky,
  .definitive-site .def-footer {
    animation: none;
  }
}

/* ==========================================================================
   ROUND 16 - ITEM 3: all twelve marks on a phone
   ==========================================================================
   Four separate rules below 620px were hiding marks 5, 7 and 9-12, so a phone
   saw four of the twelve brands - Giovani's "logos missing in the logo
   section". They all go, and the ring is re-laid for the aspect ratio it is
   actually being read at.

   Two things constrain where a mark can sit on a phone, and the desktop
   percentages respect neither:

   1. The chapter is a TRANSIT, not a pin (see the note above the
      `position: relative` rule): the pane is one viewport tall, centred in a
      112dvh block, and the whole composition is on screen at the middle of
      that transit. Every mark therefore has to read at that one moment.
   2. script.js fades any mark whose top comes within ~144px of the viewport
      top, so it can never collide with the nav. At the aligned moment that
      band is the top 18% of the pane. The first three marks were pitched at
      15.5-19% - which is why Gatorade, Coldstream Clear and Alpha Lion were
      still missing after the display rules came off. Nothing now starts above
      23%.

   The copy occupies 45-55% of the pane, so the ring opens around it: two
   bands above, a pair of shoulders either side, and three bands below.

   These have to be `!important`: the positions are custom properties in the
   `style` attribute, and inline custom properties cannot be overridden by a
   stylesheet any other way.
   -------------------------------------------------------------------------- */
@media (max-width: 620px) {
  .definitive-site .def-galaxy-marks a,
  .definitive-site .def-galaxy-marks a:nth-child(2n),
  .definitive-site .def-galaxy-marks a:nth-child(3n),
  .definitive-site .def-galaxy-marks a:nth-child(5),
  .definitive-site .def-galaxy-marks a:nth-child(7),
  .definitive-site .def-galaxy-marks [data-galaxy-mark],
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(n + 9) {
    display: grid;
  }

  /* Twelve marks in the space four used to have, so every mark comes down a
     size. The ring still varies - every third mark is smaller - because a ring
     of identical marks reads as a table of logos, not a field. */
  .definitive-site .def-galaxy-marks [data-galaxy-mark] {
    width: clamp(3.1rem, 13.5vw, 4.3rem);
  }

  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n) {
    width: clamp(2.7rem, 11.5vw, 3.7rem);
  }

  .definitive-site .def-galaxy-marks [data-galaxy-mark] img {
    max-height: 2.15rem;
  }

  /* Above the copy. 23% is the first row that clears the nav fade with room
     to spare once a mark's own half-height is taken off its centre. */
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(1) { --mark-x: 20% !important; --mark-y: 23% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(2) { --mark-x: 80% !important; --mark-y: 23% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3) { --mark-x: 50% !important; --mark-y: 30.5% !important; }
  /* Shoulders. 10%/90%, not the desktop 8%/92%: at 390px a mark is ~53px wide
     and half of it hangs past its own centre, which is what put Alpha Lion
     off the left edge. */
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(4) { --mark-x: 10% !important; --mark-y: 38% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(5) { --mark-x: 90% !important; --mark-y: 38% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(6) { --mark-x: 10% !important; --mark-y: 64% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(7) { --mark-x: 90% !important; --mark-y: 64% !important; }
  /* Below the copy, opening outward as it falls. */
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(8) { --mark-x: 23% !important; --mark-y: 74% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(9) { --mark-x: 77% !important; --mark-y: 74% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(10) { --mark-x: 50% !important; --mark-y: 82% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(11) { --mark-x: 29% !important; --mark-y: 90% !important; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(12) { --mark-x: 71% !important; --mark-y: 90% !important; }
}

/* ==========================================================================
   ROUND 16 - ITEM 5: headline and subline are not the same voice
   ==========================================================================
   Giovani, on the Kyle Loftus block: the headline and the line under it are
   "in the same font, so it's not really differentiated well at all". He was
   right - `.def-about-lead` was Playfair at up to 2.5rem sitting directly
   under a Playfair h2, so the two read as one run-on headline in two sizes.

   The rule, stated once for every subline on the homepage rather than patched
   per section: the headline is Playfair, the subline is Helvetica at roughly
   40% of its size, in the muted ink, with the body's line-height. Kickers keep
   the wide uppercase tracking they already had (see `.def-kicker`) - that is
   the third register, and it was never the problem.

   Not scoped to a media query: the two typefaces read as one voice at every
   width, so the separation belongs in the base treatment.
   -------------------------------------------------------------------------- */
.definitive-site .def-about-lead,
.definitive-site .def-close-copy > p:not(.def-kicker) {
  max-width: 34rem;
  color: var(--def-muted);
  font-family: var(--def-body);
  font-size: clamp(1.05rem, 1.55vw, 1.35rem);
  font-weight: 400;
  letter-spacing: 0.004em;
  line-height: 1.5;
}

/* ==========================================================================
   ROUND 16 - ITEM 4: centred section headers on a phone
   ==========================================================================
   Every kicker, headline and subline on the homepage centres at 700px and
   below. Giovani named two - Kyle Loftus / "A decade behind the camera" and
   For filmmakers / "Learn from Kyle" - but a page where two blocks centre and
   six stay left-ragged looks like a mistake rather than a decision, so it is
   all of them.

   Body copy and lists are deliberately excluded: centred paragraphs of three
   lines or more are harder to read, and the point here is the headers.
   -------------------------------------------------------------------------- */
@media (max-width: 700px) {
  .definitive-site .def-section-head {
    align-items: center;
    flex-direction: column;
    gap: 1.2rem;
    text-align: center;
  }

  .definitive-site .def-learn-intro,
  .definitive-site .def-client-proof > .def-kicker,
  .definitive-site .def-film-roll-head,
  .definitive-site .def-close-copy {
    text-align: center;
  }

  /* `.def-learn-intro h2` carries its own `text-align: left` from an earlier
     round, and a rule on the parent cannot beat a rule on the element. This is
     the "Learn from Kyle" headline Giovani named, so it is restated here
     rather than left to inherit. */
  .definitive-site .def-learn-intro h2,
  .definitive-site .def-section-head h2,
  .definitive-site .def-about-copy h2,
  .definitive-site .def-film-roll-head h2,
  .definitive-site .def-instagram .instagram-heading h2 {
    text-align: center;
  }

  /* The about block is the one Giovani pointed at. Its media sits above the
     copy at this width, so the copy centres under it as one column. */
  .definitive-site .def-about-copy {
    text-align: center;
  }

  .definitive-site .def-about-copy .def-about-lead,
  .definitive-site .def-about-copy > p:not(.def-kicker),
  .definitive-site .def-close-copy > p:not(.def-kicker) {
    margin-inline: auto;
  }

  /* An inline-flex link does not follow `text-align` on its parent - it is
     already shrink-wrapped - so the arrow links are centred as boxes. */
  .definitive-site .def-about-copy > .def-arrow-link,
  .definitive-site .def-section-head > .def-arrow-link,
  .definitive-site .def-close-copy > a {
    margin-inline: auto;
  }

  /* The Instagram header is a three-track grid (avatar / copy / link). At this
     width it stacks, so the tracks centre instead of hanging left. */
  .definitive-site .def-instagram .instagram-heading {
    justify-items: center;
    text-align: center;
  }

  .definitive-site .def-instagram .instagram-heading > .def-arrow-link {
    justify-self: center;
  }

  /* @kyleloftusstudios is one unbreakable word set `white-space: nowrap`, and
     its size floor (1.9rem via --t-h2-sm) is wider than a 320px screen - it
     ran off the right edge before, and centring it only made the clipping
     symmetrical. Measured: at 30.4px the word renders 330px wide, so it needs
     about one eleventh of its own width per pixel of type. Sized off the
     viewport at that ratio it always lands inside the padding, and the cap
     keeps it from growing past its old size on a large phone.
     Stated on `.instagram-heading h2`, not `.def-instagram h2`: the
     three-class selector is what set the size in the first place, and a
     two-class rule cannot beat it however late it appears. */
  .definitive-site .def-instagram .instagram-heading h2 {
    font-size: min(calc((100vw - 3rem) / 11), var(--t-h2-sm));
  }
}

/* ==========================================================================
   ROUND 16 - ITEM 8: the hero dips to black before the galaxy rises
   ==========================================================================
   Giovani, on the handoff: the stars "kind of morph into the image way too
   much... it looks a little bit funny". He is describing a cross-dissolve. The
   hero media was ALPHA-MASKED to transparent over its last 22-28vh, and the
   galaxy chapter is tucked up underneath it - so as the image faded out, the
   starfield behind it faded in THROUGH it, and for a couple of hundred pixels
   of scroll there were stars sitting on a legible photograph.

   The model here is a dip to black, in three stages:

     1. The hero resolves on its own terms. The mask is gone; instead the
        scrim inside the media ramps to the ground colour over the last ~30vh
        and reaches it exactly at the media's bottom edge. Nothing shows
        through, because there is no longer any transparency to show through.
     2. A beat of genuine black. The chapter is tucked -14vh/-18vh under the
        hero, which puts the hero's bottom edge about 8-9% of the way down the
        starfield canvas at every viewport. The canvas is then masked opaque-
        black-out for its first 19%, so from the hero's bottom edge there is a
        further ~10vh of nothing before the first star can appear.
     3. The field rises out of it, ramping in from 19% to 34%.

   Because the hero and the chapter scroll together, the gap between the hero's
   bottom edge and the first star is FIXED - about 92px on a 390x844 phone - at
   every scroll position. Stars over photographic content is not reduced, it is
   geometrically impossible.

   Every stage is a multi-stop ramp, per the round-14 rule: no hard edge, and
   the black is a rest in the gradient rather than a boundary between two
   painted boxes.
   -------------------------------------------------------------------------- */
/* Round 22. The footage itself dissolves. The scrim alone was darkening the
   bottom while the VIDEO BOX still ended on a straight edge - that edge, one
   pixel row wide and the full width of the page, is the section line Giovani
   sees between the fold and the galaxy. Masked, the picture has no last row:
   it thins into the ground and the star field ramps in underneath it. */
.definitive-site .hero-media {
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 0,
    #000 calc(100% - 30vh),
    rgba(0, 0, 0, 0.86) calc(100% - 22vh),
    rgba(0, 0, 0, 0.52) calc(100% - 13vh),
    rgba(0, 0, 0, 0.18) calc(100% - 6vh),
    rgba(0, 0, 0, 0) 100%
  );
  mask-image: linear-gradient(
    to bottom,
    #000 0,
    #000 calc(100% - 30vh),
    rgba(0, 0, 0, 0.86) calc(100% - 22vh),
    rgba(0, 0, 0, 0.52) calc(100% - 13vh),
    rgba(0, 0, 0, 0.18) calc(100% - 6vh),
    rgba(0, 0, 0, 0) 100%
  );
}

.definitive-site .hero-scrim {
  background:
    /* The dip. Five stops: a two-stop ramp this long shows its own start as a
       band on a dark gradient. Lands on the ground colour, not near it. */
    linear-gradient(
      to bottom,
      transparent 0,
      transparent calc(100% - 22vh),
      rgba(6, 7, 10, 0.3) calc(100% - 16vh),
      rgba(6, 7, 10, 0.68) calc(100% - 10vh),
      rgba(6, 7, 10, 0.92) calc(100% - 4vh),
      /* Flat opaque tail, not a stop that only reaches opaque AT the edge.
         Landing on `var(--def-bg) 100%` left the final rendered row still
         interpolating, and the footage underneath came through it as a 1px
         line ~20 levels brighter than the black either side of it - measured
         across the frame, not guessed at. The last 4vh is simply the ground
         colour, so there is no last row to get wrong. */
      var(--def-bg) calc(100% - 2vh),
      var(--def-bg) 100%
    ),
    linear-gradient(to bottom, rgba(3, 4, 7, 0.36), transparent 24%),
    linear-gradient(90deg, rgba(3, 4, 7, 0.18), transparent 50%);
}

/* The star-free head of the field. Masked rather than painted so the chapter's
   own ground shows through underneath - the canvas fills with the same colour
   (see script.js), so there is no step where the mask hands over. */
/* Anchored in vh, not %, because the tuck above it is `margin-top: -18vh` and
   these two must agree. They did while the sticky was locked to 100dvh; once
   the chapter became content-height the same 162px tuck landed at 21%-29% of
   the canvas - inside the ramp instead of before it - so the field was already
   partly opaque at the row where the hero's box cuts off dead straight. That
   zero-to-partial step, 1440px wide, WAS the hard edge. In vh it is the same
   distance below the hero at every width. */
/* Round 25 (E), the tail. The mask only ever described the field's HEAD: it
   reached #000 at 44vh and stayed there to the canvas's last row, which is the
   chapter's last row, which is the film rail's first row. So the star field
   ran at full strength and then simply stopped - a flat cut 1440px wide, with
   stars sliced in half sitting on it. Only the vignette's bottom wash softened
   it, and that wash landed on 0.72 alpha, so 28% of the field was still lit on
   the final row and gone on the next one. That partial-then-cut is the same
   shape as the hero-scrim bug above, and it is the abrupt line at the galaxy
   boundary.
   The ramp now runs at BOTH ends. The tail starts at 82% - below the client
   logos, which sit at roughly 72-81% of the sticky and keep their field - and
   arrives at true zero ON the canvas's last row, in three steps rather than
   one, so nothing has to be covered up. The head stays in vh (it has to track
   the -18vh tuck); the tail is in % because it has to track the canvas's own
   bottom edge, which is content-height. */
.definitive-site .galaxy-canvas {
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0,
    transparent 26vh,
    rgba(0, 0, 0, 0.22) 31vh,
    rgba(0, 0, 0, 0.62) 36vh,
    #000 44vh,
    #000 82%,
    rgba(0, 0, 0, 0.58) 90%,
    rgba(0, 0, 0, 0.2) 96%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    transparent 26vh,
    rgba(0, 0, 0, 0.22) 31vh,
    rgba(0, 0, 0, 0.62) 36vh,
    #000 44vh,
    #000 82%,
    rgba(0, 0, 0, 0.58) 90%,
    rgba(0, 0, 0, 0.2) 96%,
    transparent 100%
  );
}

@media (max-width: 620px) {
  /* The mobile hero mask is restated as none too - the 620px block set its own
     shorter ramp, and it would otherwise win over the rule above. */
  .definitive-site .hero-media {
    -webkit-mask-image: none;
    mask-image: none;
  }

  /* Phone tuck is -14vh and the flat mask head is 20vh, so the copy's top pad
     tracks 20vh here instead of 26vh. */
  .definitive-site .galaxy-sticky {
    padding-block: calc(20vh + clamp(1rem, 3vw, 2rem)) 0;
  }

  /* The phone mask restates the whole gradient, head and tail - a mask-image
     is one value, so the tail added to the desktop rule would be dropped
     wholesale here and the seam would come back on phones only. */
  .definitive-site .galaxy-canvas {
    -webkit-mask-image: linear-gradient(
      to bottom,
      transparent 0,
      transparent 20vh,
      rgba(0, 0, 0, 0.22) 24vh,
      rgba(0, 0, 0, 0.62) 29vh,
      #000 36vh,
      #000 82%,
      rgba(0, 0, 0, 0.58) 90%,
      rgba(0, 0, 0, 0.2) 96%,
      transparent 100%
    );
    mask-image: linear-gradient(
      to bottom,
      transparent 0,
      transparent 20vh,
      rgba(0, 0, 0, 0.22) 24vh,
      rgba(0, 0, 0, 0.62) 29vh,
      #000 36vh,
      #000 82%,
      rgba(0, 0, 0, 0.58) 90%,
      rgba(0, 0, 0, 0.2) 96%,
      transparent 100%
    );
  }
}

/* ==========================================================================
   ROUND 16 - ITEM 6: cinematic parallax
   ==========================================================================
   The overscale that gives the travel somewhere to go. Stated in CSS rather
   than written by initParallax so the frames are cropped correctly at first
   paint - if JS applied it, every one of these images would visibly jump the
   moment the script ran.
   1.14 gives 7% of slack at each edge against 5.5% of travel, so the image can
   never pull away from its frame.
   `scale` is the independent property, not `transform: scale()`: the hover
   states on these cards animate `transform`, and this must not be inside that
   transition.

   Above 900px only, matching initParallax's own gate. Measured on a throttled
   phone the effect cost 14% of the frame rate this round just bought back, so
   a phone gets neither the crop nor the travel - see the note in
   definitive.js.
   -------------------------------------------------------------------------- */
@media (min-width: 901px) {
  .definitive-site [data-parallax] {
    scale: 1.14;
  }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site [data-parallax] {
    scale: 1;
    translate: none;
  }
}

/* ==========================================================================
   ROUND 16 - ITEM 7: the mobile "Work with us" field
   ==========================================================================
   This is the section Giovani asked about directly. On desktop it is a
   scattered wall of tilted frames radiating out of the headline; on a phone it
   collapsed to a flat two-column grid, which is the one thing the composition
   is not.

   Rebuilt mobile-native rather than adapted:
     - the headline stays the anchor, and the frames CLUSTER ABOVE AND BELOW
       it. Nothing sits beside it, because at 390px there is no beside.
     - five frames overhead, six below, overlapping, at four different widths
       and each on its own tilt (--r is already per-frame in index.html, so the
       tilt the desktop wall uses carries straight over).
     - the copy band, 36%-58%, is kept clear. The frames crowd towards it from
       both directions but never cross it.
     - drift and playback are scroll-linked (see initClosingField): the frames
       move at their own rates as the section travels, and the frame nearest
       the middle of the viewport is the one playing.

   Placement is `--mx/--my/--mw`, not the desktop `--x/--y`: those are inline
   on each element and a stylesheet cannot override an inline custom property
   without !important, which would then also beat the entrance transform.
   -------------------------------------------------------------------------- */
@media (max-width: 620px) {
  .definitive-site .def-close {
    display: grid;
    min-height: 152vh;
    align-content: center;
    padding: 4rem var(--def-pad);
  }

  /* The field is absolutely positioned against the SECTION, deliberately
     without a grid placement. An abspos grid child that names a grid-area is
     sized against that AREA - and the only in-flow item here is the copy, so
     the area is the copy's own height. All eleven frames packed themselves
     into the height of the headline. With no placement, the containing block
     is the grid container's padding box, which is the whole section. */
  .definitive-site .def-close-media {
    position: absolute;
    z-index: 1;
    display: block;
    inset: 0 3.5vw;
  }

  .definitive-site .def-close-copy {
    grid-area: 1 / 1;
  }

  .definitive-site .def-close-copy {
    position: relative;
    z-index: 5;
    min-height: 0;
    padding: 0;
    /* The copy has to sit in the gap the frames leave, not at the top of the
       section. */
    align-self: center;
  }

  .definitive-site .def-close-media button {
    position: absolute;
    top: var(--my);
    right: auto;
    bottom: auto;
    left: var(--mx);
    width: var(--mw);
    aspect-ratio: 16 / 9;
  }

  /* Overhead: five frames falling towards the headline, biggest first. */
  .definitive-site .def-close-media button:nth-child(1)  { --mx: 1%;  --my: 1%;  --mw: 54%; }
  .definitive-site .def-close-media button:nth-child(2)  { --mx: 47%; --my: 8%;  --mw: 52%; }
  .definitive-site .def-close-media button:nth-child(3)  { --mx: 13%; --my: 15%; --mw: 47%; }
  .definitive-site .def-close-media button:nth-child(4)  { --mx: 55%; --my: 22%; --mw: 44%; }
  .definitive-site .def-close-media button:nth-child(5)  { --mx: 2%;  --my: 27%; --mw: 41%; }

  /* Below: six frames opening back out. Measured, not guessed: the copy block
     occupies 41.4%-58.4% of the section at 390x844, so the first frame below
     it starts at 61% rather than the 57% this began at, which was clipping the
     "Begin here" link by 20px. */
  .definitive-site .def-close-media button:nth-child(6)  { --mx: 55%; --my: 61%; --mw: 43%; }
  .definitive-site .def-close-media button:nth-child(7)  { --mx: 3%;  --my: 66%; --mw: 49%; }
  .definitive-site .def-close-media button:nth-child(8)  { --mx: 48%; --my: 72%; --mw: 50%; }
  .definitive-site .def-close-media button:nth-child(9)  { --mx: 6%;  --my: 78%; --mw: 45%; }
  .definitive-site .def-close-media button:nth-child(10) { --mx: 51%; --my: 84%; --mw: 45%; }
  .definitive-site .def-close-media button:nth-child(11) { --mx: 1%;  --my: 90%; --mw: 43%; }

  /* The labels were shown permanently for the flat grid, where there was no
     other way to know what a tile was. On a scatter they compete with the
     headline, so they sit back to the desktop weight and the frame that is
     playing states itself. */
  .definitive-site .def-close-media button > span {
    opacity: 0.72;
  }

  .definitive-site .def-close-media button.is-previewing > span {
    opacity: 1;
  }
}

/* ==========================================================================
   ROUND 16 - handed over from workstream B: release the case-study layer
   ==========================================================================
   `.project-layer` is declared `will-change: transform, opacity` in
   legacy-bridge.css (and in styles.css, which the homepage does not load) -
   permanently. That holds a full-screen compositing layer for the whole
   session whether or not anything is moving, on a page whose whole complaint
   is that a phone cannot keep up.

   Restated here rather than edited at source because definitive.css is the
   last stylesheet index.html loads, so this is the one place that reliably
   wins for the homepage. The layer is promoted only while the FLIP is running
   and released a beat after it lands - see hintLayer() in script.js.
   -------------------------------------------------------------------------- */
.project-layer {
  will-change: auto;
}

.project-layer.is-animating {
  will-change: transform, opacity;
}

/* ==========================================================================
   ROUND 17 - ITEM 1: the marks ARRIVE
   ==========================================================================
   Giovani, on round 16: "more pop, more movement, the logos currently just
   appear." He was describing the truth of the code. The entrance was an
   opacity ramp with a 0.94 -> 1 scale hung off it: two consecutive frames of
   that sequence differ only in how opaque the logo is. Nothing travels.

   script.js now keys real travel (see the markPlan note there). This is the
   surface it needs:
     - `--mark-rot` joins the transform, so a mark can settle out of a couple
       of degrees rather than snapping square;
     - `--mark-flash` drives the BACKLIGHT, never the art. Round 14 killed
       every filter on the img for good reason - a drop-shadow on alpha art is
       ink on the artwork, and it is what made Alpha Lion and Opus look dirty.
       The bloom is the halo swelling and brightening behind the mark.
   -------------------------------------------------------------------------- */
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  transform:
    translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px)))
    scale(var(--mark-scale, 0.34))
    rotate(var(--mark-rot, 0deg));
}
/* Settled keeps the shift - the parallax and the idle float live there - but
   drops scale and rotation entirely, so the SVG rasterises at its own layout
   size instead of being resampled. That was round 11's fix and it stands. */
.definitive-site .def-galaxy-marks [data-galaxy-mark].is-settled {
  transform: translate(calc(-50% + var(--mark-shift-x, 0px)), calc(-50% + var(--mark-shift-y, 0px)));
}

/* The landing bloom. Rest is unchanged in appearance: the gradient is ~1.2x
   the alpha it was and the layer sits at 0.7 instead of 0.85, which multiplies
   back out to the same halo. What that buys is headroom - at full flare the
   layer goes to 1 and swells to 1.55x, so the bloom is 1.7x the resting halo
   and half again its size. Both properties are composited; neither repaints
   the mark. */
.definitive-site .def-galaxy-marks [data-galaxy-mark]::before {
  opacity: calc(0.7 + var(--mark-flash, 0) * 0.3);
  scale: calc(1 + var(--mark-flash, 0) * 0.55);
  background: radial-gradient(
    circle closest-side,
    rgba(154, 180, 236, calc(0.06 + var(--mark-layer, 0.6) * 0.048)) 0%,
    rgba(120, 150, 210, 0.027) 38%,
    transparent 66%
  );
  /* Opacity comes off the transition: it is written per frame now, and a
     260ms interpolation on a per-frame value is a lag, not an ease. The
     hover's own travel is still eased - it is on transform. */
  transition: transform 260ms var(--def-ease);
}

@media (prefers-reduced-motion: reduce) {
  /* No flight, no overshoot, no bloom - the composed picture, held. */
  .definitive-site .def-galaxy-marks [data-galaxy-mark] {
    transform: translate(-50%, -50%);
  }
  .definitive-site .def-galaxy-marks [data-galaxy-mark]::before {
    opacity: 0.7;
    scale: 1;
  }
}

/* ==========================================================================
   ROUND 17 - ITEM 2: nothing in the chapter is ever still
   ==========================================================================
   Once the ring assembled, the composition stopped. The visitor is still in
   the section for another screen of scroll after that, looking at a picture.

   Three things carry on now. The nebula breathes (script.js - radius and core
   weight on their own slow clocks). The marks keep floating, each on its own
   path and period. And the headline arrives lit by the field rather than
   simply faded up.
   -------------------------------------------------------------------------- */

/* The lines come up further and out of a slight push back into the field.
   Landing on exactly 1 matters: type resampled at 0.998 is type with soft
   edges, and this headline is 3.45rem of Helvetica on near-black. */
.definitive-site .galaxy-copy span {
  opacity: var(--line-progress, 0);
  transform: translateY(var(--line-y, 52px)) scale(var(--line-scale, 0.955));
  will-change: opacity, transform;
}

/* The headline's backlight (round 14 item 3) is what "lit by the field" means
   here - it brightens on the beat the last line lands and eases back. Same
   glow language as the marks' halo, not a second one invented for the type.
   The gradient is restated ~1.35x its old alpha so that the resting 0.74
   multiplies back out to exactly what round 14 tuned. */
.definitive-site .galaxy-copy::before {
  opacity: var(--galaxy-glow, 0.74);
  background: radial-gradient(
    ellipse 50% 42% at 50% 50%,
    rgba(214, 229, 255, 0.27) 0%,
    rgba(180, 203, 255, 0.135) 34%,
    rgba(150, 180, 240, 0.054) 58%,
    transparent 76%
  );
}

/* Three float paths, not one. Twelve marks tracing the same loop at different
   speeds still reads as one mechanism; three shapes at twelve periods reads as
   twelve objects sitting in the same field. Periods stay coprime-ish so the
   ring never visibly resynchronises. */
.definitive-site .def-galaxy-marks [data-galaxy-mark] {
  --mark-drift-span: calc(var(--mark-layer, 0.6) * 11px);
  animation: def-mark-drift calc(21s / (0.45 + var(--mark-layer, 0.6))) ease-in-out infinite;
  animation-delay: calc(var(--mark-delay, 0) * -1.9s);
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n + 2) {
  animation-name: def-mark-drift-b;
  animation-duration: calc(26s / (0.45 + var(--mark-layer, 0.6)));
}
.definitive-site .def-galaxy-marks [data-galaxy-mark]:nth-child(3n) {
  animation-name: def-mark-drift-c;
  animation-duration: calc(17s / (0.45 + var(--mark-layer, 0.6)));
}

@keyframes def-mark-drift-b {
  0% { translate: 0 0; }
  25% { translate: calc(var(--mark-drift-span) * -0.9) calc(var(--mark-drift-span) * -0.45); }
  55% { translate: calc(var(--mark-drift-span) * 0.35) calc(var(--mark-drift-span) * -0.95); }
  80% { translate: calc(var(--mark-drift-span) * 0.8) calc(var(--mark-drift-span) * 0.3); }
  100% { translate: 0 0; }
}
@keyframes def-mark-drift-c {
  0% { translate: 0 0; }
  40% { translate: calc(var(--mark-drift-span) * 0.55) calc(var(--mark-drift-span) * 0.85); }
  70% { translate: calc(var(--mark-drift-span) * -0.7) calc(var(--mark-drift-span) * 0.25); }
  100% { translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .galaxy-copy span {
    opacity: 1;
    transform: none;
    will-change: auto;
  }
  .definitive-site .galaxy-copy::before { opacity: 1; }
  .definitive-site .def-galaxy-marks [data-galaxy-mark] {
    animation: none;
    translate: none;
  }
}

/* ==========================================================================
   ROUND 17 - ITEM 4: moments vs content sections
   ==========================================================================
   Giovani asked whether every section should be full-viewport. No blanket
   rule - the page has two kinds of section and they should behave differently.
   MOMENTS (hero, the galaxy, Watch the work, Work with us) get viewport-scale
   height so the composition has room to land. CONTENT (Selected work,
   Expertise, About, Instagram, Learn, the proof strip) sizes to its own
   content on the normal rhythm; padding those to full height turns the page
   into a slideshow.

   Audited at 1440x900 and 390x844 before changing anything. Measured, in
   viewports:

     moment   hero            1.00 / 1.00   already right
     moment   galaxy          1.18 / 1.12   already right
     moment   Watch the work  0.94 / 0.64   the one gap - fixed below
     moment   Work with us    1.00 / 1.52   already right
     content  Selected work   1.29 / 2.57   content-driven, not padded
     content  Expertise       1.67 / 2.41   content-driven, not padded
     content  About           0.85 / 0.96   content-driven, not padded
     content  Instagram       1.40 / 1.57   content-driven, not padded
     content  Client proof    0.46 / 0.39   content-driven, not padded
     content  Learn           1.17 / 0.99   content-driven, not padded

   So the split was already almost right and there is exactly one real change
   to make. No content section carries a viewport-derived floor (--sec-pad-y is
   clamp(5.5rem, 9vw, 9rem), a rhythm token, and About's 48rem is a layout
   floor in rem, not a screenful), so nothing needed shrinking either.

   Round 14 item 7 removed `min-height: 100dvh` from this section for a real
   reason: under block flow the reclaimed height all landed BELOW the controls,
   which is worse than not having it. The floor comes back with
   `align-content: center`, so the head, the rail and the controls centre as
   one group and the room is split above and below them. Nothing overlaps the
   film, and no edge is created - the section still rides transparent on the
   one ground, per round 14's governing rule.
   -------------------------------------------------------------------------- */
/* Round 19b. The headline is gone, so the rail follows the client strip
   directly. The section used to be floored at a viewport and centre its
   content, which meant padding could not move the rail at all - it just
   re-centred inside the same tall box. Content-height and top-aligned now, so
   the one gap that matters is the padding below.

   That gap is deliberately the SAME pair of values that separates the actions
   from the logos inside the chapter above: the sticky's `gap` plus the logo
   window's own padding. Read them together - if one changes, change both. */
.definitive-site .def-film-roll {
  display: grid;
  align-content: start;
  min-height: 0;
  padding-top: clamp(2.5rem, 5vw, 5rem);
}

.definitive-site .def-film-stage {
  margin-top: 0;
}

@media (max-width: 620px) {
  .definitive-site .def-film-roll {
    min-height: 0;
    padding-top: clamp(2rem, 6vw, 3rem);
  }
}

/* ==========================================================================
   Self-hosted <video> loops replace the Vimeo <iframe> embeds on the rail,
   the closing wall and the ambient backdrop. Every rule that positioned an
   iframe now applies identically to the video that took its place, so the
   whole visual system is inherited rather than re-authored.
   ========================================================================== */
.definitive-site .def-film-card video,
.definitive-site .def-close-media button > video,
.definitive-site .def-film-ambient {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  object-fit: cover;
}
/* Rail card video: matches the iframe treatment (concealed until active,
   fast crossfade, no letterbox bleed). */
.definitive-site .def-film-card video {
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 106%;
  height: 106%;
  opacity: 0;
  transform: translate(-50%, -50%);
  transition: opacity 200ms ease;
  pointer-events: none;
}
.definitive-site .def-film-card.is-active.is-video-ready video { opacity: 1; }
.definitive-site .def-film-card:not(.is-active) video { opacity: 0; transition: none; }

/* Closing-wall card video. */
.definitive-site .def-close-media button > video {
  z-index: 1;
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.definitive-site .def-close-media button.is-video-ready > video { opacity: 1; }

/* Ambient backdrop video. */
.definitive-site .def-film-ambient {
  width: 108%;
  height: 108%;
  top: -4%;
  left: -4%;
  opacity: 0;
  transition: opacity 600ms ease;
}
.definitive-site .def-film-roll.is-ambient-ready .def-film-ambient { opacity: 0.5; }

/* ==========================================================================
   REDESIGN — the Vidure-referenced fold sequence.
   Hero (docking mark) → the claim over the galaxy → client strip → the reel,
   wall-sized → Selected work (the rail).
   ========================================================================== */

/* The claim. Centred, kicker over one message over one action — the full
   What-We-Stand-For shape from the Vidure reference. The field behind it
   comes into focus as the words light (--field-focus, set by initWordReveal). */
.definitive-site .galaxy-canvas {
  opacity: calc(var(--galaxy-exit, 1) * var(--field-focus, 1));
}

.definitive-site .galaxy-message {
  position: relative;
  z-index: 3;
  display: flex;
  width: min(92%, 62rem);
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.definitive-site .galaxy-copy {
  margin: 0;
  font-size: clamp(2.4rem, 4.6vw, 4.3rem);
  letter-spacing: -0.02em;
  line-height: 1.12;
  text-transform: none;
  text-wrap: balance;
}

/* The reveal: each word carries its own ink progress, driven by scroll in
   script.js. Ink rises from a quarter-lit ghost to full paper - the Cameroll
   read, tuned so it feels lit by the field rather than printed by a slider.
   No blur, no movement: crisp glyphs whose LIGHT changes. */
/* Round 22: the reveal was invisible because an unlit word was already 22%
   ink on a dark field - near enough to lit that nothing appeared to happen.
   A word now arrives genuinely absent: 8% ink, softly out of focus and sunk a
   little, and RESOLVES - focus, weight and position together. Ten times the
   contrast between states, so the line writes itself as you scroll. */
.definitive-site .galaxy-copy .w {
  display: inline-block;
  color: rgb(244 241 235 / 0.08);
  filter: blur(5px);
  transform: translateY(0.14em);
  transition: color 260ms var(--u-ease), filter 260ms var(--u-ease),
    transform 260ms var(--u-ease);
}
.definitive-site .galaxy-copy .w.is-half {
  color: rgb(244 241 235 / 0.4);
  filter: blur(2px);
  transform: translateY(0.06em);
}
.definitive-site .galaxy-copy .w.is-lit {
  color: var(--u-ink);
  filter: blur(0);
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .galaxy-copy .w {
    color: var(--u-ink);
    filter: none;
    transform: none;
  }
}

.definitive-site .galaxy-lede {
  margin: clamp(1.2rem, 2vw, 1.8rem) 0 0;
  color: var(--u-ink-2);
  font-size: var(--u-lede);
  line-height: 1.55;
}

.definitive-site .galaxy-actions {
  display: flex;
  gap: var(--s2, 1rem);
  margin-top: clamp(1.8rem, 3vw, 2.6rem);
}

.definitive-site .galaxy-btn {
  display: inline-flex;
  min-height: 3rem;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 1.5rem;
  border: 1px solid var(--u-line-strong);
  border-radius: var(--u-r);
  color: var(--u-ink);
  font-size: var(--u-label);
  letter-spacing: var(--u-track);
  text-transform: uppercase;
  transition: border-color 200ms var(--u-ease), background 200ms var(--u-ease), color 200ms var(--u-ease);
}
.definitive-site .galaxy-btn:hover,
.definitive-site .galaxy-btn:focus-visible { border-color: var(--u-ink); }
.definitive-site .galaxy-btn.is-solid {
  border-color: var(--u-ink);
  background: var(--u-ink);
  color: #06070a;
}

/* The strip: on the field, directly under the actions, where Vidure carries
   its stat row. Positioned so it paints above the absolutely-placed canvas. */
.definitive-site .galaxy-sticky > .def-logo-window {
  position: relative;
  z-index: 3;
  width: 100%;
  /* The window clips horizontally for the marquee, so the hover bloom needs
     room INSIDE the clip box or it is cut off top and bottom. */
  padding-block: 2.25rem;
  margin-top: 0;
}
.definitive-site .def-logo-window.is-dragging { cursor: grabbing; }

/* Each mark answers the pointer the way the galaxy's ring did: it grows, it
   comes to full ink, and a soft light blooms behind it — the field lighting
   the logo rather than a box drawing around it. */
.definitive-site .def-logo-track a {
  position: relative;
  /* Own stacking context, so the z-index:-1 bloom sits behind the mark but
     still above the chapter's own background. */
  isolation: isolate;
  transition:
    opacity 260ms var(--u-ease),
    transform 320ms var(--u-ease);
}

.definitive-site .def-logo-track a::before {
  position: absolute;
  z-index: -1;
  top: 50%;
  left: 50%;
  /* Fixed px and a CIRCLE, not percentages. The anchors run 144px to 365px
     wide against a constant 80px tall, so a percentage box made this a 1.4:1
     ellipse on one mark and a 3.6:1 slab on another - the "box behind the
     logo". A circle is the same light on every mark. */
  width: 180px;
  height: 180px;
  content: "";
  border-radius: 50%;
  /* Peak alpha 0.05 instead of 0.30, and eased to a true zero AT the boundary.
     The old stop list stopped at `transparent 78%`, leaving a kink in the
     falloff that the eye reads as an edge; there is no kink here. */
  background: radial-gradient(closest-side circle,
    rgb(178 200 255 / 0.05) 0%,
    rgb(178 200 255 / 0.043) 14%,
    rgb(178 200 255 / 0.033) 29%,
    rgb(178 200 255 / 0.022) 45%,
    rgb(178 200 255 / 0.013) 60%,
    rgb(178 200 255 / 0.006) 74%,
    rgb(178 200 255 / 0.002) 88%,
    rgb(178 200 255 / 0) 100%);
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) scale(0.94);
  transition: opacity 420ms var(--u-ease), transform 420ms var(--u-ease);
}

.definitive-site .def-logo-track a:hover,
.definitive-site .def-logo-track a:focus-visible {
  opacity: 1;
  /* 1.13 on a 365px wordmark is a 47px jump - a pop, not a lift. */
  transform: scale(1.05);
}

.definitive-site .def-logo-track a:hover::before,
.definitive-site .def-logo-track a:focus-visible::before {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

/* NOT drop-shadow. A silhouette glow traces the artwork's alpha, and five of
   these six logos are cropped flush to their own canvas on all four edges, so
   the halo drew the bounding RECTANGLE - which is the frame Giovani saw, and
   the same mistake an earlier round already removed once. Brightness cannot
   produce a shape. */
.definitive-site .def-logo-track a img {
  transition: filter 420ms var(--u-ease);
}

.definitive-site .def-logo-track a:hover img,
.definitive-site .def-logo-track a:focus-visible img {
  filter: brightness(1.06);
}

@media (prefers-reduced-motion: reduce) {
  .definitive-site .def-logo-track a,
  .definitive-site .def-logo-track a::before { transition-duration: 1ms; }
  .definitive-site .def-logo-track a:hover,
  .definitive-site .def-logo-track a:focus-visible { transform: none; }
}
.definitive-site .visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

/* The reel, wall-sized. */
.definitive-site .def-reel-band {
  position: relative;
  width: min(96vw, 100rem);
  margin: clamp(2rem, 4vw, 4rem) auto 0;
  overflow: hidden;
  border-radius: var(--u-r);
  aspect-ratio: 16 / 9;
  max-height: 86svh;
}
.definitive-site .def-reel-band video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.definitive-site .def-reel-band::after {
  position: absolute;
  inset: 0;
  content: "";
  background: rgb(0 0 0 / 0.18);
  transition: background 200ms var(--u-ease);
}
.definitive-site .def-reel-band:hover::after { background: rgb(0 0 0 / 0.06); }
.definitive-site .def-reel-band-play {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--u-ink);
  cursor: pointer;
  transform: translate(-50%, -50%);
}
.definitive-site .def-reel-band-ring {
  display: grid;
  width: clamp(4.5rem, 7vw, 6.5rem);
  height: clamp(4.5rem, 7vw, 6.5rem);
  place-items: center;
  border: 1px solid rgb(244 241 235 / 0.6);
  border-radius: 50%;
  background: rgb(6 7 10 / 0.35);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 1rem;
  transition: transform 200ms var(--u-ease), background 200ms var(--u-ease);
}
.definitive-site .def-reel-band-play:hover .def-reel-band-ring,
.definitive-site .def-reel-band-play:focus-visible .def-reel-band-ring {
  background: rgb(244 241 235 / 0.14);
  transform: scale(1.06);
}
.definitive-site .def-reel-band-play .label { font-size: var(--u-label); letter-spacing: var(--u-track); text-transform: uppercase; }

@media (max-width: 720px) {
  .definitive-site .galaxy-actions { width: 100%; flex-direction: column; align-items: stretch; }
  .definitive-site .def-reel-band { width: 100%; border-radius: 0; }
}

/* Redesign: the chapter is ONE composition on ONE field — claim, lede,
   actions, then the client strip, all lit by the same star field. The strip
   used to be its own section below, which read as a hard black split exactly
   where the reference runs continuous. Height is auto over a viewport floor so
   the taller mobile stack grows instead of overflowing; with no travel the
   sticky is inert and there is no scroll tail. */
.definitive-site .def-galaxy {
  height: auto;
  min-height: 0;
}

/* Content-sized, not viewport-sized. A dvh floor leaves slack the flexbox has
   to distribute somewhere, and that slack IS the empty space — the chapter is
   its content plus deliberate padding, so every gap here is one we chose. */
.definitive-site .galaxy-sticky {
  display: flex;
  height: auto;
  min-height: 0;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(2.5rem, 5vw, 5rem);
  /* The top pad is in vh ON PURPOSE. The chapter is tucked under the hero by
     -18vh and its star field stays fully transparent for the first 26vh, both
     height-based; a width-based clamp here crossed over them at some window
     shapes and put the headline BEHIND the hero (measured -2px of clearance at
     1440x900 and 1280x800 - the clipped first line). Anchored to the same 26vh
     the mask uses, the copy always starts below the hero and on lit field, at
     every aspect ratio. Change this only together with the mask and the tuck. */
  /* Bottom padding 0: the chapter ends AT the logo strip, and the distance to
     the film rail is owned entirely by the rail's own padding-top - stated
     once, so the gap above the logos (sticky gap + window pad = 108px at 1440)
     and the gap below them (window pad + rail pad = 108px) cannot drift. */
  padding-block: calc(26vh + clamp(1rem, 2.5vw, 2.5rem)) 0;
}

/* Redesign fixes from the gate: the legacy chapter set its line-spans as
   blocks (nine words became nine lines), and the homepage bridge never
   carried the floating logo's positioning. Both stated here, owned. */
.definitive-site .galaxy-message .galaxy-copy span {
  display: inline;
  padding: 0;
  margin: 0;
  opacity: 1;
  transform: none;
}
/* The dock target. Without an explicit size the slot stretches to its whole
   grid column (measured 478px wide, 0 tall on the homepage — the smeared
   giant-logo bug), and initFloatingLogo docks the mark at whatever size the
   slot reports. Mirrors the interior slot in styles.css (148 x 34). */
.definitive-site .nav-logo-slot {
  grid-column: 2;
  grid-row: 1;
  justify-self: center;
  width: 9.25rem;
  height: 2.125rem;
}

@media (max-width: 1024px) {
  .definitive-site .nav-logo-slot {
    grid-column: 1;
    justify-self: start;
    width: 8rem;
    height: 1.875rem;
  }
}
/* The mark lives IN the fold, not on the viewport. `fixed` made it drag along
   as the page scrolled and snap back to centre whenever the fold re-entered -
   both faults Giovani reported. As an absolutely-placed child of the hero it
   simply sits there and scrolls away with everything else. */
.definitive-site .floating-logo {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 6;
  width: min(560px, 74vw);
  display: block;
  line-height: 0;
  transform: translate(-50%, -50%);
}

.definitive-site .floating-logo img {
  width: 100%;
  height: auto;
}

/* The legacy chapter set .galaxy-copy as a stacking context (grid), which
   turns every inline word into its own row. The message is a paragraph. */
.definitive-site .galaxy-message .galaxy-copy { display: block; }

/* Round 68, Giovani's Low Power Mode flash: for a beat on load, neither the
   reel (no frame yet - autoplay refused) nor the fallback img (still
   decoding) painted, and the bare fold flashed a band under the nav. The
   media box now carries the SAME poster as its own background floor (one
   cached fetch), and the <video> holds it natively via its poster attr -
   the fold can never be bare for a single frame. */
.definitive-site .hero-media {
  background: #06070a url("assets/posters/hero-reel.webp") center / cover no-repeat;
}

/* 9/1: the claim lights on its own clock now - the section's entrance
   triggers the sequence (60ms per word), scrolling out rewinds it. The
   scrub in script.js is retired; --field-focus alone stays scroll-fed. */
.definitive-site .galaxy-copy.is-auto .w {
  color: var(--u-ink);
  filter: blur(0);
  transform: none;
  transition-delay: calc(var(--gi, 0) * 60ms);
}
.definitive-site .galaxy-copy:not(.is-auto) .w { transition-delay: 0ms; }
