/* ═══════════════════════════════════════════════════════════════════════════
   ALPHA6 — GAME DEVELOPMENT  (dark theme)
   1. Tokens          5. Timeline scrubber
   2. Reset & base    6. Captions & finale
   3. Nav & hero      7. Content sections
   4. Stage / monitor 8. Viewer, responsive, a11y
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────── 1. Tokens ─────────────────────────── */
:root {
  /* Dark, near-violet base — the footage lives in neon on black. */
  --paper: #07070d;
  /* page base */
  --paper-2: #0c0c16;
  /* alternating sections */
  --paper-3: #171826;
  /* tracks and wells */
  --ink: #eef0f6;
  /* primary text */
  --ink-soft: #9096ab;
  /* muted text */
  --stage: #07070d;
  /* canvas clear colour */
  --accent: #7c5cff;
  /* the controller's neon */
  --accent-2: #22c77e;
  /* Roblox green */
  --accent-3: #4a9eff;
  /* Unreal blue */
  --line: rgba(238, 240, 246, 0.16);
  --line-soft: rgba(238, 240, 246, 0.08);

  /* Headline gradient — deep royal blue into violet. Defined once here and
     reused by the hero, captions and finale so all three stay in step. */
  --grad: linear-gradient(100deg, #195fc7 0%, #4a5fbe 45%, #7a6fd0 100%);

  --display: "Century Gothic", "CenturyGothic", "URW Gothic", "Poppins",
    "Avant Garde", "Futura", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --gut: clamp(1.25rem, 4vw, 4rem);
  --nav-h: 5.5rem;
}

/* ─────────────────────────── 2. Reset & base ─────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

/* Fallback for anchor jumps that bypass Lenis (reduced motion, no JS): keeps
   the target clear of the fixed nav. */
:where(section[id], form[id]) {
  scroll-margin-top: calc(var(--nav-h) + 1.25rem);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  line-height: 1.6;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.is-locked,
.is-locked body {
  overflow: hidden;
}

h1,
h2,
h3 {
  margin: 0;
  font-weight: 700;
}

p,
ul {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
}

svg {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.mono {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.rule {
  display: inline-block;
  width: 1.75rem;
  height: 1px;
  margin-right: 0.75rem;
  vertical-align: 0.2em;
  background: var(--accent);
}

/* Reusable gradient text. background-clip paints the glyphs, so any flat
   text-shadow has to go — a drop-shadow filter follows the letterforms. */
.grad-text,
.caption__line:last-child,
.finale__line:nth-child(3)>span {
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: none;
}

.caption__line:last-child,
.finale__line:nth-child(3)>span {
  filter: drop-shadow(0 4px 22px rgba(0, 0, 0, 0.9));
}

/* ─── Buttons ─── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.45s var(--ease), border-color 0.45s var(--ease), color 0.45s var(--ease);
}

.btn svg {
  width: 0.85em;
  height: 0.85em;
  transition: transform 0.45s var(--ease);
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}

.btn--primary:hover {
  background: #9377ff;
  border-color: #9377ff;
}

.btn--ghost:hover {
  border-color: var(--ink);
}

.btn--full {
  width: 100%;
  margin-top: 1.5rem;
}

.btn--sm {
  padding: 0.6rem 1.15rem;
  font-size: 0.8125rem;
}

.btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ─────────────────────────── Preloader ─────────────────────────── */
.loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: var(--paper);
  transition: opacity 0.9s var(--ease), visibility 0.9s;
}

.loader.is-done {
  opacity: 0;
  visibility: hidden;
}

.loader__inner {
  width: min(20rem, 70vw);
  text-align: center;
}

.loader__label {
  margin-bottom: 1.25rem;
}

.loader__bar {
  height: 2px;
  background: var(--paper-3);
  overflow: hidden;
  border-radius: 2px;
}

.loader__fill {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.35s linear;
}

.loader__count {
  margin-top: 1rem;
  color: var(--ink);
}

.loader__error {
  max-width: 26rem;
  margin: 1.25rem auto 0;
  color: var(--accent);
  font-size: 0.625rem;
  line-height: 1.7;
  text-transform: none;
  letter-spacing: 0.06em;
  word-break: break-all;
}

.protocol-note {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 120;
  padding: 1rem var(--gut);
  background: var(--accent);
  color: #fff;
  text-align: center;
}

.protocol-note .mono {
  color: rgba(255, 255, 255, 0.85);
}

/* ─────────────────────────── 3. Nav & hero ─────────────────────────── */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: 100%;
  height: var(--nav-h);
  padding: 0 var(--gut);
  background: rgba(7, 7, 13, 0.9);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-soft);
}

.nav__mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-decoration: none;
}

/* Height-driven so a logo of any aspect ratio sits on the same optical line
   as the wordmark; `width: auto` keeps a wide lockup from being squashed.
   Sized to the full two-line lockup now, not just the wordmark. */
.nav__logo {
  display: block;
  height: 4.8rem;
  max-height: calc(var(--nav-h) - 0.5rem);
  width: auto;
  object-fit: contain;
  flex: none;
}

/* Works with the plain `<span>Alpha6</span>` markup too: the descriptor is
   generated so the lockup appears without an HTML edit. `:not(.nav__name)`
   stops it doubling up once the proper two-element markup is in place —
   which is the better version, since generated text is invisible to search
   engines and inconsistently announced by screen readers. */
