/* ═══════════════════════════════════════════════════════════════════════════
   ALPHA6 — ADVANCED VIDEO PRODUCTION  (light 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 {
  /* Warm paper rather than pure white — less glare behind a dark monitor. */
  --paper: #f4f2ee;
  --paper-2: #eceae4;
  --paper-3: #e2ded6;
  --ink: #14161a;
  --ink-soft: #5c6169;
  --stage: #0b0d11;
  /* the monitor interior; matches the canvas clear */
  --accent: #dc4a16;
  /* the warm streaks that run through the footage */
  --line: rgba(20, 22, 26, 0.13);
  --line-soft: rgba(20, 22, 26, 0.07);

  /* Headline gradient — deep royal blue into violet. Defined once here so
     every gradient headline on the page stays 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: 4.5rem;
}

/* ─────────────────────────── 2. Reset & base ─────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Native anchor offset, so a hard link (page.html#contact) also lands right */
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  /* `clip` rather than `hidden`: hidden turns the element into a scroll
     container, which breaks position:sticky inside it and fights Lenis. clip
     just crops the overflow. Backstop only — real overflow is fixed at source
     (see the min-width:0 rules on the contact form). */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--paper);
  background-image:
    radial-gradient(ellipse at 15% 10%, rgba(123, 92, 240, 0.08) 0%, transparent 40%),
    radial-gradient(ellipse at 85% 60%, rgba(0, 179, 164, 0.08) 0%, transparent 40%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--display);
  font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  line-height: 1.6;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

/* Interim guard while the overflow source is confirmed. `main` is the only
   normal-flow wrapper, so clipping here catches anything in the document flow
   without affecting the fixed-position nav, loader or viewer overlay. */
main {
  overflow-x: clip;
  max-width: 100%;
}

/* Belt and braces for browsers predating overflow:clip (iOS < 16). Applied to
   the sections rather than a scroll container so position:sticky still works. */
.section,
.contact-layout,
.foot-new,
.foot-grid,
.role-cards,
.cta-banner {
  max-width: 100%;
}

.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 the fill has
   to be transparent — and any flat text-shadow would land on top of the
   clipped gradient and smear it, which is why the separation is a
   drop-shadow filter instead (see .caption__title span below). */
.grad-text {
  background-image: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ─── 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);
}

/* The brand teal, not the orange `--accent`. This covers every filled button
   — the nav CTA, the finale "Book free counselling", the level-card "Enquire
   Now" and the form submit — so they all read as one action colour, and it
   matches the #00b3a4 already used for eyebrows, rules and tick dots.

   Note: white on #00b3a4 measures 2.6:1, which is below the WCAG AA threshold
   of 4.5:1 for text this size. It is the brand colour and it is what the
   design calls for; #007e73 is the same hue at 4.96:1 if accessibility ever
   needs to win. Changing it is a one-line edit here.

   `--accent` itself is untouched, so the loader bar, marquee dots, outcome
   top-borders and focus rings keep the orange that ties them to the footage. */
.btn--primary {
  background: #00b3a4;
  border-color: #00b3a4;
  color: #fff;
  font-weight: 600;
}

.btn--primary:hover {
  background: #009488;
  border-color: #009488;
}

.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;
}

#exploreBtn:hover svg {
  transform: translateY(2px);
}

/* ─────────────────────────── 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(244, 242, 238, 0.94);
  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;
}

.nav__sigil {
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  object-fit: contain;
  flex: none;
}

/* Absolutely centred on the viewport rather than flexed into the middle: the
   logo 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);
}

/* Out of flow, the strip can no longer push the logo and CTA apart — it has
   to shrink before it reaches either of them. */
@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;
  }
}

/* The Book-a-seat CTA. Stated explicitly so it can never be collapsed by an
   inherited rule. The links are now absolutely positioned, so space-between
   puts the logo left and this right on its own. */
.nav__cta {
  display: inline-flex;
  flex: none;
  margin-left: auto;
  white-space: nowrap;
  /* Colour now comes from `.btn--primary` above — every filled button shares
     it, so there is one place to change the action colour. */
}

.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 100svh;
  padding: calc(var(--nav-h) + 2rem) var(--gut) 5rem;
}

.hero__inner {
  width: min(74rem, 100%);
}

.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__line:nth-child(3)>span {
  color: var(--accent);
}

.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: 950svh;
}

/* The pinned section paints the stage colour too. `.sequence__sticky` is the
   only thing covering the viewport while the frames scrub, so any strip it
   fails to cover exposes the page background — which on this theme is light,
   and reads as a white band under dark footage. */
.sequence {
  background: var(--stage);
}

/* `svh` is the SMALLEST viewport height — the height with the mobile URL bar
   showing. The moment that bar retracts the visible area grows past 100svh
   and a gap opens along the bottom. `dvh` tracks the live height, so the
   sticky pane always fills the screen; the `svh` line above it stays as the
   fallback for engines without `dvh`, and the two are identical on desktop
   where there is no retracting chrome. */
.sequence__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  height: 100dvh;
  overflow: hidden;
  background: var(--stage);
}

/* Full-bleed: the footage owns the whole viewport while the section is
   pinned, and the light 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 */
.stage__gloss {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(11, 13, 17, 0.55) 0%, transparent 18%),
    linear-gradient(to top, rgba(11, 13, 17, 0.85) 0%, rgba(11, 13, 17, 0.35) 26%, transparent 48%);
}

