/* ==========================================================================
   Canopus — landing page
   Replica of the Figma frame "Home Page" (1920 × 6945).
   Fluid: every design measurement is expressed as a clamp() that resolves to
   the Figma value at a 1920px viewport and scales down gracefully.
   ========================================================================== */

@import url('../assets/fonts/poppins.css');

/* --- Display face -------------------------------------------------------
   Afacad, self-hosted. Real weights ship for both roles the stylesheet asks
   for — Regular for the 300 (light) slot, Bold for the 700 — so nothing is
   synthesised. */
@font-face {
  font-family: 'Afacad';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('../assets/fonts/afacad-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Afacad';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/afacad-700.woff2') format('woff2');
}

/* ---------------------------------------------------------------- tokens */
:root {
  /* colour — gold sampled straight from the exported hatch artwork */
  --gold: #c7b77a;
  --gold-deep: #b6a66c;
  --gold-dark: #a8975b;
  --ink: #262626;
  --ink-soft: #3d3d3d;
  --paper: #ffffff;
  --paper-2: #fcfcfb;
  --ghost: #f1f0ec;
  --rule: rgba(38, 38, 38, 0.16);

  /* type */
  --font-display: 'Afacad', 'Poppins', system-ui, sans-serif;
  --font-body: 'Poppins', system-ui, -apple-system, sans-serif;

  /* Azedo's caps are only 0.523em tall (its sCapHeight metadata of 733 is
     wrong — the real glyph bounds top out at 522/1000), so the display sizes
     run much larger than they would for a normal face to hit the design's
     cap heights. Cross-checked against the rendered width of the longest
     string in each role. */
  --fs-hero:    clamp(2.6rem,  5.68vw, 6.8rem);    /* 109px @1920 */
  --fs-tagline: clamp(1.15rem, 2.28vw, 2.75rem);   /* 44px @1920 */
  --fs-ghost:   clamp(3.5rem,  9.27vw, 11.1rem);   /* 178px @1920 */
  --fs-h2:      clamp(1.9rem,  2.6vw,  3.13rem);   /* 50px @1920 */
  --fs-h3:      clamp(1.15rem, 1.46vw, 1.75rem);   /* 28px @1920 */
  /* NB: keep every min below the value the vw term produces at 1440, or the
     clamp floors out early and the type stops scaling with the design. */
  --fs-body:    clamp(0.9rem,   0.9vw,  1rem);     /* 16px @1920 */
  --fs-list:    clamp(0.9rem,   1.15vw, 1.38rem);  /* 22px @1920 */
  --fs-nav:     clamp(0.85rem,  1.04vw, 1.25rem);  /* 20px @1920 */
  --fs-btn:     clamp(0.85rem,  1.04vw, 1.25rem);

  /* layout */
  /* Figma: 1400px of content in a 1920 frame = 72.9%, so the side margins stay
     proportional as the viewport narrows rather than collapsing to nothing. */
  --container: min(1400px, 74vw);
  --section-y: clamp(2.5rem, 4.2vw, 5rem);         /* tightened section rhythm */
  --track-wide: 0.10em;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ----------------------------------------------------------------- reset */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
ul { list-style: none; margin: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
button, input { font: inherit; color: inherit; }
h1, h2, h3, p { margin: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; top: 0; left: 50%; transform: translate(-50%, -120%);
  z-index: 200; background: var(--ink); color: #fff;
  padding: 0.75rem 1.25rem; border-radius: 0 0 6px 6px;
}
.skip-link:focus-visible { transform: translate(-50%, 0); }

:where(a, button, input):focus-visible {
  outline: 2px solid var(--gold-dark);
  outline-offset: 3px;
}

.container { width: var(--container); margin-inline: auto; }

/* anchor targets clear the fixed header */
section[id], footer[id] { scroll-margin-top: clamp(4rem, 6vw, 7rem); }

/* ------------------------------------------------------------- typography */
.h-gold {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h2);
  line-height: 1.1;
  /* Azedo's space glyph is a wide 0.347em, and letter-spacing stacks on top of
     it, so word gaps balloon to ~0.45em. Pull the tracking back and claw the
     word gap down to ~0.27em, which reads as a normal display setting. */
  letter-spacing: 0.06em;
  text-transform: capitalize;
  color: var(--gold);
}
/* the grid column governs the measure; the em cap only kicks in past 1920 */
.lede { max-width: min(100%, 36em); color: var(--ink-soft); text-align: justify; }

/* Oversized outline-of-a-word watermark that bleeds off the right edge,
   exactly as in the Figma frame. */
.ghost {
  position: absolute;
  top: clamp(1rem, 2.4vw, 2.9rem);
  right: clamp(-1.5rem, -1.8vw, -0.5rem);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-ghost);
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ghost);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

/* ---------------------------------------------------------------- buttons */
.btn {
  --btn-bg: transparent;
  --btn-fg: #fff;
  --btn-bd: currentColor;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: clamp(9rem, 10.6vw, 12.7rem);
  padding: clamp(0.7rem, 0.85vw, 1rem) clamp(1.4rem, 1.7vw, 2rem);
  font-family: var(--font-display);
  font-size: var(--fs-btn);
  font-weight: 700;
  letter-spacing: 0px;
  text-transform: capitalize;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1.5px solid var(--btn-bd);
  /* bottom-up wipe fill: a gradient layer that grows above the background
     colour but below the text — no extra markup, no stacking-context traps */
  background-image: linear-gradient(var(--btn-hover-bg, #fff), var(--btn-hover-bg, #fff));
  background-repeat: no-repeat;
  background-position: bottom center;
  background-size: 100% 0%;
  transition: background-size 0.45s var(--ease), color 0.4s var(--ease),
              border-color 0.4s var(--ease);
}
.btn:hover, .btn:focus-visible { background-size: 100% 100%; }

.btn--solid  { --btn-bg: #fff; --btn-fg: var(--ink); --btn-bd: #fff; --btn-hover-bg: var(--gold); }
.btn--solid:hover  { color: #fff; border-color: var(--gold); }
.btn--ghost  { --btn-hover-bg: #fff; }
.btn--ghost:hover  { color: var(--ink); }
.btn--gold   { --btn-bg: var(--gold-deep); --btn-fg: #fff; --btn-bd: var(--gold-deep); --btn-hover-bg: var(--ink); }
.btn--gold:hover   { border-color: var(--ink); }
/* Tighter than the rest: `min-width` is dropped as well as the padding —
   it was the 203px floor, not the padding, holding the box open. */
.btn--gold {
  min-width: 0;
  padding: clamp(0.5rem, 0.6vw, 0.72rem) clamp(0.95rem, 1.15vw, 1.38rem);
}
.btn--outline-light { --btn-bd: rgba(255,255,255,0.85); --btn-hover-bg: #fff; }
.btn--outline-light:hover { color: var(--gold-deep); border-color: #fff; }

/* ===================================================================
   HEADER
   =================================================================== */
.header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  padding-block: clamp(1rem, 1.7vw, 2rem);
  transition: background-color 0.45s var(--ease), padding 0.45s var(--ease),
              backdrop-filter 0.45s var(--ease);
}
.header.is-stuck {
  padding-block: clamp(0.6rem, 0.9vw, 1rem);
  background: rgba(26, 26, 26, 0.72);
  backdrop-filter: blur(14px) saturate(140%);
}

.nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(1rem, 2vw, 2.5rem);
}
.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 3.1vw, 3.7rem);
}
.nav__list--left  { justify-content: flex-end; }
.nav__list--right { justify-content: flex-start; }

.nav__link {
  position: relative;
  display: inline-block;
  padding-block: 0.35rem;
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: var(--track-wide);
  text-transform: capitalize;
  color: #fff;
  white-space: nowrap;
}
.nav__link::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}
.nav__link:hover::after,
.nav__link.is-active::after { transform: scaleX(1); }

.nav__brand img {
  width: clamp(7.5rem, 11vw, 13.2rem);
  height: auto;
}

.nav__toggle {
  display: none;
  width: 46px; height: 40px;
  padding: 8px; margin-left: auto;
  background: none; border: 0; cursor: pointer;
}
.nav__toggle span {
  display: block; height: 2px; margin: 5px 0;
  background: #fff; border-radius: 2px;
  transition: transform 0.35s var(--ease), opacity 0.25s linear;
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav {
  display: grid;
  gap: 0.25rem;
  padding: 1.25rem 6vw 1.75rem;
  background: rgba(26, 26, 26, 0.95);
  backdrop-filter: blur(12px);
}
/* a class `display` beats the UA sheet's [hidden]{display:none}, so restate it */
.mobile-nav[hidden] { display: none; }
.mobile-nav a {
  padding: 0.85rem 0;
  font-family: var(--font-body);
  font-weight: 700;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: #fff;
  border-bottom: 1px solid rgba(255,255,255,0.12);
}

/* ===================================================================
   HERO
   =================================================================== */
/* The section itself is the scroll track — JS pins .hero__stage inside it and
   scrubs the frame sequence across its length. Height is set by JS so it stays
   in one place; this is the no-JS / reduced-motion default. */
.hero {
  position: relative;
  min-height: 100svh;
}
.hero__stage {
  position: relative;
  display: flex;
  align-items: flex-end;
  /* Full screen, uncapped. This used to be capped at the Figma frame's 1072px
     hero height, which left the next section peeking in on any viewport
     taller than that. */
  height: 100svh;
  padding-block: clamp(6rem, 12vh, 10rem) clamp(3.5rem, 8.5vh, 8.25rem);
  overflow: hidden;
  isolation: isolate;
}
.hero__media { position: absolute; inset: 0; z-index: -2; }
.hero__media > * {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 42%;
}
.hero__canvas { opacity: 0; transition: opacity 0.5s linear; }
.hero__canvas.is-ready { opacity: 1; }
.hero__poster { transition: opacity 0.5s linear; }

/* barely-there scrim: keeps the white type legible on the bright floor */
.hero__stage::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(20,22,28,0.28) 0%, rgba(20,22,28,0.06) 34%,
                                       rgba(20,22,28,0.18) 70%, rgba(20,22,28,0.42) 100%);
}

.hero__inner { position: relative; width: var(--container); margin-inline: auto; text-align: center; color: #fff; }

/* scroll cue — a slow travelling line, hidden once the sequence starts */
.hero__cue {
  position: absolute;
  left: 50%; bottom: clamp(1.25rem, 3vh, 2.5rem);
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  color: rgba(255, 255, 255, 0.7);
  pointer-events: none;
}
/* mouse icon */
.hero__cue-mouse {
  width: clamp(1.15rem, 1.5vw, 1.5rem);
  height: auto;
}
/* the wheel travels up and down inside the mouse */
.hero__cue-wheel {
  animation: cueWheel 1.6s ease-in-out infinite;
}
@keyframes cueWheel {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(6px); }
}
/* "Scroll" label beside the mouse */
.hero__cue-label {
  font-family: "Poppins", sans-serif;
  font-style: normal;
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .hero__cue-wheel { animation: none; }
}
@keyframes cue {
  0%   { transform: translateY(-100%); }
  60%, 100% { transform: translateY(100%); }
}

/* All three slides occupy the same grid cell, so the block is as tall as the
   tallest one and the buttons below never shift as the copy changes. */
.hero__slides {
  display: grid;
  align-items: end;
  justify-items: center;
  min-height: clamp(9rem, 15vh, 13rem);
}
.hero__slide {
  grid-area: 1 / 1;
  align-self: end;
  width: 100%;
  /* drop-shadow, not text-shadow: the per-word reveal masks would clip a
     text-shadow at the mask edge. A filter renders after the clip, so the
     glow survives — and one filter covers both lines. */
  filter: drop-shadow(0 3px 18px rgba(0, 0, 0, 0.5));
  will-change: transform, opacity;
}
/* With no JS, or when motion is reduced, nothing cross-fades — so show only
   the brand slide (it carries the <h1>) instead of stacking all three. */
html:not(.js) .hero__slide:not([data-slide="1"]),
html.no-motion .hero__slide:not([data-slide="1"]) { display: none; }

.hero__tagline {
  font-size: var(--fs-tagline);
  font-style: normal;
  font-weight: 300;
  line-height: 1.2;
  margin-bottom: clamp(0.5rem, 1vw, 1.1rem);
}
.hero__title {
  font-family: var(--font-display);
  font-size: var(--fs-hero);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-wrap: balance;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(0.75rem, 1.2vw, 1.4rem);
  margin-top: clamp(1.5rem, 2.9vw, 3.5rem);
}

/* ===================================================================
   PROGRAMS GRID  (6 cells, hairline rules between)
   =================================================================== */
.programs {
  padding-block: clamp(2.5rem, 4vw, 5rem);
  background: var(--paper-2);
}
.programs__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}
/* Fixed-height icon row with the mark bottom-aligned, so the taller dance and
   kids marks don't push their titles down — in the design every title in a row
   sits on the same baseline. */
.prog {
  display: grid;
  grid-template-rows: clamp(52.7px, calc(85 * 0.05208vw), 85px) auto auto;
  align-content: start;
  justify-items: center;
  text-align: center;
  padding: clamp(1.75rem, 2.6vw, 3.1rem) clamp(1rem, 2.2vw, 2.65rem);
}
/* rules only on the inside edges of the grid */
.prog:not(:nth-child(3n))     { border-right: 1px solid var(--rule); }
.prog:nth-child(-n + 3)       { border-bottom: 1px solid var(--rule); }

/* The exported icons are trimmed to their glyph, so --ih is the glyph height in
   Figma px at the 1920 frame and each icon keeps its own designed size — the
   dance and kids marks really are taller than the rest. 0.05208vw == 1px @1920. */
.prog__icon {
  width: auto;
  height: clamp(calc(var(--ih) * 0.62px), calc(var(--ih) * 0.05208vw), calc(var(--ih) * 1px));
  align-self: end;
  transform-origin: center bottom;
  transition: transform 0.5s var(--ease);
}
.prog--yoga    .prog__icon { --ih: 53; }
.prog--pilates .prog__icon { --ih: 49; }
.prog--aerials .prog__icon { --ih: 54; }
.prog--dance   .prog__icon { --ih: 85; }
.prog--fitness .prog__icon { --ih: 51; }
.prog--kids    .prog__icon { --ih: 61; }

.prog:hover .prog__icon { transform: translateY(-6px) scale(1.06); }

.prog__title {
  margin-top: clamp(1rem, 1.6vw, 1.9rem);
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 700;
  letter-spacing: 0em;
  text-transform: capitalize;
  color: var(--ink);
}
.prog__text {
  margin-top: clamp(1.25rem, 2vw, 2.4rem);
  color: var(--ink-soft);
  font-size: 0.85em;   /* the cell copy is a step down from the section ledes */
  max-width: 34ch;
}

/* ===================================================================
   WAVE RIBBON  (curved marquee bridging Programs → About)
   The gold band is a single stroked path; the tagline rides the very
   same centreline via <textPath>, so text and band never drift apart.
   =================================================================== */
.ribbon {
  position: relative;
  width: 100%;
  overflow: hidden;
  line-height: 0;                 /* kill the inline-SVG descender gap */
  padding-block: clamp(1.5rem, 4vw, 4.5rem);
  background: var(--paper-2);      /* continuous with the programs grid above */
}
.ribbon__svg { display: block; width: 100%; height: auto; }
.ribbon__text {
  font-family: var(--font-body);
  font-style: italic;
  font-weight: 300;
  font-size: 34px;                 /* viewBox units — scales with the SVG */
  letter-spacing: 0.05em;
  fill: var(--paper);              /* cream text reading over the gold band */
}
/* Narrower viewports stretch the band taller, so bump the type to match. */
@media (max-width: 860px) { .ribbon__text { font-size: 42px; } }
@media (max-width: 560px) { .ribbon__text { font-size: 52px; } }

/* ===================================================================
   BRAND SEAL  (tagline badge tucked left, between What-we-do → Classes)
   =================================================================== */
/* No vertical padding: the badge is pulled down with translateY so it
   straddles the white → grey boundary that starts the Classes section.
   z-index keeps it painting over that later (grey) section. */
.seal-row { padding-block: 0; position: relative; z-index: 2; }
.seal {
  width: clamp(92px, 8vw, 150px);
  margin-left: clamp(0rem, 2vw, 2.5rem);   /* nudge in from the container edge */
  transform: translateY(50%);              /* centre it on the section seam */
}
.seal__svg { display: block; width: 100%; height: auto; overflow: visible; }
.seal__ring { transform-origin: 100px 100px; }   /* spin about the SVG centre */

/* ===================================================================
   SPLIT SECTIONS  (About / What we do / Classes / Vision)
   =================================================================== */
.split {
  position: relative;
  padding-block: var(--section-y);
  overflow: hidden;
}
.split__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 6rem);
}
.split__body { display: grid; justify-items: start; gap: clamp(1.25rem, 2.2vw, 2.6rem); }
.split--about  .split__body,
.split--vision .split__body { padding-top: clamp(0rem, 3vw, 3.5rem); }
/* the watermark word sits at the top of these two sections — give the whole
   row extra headroom so the artwork clears the word instead of touching it */