.nav__mark>span:not(.nav__name) {
  display: grid;
  gap: 0.15rem;
  line-height: 1.05;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

.nav__mark>span:not(.nav__name)::after {
  content: "Institute of Multimedia";
  font-family: var(--mono);
  font-size: 0.5rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Stacked lockup: name over descriptor. Grid rather than two blocks so the
   baseline gap is a single value and the pair centres against the logo. */
.nav__name {
  display: grid;
  gap: 0.15rem;
  line-height: 1.05;
}

.nav__name b {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Mono, tracked out and small — the same treatment as every other eyebrow on
   the page, so the descriptor reads as a label rather than a second title. */
.nav__name em {
  font-family: var(--mono);
  font-style: normal;
  font-size: 0.5rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  white-space: nowrap;
}

/* Absolutely centred on the viewport rather than flexed into the middle: the
   wordmark and the CTA are different widths, so any flow-based centring puts
   the links off-centre by half that difference. Taken out of flow, the two
   flanking items still space-between correctly around them. */
.nav__links {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 1.6rem;
}

.nav__links a {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.35s var(--ease);
}

.nav__links a:hover {
  color: var(--ink);
}

@media (max-width: 1200px) {
  .nav__links {
    gap: 1.1rem;
  }

  .nav__links a {
    font-size: 0.625rem;
  }
}

@media (max-width: 980px) {
  .nav__links {
    gap: 0.85rem;
  }

  .nav__links a {
    font-size: 0.5625rem;
    letter-spacing: 0.1em;
  }
}

.hero {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  padding: calc(var(--nav-h) + 1.5rem) var(--gut) 4rem;
  z-index: 5;
  pointer-events: none;
}

.hero__inner {
  width: min(74rem, 100%);
  pointer-events: auto;
}

/* Set from the scrub once the hero has faded out. Opacity alone does not stop
   an element intercepting clicks across the middle of the viewport. */
.hero.is-gone .hero__inner {
  pointer-events: none;
}

.hero__eyebrow {
  margin-bottom: clamp(1.25rem, 3.5vh, 2.5rem);
}

.hero__title {
  font-size: clamp(2.6rem, 9.5vw, 8.5rem);
  font-weight: 700;
  line-height: 0.92;
  letter-spacing: -0.035em;
}

.hero__line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.04em;
}

.hero__line>span {
  display: block;
}

.hero__sub {
  max-width: 34rem;
  margin-top: clamp(1.25rem, 3.5vh, 2.25rem);
  color: var(--ink-soft);
  font-size: clamp(1rem, 0.95rem + 0.4vw, 1.2rem);
  font-weight: 300;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: clamp(1.5rem, 4vh, 2.5rem);
}

.hero__stats {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 5vw, 3.5rem);
  margin-top: clamp(2rem, 6vh, 3.5rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-soft);
}

.hero__stats b {
  display: block;
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  font-weight: 600;
}

.hero__stats span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.625rem;
}

.hero__scroll {
  position: absolute;
  right: var(--gut);
  bottom: 2rem;
  font-size: 0.625rem;
  writing-mode: vertical-rl;
}

.hero__scroll::after {
  content: "";
  display: block;
  width: 1px;
  height: 2.5rem;
  margin: 0.75rem auto 0;
  background: linear-gradient(var(--ink-soft), transparent);
}

/* ─────────────────────────── 4. Stage / monitor ─────────────────────────── */
.sequence {
  position: relative;
  height: 1600svh;
}

.sequence__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--stage);
}

/* Full-bleed: the footage owns the whole viewport while the section is
   pinned, and the page resumes underneath it. */
.stage {
  position: absolute;
  inset: 0;
}

.stage__monitor {
  position: absolute;
  inset: 0;
}

.frames {
  display: block;
  width: 100%;
  height: 100%;
}

/* Scrim only where copy sits, so text stays legible without dulling the shot.
   The frame always covers now, so there is picture behind the copy at every
   ratio — the scrim is no longer optional on any layout. */
.stage__gloss {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(7, 7, 13, 0.6) 0%, transparent 18%),
    linear-gradient(to top, rgba(7, 7, 13, 0.9) 0%, rgba(7, 7, 13, 0.45) 30%, transparent 52%);
}

/* ─── HUD framing guides ─── */
.hud {
  position: absolute;
  inset: calc(var(--nav-h) * 0.9) var(--gut) 2rem;
  pointer-events: none;
  opacity: 0;
}

.hud__bracket {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 1px solid rgba(255, 255, 255, 0.26);
}

.hud__bracket--tl {
  top: 0;
  left: 0;
  border-right: 0;
  border-bottom: 0;
}

.hud__bracket--tr {
  top: 0;
  right: 0;
  border-left: 0;
  border-bottom: 0;
}

.hud__bracket--bl {
  bottom: 0;
  left: 0;
  border-right: 0;
  border-top: 0;
}

.hud__bracket--br {
  bottom: 0;
  right: 0;
  border-left: 0;
  border-top: 0;
}

/* ─────────────────────────── 5. Timeline scrubber ─────────────────────────── */
/* Overlaid on the footage like a player scrubber. The scroll position IS the
   playhead, which is the craft this course teaches. */
.timeline {
  position: absolute;
  left: var(--gut);
  right: var(--gut);
  bottom: 1.4rem;
  pointer-events: none;
}

.timeline__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.5rem;
}

.timeline__meta p {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.625rem;
  color: rgba(242, 245, 247, 0.6);
}

.timeline__meta b {
  color: #f2f5f7;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.timeline__meta em {
  font-style: normal;
  opacity: 0.6;
}

.timeline__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
  background: var(--accent);
  animation: rec 1.6s ease-in-out infinite;
}

@keyframes rec {

  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.25;
  }
}

.timeline__tracks {
  position: relative;
  padding: 0.4rem;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0.4rem;
  background: rgba(7, 7, 13, 0.6);
  backdrop-filter: blur(8px);
}

.timeline__row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.timeline__row+.timeline__row {
  margin-top: 0.3rem;
}

.timeline__label {
  flex: none;
  width: 1.5rem;
  font-size: 0.5625rem;
  color: rgba(242, 245, 247, 0.45);
}

.timeline__track {
  position: relative;
  flex: 1;
  height: 1.25rem;
  border-radius: 0.2rem;
  background: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}