/* ─── 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;
}

.hud__thirds {
  position: absolute;
  inset: 0;
  opacity: 0.3;
}

.hud__thirds span {
  position: absolute;
  background: rgba(255, 255, 255, 0.3);
}

.hud__thirds span:nth-child(1) {
  left: 33.33%;
  top: 0;
  width: 1px;
  height: 100%;
}

.hud__thirds span:nth-child(2) {
  left: 66.66%;
  top: 0;
  width: 1px;
  height: 100%;
}

.hud__thirds span:nth-child(3) {
  top: 33.33%;
  left: 0;
  height: 1px;
  width: 100%;
}

.hud__thirds span:nth-child(4) {
  top: 66.66%;
  left: 0;
  height: 1px;
  width: 100%;
}

/* ─────────────────────────── 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(11, 13, 17, 0.55);
  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(220, 74, 22, 0.3);
  box-shadow: inset 0 0 0 1px rgba(220, 74, 22, 0.5);
  font-family: var(--mono);
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #ffd9c8;
  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(242, 245, 247, 0.3) 2px 3px,
      transparent 3px 5px, rgba(242, 245, 247, 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;
  /* Sits well clear of the timeline scrubber at the bottom of the monitor.
     Raised from 6-9rem so the headline never collides with the footage's own
     on-screen text. */
  bottom: clamp(9rem, 24vh, 14rem);
  /* Wide enough to carry the longest single line ("FROM BEGINNER", ~9.4em in
     this face) at the type sizes below. The headline deliberately runs wider
     than the body copy underneath it. */
  width: min(70rem, 62vw);
  opacity: 0;
  color: #f2f5f7;
}

.caption--left {
  left: var(--gut);
}

.caption--right {
  right: var(--gut);
  text-align: right;
}

.caption__eyebrow {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
  color: #ff8a5c;
}

.caption__eyebrow::before {
  content: "";
  width: 0.9rem;
  height: 1px;
  background: var(--accent);
}

.caption--right .caption__eyebrow {
  flex-direction: row-reverse;
}

.caption__title {
  /* Caps + heavy weight + tight leading: the headline reads as a title card
     rather than body copy sitting on the footage.
     The 6vw slope is the binding constraint, not the 7rem ceiling — at 62vw
     of box and ~9.4em for the longest line, anything steeper overflows on
     mid-size laptops (1440px) before the ceiling ever engages. */
  font-size: clamp(3rem, 6vw, 7rem);
  font-weight: 800;
  line-height: 0.92;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  /* Three stacked shadows instead of a scrim box: a tight dark halo hugging
     the glyph edges, then two progressively wider soft ones. This separates
     the type from busy footage without drawing a visible rectangle. */
  text-shadow:
    0 1px 3px rgba(0, 0, 0, 0.95),
    0 4px 18px rgba(0, 0, 0, 0.85),
    0 8px 46px rgba(0, 0, 0, 0.7);
  /* Last-resort guard: never let a word bleed off the monitor edge. */
  overflow-wrap: break-word;
}

/* The coloured spans inside a headline use -webkit-background-clip:text with a
   transparent fill. Paint order is background → text-shadow → glyphs, so a
   text-shadow lands on top of the clipped gradient and replaces it with a dark
   smear. drop-shadow works off the rendered alpha instead, so the gradient
   shows through and still gets separation from the footage. */
.caption__title span {
  text-shadow: none;
  filter:
    drop-shadow(0 1px 3px rgba(0, 0, 0, 0.95)) drop-shadow(0 4px 18px rgba(0, 0, 0, 0.8));
}

.caption__body {
  margin-top: 1.1rem;
  /* The box is now sized for the headline; hold the body copy to a readable
     measure rather than letting it run the full 70rem. */
  max-width: 34rem;
  color: rgba(242, 245, 247, 0.75);
  font-size: clamp(1rem, 1.2vw, 1.25rem);
  font-weight: 300;
  line-height: 1.55;
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.95),
    0 2px 12px rgba(0, 0, 0, 0.9),
    0 4px 30px rgba(0, 0, 0, 0.75);
}

.caption--right .caption__body {
  margin-left: auto;
}

.finale {
  position: absolute;
  inset: 0;
  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(11, 13, 17, 0.86), rgba(11, 13, 17, 0.55) 70%, rgba(11, 13, 17, 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 ─────────────────────────── */
/* NOTE: `content-visibility: auto` + `contain-intrinsic-size: auto 60rem` were
   removed here. They told the browser to skip layout for off-screen sections
   and substitute a 60rem placeholder height, so the document position of
   #contact resolved badly wrong on a fresh page load — the anchor landed in
   the wrong place on the first click and only corrected on the second, once
   the browser had actually laid those sections out and cached real sizes. */
.section {
  padding: clamp(4.5rem, 12vh, 9rem) var(--gut);
  /* Anchor offset so the fixed nav never covers a section heading */
  scroll-margin-top: calc(var(--nav-h) + 1rem);
}

.section--alt {
  background: var(--paper-2);
}

/* Every section heading shares the same 70rem content column the card grids
   below it use, so heading, lede, cards and chips all hang off one left edge.
   Stated once here rather than per-section id, so no section can be missed —
   `.section` itself keeps the full-bleed width because `.section--alt` paints
   a background stripe that has to run edge to edge. */
.section>.section__head {
  max-width: 70rem;
  margin-inline: auto;
  margin-bottom: clamp(2.5rem, 7vh, 4.5rem);
}

/* The head box is 70rem now, so hold its own copy to a readable measure
   rather than letting the lede run the full width. */
.section>.section__head>* {
  max-width: 48rem;
}

/* Kept for any head outside a .section wrapper. */
.section__head {
  max-width: 48rem;
  margin-bottom: clamp(2.5rem, 7vh, 4.5rem);
}

/* The reference runs the eyebrow in teal — rule and label together. The
   `.rule` element takes `--accent` (orange) by default, so both need stating.
   Sections that set their own eyebrow colour inline (the live-projects card)
   still override this. */
.section__eyebrow {
  margin-bottom: 1.25rem;
  color: #00b3a4;
}

.section__eyebrow .rule {
  background: #00b3a4;
}

.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.55rem;
}

.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.55em;
  width: 0.35rem;
  height: 0.35rem;
  border-radius: 50%;
  background: #00b3a4;
}

/* ─── Marquee ─── */
.marquee {
  width: 100%;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.6);
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  padding: 1rem 0;
}

.marquee__track {
  display: flex;
  width: max-content;
}