.split--vision { padding-top: clamp(4rem, 7vw, 8rem); }
.split--about { padding-top: clamp(6rem, 11vw, 13rem); }

/* the exported blob artwork already carries its mask + gold hatch */
.blob img { width: 100%; }
.blob--flip img { transform: scaleX(-1); }

/* About Us keeps its blob on the same side as the ghost watermark, so drop the
   artwork down and cap its width to clear the word instead of colliding with it */
.split--about .split__media {
  margin-top: clamp(3rem, 6vw, 6.5rem);
  justify-self: end;
}
.split--about .split__media img { max-width: 90%; margin-left: auto; }

.split__media--rect img {
  width: 100%;
  box-shadow: 0 24px 60px -30px rgba(38, 38, 38, 0.4);
}

.split--classes { background: #fafafa; }
.split--classes .split__body .btn { margin-top: clamp(0.5rem, 1.5vw, 1.75rem); }

/* ===================================================================
   SERVICES PAGE
   =================================================================== */
/* A static hero — no frame sequence, so the copy just sits there. */
.hero--page .hero__slides { min-height: 0; }

.svc {
  position: relative;
  padding-block: clamp(4.5rem, 8vw, 9.5rem) var(--section-y);
  overflow: hidden;
}
.svc__row {
  display: grid;
  /* the artwork column is narrower than the copy, matching the Figma rows */
  grid-template-columns: 0.85fr 1.15fr;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 3.5rem);
}
.svc__row + .svc__row { margin-top: clamp(3rem, 6vw, 7.5rem); }