.timeline__clip {
  position: absolute;
  top: 0;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 0.5rem;
  border-radius: 0.2rem;
  background: rgba(124, 92, 255, 0.28);
  box-shadow: inset 0 0 0 1px rgba(124, 92, 255, 0.5);
  font-family: var(--mono);
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #cdc0ff;
  white-space: nowrap;
  overflow: hidden;
}

.timeline__progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 0%;
  background: rgba(255, 255, 255, 0.16);
}

.timeline__track--audio {
  height: 0.85rem;
}

.timeline__wave {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(90deg,
      transparent 0 2px, rgba(238, 240, 246, 0.3) 2px 3px,
      transparent 3px 5px, rgba(238, 240, 246, 0.16) 5px 6px);
  mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
}

.timeline__playhead {
  position: absolute;
  top: 0.3rem;
  bottom: 0.3rem;
  left: calc(2.5rem + (100% - 3rem) * var(--p, 0));
  width: 2px;
  background: var(--accent);
  border-radius: 2px;
}

.timeline__playhead::before {
  content: "";
  position: absolute;
  top: -3px;
  left: 50%;
  width: 9px;
  height: 9px;
  transform: translateX(-50%) rotate(45deg);
  background: var(--accent);
  border-radius: 1px;
}

/* ─────────────────────────── 6. Captions & finale ─────────────────────────── */
.captions {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.caption {
  position: absolute;
  bottom: clamp(10rem, 22vh, 16rem);
  width: min(48rem, 46vw);
  opacity: 0;
  color: #f2f5f7;
}

.caption--left {
  left: calc(var(--gut) + 0.5rem);
}

.caption--right {
  right: calc(var(--gut) + 0.5rem);
  text-align: right;
}

.caption__eyebrow {
  font-size: clamp(1.1rem, 1.35vw, 1.55rem);
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.1rem;
  color: #b8a4ff;
  letter-spacing: 0.06em;
  font-weight: 500;
}

.caption__eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 2px;
  background: var(--accent);
}

.caption--right .caption__eyebrow {
  flex-direction: row-reverse;
}

/* Three deliberate lines per caption. The breaks are authored in the markup
   rather than left to the browser, so the poster shape is identical at every
   width — and the type is sized to fit inside the column, never past it.
   Longest authored line is "Worlds with" at ~6.8em: 6.8 x 5.4vw = 37vw,
   which clears the 46vw column with room to spare. */
.caption__title {
  font-size: clamp(2.6rem, 5.4vw, 6.5rem);
  font-weight: 800;
  line-height: 0.94;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  text-shadow: 0 4px 32px rgba(0, 0, 0, 0.95);
  overflow-wrap: break-word;
  /* safety net; should never fire */
}

.caption__line {
  display: block;
}

.caption__body {
  margin-top: 1.4rem;
  max-width: 32rem;
  color: rgba(242, 245, 247, 0.92);
  font-size: clamp(1.15rem, 1.45vw, 1.65rem);
  font-weight: 300;
  line-height: 1.5;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.98);
}

.caption--right .caption__body {
  margin-left: auto;
}

/* Above the hero. `.hero` carries `z-index: 5`, and a positioned element with
   an explicit z-index paints over every `z-index: auto` sibling no matter the
   DOM order — so without this the faded-out hero sat on top of the finale and
   ate the click. An opacity-0 element still receives pointer events. */
.finale {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 4vh, 2.5rem);
  padding: var(--gut);
  text-align: center;
  opacity: 0;
  pointer-events: none;
  color: #f2f5f7;
  background: radial-gradient(70% 60% at 50% 50%, rgba(7, 7, 13, 0.88), rgba(7, 7, 13, 0.55) 70%, rgba(7, 7, 13, 0.25));
}

.finale.is-live {
  pointer-events: auto;
}

.finale__title {
  font-size: clamp(2rem, 6.5vw, 5.5rem);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.035em;
}

.finale__line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.04em;
}

.finale__line>span {
  display: block;
}

.finale__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}

.finale .btn--ghost {
  color: #f2f5f7;
  border-color: rgba(255, 255, 255, 0.25);
}

.finale .btn--ghost:hover {
  border-color: #f2f5f7;
}

/* ─────────────────────────── 7. Content sections ─────────────────────────── */
/* No `content-visibility: auto` here, deliberately. It skips layout for
   off-screen sections and substitutes the `contain-intrinsic-size`
   placeholder instead, so on a fresh load every section between the top and
   an anchor target is measured at the guessed height rather than its real
   one. Anchor jumps then land in the wrong place until the browser has
   rendered those sections once and cached their true sizes — which is why a
   second click on the same link worked. Every section here is a nav target,
   so correctness wins over the paint saving. */
.section {
  padding: clamp(4.5rem, 12vh, 9rem) var(--gut);
}

.section--alt {
  background: var(--paper-2);
}

.section__head {
  max-width: 48rem;
  margin-bottom: clamp(2.5rem, 7vh, 4.5rem);
}

.section__eyebrow {
  margin-bottom: 1.25rem;
}

.section__title {
  font-size: clamp(1.75rem, 4.2vw, 3.25rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.03em;
}

.section__lede {
  margin-top: 1.25rem;
  color: var(--ink-soft);
  font-weight: 300;
}

.ticks {
  display: grid;
  gap: 0.6rem;
}

.ticks li {
  position: relative;
  padding-left: 1.35rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
  line-height: 1.5;
}

.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.5rem;
  height: 1px;
  background: var(--accent);
}

/* ─── Journey ─── */
.stages {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.25rem;
}

.stage-card {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper-2);
}

.stage-card__n {
  font-family: var(--mono);
  font-size: 2.75rem;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line);
}

.stage-card:hover .stage-card__n {
  -webkit-text-stroke-color: var(--accent);
  transition: -webkit-text-stroke-color 0.5s var(--ease);
}

.stage-card__tag {
  margin-top: 1rem;
  color: var(--accent);
}