.marquee__group {
  display: flex;
  align-items: center;
  gap: 2rem;
  padding-right: 2rem;
  animation: scroll 20s linear infinite;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink-soft);
}

.marquee__dot {
  width: 4px;
  height: 4px;
  background: var(--accent);
  border-radius: 50%;
  flex-shrink: 0;
}

@keyframes scroll {
  0% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(-100%);
  }
}

/* ─── Journey ─── */
#journey {
  padding-top: clamp(2rem, 5vh, 4rem);
}

/* Same 70rem container as #skills and #tariff. Full-bleed, the three cards run
   ~575px each on a 1920 screen — the tick lists never wrap and the numerals
   sit marooned in a lot of white. The head is included so its left edge stays
   flush with the first card. */
.stages {
  max-width: 70rem;
  margin-inline: auto;
}

#journey .section__lede {
  max-width: 34rem;
}

/* No `align-items: start` here: start-aligned, each card shrinks to its own
   content and the three end at different heights because the tick lists are
   different lengths. The grid default of `stretch` makes every card as tall as
   the tallest in the row, which is what squares the boxes off. */
.stages {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
}

/* The transparent border is load-bearing: it reserves the 1px the hover state
   colours in, so picking a card up cannot nudge its neighbours by a pixel. */
.stage-card {
  padding: 1.5rem;
  border: 1px solid transparent;
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.05);
  transition: transform 0.4s var(--ease), border-color 0.4s var(--ease),
    box-shadow 0.4s var(--ease);
}

/* The teal outline is a hover state, not a fixed highlight on one card —
   an earlier revision pinned it to :nth-child(2) after misreading a
   screenshot where the pointer happened to be resting there. */
.stage-card:hover {
  transform: translateY(-4px);
  border-color: #00b3a4;
  box-shadow: 0 14px 40px rgba(0, 179, 164, 0.16);
}

.stage-card__n {
  font-size: 3rem;
  font-weight: 800;
  line-height: 1;
  color: #5c55d9;
  letter-spacing: -0.05em;
  font-family: var(--display);
}

.stage-card__tag {
  margin-top: 1.1rem;
  color: #00b3a4;
  font-weight: 600;
}

/* Was 1.25rem below the title — the reference sits the list right under it, so
   the heading reads as a label for the ticks rather than a separate block. */
.stage-card__title {
  margin: 0.35rem 0 0.7rem;
  font-size: 1.25rem;
  letter-spacing: -0.02em;
}

/* ─── Verticals ─── */
/* The heads take the same 70rem box as the card grids below them, so heading,
   lede, cards and chips all hang off one left edge. */
.chips {
  max-width: 70rem;
  margin-inline: auto;
}

.verticals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
}

.verticals li {
  padding: clamp(1.5rem, 3vw, 2rem);
  background: #fff;
  border-radius: 1rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.04);
  display: flex;
  flex-direction: column;
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}

.verticals li:hover {
  transform: translateY(-4px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.06);
}

.verticals__icon {
  width: 2.75rem;
  height: 2.75rem;
  background: #eef2ff;
  border-radius: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  margin-bottom: 1.25rem;
}

.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;
}

.chips {
  margin-top: 2.5rem;
}

/* Matches the section eyebrows — teal, with the same leading rule. Drawn as a
   pseudo-element so no `<span class="rule">` is needed in the markup. */
.chips__label {
  margin-bottom: 0.9rem;
  color: #00b3a4;
}

.chips__label::before {
  content: "";
  display: inline-block;
  width: 1.75rem;
  height: 1px;
  margin-right: 0.75rem;
  vertical-align: 0.2em;
  background: #00b3a4;
}

.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;
}

/* ─── Why / technical ─── */
/* The reference page runs this section inside a ~70rem centred container.
   Left full-bleed, each column is ~870px on a 1920 screen — wide enough that
   the body copy never wraps, so the divider lines run on into empty space to
   the right of the text. Scoped to #skills so no other section moves. */
#skills .skills-layout {
  max-width: 70rem;
  margin-inline: auto;
}

/* `align-items: start` is load-bearing for the sticky panel below: a stretched
   grid item is as tall as its row, and a sticky element that already fills its
   container has nowhere to travel. Start-aligned, the card is only as tall as
   its own content. (This was `center` before.) */
/* The gutter was clamp(2rem, 5vw, 4rem) — 64px on a desktop, which left the
   dead channel between the divider lines and the card. Tightened so the lines
   run up close to the card edge the way the reference page does. */
.skills-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 3vw, 2.75rem);
  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. */
.skills-layout>.bars {
  position: sticky;
  top: calc(var(--nav-h) + 1.5rem);
}

@media (max-width: 860px) {
  .skills-layout {
    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. */
  .skills-layout>.bars {
    position: static;
  }
}

/* Rows carry their own vertical padding, so a grid gap here would double up
   the spacing between the divider and the next number. */
.why {
  display: grid;
  gap: 0;
}

.why li {
  display: flex;
  gap: clamp(1.25rem, 2vw, 2rem);
  align-items: flex-start;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line-soft);
}

.why li:first-child {
  padding-top: 0;
}

.why li:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

/* Fixed width keeps every heading on the same left edge, whatever the number.
   Display face rather than the inherited `mono`, to match the reference. */
.why__n {
  flex: none;
  width: 1.5rem;
  font-family: var(--display);
  font-size: 0.875rem;
  letter-spacing: 0;
  color: #00b3a4;
  font-weight: 700;
  margin-bottom: 0;
  padding-top: 0.3rem;
}

.why h3 {
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

.why li>div>p:last-child {
  margin-top: 0.4rem;
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
  line-height: 1.5;
}

/* ─── Skill bars ─── */
/* `position: relative` + a stacking context: as the sticky card travels it
   passes over content below it, and without this it can render underneath. */
/* Kept deliberately compact: the card is the shorter column, and the height
   it doesn't use is the travel the sticky panel gets while the list on the
   left scrolls past it. A taller card = less travel. */
.bars {
  position: relative;
  z-index: 1;
  background: #fff;
  padding: clamp(1.5rem, 3vw, 2.125rem);
  border-radius: 1.5rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04);
}