/* the blob artwork carries its own mask + gold hatch, same as the home page */
.svc__media { margin: 0; }
.svc__media img { width: 100%; }

.svc__body { display: grid; justify-items: start; gap: clamp(1.25rem, 2.2vw, 2.6rem); }

.svc__list { display: grid; gap: clamp(0.55rem, 0.95vw, 1.1rem); }
.svc__list li {
  position: relative;
  padding-left: 1.7em;
  color: var(--ink-soft);
  font-weight: 300;
}
.svc__list li::before {
  content: '';
  position: absolute; left: 0.35em; top: 0.62em;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--gold);
}
.svc__list b { font-weight: 600; color: var(--ink); }

@media (max-width: 860px) {
  .svc__row { grid-template-columns: 1fr; }
  .svc__media { max-width: 30rem; }
}

/* ------ More ways to train: two bordered cards below the services list ----- */
.extras { padding-block: var(--section-y); }
.extras__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 3vw, 3rem);
}
.extra-card {
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: clamp(2.5rem, 5vw, 5rem) clamp(1.75rem, 3.5vw, 3.5rem);
  display: grid;
  align-content: center;
  gap: clamp(1rem, 1.6vw, 1.6rem);
  min-height: clamp(14rem, 22vw, 17rem);
}
.extra-card__text {
  max-width: 34em;
  color: var(--ink-soft);
  font-weight: 300;
  text-align: justify;
}