.stage-card__title {
  margin: 0.4rem 0 1.25rem;
  font-size: 1.375rem;
  letter-spacing: -0.02em;
}

/* ─── Verticals ─── */
/* Fixed tracks rather than auto-fit: eight tiles divide evenly into 4x2 and
   2x4, where auto-fit leaves a lone orphan on the last row. */
.verticals {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
}

.verticals li {
  padding: clamp(1.5rem, 3vw, 2rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper-2);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease), transform 0.4s var(--ease);
}

.verticals li:hover {
  background: var(--paper-3);
  border-color: var(--line);
  transform: translateY(-3px);
}

.section--alt .verticals li {
  background: var(--paper);
}

.section--alt .verticals li:hover {
  background: var(--paper-3);
}

.verticals__icon {
  display: block;
  margin-bottom: 0.9rem;
  font-size: 1.5rem;
  line-height: 1;
}

.verticals h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.verticals p {
  margin-top: 0.5rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
}

@media (max-width: 1100px) {
  .verticals {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 520px) {
  .verticals {
    grid-template-columns: 1fr;
  }
}

.chips {
  margin-top: 2.5rem;
}

.chips__label {
  margin-bottom: 0.9rem;
}

.chips ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.chips li {
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 300;
}

/* ─── Marquee ───────────────────────────────────────────────────────────
   The list is duplicated once in the markup and the track slides exactly
   -50%, so the loop closes on itself with no runtime cloning. Only
   `transform` animates, so it stays on the compositor and costs nothing. */
.marquee {
  position: relative;
  overflow: hidden;
  padding: clamp(0.7rem, 1.4vw, 0.95rem) 0;
  border-block: 1px solid var(--line-soft);
  background: var(--paper-2);
  /* Ends fade instead of cutting, so the strip reads as continuous. */
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}

.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee 48s linear infinite;
  will-change: transform;
}

.marquee:hover .marquee__track {
  animation-play-state: paused;
}

.marquee__track ul {
  display: flex;
  align-items: center;
}

.marquee__track li {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 1.75rem);
  padding-right: clamp(1rem, 2vw, 1.75rem);
  font-size: clamp(0.8125rem, 1vw, 0.9375rem);
  font-weight: 400;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--ink-soft);
}

.marquee__track li::after {
  content: "";
  flex: none;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.7;
}

@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

/* ─── Why / technical ─── */
/* Six items on fixed tracks: 3x2 and 2x3 both divide evenly, so no row is
   ever left with a single stranded card. */
.why {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.why li {
  padding: clamp(1.5rem, 3vw, 2rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper-2);
  transition: border-color 0.45s var(--ease), background 0.45s var(--ease);
}

.why li:hover {
  border-color: var(--line);
  background: var(--paper-3);
}

.why__n {
  color: var(--accent);
  margin-bottom: 0.85rem;
}

.why h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.why li>p:last-child {
  margin-top: 0.55rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
}

.section--alt .why li {
  background: var(--paper);
}

.section--alt .why li:hover {
  background: var(--paper-3);
}

@media (max-width: 900px) {
  .why {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 560px) {
  .why {
    grid-template-columns: 1fr;
  }
}

/* ─── Technical mastery ─── */
/* Two tracks: a scannable list of disciplines on the left, the confidence
   panel pinned beside it so both read as one argument. */
/* `.section` is full-bleed, so on a 1920 screen each of these two columns runs
   ~870px. Nothing in the list wraps at that width and the panel stretches to
   match, which is what reads as oversized. A 70rem container puts each column
   at ~538px, where the copy wraps and the card stays compact. The head is
   included so its left edge stays flush with the list below it. */
#careers .section__head,
.mastery {
  max-width: 70rem;
  margin-inline: auto;
}

/* The head now spans the full container, so hold its copy to its own measure
   rather than letting the lede run the whole 70rem. */
#careers .section__title,
#careers .section__lede {
  max-width: 48rem;
}

/* `align-items: start` is load-bearing: stretched grid items are as tall as
   the row, and a sticky element that already fills its container has nowhere
   to travel. Start-aligned, the panel is only as tall as its content. */
.mastery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: start;
}

/* The confidence panel holds while the discipline list scrolls past it, so
   both halves of the argument stay on screen together. Travel comes from the
   list being the taller column — six rows against one card. */
.mastery>.bars {
  position: sticky;
  top: calc(var(--nav-h) + 1.5rem);
}

.mastery__list {
  display: grid;
  gap: 0.75rem;
}

.mastery__row {
  display: flex;
  gap: clamp(0.9rem, 2vw, 1.35rem);
  padding: clamp(1.15rem, 2.4vw, 1.5rem) clamp(1.25rem, 2.6vw, 1.75rem);
  border: 1px solid var(--line-soft);
  border-radius: 1rem;
  background: var(--paper);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}

.mastery__row:hover {
  background: var(--paper-3);
  border-color: var(--line);
}

.mastery__n {
  flex: none;
  padding-top: 0.25rem;
  color: var(--accent);
}

.mastery__row h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.mastery__row p {
  margin-top: 0.4rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
}

@media (max-width: 980px) {
  .mastery {
    grid-template-columns: 1fr;
  }

  /* Stacked, there is no second column to scroll against — a pinned card
     would just hover over the list it is meant to sit beside. */
  .mastery>.bars {
    position: static;
  }
}

/* ─── Skill bars ─── */
.bars {
  position: relative;
  z-index: 1;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper);
}

.bars__title {
  font-size: 1.25rem;
  letter-spacing: -0.015em;
}

/* Overrides the `mono` class in the markup: the reference runs this as a
   plain sentence-case line, not a spaced uppercase eyebrow. */
.bars__sub {
  margin: 0.35rem 0 1.5rem;
  font-family: var(--display);
  font-size: 0.9375rem;
  letter-spacing: 0;
  text-transform: none;
}