.bars__title {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.02em;
}

/* Also overrides `mono`: the reference runs this as a plain sentence-case
   line, not a spaced uppercase eyebrow. */
.bars__sub {
  margin: 0.4rem 0 1.5rem;
  font-family: var(--display);
  font-size: 0.9375rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
}

.bars ul {
  display: grid;
  gap: 0.875rem;
}

/* Label and value share the top line; the track spans the full width beneath
   them. Placement is explicit rather than automatic: in the markup the track
   sits BETWEEN the label and the value, and because it spans 1/-1 it opens a
   new row — auto-placement then drops the percentage onto a third line under
   the bar. Pinning all three to a row/column fixes the order regardless of
   source order. */
.bars li {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 1rem;
}

.bars__k {
  grid-column: 1;
  grid-row: 1;
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
}

/* Overrides the `mono` class on this element: the reference sets the figure in
   the display face, not the uppercase mono used for eyebrows. */
.bars__v {
  grid-column: 2;
  grid-row: 1;
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  text-transform: none;
  color: #00b3a4;
  font-weight: 700;
  font-size: 0.875rem;
}

.bars__track {
  grid-column: 1 / -1;
  grid-row: 2;
  margin-top: 0.5rem;
  height: 5px;
  border-radius: 6px;
  background: var(--paper-3);
  overflow: hidden;
}

.bars__track i {
  display: block;
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #5c55d9, #00b3a4);
  border-radius: 6px;
}

/* ─── Live projects ─── */
.live-card {
  background: linear-gradient(135deg, #4a2f9e, #00b3a4);
  color: #fff;
  border-radius: 1.5rem;
  padding: clamp(2.5rem, 6vw, 4.5rem);
  box-shadow: 0 20px 50px rgba(0, 179, 164, 0.15);
  max-width: 58rem;
  margin: 0 auto;
}

.clients {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-content: center;
}

.clients li {
  padding: 0.5rem 1rem;
  border: 1px solid rgba(255, 255, 255, 0.25);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.15);
  font-size: 0.8125rem;
  font-weight: 500;
  color: #fff;
  backdrop-filter: blur(4px);
}

/* ─── Why Alpha6 Cards ─── */
.why-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.5rem;
}

.why-cards li {
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: #fff;
  border-radius: 1.25rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04);
}

.why-cards h3 {
  font-size: 1.125rem;
  margin: 0.5rem 0;
  letter-spacing: -0.01em;
}

.why-cards p {
  color: var(--ink-soft);
  font-size: 0.875rem;
  font-weight: 300;
}

/* ─── Levels ─── */
/* Same 70rem container as the skills section: full-bleed, the three cards run
   ~575px each on a 1920 screen, which is what made the headers and chips read
   oversized rather than any one type size being wrong. */
.levels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.5rem;
  align-items: stretch;
  max-width: 70rem;
  margin-inline: auto;
}

/* Centred and narrower than the rest — it carries an inline `margin: 0 auto`
   and `text-align: center` in the markup, and inline wins over the rule above. */
#tariff .section__head {
  max-width: 44rem;
}

.level {
  display: flex;
  flex-direction: column;
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.04);
  overflow: hidden;
}

.level--featured {
  box-shadow: 0 20px 50px -20px rgba(123, 92, 240, 0.35);
}

/* `relative` anchors the Most-popular badge; `overflow: hidden` crops the
   pinwheel so it reads as a corner motif rather than a floating circle. */
.level__head {
  position: relative;
  overflow: hidden;
  padding: 1.5rem;
  color: #fff;
}

/* The rotating motif. A repeating conic gradient gives the radiating blades;
   the radial mask punches out the hub so it reads as a pinwheel rather than a
   filled pie. Rotation is a compositor-only transform, so six of these on
   screen cost nothing. */
.level__head::after {
  content: "";
  position: absolute;
  top: -3rem;
  right: -3rem;
  width: 11rem;
  height: 11rem;
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg,
      rgba(255, 255, 255, 0.16) 0deg 15deg,
      rgba(255, 255, 255, 0) 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;
}

@keyframes level-spin {
  to {
    transform: rotate(360deg);
  }
}