@media (max-width: 860px) {
  .extras__grid { grid-template-columns: 1fr; }
  .extra-card { min-height: 0; }
}

/* ===================================================================
   DOWNLOAD THE APP  (image bleeds to the right viewport edge)
   =================================================================== */
.app {
  padding-block: var(--section-y);
  overflow: hidden;
}
.app__inner {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  align-items: center;
  gap: clamp(2rem, 4vw, 5rem);
}
.app__title { display: grid; gap: 0.15em; line-height: 1.08; }
.app__list {
  display: grid;
  gap: clamp(0.5rem, 0.85vw, 1rem);
  margin-top: clamp(1.5rem, 2.6vw, 3.1rem);
  font-size: var(--fs-list);
}
.app__list li { position: relative; padding-left: 1.4em; }
.app__list li::before {
  content: '';
  position: absolute; left: 0.25em; top: 0.62em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--ink);
}
.badges {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.6rem, 1vw, 1.2rem);
  margin-top: clamp(1.5rem, 2.6vw, 3.1rem);
}
.badge img {
  height: clamp(2.5rem, 2.9vw, 3.5rem);
  width: auto;
  transition: transform 0.4s var(--ease);
}
.badge:hover img { transform: translateY(-4px); }

.app__media {
  margin: 0;
  /* sits within the container, centred in its column (no viewport-edge bleed) */
}
.app__media img { width: 100%; }