.bars ul {
  display: grid;
  gap: 1rem;
}

/* Name left, figure right, track spanning underneath — the bar gets the full
   width instead of being squeezed between two columns of text. */
.bars li {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0.55rem 1rem;
}

.bars__k {
  font-size: 0.9375rem;
  font-weight: 400;
}

.bars__track {
  grid-column: 1 / -1;
  height: 5px;
  border-radius: 5px;
  background: var(--paper-3);
  overflow: hidden;
}

.bars__track i {
  display: block;
  height: 100%;
  width: 0%;
  border-radius: 5px;
  background: linear-gradient(90deg, var(--accent), var(--accent-3));
}

/* Same override: the figure is set in the display face, not mono caps. */
.bars__v {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--accent-3);
}

/* ─── Live projects ─── */
.live {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.live .btn {
  margin-top: 2rem;
}

/* Grid, not flex-wrap. Flex sizes each pill to its own text, so with labels
   this uneven the rows pack raggedly — two on the first row, then one on each
   row after, with every left edge in a different place. Equal tracks give one
   aligned column edge and a tidy pair of columns. */
.clients {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
  gap: 0.6rem;
  align-content: center;
}

.clients li {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.9rem 1.25rem;
  border: 1px solid var(--line-soft);
  border-radius: 0.75rem;
  background: var(--paper-2);
  font-size: 0.9375rem;
  font-weight: 500;
  text-align: center;
}

/* ─── Levels ─── */
/* Stretch, not start: equal-height cards let `.level__out { margin-top:auto }`
   push all three buttons onto the same baseline despite unequal module counts. */
/* Same 70rem container as the mastery block. Full-bleed, two cards run ~870px
   each on a wide screen, which is what makes the headers and chips read
   oversized — no single type size is wrong. */
#programs .section__head,
.levels,
.levels__note,
.outcomes {
  max-width: 70rem;
  margin-inline: auto;
}

#programs .section__title,
#programs .section__lede {
  max-width: 48rem;
}

.levels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.25rem;
  align-items: stretch;
}

/* `relative` + `overflow: hidden` for the rotating motif below: it is cropped
   into a corner device rather than floating free of the card. */
.level {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper-2);
}

/* The rotating motif. A repeating conic gradient draws the radiating blades;
   the radial mask punches out the hub so it reads as a pinwheel rather than a
   filled pie. It takes the card's own engine accent, and rotation is a
   compositor-only transform, so it costs nothing to leave running. */
.level::after {
  content: "";
  position: absolute;
  top: -3.5rem;
  right: -3.5rem;
  width: 13rem;
  height: 13rem;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
      rgba(238, 240, 246, 0.07) 0deg 15deg,
      rgba(238, 240, 246, 0) 15deg 30deg);
  background: repeating-conic-gradient(from 0deg,
      color-mix(in srgb, var(--eng, var(--accent)) 22%, transparent) 0deg 15deg,
      transparent 15deg 30deg);
  -webkit-mask-image: radial-gradient(circle, transparent 24%, #000 25%);
  mask-image: radial-gradient(circle, transparent 24%, #000 25%);
  animation: level-spin 34s linear infinite;
  pointer-events: none;
  z-index: 0;
}

@keyframes level-spin {
  to {
    transform: rotate(360deg);
  }
}

/* An absolutely positioned pseudo-element paints above static siblings, so
   without this the motif would sit on top of the card copy. */
.level>* {
  position: relative;
  z-index: 1;
}

.level--featured {
  border-color: var(--accent);
  background: var(--paper-2);
  box-shadow: 0 24px 60px -30px rgba(124, 92, 255, 0.7);
}

.level__tag {
  margin-bottom: 1rem;
  color: var(--accent);
}

.level__name {
  font-size: 1.375rem;
  letter-spacing: -0.02em;
}

.level__sub {
  margin-top: 0.4rem;
}

.level__price {
  margin: 1.25rem 0 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line-soft);
  font-size: 1.875rem;
  font-weight: 600;
  letter-spacing: -0.02em;
}

/* Duration reads as a sentence-case aside, not a tracked-out eyebrow. */
.level__price span {
  font-family: var(--display);
  font-size: 0.8125rem;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 400;
  color: var(--ink-soft);
}

.module+.module {
  margin-top: 1.25rem;
}

/* Module headings take the card's engine accent instead of flat ink — that is
   what separates the groups at a glance once the chips are this quiet. */
.module__h {
  margin-bottom: 0.6rem;
  color: var(--eng, var(--accent));
}

/* Squarer, smaller tags inside the programme cards. Scoped to `.level` so the
   engine-comparison cards above keep their pill shape. */
.level .chips-inline {
  gap: 0.35rem;
  margin-top: 0.75rem;
}

.level .chips-inline li {
  padding: 0.28rem 0.6rem;
  border-radius: 0.4rem;
  font-size: 0.75rem;
}

.level__out {
  margin-top: auto;
  padding-top: 1.75rem;
  font-size: 0.875rem;
}

.levels__note {
  margin-top: 2rem;
  text-transform: none;
  letter-spacing: 0.06em;
  line-height: 1.8;
}

.outcomes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

.outcomes li {
  padding: clamp(1.35rem, 2.5vw, 1.75rem);
  border: 1px solid var(--line-soft);
  border-radius: 1rem;
  background: var(--paper);
  border-top: 2px solid var(--accent);
  transition: border-color 0.45s var(--ease), background 0.45s var(--ease);
}

.outcomes li:hover {
  background: var(--paper-3);
  border-color: var(--line);
  border-top-color: var(--accent);
}

.outcomes h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.outcomes p {
  margin-top: 0.45rem;
  text-transform: none;
  letter-spacing: 0.06em;
}