.level__head--1 {
  background: linear-gradient(145deg, #00b3a4, #008c80);
}

.level__head--2 {
  background: linear-gradient(145deg, #7b5cf0, #4a2f9e);
}

.level__head--3 {
  background: linear-gradient(145deg, #3273dc, #1d4d8a);
}

/* The numeral carries the level, so the pill background comes off and the `b`
   in the markup is promoted to display size. `relative` + z-index keeps the
   line above the rotating motif behind it. */
.level__tag {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: baseline;
  gap: 0.45rem;
  margin-bottom: 0.35rem;
  padding: 0;
  background: none;
  border-radius: 0;
  font-family: var(--display);
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.9);
}

.level__tag b {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: #fff;
}

/* Out of the tag line and pinned to the corner, so a long card name can never
   push it around. */
.level__badge {
  position: absolute;
  top: 1.1rem;
  right: 1.1rem;
  margin-left: 0;
  padding: 0.3rem 0.7rem;
  background: #00b3a4;
  border-radius: 999px;
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  white-space: nowrap;
}

.level__name {
  position: relative;
  z-index: 1;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: #fff;
}

.level__sub {
  position: relative;
  z-index: 1;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.85);
}

.level__price {
  position: relative;
  z-index: 1;
  margin-top: 1.25rem;
  font-size: 1.625rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #fff;
}

/* Overrides the `mono` class: the reference sets the duration as plain
   sentence-case text, not a spaced uppercase eyebrow. */
.level__price span {
  font-family: var(--display);
  font-size: 0.8125rem;
  letter-spacing: 0;
  text-transform: none;
  color: rgba(255, 255, 255, 0.75);
  font-weight: 400;
}

.level__body {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  flex: 1;
}

.module+.module {
  margin-top: 1.25rem;
}

/* Module headings take the card's own accent instead of flat ink — it's what
   separates the groups at a glance now that the chips are quieter. */
.module__h {
  margin-bottom: 0.6rem;
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #00b3a4;
}

.level--featured .module__h {
  color: #7b5cf0;
}

.module-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.module-chips li {
  padding: 0.3rem 0.65rem;
  background: #fff;
  border: 1px solid rgba(20, 22, 26, 0.1);
  border-radius: 0.4rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

.level__outcome {
  margin-top: 1.5rem;
  margin-bottom: 1.25rem;
  padding: 1rem;
  background: var(--paper);
  border: 1px dashed var(--line-soft);
  border-radius: 0.75rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  line-height: 1.6;
}

.level__outcome b {
  color: var(--ink);
}

.level__body .btn {
  margin-top: auto;
}

.levels__note {
  margin-top: 2rem;
  text-transform: none;
  letter-spacing: 0.06em;
  line-height: 1.8;
}

.outcomes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 1.25rem;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

.outcomes li {
  padding: 1.5rem;
  border-top: 2px solid var(--accent);
}

.outcomes h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.01em;
}

.outcomes p {
  margin-top: 0.4rem;
}

/* ─── CTA & footer ─── */
.cta {
  text-align: center;
}

.cta__title {
  margin-top: 1.25rem;
  font-size: clamp(2rem, 5.5vw, 4rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.035em;
}

.cta__lede {
  max-width: 38rem;
  margin: 1.25rem auto 0;
  color: var(--ink-soft);
  font-weight: 300;
}

.cta__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
  margin-top: 2rem;
}

.cta__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 2rem;
  max-width: 60rem;
  margin: clamp(3rem, 8vh, 5rem) auto 0;
  padding-top: 2.5rem;
  border-top: 1px solid var(--line-soft);
  text-align: left;
}

.cta__k {
  margin-bottom: 0.5rem;
}

.cta__v {
  font-size: 0.9375rem;
  font-weight: 300;
  line-height: 1.6;
}

.cta__v a {
  color: var(--accent);
  text-decoration: none;
}

.foot {
  padding: clamp(3rem, 8vh, 4.5rem) var(--gut) 2.5rem;
  background: var(--paper-2);
  border-top: 1px solid var(--line-soft);
}

.foot__top {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 2rem;
  padding-bottom: 2.5rem;
}

.foot__blurb {
  max-width: 30rem;
  color: var(--ink-soft);
  font-weight: 300;
}

.foot__blurb a {
  color: var(--accent);
  text-decoration: none;
}

.foot__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-content: start;
}

.foot__nav a {
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-decoration: none;
}

.foot__nav a:hover {
  color: var(--ink);
}

.foot__note {
  padding-top: 2rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.625rem;
}

/* ─────────────────────────── 8. Viewer ─────────────────────────── */
/* The 3D stage stays dark — a lit studio is how you actually inspect a camera. */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--stage);
  color: #f2f5f7;
  opacity: 0;
}

.viewer__stage {
  position: absolute;
  inset: 0;
}

.viewer__stage canvas {
  display: block;
  touch-action: none;
}

.viewer__ui {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 1.5rem var(--gut);
  pointer-events: none;
}

.viewer__top,
.viewer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.viewer__bottom {
  align-items: flex-end;
}

.viewer__ui .btn {
  pointer-events: auto;
  color: #f2f5f7;
  border-color: rgba(255, 255, 255, 0.2);
}

.viewer__ui .btn:hover {
  border-color: #f2f5f7;
}

.viewer .mono {
  color: rgba(242, 245, 247, 0.62);
}

.viewer__part {
  min-height: 1.25rem;
  font-size: 0.75rem;
  transition: opacity 0.35s var(--ease);
}

.viewer__part[data-state="idle"] {
  opacity: 0.55;
}

.viewer__hint {
  font-size: 0.625rem;
  opacity: 0.5;
  text-align: right;
}

.viewer__loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transition: opacity 0.5s var(--ease);
}

.viewer__loading.is-hidden {
  opacity: 0;
}