/* ===================================================================
   FOOTER
   =================================================================== */
.footer {
  padding-block: clamp(2.75rem, 4.6vw, 5.5rem);
  /* gold field with the looping-ribbon motif; the solid colour is both a
     fallback and a seamless fill for any area the artwork doesn't cover */
  background: #b8a970 url("../assets/img/footer.png") center / cover no-repeat;
  color: #fff;
}
.footer__inner {
  display: grid;
  grid-template-columns: 1fr 1.1fr 1fr;
  gap: clamp(2rem, 4vw, 5rem);
}
.footer__nav { display: flex; gap: clamp(2rem, 4.2vw, 5rem); }
.footer__nav ul { display: grid; gap: clamp(0.9rem, 1.5vw, 1.8rem); align-content: start; }
.footer__nav a {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-nav);
  letter-spacing: var(--track-wide);
  text-transform: capitalize;
  transition: opacity 0.3s var(--ease);
}
.footer__nav a:hover { opacity: 0.68; }

.footer__label {
  margin-top: clamp(2rem, 3.3vw, 4rem);
  font-size: var(--fs-list);
}
.footer__col--links .badges { margin-top: clamp(0.9rem, 1.4vw, 1.7rem); }

.footer__col--brand { text-align: center; }
.footer__logo {
  width: clamp(9rem, 12.5vw, 15rem);
  margin: 0 auto clamp(1.25rem, 2.2vw, 2.6rem);
}
.footer__col--brand p { font-weight: 300; color: rgba(255,255,255,0.92); }