@media (max-width: 900px) {
  .outcomes {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .outcomes {
    grid-template-columns: 1fr;
  }
}

/* ─── CTA & contact ─── */
.cta__title {
  font-size: clamp(2rem, 4.5vw, 3.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.cta__lede {
  max-width: 34rem;
  margin-top: 1.25rem;
  color: var(--ink-soft);
  font-weight: 300;
}

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

/* Same 70rem container as the mastery and programme blocks. Full-bleed, each
   column runs ~830px on a 1920 screen — the intro copy stops wrapping and the
   form fields stretch to nearly twice a comfortable input width. */
.contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 4vw, 4rem);
  align-items: stretch;
  max-width: 70rem;
  margin-inline: auto;
}

.contact__intro {
  display: flex;
  flex-direction: column;
}

.contact__intro .section__eyebrow {
  margin-bottom: 1.25rem;
}

.contact__list {
  display: grid;
  gap: 1.25rem;
  margin-top: clamp(1.75rem, 4vh, 2.25rem);
  padding-top: clamp(1.75rem, 4vh, 2rem);
  border-top: 1px solid var(--line-soft);
}

.contact__list li {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.contact__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.75rem;
  border: 1px solid var(--line-soft);
  background: var(--paper-2);
  font-size: 1rem;
  line-height: 1;
}

.cta__k {
  margin-bottom: 0.35rem;
}

.cta__v {
  font-size: 0.9375rem;
  font-weight: 300;
  line-height: 1.6;
}

.cta__v a {
  color: var(--accent);
  text-decoration: none;
}

.cta__v a:hover {
  text-decoration: underline;
}

@media (max-width: 980px) {
  .contact {
    grid-template-columns: 1fr;
  }
}

/* ─── Contact Map ─── */
.contact-map {
  margin-top: 2rem;
  border: 1px solid var(--line-soft);
  border-radius: 1.5rem;
  background: var(--paper-2);
  overflow: hidden;
  flex: 1; /* Stretches to fill remaining height on desktop */
  min-height: 300px; /* Ensures height on mobile when columns stack */
}

.contact-map iframe {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
}

/* ─── Enquiry form ─── */
.enquiry {
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.5rem;
  background: var(--paper-2);
  text-align: left;
}

.section--alt .enquiry {
  background: var(--paper);
}

.enquiry:target {
  border-color: var(--line);
}

.enquiry__title {
  font-size: 1.5rem;
  letter-spacing: -0.02em;
}

.enquiry__sub {
  margin-top: 0.6rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  font-weight: 300;
}

.enquiry__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
  margin: 1.5rem 0 1.25rem;
}

.field {
  display: grid;
  gap: 0.5rem;
  align-content: start;
}

.field--wide {
  grid-column: 1 / -1;
}

.field__k {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--ink);
}

.field__k em {
  font-style: normal;
  color: var(--ink-soft);
  font-size: 0.8125rem;
}

.field :where(input, select, textarea) {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: 0.75rem;
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: 0.9375rem;
  transition: border-color 0.35s var(--ease), background 0.35s var(--ease);
}

.section--alt .field :where(input, select, textarea) {
  background: var(--paper-2);
}

.field ::placeholder {
  color: var(--ink-soft);
  opacity: 0.65;
}

.field textarea {
  resize: vertical;
  min-height: 5.5rem;
}

.field :where(input, select, textarea):focus {
  outline: none;
  border-color: var(--accent);
}

.field select {
  appearance: none;
  cursor: pointer;
}

.enquiry .btn--full {
  margin-top: 0;
}

.enquiry__note {
  margin-top: 1rem;
  text-transform: none;
  letter-spacing: 0.06em;
  text-align: center;
  line-height: 1.6;
}

.enquiry__note[data-state="error"] {
  color: var(--accent);
}

@media (max-width: 400px) {

  .nav__name em,
  .nav__mark>span:not(.nav__name)::after {
    display: none;
  }

  .nav__logo {
    height: 3.2rem;
  }
}

@media (max-width: 520px) {
  .enquiry__grid {
    grid-template-columns: 1fr;
  }
}

/* ─── Footer ─────────────────────────────────────────────────── */
.foot {
  background: var(--paper-2);
  border-top: 1px solid var(--line-soft);
}

/* 4-column grid: brand | course | institute | reach us */
.foot__grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  gap: 2.5rem 3rem;
  max-width: 1200px;
  margin: 0 auto;
  padding: clamp(2.5rem, 6vh, 4rem) var(--gut) clamp(2rem, 4vh, 3rem);
}