/* ─────────────────────────── Responsive ─────────────────────────── */
@media (max-width: 860px) {
  :root {
    --nav-h: 3.5rem;
  }

  .sequence {
    height: 580svh;
  }

  .nav__links {
    display: none;
  }

  /* Links collapse on mobile but the CTA stays — tighten it so it doesn't
     crowd the logo on narrow phones. */
  .nav__cta {
    padding: 0.5rem 1rem;
    font-size: 0.75rem;
    margin-left: auto;
    white-space: nowrap;
  }

  .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%;
  }

  /* NOTE: the old `.bars li { grid-template-columns: 1fr auto }` and
     `.bars__track { grid-column: 1 / -1; order: 3 }` overrides lived here.
     The desktop layout now uses that same two-column / full-width-track
     shape, so the overrides were redundant and have been removed. */

  .finale__actions .btn {
    flex: 1 1 100%;
  }

  .viewer__hint {
    display: none;
  }

  .cta__grid {
    text-align: center;
  }

  /* 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. Sections carrying an
     inline padding value in the markup keep it — inline still wins. */
  .section {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }

  /* Id selectors, so they outrank the rule above and need restating to come
     down with everything else. */
  #journey {
    padding-top: 2.5rem;
  }

  .foot-new {
    padding-top: 2.5rem;
  }

  /* Same rhythm where the spacing came from a margin rather than padding. */
  .verticals,
  .why-cards {
    margin-block: 2rem;
  }

  /* Flex sizes each card to its own label, so "Freelance / Studio Pro" comes
     out wider than "Content Creator" and the stack reads ragged. Equal grid
     tracks give one width for all four. `min-width: 0` releases the 14rem
     floor, which would otherwise overflow a narrow phone. */
  .role-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 0.75rem;
  }

  .role-card {
    min-width: 0;
  }

  /* MOST POPULAR badge: on desktop this sits fine in the corner because the
     card is wide. Stacked to a narrow phone-width column, the absolute
     position had nothing keeping it clear of the tag text — dropping it back
     into normal flow lets it wrap onto its own line under the tag. */
  .level__tag {
    flex-wrap: wrap;
    row-gap: 0.4rem;
  }

  .level__badge {
    position: static;
    display: inline-block;
  }

  /* Must match the `.section > .section__head` selector above, not the bare
     class — an id-free descendant selector at (0,2,0) outranks (0,1,0)
     regardless of source order, so a bare `.section__head` here would be
     silently ignored and the desktop clamp would apply on phones. */
  .section>.section__head {
    margin-bottom: 2rem;
  }

  /* 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(11, 13, 17, 0.8);
  }
}

/* ── Portrait phones: full view without letterboxing ──────── */
@media (max-width: 860px) and (orientation: portrait) {
  .hud__thirds {
    opacity: 0.4;
  }

  .timeline__meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.25rem;
  }

  .timeline__clip {
    font-size: 0.4375rem;
    padding: 0 0.35rem;
  }

  .timeline__tracks {
    background: rgba(11, 13, 17, 0.35);
  }

  .caption,
  .caption--left,
  .caption--right {
    top: auto;
    /* Dropped from 26svh: that left a dead band between the body copy and the
       timeline scrubber. This sits the block just above the scrubber and lets
       the type grow into the reclaimed space. */
    bottom: 15svh;
    left: var(--gut);
    right: var(--gut);
    width: auto;
    text-align: left;
  }

  .caption--right .caption__eyebrow {
    flex-direction: row;
  }

  /* 9.5vw left the poster reading small against a full-bleed frame. 14vw is
     the ceiling the copy allows: the longest authored line is "TO PRO EDITOR"
     at ~5.9em, and at 14vw that still clears the gutters down to a 320px
     phone. Anything steeper wraps that line and breaks the three-line shape
     the <br>s in the markup are there to guarantee. */
  .caption__title {
    font-size: clamp(2.6rem, 14vw, 4.75rem);
    line-height: 0.92;
  }

  .caption__body {
    max-width: none;
    font-size: clamp(0.9rem, 3.6vw, 1.05rem);
    line-height: 1.5;
  }
}

/* Short phones: tighten so the scrubber and copy still fit 640px. */
@media (max-width: 860px) and (orientation: portrait) and (max-height: 720px) {
  .timeline__row:nth-child(2) {
    display: none;
  }

  .caption {
    bottom: 16svh;
  }

  .caption__title {
    font-size: clamp(2.2rem, 12vw, 3.75rem);
  }

  .caption__body {
    font-size: 0.875rem;
    line-height: 1.45;
  }
}

@media (max-width: 460px) {
  .timeline__row:nth-child(2) {
    display: none;
  }

  /* audio track is decoration */
}

/* ─────────────────────────── 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;
  }

  .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__title span {
    filter: none;
  }

  .caption__body {
    color: var(--ink-soft);
  }

  .finale {
    position: static;
    gap: 2rem;
    padding: 5rem var(--gut) 0;
    opacity: 1;
    pointer-events: auto;
    background: none;
    color: var(--ink);
  }

  .bars__track i {
    width: var(--pct, 0%) !important;
  }
}

:where(a, button):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ─────────────────────────── Role Cards ─────────────────────────── */
.role-cards {
  display: flex;
  gap: 1.5rem;
  justify-content: center;
  flex-wrap: wrap;
  max-width: 60rem;
  margin: 0 auto;
  padding: 0 var(--gut);
}

.role-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  background: #fff;
  padding: 0.8rem 1.25rem;
  border-radius: 0.8rem;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.03);
  min-width: 14rem;
}

.role-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  background: #f0f7ff;
  border-radius: 0.5rem;
  font-size: 1.2rem;
}

.role-card:nth-child(2) .role-card__icon {
  background: #eefaf6;
}

.role-card:nth-child(3) .role-card__icon {
  background: #f0f2fa;
}

.role-card:nth-child(4) .role-card__icon {
  background: #fffcf0;
}

.role-card__text h4 {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink);
}

.role-card__text p {
  margin: 0;
  font-size: 0.75rem;
  color: var(--ink-soft);
}

/* ─────────────────────────── CTA Banner ─────────────────────────── */
.cta-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 4rem 2rem;
  background: var(--paper-2);
  border-radius: 1.5rem;
  margin: 0 auto;
  max-width: 60rem;
}

.cta-banner__eyebrow {
  font-family: var(--display);
  font-weight: 600;
  color: #00b3a4;
  margin-bottom: 1rem;
}

.cta-banner__title {
  font-size: clamp(2rem, 5vw, 3.5rem);
  line-height: 1.1;
  margin-bottom: 1rem;
}

.cta-banner__title span {
  color: #5c55d9;
}

.cta-banner__lede {
  font-size: 1.1rem;
  color: var(--ink-soft);
  max-width: 40rem;
  margin: 0 auto 2rem;
}

.cta-banner__actions {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* ─────────────────────────── Contact Section ─────────────────────────── */
.contact-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4rem;
  max-width: 70rem;
  margin: 0 auto;
  padding: 0 var(--gut);
}

/* Grid children default to min-width:auto, which lets a wide descendant (the
   course <select>) stretch the column. */
.contact-layout>* {
  min-width: 0;
}

@media (max-width: 768px) {
  .contact-layout {
    grid-template-columns: 1fr;
  }
}

.contact-info {
  display: flex;
  flex-direction: column;
}

.contact-methods {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  margin-top: 2rem;
}

.contact-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

.contact-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  background: #eefaf6;
  border-radius: 0.5rem;
  font-size: 1.2rem;
  flex-shrink: 0;
}

.contact-k {
  font-size: 0.75rem;
  color: var(--ink-soft);
  margin-bottom: 0.25rem;
}

.contact-v {
  font-weight: 500;
}