.footer__heading {
  font-family: var(--font-display);
  font-size: var(--fs-nav);
  font-weight: 700;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
}
.news { display: grid; justify-items: start; gap: clamp(1rem, 1.7vw, 2rem); margin-top: clamp(1.5rem, 2.6vw, 3.1rem); }
.news input {
  width: 100%;
  max-width: 18rem;
  padding: clamp(0.85rem, 1.05vw, 1.25rem) clamp(1rem, 1.25vw, 1.5rem);
  color: var(--ink);
  background: #fff;
  border: 0;
}
.news input::placeholder { color: #9a9a9a; }
.news__msg { min-height: 1.4em; font-size: 0.9em; }

/* ===================================================================
   RESPONSIVE
   =================================================================== */
@media (max-width: 1080px) {
  :root { --container: 90vw; }
  .programs__grid { grid-template-columns: repeat(2, 1fr); }
  .prog:not(:nth-child(3n))   { border-right: 0; }
  .prog:nth-child(-n + 3)     { border-bottom: 0; }
  .prog:not(:nth-child(2n))   { border-right: 1px solid var(--rule); }
  .prog:not(:nth-last-child(-n + 2)) { border-bottom: 1px solid var(--rule); }

  .footer__inner { grid-template-columns: 1fr 1fr; }
  .footer__col--news { grid-column: 1 / -1; }
}

@media (max-width: 860px) {
  .nav { grid-template-columns: auto 1fr; }
  .nav__list { display: none; }
  .nav__brand { order: -1; }
  .nav__toggle { display: block; }

  .split__inner,
  .app__inner { grid-template-columns: 1fr; }
  /* keep the image above the copy on every split, matching the desktop read */
  .split--about .split__media,
  .split--do .split__media,
  .split--classes .split__media { grid-row: 1; }
  .split--about .split__media { margin-top: 0; justify-self: stretch; }
  .split--about .split__media img { max-width: 100%; }
  .split__body { justify-items: start; }
  .lede { max-width: none; }

  .app__media { margin-right: 0; }

  .ghost { font-size: clamp(2.5rem, 11vw, 5rem); top: 0; }

  .footer__inner { grid-template-columns: 1fr; }
  .footer__col--brand { text-align: left; }
  .footer__logo { margin-inline: 0; }
}

@media (max-width: 560px) {
  .programs__grid { grid-template-columns: 1fr; }
  .prog { border-right: 0 !important; }
  .prog:not(:last-child) { border-bottom: 1px solid var(--rule) !important; }
  .prog__text { max-width: none; }
  .lede { text-align: left; }
  .hero__actions .btn { flex: 1 1 12rem; }
}

/* ===================================================================
   MOTION — initial states are only applied when JS + motion are on,
   so the page is fully readable without either.
   =================================================================== */
.js .anim { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .anim { opacity: 1; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