/* Col 1: brand */
.foot__brand {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.foot__logo {
  height: 4rem;
  width: auto;
  object-fit: contain;
  display: block;
}

.foot__tagline {
  font-size: 0.8125rem;
  line-height: 1.65;
  color: var(--ink-soft);
  font-weight: 300;
  max-width: 22rem;
}

.foot__tagline a {
  color: var(--accent);
  text-decoration: none;
}

/* Cols 2–4 */
.foot__col {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.foot__heading {
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}

.foot__nav {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.foot__nav a {
  font-size: 0.8125rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color 0.2s;
}

.foot__nav a:hover {
  color: var(--ink);
}

.foot__addr {
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

/* Bottom bar */
.foot__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 1200px;
  margin: 0 auto;
  padding: 1.25rem var(--gut) 1.5rem;
  border-top: 1px solid var(--line-soft);
  gap: 1rem;
}

.foot__copy {
  font-size: 0.5625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0;
}

/* ─── Engine comparison ─── */
.engines {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1.25rem;
}

.engine {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  border: 1px solid var(--line-soft);
  border-radius: 1.25rem;
  background: var(--paper-2);
  border-top: 2px solid var(--eng, var(--accent));
}


.engine--unity {
  --eng: var(--accent);
}

.engine--unreal {
  --eng: var(--accent-3);
}

.engine__k {
  color: var(--eng);
  margin-bottom: 0.9rem;
}

.engine h3 {
  font-size: 1.25rem;
  letter-spacing: -0.02em;
}

.engine>p {
  margin-top: 0.7rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  font-weight: 300;
}

/* Syllabus tags — the shape from the source card, restyled for dark */
.chips-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 1rem;
}

.chips-inline li {
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  background: rgba(238, 240, 246, 0.04);
  color: var(--ink-soft);
  font-size: 0.75rem;
  font-weight: 300;
}

/* Per-engine accents on the programme cards */
.level--roblox {
  --eng: var(--accent-2);
}

.level--unity {
  --eng: var(--accent);
}

.level--unreal {
  --eng: var(--accent-3);
}

/* `space-between` pushes the badge to the right end of the tag line without
   taking it out of flow. Absolute positioning would anchor it to `.level__tag`
   (now a positioned element via the `.level > *` rule) rather than the card,
   so this is both simpler and correct. */
.level__tag {
  color: var(--eng, var(--accent));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.level__badge {
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.1em;
}

.level--roblox,
.level--unreal {
  border-top: 2px solid var(--eng);
}

.level__price {
  color: var(--ink);
}

/* ─── FAQ ─── */
/* Two tracks so six questions read as three balanced pairs; the rule above
   each question separates them without boxing them in. */
.faq {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.75rem, 4vw, 2.75rem);
}

.faq li {
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-soft);
}

.faq h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.faq p {
  margin-top: 0.6rem;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  font-weight: 300;
  line-height: 1.6;
}

@media (max-width: 820px) {
  .faq {
    grid-template-columns: 1fr;
  }
}

/* ─────────────────────────── Responsive ─────────────────────────── */
@media (max-width: 860px) {
  :root {
    --nav-h: 4rem;
  }

  .nav__logo {
    height: 3.6rem;
  }

  .nav__name b,
  .nav__mark>span:not(.nav__name) {
    font-size: 0.9375rem;
  }

  .nav__name em,
  .nav__mark>span:not(.nav__name)::after {
    font-size: 0.4375rem;
    letter-spacing: 0.14em;
  }

  .sequence {
    height: 1200svh;
  }

  .nav__links {
    display: none;
  }

  .hero__scroll {
    display: none;
  }

  .hero__title {
    font-size: clamp(2.4rem, 12vw, 4.5rem);
  }

  .hero__stats {
    gap: 1.25rem 2rem;
  }

  .hero__stats li {
    flex: 1 1 7rem;
  }

  .hero__actions .btn {
    flex: 1 1 100%;
  }

  .marquee__track {
    animation-duration: 34s;
  }

  .finale__actions .btn {
    flex: 1 1 100%;
  }

  /* Both force a full-viewport recomposite on every scroll frame — the
     difference between 60fps and visible stutter on a phone. */
  .nav {
    backdrop-filter: none;
    background: var(--paper);
  }

  .timeline__tracks {
    backdrop-filter: none;
    background: rgba(7, 7, 13, 0.85);
  }

  /* On a phone the 12vh slope in `.section` resolves near 100px while the
     content is narrow, so every section-to-section run reads as dead space.
     One flat 2.5rem rhythm for the whole page instead. */
  .section {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }

  .section__head {
    margin-bottom: 2rem;
  }

  /* Spacing that came from margins rather than section padding. */
  .foot__grid {
    grid-template-columns: 1fr 1fr;
  }

  .foot__brand {
    grid-column: 1 / -1;
  }

  .foot__bar {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }

  .contact__list {
    margin-top: 2rem;
    padding-top: 2rem;
  }

  .levels__note {
    margin-top: 1.5rem;
  }

  .outcomes {
    margin-top: 2rem;
  }

  .chips {
    margin-top: 2rem;
  }

  .live .btn {
    margin-top: 1.5rem;
  }
}

/* ── Any portrait viewport, phone or tablet ─────────────────────────────────
   The canvas covers at every ratio now, so a tall window no longer needs the
   letterbox treatment — it only needs the copy to stop sitting in two narrow
   columns beside a subject that fills the frame. */
@media (orientation: portrait) {

  .caption,
  .caption--left,
  .caption--right {
    width: min(40rem, 100%);
    left: var(--gut);
    right: var(--gut);
    text-align: left;
  }

  .caption--right .caption__eyebrow {
    flex-direction: row;
  }

  .caption--right .caption__body {
    margin-left: 0;
  }
}

/* ── Portrait phones: full-bleed, not letterboxed ───────────────────────────
   A 16:9 frame in a 9:19.5 viewport can be cropped or boxed. Boxing it left a
   thin band stranded in a field of black, so the canvas crops to cover
   instead and the footage fills the screen the way it does on desktop. The
   subject sits centre-frame, so the crop takes only empty edges.          */
@media (max-width: 860px) and (orientation: portrait) {
  .stage__monitor {
    inset: 0;
    top: 0;
    height: auto;
  }

  /* With copy sitting over the picture again, the scrim comes back — heavier
     than desktop because phone type is smaller against a busy frame. */
  .stage__gloss {
    display: block;
    background:
      linear-gradient(to bottom,
        rgba(7, 7, 13, 0.62) 0%,
        rgba(7, 7, 13, 0.08) 16%,
        rgba(7, 7, 13, 0.10) 40%,
        rgba(7, 7, 13, 0.80) 62%,
        rgba(7, 7, 13, 0.97) 100%);
  }

  .hud {
    inset: calc(var(--nav-h) + 0.5rem) 0.9rem 1.25rem;
  }

  .hud__bracket {
    width: 14px;
    height: 14px;
  }

  /* No hero copy on phones. There isn't room for a headline, a sub, a button
     and a stats block over the frame without burying the subject, and the
     captions already carry the pitch. The sequence opens clean and the first
     caption does the talking. `visibility` rather than `display: none` so the
     GSAP tweens targeting these nodes still have something to write to. */
  .hero {
    visibility: hidden;
    pointer-events: none;
  }

  .hero__stats {
    gap: 1rem 1.75rem;
    padding-top: 1.25rem;
  }

  .hero__stats li {
    flex: 1 1 40%;
  }

  /* Captions return to the bottom of the frame, full width, left aligned. */
  .caption,
  .caption--left,
  .caption--right {
    top: auto;
    bottom: clamp(2.5rem, 8vh, 5rem);
    left: var(--gut);
    right: var(--gut);
    width: auto;
    text-align: left;
  }

  .caption--right .caption__eyebrow {
    flex-direction: row;
  }

  .caption--right .caption__body {
    margin-left: 0;
  }

  .caption__eyebrow {
    font-size: 0.9375rem;
    margin-bottom: 0.85rem;
  }

  .caption__title {
    font-size: clamp(2.3rem, 11vw, 3.6rem);
  }

  .caption__body {
    font-size: clamp(1rem, 4vw, 1.2rem);
    max-width: none;
  }

  .finale__title {
    font-size: clamp(2.2rem, 11vw, 3.4rem);
  }
}

/* Short phones: tighten the hero so the stats block still clears the fold. */
@media (max-width: 860px) and (orientation: portrait) and (max-height: 720px) {
  .hero__stats {
    margin-top: 1.25rem;
  }

  .hero__sub {
    margin-top: 1rem;
  }

  .caption {
    bottom: clamp(2rem, 6vh, 3.5rem);
  }

  .caption__title {
    font-size: clamp(2rem, 9.5vw, 2.9rem);
  }

  .caption__body {
    font-size: 0.9375rem;
    line-height: 1.45;
  }
}

/* ─────────────────────────── Accessibility ─────────────────────────── */
@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  .hud,
  .timeline {
    display: none;
  }

  .marquee__track {
    animation: none;
  }

  .marquee {
    mask-image: none;
    -webkit-mask-image: none;
  }

  .sequence {
    height: auto;
  }

  .sequence__sticky {
    position: static;
    height: auto;
    overflow: visible;
  }

  .stage {
    position: static;
  }

  .stage__monitor {
    position: relative;
    aspect-ratio: 16 / 9;
  }

  .stage__gloss {
    display: none;
  }

  .captions {
    position: static;
    display: grid;
    gap: 3rem;
    width: 100%;
    margin-top: 3rem;
    padding: 0 var(--gut);
  }

  .caption,
  .caption--left,
  .caption--right {
    position: static;
    width: auto;
    opacity: 1;
    text-align: left;
    color: var(--ink);
  }

  .caption__title,
  .caption__body {
    text-shadow: none;
  }

  .caption__line:last-child {
    filter: none;
  }

  .caption__body {
    color: var(--ink-soft);
    margin-left: 0;
  }

  .finale {
    position: static;
    gap: 2rem;
    padding: 5rem var(--gut) 0;
    opacity: 1;
    pointer-events: auto;
    background: none;
    color: var(--ink);
  }

  .finale__line:nth-child(3)>span {
    filter: none;
  }

  .bars__track i {
    width: var(--pct, 0%) !important;
  }
}