/* ─── Map card ─── */
/* Deliberately the same shell as `.contact-form-card` below — white, 1rem
   radius, the same soft shadow — so the two columns read as a matched pair
   rather than a map dropped beside a form.

   `flex: 1` is what squares the bottom edges off: `.contact-info` is already
   a flex column, so the map absorbs whatever height is left after the heading
   and the address block, which is roughly the height of the form beside it.
   `min-height` is the floor for the case where the form is the shorter of the
   two (a short viewport, or the column stacked on a phone). */
.contact-map {
  position: relative;
  flex: 1;
  min-height: 22rem;
  margin-top: 2rem;
  /* The padding is the white frame; the iframe takes its own smaller radius
     inside it, which is what makes the map read as mounted in the card rather
     than as the card itself. */
  padding: 0.5rem;
  background: #fff;
  border-radius: 1rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.contact-map iframe {
  display: block;
  width: 100%;
  height: 100%;
  /* An iframe with height:100% inside a flex item can collapse to 0 before
     the flex height resolves — this is the guard against that. */
  min-height: 21rem;
  border: 0;
  border-radius: 0.65rem;
  /* Google's default map saturation fights the page palette slightly. */
  filter: saturate(0.9);
}

@media (max-width: 768px) {
  .contact-map {
    min-height: 16rem;
    margin-top: 1.5rem;
  }

  .contact-map iframe {
    min-height: 15rem;
  }
}

.contact-form-card {
  background: #fff;
  padding: 2.5rem;
  border-radius: 1rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.05);
  /* Anchor offset: #contact-form is a link target, keep it clear of the nav */
  scroll-margin-top: calc(var(--nav-h) + 1rem);
}

.contact-form-card h3 {
  font-size: 1.5rem;
  margin-bottom: 0.5rem;
}

.contact-form-card p {
  color: var(--ink-soft);
  font-size: 0.9rem;
  margin-bottom: 2rem;
}

.c-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  /* Same reason as the inputs: without this the group inherits its child's
     intrinsic width instead of shrinking to the column. */
  min-width: 0;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  min-width: 0;
}

@media (max-width: 500px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.c-form label {
  font-size: 0.8rem;
  color: var(--ink-soft);
}

.c-form input,
.c-form select,
.c-form textarea {
  width: 100%;
  /* A <select> reports an intrinsic min-width equal to its widest option, and
     flex/grid children default to min-width:auto — so the long course names in
     the dropdown were forcing the whole page wider than the phone and creating
     a horizontal swipe. min-width:0 lets width:100% actually win. */
  min-width: 0;
  padding: 0.8rem 1rem;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 0.5rem;
  font-family: inherit;
  font-size: 0.95rem;
  background: #fcfcfc;
}

.c-form input:focus,
.c-form select:focus,
.c-form textarea:focus {
  outline: none;
  border-color: #00b3a4;
  background: #fff;
}

.form-note {
  font-size: 0.75rem !important;
  text-align: center;
  margin-top: 0.5rem !important;
  margin-bottom: 0 !important;
}

/* ─────────────────────────── Footer ─────────────────────────── */
/* No top margin: the contact section already closes with its own bottom
   padding and the footer opens with 4rem of its own, so a margin on top of
   that just rendered as a dead strip of page background between the two. */
.foot-new {
  background: var(--paper-2);
  padding: 4rem var(--gut) 2rem;
  margin-top: 0;
}

.foot-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 3rem;
  max-width: 70rem;
  margin: 0 auto 3rem;
}

@media (max-width: 900px) {
  .foot-grid {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 500px) {
  .foot-grid {
    grid-template-columns: 1fr;
  }
}

.foot-brand p {
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.5;
}

.foot-col h4 {
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  color: var(--ink);
  margin-bottom: 1.5rem;
}

.foot-col a,
.foot-col p {
  display: block;
  color: var(--ink-soft);
  text-decoration: none;
  margin-bottom: 0.8rem;
  font-size: 0.9rem;
}

.foot-col a:hover {
  color: var(--accent);
}

.foot-bottom {
  max-width: 70rem;
  margin: 0 auto;
  padding-top: 2rem;
  border-top: 1px solid rgba(0, 0, 0, 0.05);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
}

.foot-bottom p {
  margin: 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/* ─────────────────────────── Verticals & Why Cards ─────────────────────────── */
/* 70rem to match #journey, #skills and #tariff, and no `padding: 0 var(--gut)`
   of its own — the section already supplies the gutter, so the extra inset was
   pushing the cards in from the heading's left edge. At 75rem centred against
   a gutter-aligned head the two started ~350px apart on a 1920 screen. */
.verticals,
.why-cards {
  display: grid;
  gap: 1rem;
  max-width: 70rem;
  margin: 2.5rem auto 0;
  padding: 0;
}

.verticals {
  grid-template-columns: repeat(4, 1fr);
}

.why-cards {
  grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 1024px) {
  .verticals {
    grid-template-columns: repeat(3, 1fr);
  }

  .why-cards {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .verticals {
    grid-template-columns: repeat(2, 1fr);
  }

  .why-cards {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 480px) {
  .verticals {
    grid-template-columns: 1fr;
  }
}

.verticals li,
.why-cards li {
  background: #fff;
  padding: 1.5rem;
  border-radius: 1rem;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.03);
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}

.verticals__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  background: #f0f7ff;
  border-radius: 0.5rem;
  font-size: 1.2rem;
}

.verticals li:nth-child(2) .verticals__icon,
.why-cards li:nth-child(2) .verticals__icon {
  background: #f3f0ff;
}

.verticals li:nth-child(3) .verticals__icon,
.why-cards li:nth-child(3) .verticals__icon {
  background: #f0f2fa;
}

.verticals li:nth-child(4) .verticals__icon,
.why-cards li:nth-child(4) .verticals__icon {
  background: #fffcf0;
}

.verticals li:nth-child(5) .verticals__icon,
.why-cards li:nth-child(5) .verticals__icon {
  background: #f0f7ff;
}

.verticals li:nth-child(6) .verticals__icon,
.why-cards li:nth-child(6) .verticals__icon {
  background: #eefaf6;
}

.verticals li:nth-child(7) .verticals__icon,
.why-cards li:nth-child(7) .verticals__icon {
  background: #fff0f0;
}

.verticals li:nth-child(8) .verticals__icon,
.why-cards li:nth-child(8) .verticals__icon {
  background: #f0f7ff;
}

.verticals h3,
.why-cards h3 {
  font-size: 1.1rem;
  color: var(--ink);
  margin: 0;
}

.verticals p,
.why-cards p {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.5;
}

/* ═══════════════════════════════════════════════════════════════════════════
   iOS: THE SIDEWAYS SWIPE
   ───────────────────────────────────────────────────────────────────────────
   Same fix that resolved this on the Cinematography page. Android clips these
   correctly and iOS does not, which narrows it to WebKit.

   Two boxes here are much wider than the screen and rely on an ancestor's
   `overflow: hidden` to crop them:

     .marquee__track   width: max-content  -> several thousand px inside a
                                              full-width strip
     #frames           GSAP scales it to 1.06 and pushes to 1.05 at the
                                              finale, so it overhangs the pin

   Both are transform-animated, so WebKit promotes each to its own compositing
   layer — and WebKit has a long-standing bug where `overflow: hidden` on an
   ancestor fails to clip a composited descendant. Blink clips correctly, which
   is why Android looks right.

   `contain: paint` states the clip as a containment guarantee rather than a
   paint-time hint, which WebKit honours on composited layers. Supported from
   Safari 15.4. It also makes the element a containing block for absolutely
   positioned descendants — already true of `.sequence__sticky`, which is a
   positioned element, so `.captions`, `.hud`, `.timeline` and `.finale` are
   unaffected. */
.sequence__sticky,
.marquee {
  contain: paint;
}

/* ═══════════════════════════════════════════════════════════════════════════
   HUD: FRAMING OVERLAY OFF
   ───────────────────────────────────────────────────────────────────────────
   Both the rule-of-thirds grid and the four corner brackets read as rendering
   artefacts rather than as a viewfinder overlay — thin pale lines sitting on
   top of the footage, which people take for a glitch rather than a device.

   `display: none` rather than deleting the rules: the markup keeps the spans,
   so switching the overlay back on is one line. Anything else inside `.hud`
   (the REC readout and progress bar on the cinematography build) is untouched,
   which is why this hides the two children rather than `.hud` itself. */
.hud__thirds,
.hud__bracket {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   NAV LOCKUP
   ───────────────────────────────────────────────────────────────────────────
   logo.png is the full lockup — the sigil plus the INSTITUTE OF / MULTIMEDIA
   wordmark, on transparency — so the bar places the artwork directly instead
   of rebuilding it out of an icon and live text. The old `.nav__sigil` /
   `.nav__name` rules in section 3 are now unused by the markup; they are left
   in place only so the text lockup can be restored without rewriting them.
   ═══════════════════════════════════════════════════════════════════════════ */
.nav__mark {
  display: inline-flex;
  align-items: center;
  flex: none;
}

/* Height-driven with width auto: the bar height is the fixed dimension and the
   artwork keeps its own aspect ratio, whatever the source file measures.

   1.9rem rather than the bar height: logo.png carries the "ALPHA6" line under
   the sigil, so its bounding box is noticeably taller than the wordmark that
   reads as the logo — matching the box to the bar makes the visible mark look
   oversized. The max-height is a hard ceiling against --nav-h so the artwork
   can never exceed the bar whatever its intrinsic size. */
.nav__logo {
  display: block;
  height: 4rem;
  max-height: calc(var(--nav-h) - 0.5rem);
  width: auto;
  object-fit: contain;
}

/* --nav-h drops to 3.5rem at this breakpoint, so the logo comes down with it
   and keeps its breathing room above and below. */
@media (max-width: 860px) {
  .nav__logo {
    height: 3.2rem;
  }
}

/* Narrow phones: the CTA needs the width more than the logo does. */
@media (max-width: 460px) {
  .nav__logo {
    height: 2.9rem;
  }
}

/* Backstop: whatever happens to the artwork, nothing inside the bar spills
   past it onto the footage below. */
.nav {
  overflow: hidden;
}

/* ─────────────────────────── SEO Block ─────────────────────────── */
.seo-card-container {
  max-width: 70rem;
  margin: 4rem auto 0;
  padding: 0 var(--gut);
}

.seo-card {
  background: #ffffff;
  border-radius: 4px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.04), 0 4px 15px rgba(0, 0, 0, 0.02);
  padding: 3rem 2.5rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3rem;
}

.seo-content {
  flex: 1 1 300px;
}

.seo-badge {
  display: inline-block;
  background-color: #e2f6f4;
  color: #2b9893;
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.4rem 0.8rem;
  border-radius: 50px;
  margin-bottom: 1.25rem;
}

.seo-title {
  color: #4a3359;
  font-size: 1.85rem;
  font-weight: 500;
  line-height: 1.25;
  margin-bottom: 1rem;
}

.seo-desc {
  color: #646a75;
  font-size: 1.15rem;
  line-height: 1.6;
}

.seo-features {
  flex: 1 1 350px;
  background: #fafafc;
  border: 1px solid #f0f0f4;
  border-radius: 4px;
  padding: 2rem;
}

.seo-features-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

.seo-features-list li {
  display: flex;
  align-items: center;
}

.seo-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: #ffffff;
  border-radius: 50%;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  margin-right: 12px;
  flex-shrink: 0;
}

.seo-check-inner {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  background: #4f4c64;
  border-radius: 50%;
  color: #ffffff;
}

.seo-check-inner svg {
  width: 8px;
  height: 8px;
  stroke-width: 3;
}

.seo-feature-text {
  color: #5c6169;
  font-size: 1.05rem;
  line-height: 1.4;
  font-weight: 500;
}

@media (max-width: 600px) {
  .seo-features-list {
    grid-template-columns: 1fr;
  }
}