:where(a, button):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   HUD: FRAMING OVERLAY OFF
   ───────────────────────────────────────────────────────────────────────────
   The four corner brackets read as rendering artefacts rather than as a
   viewfinder overlay — thin pale marks on top of the footage that people take
   for a glitch. This build never had the rule-of-thirds grid, but the selector
   is listed anyway so every course page carries the same rule.

   `display: none` rather than deleting: the markup keeps the spans, so
   switching the overlay back on is one line. */
.hud__thirds,
.hud__bracket {
  display: none;
}

/* ─────────────────────────── SEO Section ─────────────────────────── */
.seo-section {
  padding: 5rem var(--gut);
  background: var(--paper);
  color: var(--ink);
}

.seo-container {
  max-width: 1060px;
  margin: 0 auto;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  display: flex;
  align-items: center;
  padding: 4rem;
  gap: 3.5rem;
}

.seo-left {
  flex: 1.3;
}

.seo-right {
  flex: 1;
  border: 1px solid var(--line-soft);
  padding: 2.5rem;
  border-radius: 12px;
  background: rgba(238, 240, 246, 0.02);
}

.seo-tag {
  display: inline-block;
  background: rgba(124, 92, 255, 0.15);
  color: #cdc0ff;
  font-family: var(--mono);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  padding: 0.3rem 0.9rem;
  border-radius: 999px;
  letter-spacing: 0.06em;
  margin-bottom: 1.5rem;
}

.seo-title {
  color: var(--ink);
  font-size: clamp(1.75rem, 2.5vw, 2.1rem);
  line-height: 1.25;
  font-weight: 500;
  margin-bottom: 1.25rem;
  letter-spacing: -0.02em;
}

.seo-title .nowrap {
  white-space: nowrap;
}

.seo-desc {
  color: var(--ink-soft);
  font-size: 1.05rem;
  line-height: 1.7;
  font-weight: 400;
  max-width: 34rem;
}

.seo-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem 1rem;
}

.seo-list li {
  display: flex;
  align-items: center;
  gap: 1.2rem;
}

.seo-check {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.04);
  margin-left: 6px;
  flex-shrink: 0;
}

.seo-check circle {
  fill: rgba(255, 255, 255, 0.15);
}

.seo-list span {
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.35;
}

@media (max-width: 980px) {
  .seo-container {
    flex-direction: column;
    padding: 3rem;
    gap: 3rem;
  }
  .seo-right {
    width: 100%;
    padding: 2rem;
  }
  .seo-title .nowrap {
    white-space: normal;
  }
}

@media (max-width: 600px) {
  .seo-list {
    grid-template-columns: 1fr;
  }
  .seo-container {
    padding: 1.5rem;
  }
  .seo-right {
    padding: 1.5rem;
  }
  .seo-title {
    font-size: 1.6rem;
  }
}