/* ============================================================================
 * Howzit Buddy, front page ("the stage")
 * Plain CSS, no build step and no runtime framework: this page is the first
 * thing a principal opens, often on a phone on school Wi-Fi, so it has to be
 * light. Colours are sampled from the mascot artwork (assets/brand/palette.json)
 * so the characters sit in the page as if it were their own wall, and each
 * section wears one letter-colour of the logo (H blue, O coral, w green, z amber).
 * Mobile first: 360-390 phone, 768 tablet, 1024+ laptop.
 * ========================================================================== */

:root {
  /* The characters' world: the petrol wall from the artwork, lit behind them. */
  --wall:       #014f76;
  --wall-glow:  #0a6a98;
  --wall-edge:  #013f60;
  --deep:       #072a41;   /* the art's corner, pulled toward the app's navy */
  --navy:       #0d1828;   /* the app itself, so the footer hands over to it */
  --navy-2:     #12203a;

  /* Light sections */
  --paper:  #ffffff;
  --mist:   #eef6fa;
  --line:   #d7e7ef;
  --ink:    #0a2536;       /* 15.8:1 on white */
  --ink-2:  #3f5b6b;       /*  7.2:1 on white, 6.6:1 on mist */

  /* The logo's letters. "-t" is a darker shade for text on white, where the
     letter colour itself would not pass AA; "-lt" a lighter one for text on
     the dark petrol and navy. */
  --sun:      #fda002;  --sun-hi: #ffb42e;  --sun-lt: #ffd366;     /* the z: every main button */
  --blue:     #0167fe;  --blue-t:  #0157d6; --blue-lt: #8ab8ff;    /* the H */
  --green:    #53bc96;  --green-t: #1b7a5a; --green-lt: #7fd6b4;   /* the w */
  --amber:    #fda002;  --amber-t: #9a5a00;                        /* the z */
  --coral:    #fc5338;  --coral-t: #c8381f; --coral-lt: #ff9b85;   /* the O */

  --f-head:  'Schibsted Grotesk', 'Segoe UI', system-ui, sans-serif;
  --f-body:  'Nunito', 'Segoe UI', system-ui, sans-serif;
  --f-voice: 'Fredoka', 'Nunito', system-ui, sans-serif;

  --focus: #0157d6;
  --radius: 20px;
  --gutter: 16px;
  --bar-h: 60px;           /* the top bar, which floats over the top of the stage */
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  font: 400 16px/1.6 var(--f-body);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;           /* belt and braces: nothing should ever poke out sideways */
}
img, svg, picture { display: block; max-width: 100%; }
h1, h2, h3 { font-family: var(--f-head); margin: 0; letter-spacing: -0.02em; }
p, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; }

.wrap { width: 100%; max-width: 1280px; margin-inline: auto; padding-inline: var(--gutter); }
@media (min-width: 700px)  { :root { --gutter: 32px; } }
@media (min-width: 1100px) { :root { --gutter: 40px; } }
@media (min-width: 1200px) { :root { --bar-h: 76px; } }

/* Invitations to try the phone demo, which needs the script to answer. */
@media (scripting: none) { .js-only { display: none; } }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.nowrap { white-space: nowrap; }
/* The second half of a line, for screens with room for it. A phone gets the
   short version so a principal reaches the point (and the button) sooner. */
.more, .l { display: none; }
@media (min-width: 700px) { .more, .l { display: inline; } .s { display: none; } }

/* Visible keyboard focus everywhere; yellow on the dark, blue on the light. */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 10px; }
.masthead, .hero, .join, .foot, .phone { --focus: #ffd366; }

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 50;
  background: var(--sun); color: var(--ink); font-weight: 800; padding: 10px 16px; border-radius: 10px;
}
.skip:focus { top: 12px; }

.ic { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.9;
      stroke-linecap: round; stroke-linejoin: round; }
.flag { width: 24px; height: 16px; border-radius: 3px; overflow: hidden; flex: none;
        box-shadow: 0 0 0 1px rgba(255,255,255,.25); }
.flag--sm { width: 20px; height: 14px; display: inline-block; vertical-align: -2px; }

/* ------------------------------------------------------------- buttons ---- */
/* Chunky like the logo's balloon letters: a darker lip along the bottom edge. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 54px; padding: 0 24px; border-radius: 14px;
  font: 700 17px/1 var(--f-head); letter-spacing: -0.01em; text-decoration: none;
  transition: transform .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.btn .ic { width: 18px; height: 18px; stroke-width: 2.4; transition: transform .15s ease; }
.btn:hover .ic { transform: translateX(3px); }
.btn--sun {
  background: var(--sun); color: var(--ink);
  box-shadow: inset 0 -4px 0 rgba(120, 60, 0, .28), 0 14px 30px -12px rgba(253, 160, 2, .65);
}
.btn--sun:hover { background: var(--sun-hi); transform: translateY(-2px); }
.btn--sun:active { transform: translateY(1px); box-shadow: inset 0 -2px 0 rgba(120, 60, 0, .28); }
.btn--ghost { color: #fff; box-shadow: inset 0 0 0 2px rgba(255,255,255,.5); }
.btn--ghost:hover { box-shadow: inset 0 0 0 2px #fff; background: rgba(255,255,255,.08); }
.cta-row { display: flex; flex-wrap: wrap; gap: 12px; }

.pill {
  display: inline-flex; align-items: center; min-height: 40px; padding: 0 14px; border-radius: 999px;
  font: 700 14px/1 var(--f-head); text-decoration: none; white-space: nowrap;
}
.pill--ghost { color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.5); }
.pill--ghost:hover { box-shadow: inset 0 0 0 1.5px #fff; }
.pill--sun { background: var(--sun); color: var(--ink); box-shadow: inset 0 -3px 0 rgba(120,60,0,.25); }
.pill--sun:hover { background: var(--sun-hi); }
/* The learners' own door, in the logo's green (the colour of "For learners"
   further down), so it can't be mistaken for the white-outlined school one. */
.pill--learner { gap: 7px; background: var(--green-lt); color: var(--ink); box-shadow: inset 0 -3px 0 rgba(0,70,45,.22); }
.pill--learner:hover { background: #a3e6cc; }
.pill__ic { width: 17px; height: 17px; stroke-width: 2.1; }

/* "Sample data" and friends: a small label that sits INSIDE a mock-up, so a
   screenshot of it can never pass for a real school's numbers. */
.mock-tag {
  display: inline-flex; align-items: center; white-space: nowrap; font-style: normal;
  font: 800 10px/1 var(--f-body); letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 8px; border-radius: 999px;
  color: #ffd366; background: rgba(255,211,102,.14); box-shadow: inset 0 0 0 1px rgba(255,211,102,.55);
}
.mock-tag--w { color: #fff; background: var(--green-t); box-shadow: none; }

/* ============================================================== HERO ====== */
.hero {
  position: relative; isolation: isolate; color: #fff; overflow: hidden;
  padding-top: var(--bar-h);     /* the top bar floats here (.masthead) */
  padding-bottom: 46px;          /* the floor; the white sheet slides over part of it */
  background:
    radial-gradient(70% 45% at 50% 38%, rgba(10,106,152,.9) 0%, rgba(10,106,152,0) 70%),
    radial-gradient(130% 100% at 50% 20%, var(--wall) 0%, var(--wall-edge) 60%, var(--deep) 100%);
}
/* The wall in the artwork is textured plaster; a faint grain keeps this one
   from looking like a flat gradient next to them. */
.hero::before, .join::before {
  content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .35;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* The floor: where wall meets ground, a little darker, like a studio sweep. */
.hero::after, .join::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 170px; z-index: -1;
  background: linear-gradient(to bottom, rgba(4,30,48,0) 0%, rgba(4,30,48,.55) 100%);
}

/* ---------------------------------------------------------------- top bar */
/* Phone: the way to help on the left, the two sign-ins (learner, school) on
   the right. Adding a school is the big button right under the characters, so
   it isn't repeated. The bar sits outside <main> but floats over the top of
   the stage, which keeps exactly its height free (--bar-h), so it looks like
   part of it. */
.masthead { position: absolute; top: 0; left: 0; right: 0; z-index: 5; color: #fff; }
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  min-height: var(--bar-h); position: relative; z-index: 4;
}
.topbar__tag { display: none; align-items: center; gap: 10px; font: 700 14px/1 var(--f-head); color: rgba(255,255,255,.9); }
.topbar__links { flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.topbar__links a:not(.pill) {
  font: 600 15px/1 var(--f-head); color: rgba(255,255,255,.92); text-decoration: none; padding: 10px 8px;
}
.topbar__links a:not(.pill):hover { color: #fff; text-decoration: underline; text-underline-offset: 6px; }
.topbar__help-li { margin-right: auto; }
.topbar__links .topbar__help {
  display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 10px 0 2px;
  font: 700 14.5px/1 var(--f-body);
}
.topbar__help .ic { width: 18px; height: 18px; color: #ffd366; fill: #ffd366; stroke: none; }
.hide-sm, .topbar__add { display: none; }
/* Three things share a phone's top bar, so they tighten up to fit on one
   line: smaller pills, no icon, and "Need help" without the "now?" (the
   floating pill further down still says it in full). */
.topbar__links .topbar__help, .topbar .pill { white-space: nowrap; }
@media (max-width: 559px) {
  .topbar__links { gap: 6px; }
  .topbar .pill { min-height: 36px; padding: 0 11px; font-size: 13px; }
  .topbar .pill__ic { display: none; }
  .topbar__links .topbar__help { gap: 6px; padding-right: 0; font-size: 13.5px; }
  .topbar__help .ic { width: 16px; height: 16px; }
}
@media (max-width: 429px) { .topbar__now { display: none; } }
@media (max-width: 379px) {
  .topbar .pill { padding: 0 9px; font-size: 12.5px; }
  .topbar__links { gap: 4px; }
  .topbar__links .topbar__help { gap: 5px; font-size: 13px; }
}
/* The very narrowest phones keep the heart, and its words for screen readers. */
@media (max-width: 339px) {
  .topbar__help > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .topbar__help .ic { width: 20px; height: 20px; }
}
@media (min-width: 640px) { .topbar__add { display: list-item; } }
/* The "For South African schools" tag waits for a laptop: on a tablet the
   bar is already full with help, both sign-ins and "Add your school", so
   until then help keeps the left end and the buttons the right. */
@media (min-width: 1024px) {
  .topbar__tag { display: flex; }
  .topbar__links { flex: 0 1 auto; justify-content: flex-end; }
  .topbar__help-li { margin-right: 4px; }
}
@media (min-width: 1200px) { .hide-sm { display: list-item; } .topbar__links { gap: 6px; } }

/* ------------------------------------------------------------ hero words */
/* Phone first: logo, then the stage, then the words. */
.hero__grid {
  display: grid; grid-template-areas: "brand" "stage" "copy";
  justify-items: center; text-align: center;
}
.hero__brand { grid-area: brand; }
.hero__logo { width: min(62vw, 232px); height: auto; filter: drop-shadow(0 10px 24px rgba(0,20,35,.35)); }
.hero__copy { grid-area: copy; max-width: 620px; margin-top: 16px; position: relative; z-index: 3; }
.hero__title { font-size: clamp(25px, 7vw, 46px); line-height: 1.08; font-weight: 800; text-wrap: balance; }
.hero__lede { margin-top: 10px; font-size: 15.5px; line-height: 1.5; color: rgba(255,255,255,.92); text-wrap: pretty; }
.hero__copy .cta-row { margin-top: 18px; justify-content: center; }
.hero__copy .cta-row .btn { flex: 1 1 220px; }
.cta-row--hero .btn--ghost { display: none; }
@media (min-width: 560px) { .cta-row--hero .btn--ghost { display: inline-flex; } }

.learner-note {
  margin-top: 18px; display: flex; gap: 12px; align-items: flex-start; text-align: left;
  font-size: 14px; line-height: 1.45; color: rgba(255,255,255,.88);
  padding: 12px 14px; border-radius: 16px; background: rgba(0,24,40,.32);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
}
.learner-note strong { color: #fff; font-weight: 800; }
.learner-note a { color: var(--green-lt); font-weight: 800; text-underline-offset: 3px; white-space: nowrap; }
.learner-note a:hover { color: #a3e6cc; }
.ic--note { width: 22px; height: 22px; color: #ffd366; margin-top: 1px; }

.welcome { margin-top: 20px; padding: 20px; border-radius: 18px; background: rgba(0,24,40,.32);
           box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.welcome__hi { font: 700 22px/1.2 var(--f-head); }
.welcome__sub { margin-top: 4px; color: rgba(255,255,255,.82); }
.welcome .cta-row { margin-top: 16px; justify-content: center; }
.welcome .cta-row .btn { flex: 1 1 200px; }

/* ----------------------------------------------------------- the stage --- */
/* --mr is the room to the right of the characters. The right-hand bubbles are
   anchored to its far edge (the content edge), so however wide the window is,
   a bubble can overlap her a little but never run off the screen.
   On a phone the picture takes whatever height is left once the logo, the
   headline and the main button have their room, so all of them fit on the
   first screen (390 x 844 and 360 x 740 both checked). */
.stage { grid-area: stage; position: relative; width: 100%; display: flex; justify-content: flex-end;
         padding-top: 14px; z-index: 2; }
.stage__figure {
  --fig-h: clamp(250px, calc(100svh - 480px), 368px); --mr: 44px;
  position: relative; height: var(--fig-h); aspect-ratio: 800 / 1080; margin-right: var(--mr);
}
@media (max-width: 380px) { .stage__figure { --mr: 36px; } }
.stage__img img { width: 100%; height: 100%; object-fit: contain; position: relative; z-index: 1; user-select: none; }
/* Floor light: a soft pool under their feet... */
.stage__figure::before, .join__figure::before {
  content: ''; position: absolute; left: -30%; right: -30%; bottom: -9%; height: 22%; z-index: 0;
  background: radial-gradient(closest-side, rgba(140,215,255,.42), rgba(126,206,255,.12) 55%, rgba(126,206,255,0) 100%);
}
/* ...and a contact shadow, since the cut-out has none baked in. */
.stage__figure::after, .join__figure::after, .showcase__buddies::after {
  content: ''; position: absolute; left: 2%; right: 0; bottom: -2.2%; height: 6%; z-index: 0;
  background: radial-gradient(closest-side, rgba(0,12,22,.62), rgba(0,12,22,0));
}

/* ---------------------------------------------------- speech bubbles ---- */
/* Shaped like the O in the logo: a rounded bubble with a small tail that
   points at whoever is talking. The tail inherits the bubble's colour. */
.bubble {
  position: absolute; z-index: 3; margin: 0;
  font: 500 14.5px/1.3 var(--f-voice); color: var(--ink); text-align: left; text-wrap: pretty;
  background: #fff; border-radius: 18px; padding: 10px 14px 11px;
  box-shadow: inset 0 -3px 0 rgba(1,79,118,.10);
  filter: drop-shadow(0 12px 16px rgba(0,16,28,.32));
}
.bubble b { font-weight: 600; }
.bubble::after { content: ''; position: absolute; width: 18px; height: 16px; background: inherit; }
.from-below::after { left: 20px; bottom: -12px; clip-path: polygon(0 0, 100% 0, 0 100%); }
.from-left::after  { left: -12px; top: 14px; width: 16px; clip-path: polygon(100% 0, 100% 100%, 0 0); }
.from-right::after { right: -12px; top: 14px; width: 16px; clip-path: polygon(0 0, 0 100%, 100% 0); }
.greet { color: var(--coral-t); }

/* Phone positions, as a share of the figure so they scale with it: his line
   over his cap, her line beside her, below her chin. The stage keeps room
   above him so his two-line bubble never covers the logo. */
@media (max-width: 699px) { .stage { padding-top: 48px; } }
.bubble--b1 { left: 34%; top: auto; bottom: calc(89% + 2px); width: 178px; font-size: 16px; padding: 8px 13px 9px; }
.bubble--b2 { right: calc(-1 * var(--mr)); top: 66%; width: 136px; }

/* A short phone (an iPhone SE with Safari's bars, or 360 x 640) still gets
   the headline and the main button on the first screen: a smaller logo and
   smaller characters, whose height follows the screen's. */
@media (max-width: 699px) and (max-height: 640px) {
  .hero__logo { width: min(50vw, 180px); }
  .stage { padding-top: 40px; }
  .stage__figure { --fig-h: clamp(170px, calc(100svh - 400px), 250px); }
  .hero__copy { margin-top: 10px; }
}
/* Under 600px tall her bubble would cover most of her ("free" is on the
   button right below anyway), and his hello shrinks to sit over his cap. */
@media (max-width: 699px) and (max-height: 600px) {
  .bubble--b2 { display: none; }
  .bubble--b1 { left: 30%; width: 160px; font-size: 14px; padding: 5px 11px 6px; }
}

/* The characters walk on, then say their lines one after the other. */
@keyframes rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes pop  { 0% { opacity: 0; transform: translateY(10px) scale(.88); } 70% { opacity: 1; transform: scale(1.03); } 100% { opacity: 1; transform: none; } }
.stage__img { animation: rise .8s cubic-bezier(.2,.8,.2,1) both; }
.bubble--hero { animation: pop .55s cubic-bezier(.2,.8,.2,1) both; transform-origin: 20% 100%; }
.bubble--b1 { animation-delay: .55s; }
.bubble--b2 { animation-delay: 1.05s; }

@media (min-width: 700px) {
  .hero__logo { width: 400px; }
  .hero__title { font-size: clamp(34px, 5.4vw, 46px); }
  .stage { padding-top: 60px; justify-content: center; }
  /* As tall as the screen leaves room for, so an iPad keeps the headline and
     the main button on its first screen (768 x 950 checked). */
  .stage__figure { --fig-h: clamp(300px, calc(100svh - 580px), 520px); --mr: 170px; }
  .bubble { font-size: 17px; padding: 12px 16px 13px; border-radius: 20px; }
  /* His line sits over HIS cap (it tops out at 11% of the picture, between
     31% and 60% across), anchored by its bottom edge so a longer line grows
     up into the space above him, never down onto their faces. */
  .bubble--b1 { left: 31%; top: auto; bottom: calc(89% + 2px); width: 230px; font-size: 17px; padding: 12px 16px 13px; white-space: normal; }
  /* Below her chin (her face ends at about 40% of the picture), never across it. */
  .bubble--b2 { top: 42%; width: 220px; }
  .hero__lede { font-size: 18px; line-height: 1.6; margin-top: 14px; }
  .hero__copy { margin-top: 26px; }
  .hero__copy .cta-row { margin-top: 24px; }
}
/* A phone on its side: little room above him, so his line runs on one row. */
@media (min-width: 700px) and (max-width: 1023px) and (max-height: 560px) {
  .bubble--b1 { width: auto; white-space: nowrap; font-size: 16px; }
}

/* Laptop and up: words on the left, the stage on the right, all on one
   screen. Heights are capped in px so a very tall window never blows the
   stage up. */
/* Room for the client's headline on two lines and both buttons on one row. */
.hero { --text-col: 520px; }
@media (min-width: 1200px) { .hero { --text-col: 620px; } }
@media (min-width: 1024px) {
  .hero { min-height: min(100svh, 980px); display: flex; flex-direction: column; padding-bottom: 60px; }
  .hero {
    background:
      radial-gradient(42% 56% at 70% 50%, rgba(12,112,160,.95) 0%, rgba(10,106,152,0) 72%),
      radial-gradient(120% 110% at 60% 25%, var(--wall) 0%, var(--wall-edge) 58%, var(--deep) 100%);
  }
  .hero__grid {
    flex: 1; text-align: left; justify-items: start; align-items: end; column-gap: 32px;
    grid-template-columns: minmax(0, var(--text-col)) minmax(0, 1fr);
    /* The words sit level with the middle of the stage; the characters
       stand on its floor. */
    grid-template-rows: 1fr auto auto 1fr;
    grid-template-areas: ". stage" "brand stage" "copy stage" ". stage";
  }
  .hero__brand { align-self: end; margin: 0 0 0 -6px; }
  .hero__logo { width: min(380px, 100%); }
  .hero__copy { margin: 18px 0 8px; align-self: start; }
  .hero__title { font-size: clamp(34px, 3.1vw, 46px); }
  .hero__copy .cta-row { justify-content: flex-start; }
  .hero__copy .cta-row .btn { flex: 0 0 auto; }
  .learner-note { margin-top: 20px; padding: 12px 16px; font-size: 14px; }
  .welcome .cta-row { justify-content: flex-start; }
  .welcome .cta-row .btn { flex: 0 0 auto; }
  .stage { justify-content: flex-end; padding-top: 0; align-self: end; }
  /* As tall as the window allows (capped), but never wider than its column
     plus a 40px lean into the gap, so feet never land on the words. */
  .stage__figure {
    --mr: clamp(120px, 13vw, 200px);
    --stage-w: calc(min(1280px, 100vw) - 2 * var(--gutter) - var(--text-col) - 32px + 40px);
    --fig-h: min(clamp(400px, calc(100svh - 290px), 690px), calc((var(--stage-w) - var(--mr)) * 1.35));
    margin-bottom: 4px;
  }
  .bubble { font-size: 18px; }
  .bubble--b1 { width: 240px; }
  .bubble--b2 { top: 41%; width: 210px; }
}

/* Short laptops: the usual school laptop (1366 x 768, 1280 x 720, or 1920 x
   1080 at 125%) leaves a window only 610-730px tall. The words column gets
   tighter and the stage stops waiting at the bottom of it: the characters
   stand right under the top bar, sized to the window, so they are always
   seen whole, with his bubble in the room kept above them. */
@media (min-width: 1024px) and (max-height: 800px) {
  :root { --bar-h: 64px; }
  .hero__logo { width: min(clamp(260px, 50svh, 380px), 100%); }
  .hero__copy { margin-top: 12px; }
  .hero__title { font-size: clamp(32px, 2.8vw, 40px); }
  .hero__lede { margin-top: 10px; font-size: 16.5px; line-height: 1.5; }
  .hero__copy .cta-row { margin-top: 18px; }
  .learner-note { margin-top: 16px; padding: 10px 14px; }
  .welcome { margin-top: 16px; padding: 16px 18px; }
  .stage { align-self: start; padding-top: 56px; }
  .stage__figure { --fig-h: min(calc(100svh - 150px), 690px, calc((var(--stage-w) - var(--mr)) * 1.35)); }
}
@media (min-width: 1200px) { .hero__logo { width: min(440px, 100%); } }
@media (min-width: 1280px) {
  .bubble { font-size: 19px; }
  .bubble--b1 { width: 270px; }
  .bubble--b2 { width: 240px; }
}

/* =========================================================== SECTIONS ===== */
/* The page below the stage is a sheet that slides up over the floor. */
.sheet { position: relative; z-index: 2; margin-top: -28px; background: var(--paper);
         border-radius: 28px 28px 0 0; overflow: clip; }
.band { padding-block: 36px; }
.band--paper { background: transparent; }
.band--mist  { background: var(--mist); }
@media (min-width: 700px)  { .band { padding-block: 72px; } }
@media (min-width: 1024px) { .band { padding-block: 100px; } }

.band h2 { font-size: clamp(26.5px, 4.2vw, 48px); line-height: 1.06; font-weight: 800; text-wrap: balance; }
.band__head { max-width: 720px; }
.band__sub { margin-top: 12px; font-size: 17px; color: var(--ink-2); max-width: 60ch; text-wrap: pretty; }
/* A phone skips the sub-lines: the characters and the lists say it. */
@media (max-width: 699px) { .band__sub { display: none; } }
/* On a phone the headings speak for themselves; only "Why it matters" keeps its label. */
@media (max-width: 699px) { .kicker:not(.why .kicker) { display: none; } }
.kicker { margin-bottom: 10px; font: 800 12.5px/1 var(--f-body); letter-spacing: .14em; text-transform: uppercase; color: var(--key-t); }

/* Each section's key colour, from one letter of the logo. */
.key-blue  { --key: var(--blue);  --key-t: var(--blue-t);  --key-tint: #e5efff; }
.key-green { --key: var(--green); --key-t: var(--green-t); --key-tint: #dcf2e9; }
.key-amber { --key: var(--amber); --key-t: var(--amber-t); --key-tint: #fff0d4; }
.key-coral { --key: var(--coral); --key-t: var(--coral-t); --key-tint: #ffe6e0; }

/* Heading block with its character: stacked on a phone, side by side (words
   left, character right) on a laptop. */
.band__top { display: grid; gap: 4px; }
@media (min-width: 1024px) {
  .band__top { grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: 48px; }
  .band__top .band__head { order: -1; }
  .band__top .moment { margin-bottom: 6px; max-width: 470px; }
}

/* ------------------------------------------------------ mascot moments --- */
/* A round window back into the characters' world, and a line in their voice.
   The face files are cut so the whole head (cap, hair and chin) sits inside
   the circle with room to spare: nothing of them is clipped by the ring. */
.moment { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; }
/* Above a section's label, the ring round the face needs more air. (On a
   laptop the How-it-works character stands beside the heading.) */
.split__head .moment { margin-bottom: 22px; }
@media (max-width: 1023px) { .band__top .moment { margin-bottom: 22px; } }
.face {
  width: 112px; height: 112px; flex: none; border-radius: 50%; overflow: hidden; background: var(--wall);
  box-shadow: 0 0 0 4px #fff, 0 0 0 7px var(--key), 0 16px 28px -12px rgba(1,40,60,.55);
}
.face img { width: 100%; height: 100%; object-fit: cover; }
.bubble--moment {
  position: relative; filter: none; box-shadow: none;
  font-size: 16.5px; padding: 12px 16px 13px; max-width: 34ch; background: var(--key-tint);
}
.bubble--moment::after { left: -11px; top: calc(50% - 9px); width: 14px; height: 18px; clip-path: polygon(100% 0, 100% 100%, 0 50%); }
@media (min-width: 700px) {
  .face { width: 136px; height: 136px; }
  .bubble--moment { font-size: 19px; padding: 14px 18px 15px; }
}

/* Scroll reveals, driven by the scroll position itself (no script). Where a
   browser can't do scroll-driven animation, nothing is ever hidden: the
   rule below simply doesn't apply, so content can never get stuck invisible. */
@keyframes reveal-in { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes say-in    { from { opacity: 0; transform: scale(.82); } 60% { opacity: 1; } to { opacity: 1; transform: none; } }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal { animation: reveal-in linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
    .moment .bubble, .bubble--join, .bubble--show { transform-origin: 0 100%;
      animation: say-in linear both; animation-timeline: view(); animation-range: entry 10% entry 100%; }
  }
}

/* ------------------------------------------------------ why it matters --- */
.why { display: grid; gap: 8px; }
.why h2 { margin-bottom: 14px; }
.why__cards { display: grid; gap: 7px; }
.why-card {
  padding: 9px 14px 10px 18px; border-radius: 16px; background: #fff;
  box-shadow: inset 5px 0 0 var(--c), inset 0 0 0 1px var(--line), 0 16px 30px -26px rgba(1,50,80,.45);
}
.why-card h3 { font-size: 16.5px; line-height: 1.25; font-weight: 700; }
.why-card p { margin-top: 2px; font-size: 14.5px; line-height: 1.45; color: var(--ink-2); }
@media (min-width: 1024px) {
  .why { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 72px; align-items: center; }
  .why h2 { margin-bottom: 28px; }
  .why .moment { margin-bottom: 0; }
  .why__cards { gap: 14px; }
  .why-card { padding: 20px 24px 21px 28px; }
  .why-card h3 { font-size: 19px; }
  .why-card p { font-size: 16px; }
}

/* --------------------------------------------------------------- steps --- */
.how { margin-top: 22px; display: grid; gap: 30px; }
.steps { display: grid; gap: 10px; }
/* Phone: number beside the title, so four steps don't turn into a long scroll. */
.step {
  position: relative; padding: 14px 16px 15px; border-radius: var(--radius);
  display: grid; grid-template-columns: 40px 1fr; column-gap: 14px; align-items: center;
  background: #fff; box-shadow: inset 0 0 0 1px var(--line), 0 18px 40px -30px rgba(1,50,80,.35);
}
.step p { grid-column: 2 / -1; }
/* The numbers are the logo's balloon letters: blue H, coral O, green w, amber z. */
.step__num {
  grid-row: span 2; align-self: start;
  display: grid; place-items: center; width: 40px; height: 40px; border-radius: 13px;
  font: 800 21px/1 var(--f-head); color: #fff; background: var(--sc);
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.2), inset 0 2px 0 rgba(255,255,255,.25);
}
.step--h { --sc: var(--blue); }
.step--o { --sc: var(--coral); }
.step--w { --sc: var(--green); }
.step--w .step__num { color: var(--ink); }
.step--z { --sc: var(--amber); }
.step--z .step__num { color: var(--ink); }
.step h3 { font-size: 17.5px; line-height: 1.2; font-weight: 700; }
.step p { margin-top: 3px; color: var(--ink-2); font-size: 14.5px; line-height: 1.45; }
@media (min-width: 700px)  {
  .steps { grid-template-columns: 1fr 1fr; gap: 16px; }
  .step { display: block; padding: 22px 22px 24px; }
  .step__num { width: 46px; height: 46px; font-size: 23px; border-radius: 15px; }
  .step h3 { margin-top: 16px; font-size: 20px; }
  .step p { margin-top: 6px; font-size: 15.5px; }
}
@media (min-width: 1024px) {
  .how { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); column-gap: 56px; align-items: center; margin-top: 44px; }
  /* Step 3 wears the poster tag's green, so the two read as one. */
  .step--w { box-shadow: inset 0 0 0 2px var(--green), 0 18px 40px -30px rgba(1,50,80,.35); }
}

/* ------------------------------------------------------ the A4 poster --- */
/* The printed poster as a school will see it (see poster.php): light paper,
   the logo, the school's name, the QR and three steps. */
.poster-fig { display: grid; justify-items: center; }
/* A phone gets the poster as a thumbnail inside step 3 instead (below). */
@media (max-width: 699px) { .poster-fig { display: none; } }
.mini-poster {
  position: relative; grid-column: 3; grid-row: 1 / span 2; align-self: start; width: 92px; margin: 2px 0 0 4px;
  display: grid; justify-items: center; gap: 3px; padding: 8px 7px 9px; border-radius: 8px;
  background: #fffdf7; color: #0d1828; transform: rotate(3deg);
  box-shadow: 0 0 0 1px rgba(20,35,58,.1), 0 12px 22px -12px rgba(1,40,60,.6);
}
.mini-poster img { width: 64px; height: auto; }
.mini-poster b { font: 600 11px/1 var(--f-voice); }
.mini-poster svg { width: 52px; height: 52px; margin-top: 2px; }
.mini-poster i { position: absolute; right: -12px; top: 58px; transform: rotate(8deg); font: 600 9.5px/1 var(--f-voice); font-style: normal;
  color: #fff; background: var(--coral-t); padding: 4px 5px; border-radius: 6px; }
.step--w { grid-template-columns: 40px 1fr auto; }
.step--w .mini-poster ~ p { grid-column: 2; }
@media (min-width: 700px) { .mini-poster { display: none; } }
.poster {
  position: relative; width: min(300px, 86vw); text-align: center;
  background: #fffdf7; color: #14233a; border-radius: 14px; padding: 26px 20px 18px;
  box-shadow: 0 0 0 1px rgba(20,35,58,.06), 0 30px 60px -28px rgba(1,40,60,.55);
  transform: rotate(-1.5deg);
}
.poster .mock-tag { position: absolute; top: -11px; left: 50%; transform: translateX(-50%); }
.poster__logo { width: 150px; height: auto; margin: 0 auto 8px; }
.poster__eyebrow { font: 800 11.5px/1.2 var(--f-body); color: #3b4a5e; letter-spacing: .06em; text-transform: uppercase; }
.poster__school { font: 600 26px/1.15 var(--f-voice); color: #0d1828; }
.poster__lead { font-size: 12.5px; font-weight: 700; color: #3b4a5e; line-height: 1.45; margin: 6px auto 12px; max-width: 230px; }
.poster__qr { position: relative; width: 124px; margin: 0 auto; padding: 8px; background: #fff; border-radius: 10px; box-shadow: 0 0 0 2px #e6edf2; }
.poster__qr svg { width: 100%; height: auto; }
.poster__sticker {
  position: absolute; right: -40px; top: -12px; transform: rotate(10deg);
  background: var(--coral-t); color: #fff; font: 600 13px/1 var(--f-voice);
  padding: 7px 10px; border-radius: 12px; box-shadow: 0 6px 12px -6px rgba(0,0,0,.5);
}
.poster__steps { display: flex; gap: 8px; margin-top: 14px; font-size: 11px; font-weight: 800; color: #3b4a5e; line-height: 1.25; }
.poster__steps li { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 5px; }
.poster__steps b { display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--blue-t); color: #fff; font-size: 12px; }
.poster-fig figcaption, .split__art figcaption {
  margin-top: 16px; text-align: center; font-size: 13.5px; color: var(--ink-2); max-width: 44ch; margin-inline: auto;
}

/* ------------------------------------------------------ split sections --- */
.split { display: grid; grid-template-areas: "head" "art" "list"; row-gap: 22px; }
.split__head { grid-area: head; }
.split__art  { grid-area: art; }
.split__list { grid-area: list; }
@media (min-width: 1024px) {
  .split { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); grid-template-areas: "head art" "list art";
           grid-template-rows: auto 1fr; column-gap: 64px; row-gap: 34px; align-items: start; }
  .split--flip { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); grid-template-areas: "art head" "art list"; }
  .split__art { align-self: center; }
}

/* Features. Phone: a compact two-column grid of icons with one short line
   each; wider screens get the full sentence (the .more parts). */
.features { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 14px; }
.features li { display: grid; grid-template-columns: 30px 1fr; column-gap: 9px; align-items: center; align-content: start; }
.features li > div { display: contents; }
.features p { grid-column: 1 / -1; }
/* Side by side on a phone, two headings can wrap to different lengths. Each
   item borrows its row's tracks (subgrid), so both descriptions start on the
   same line. */
@supports (grid-template-rows: subgrid) {
  @media (max-width: 699px) {
    .features li { grid-row: span 2; grid-template-rows: subgrid; row-gap: 4px; }
    .features p { margin-top: 0; align-self: start; }
  }
}
.feat__ic {
  width: 30px; height: 30px; padding: 6px; border-radius: 9px;
  color: var(--key-t); background: var(--key-tint); stroke-width: 2;
}
.band--mist .feat__ic { background: #fff; box-shadow: inset 0 0 0 1px var(--line); }
.features h3 { font-size: 15px; line-height: 1.2; font-weight: 700; }
.features p { margin-top: 4px; font-size: 13.5px; line-height: 1.4; color: var(--ink-2); }
/* Beside a mock-up on a laptop the column is too narrow for two: one column
   of full sentences reads better than two of three-word lines. */
@media (min-width: 1024px) { .split .features { grid-template-columns: minmax(0, 1fr); gap: 18px; } }
@media (min-width: 700px) {
  .features { gap: 24px 28px; }
  .features li { display: flex; gap: 14px; align-items: flex-start; }
  .features li > div { display: block; }
  .feat__ic { width: 44px; height: 44px; padding: 10px; }
  .features h3 { margin-top: 2px; font-size: 17px; }
  .features p { font-size: 15px; line-height: 1.55; }
}

/* ------------------------------------------ the showcase panels (colour) --- */
/* A panel in the section's logo colour behind each mock-up: it breaks up the
   long run of white and says, at a glance, which part of the page you're in.
   The characters stand beside the learner phone when the panel has room. */
.showcase__panel {
  position: relative; isolation: isolate; container-type: inline-size;
  display: flex; justify-content: center; align-items: flex-end;
  padding: 30px 16px 28px; border-radius: 28px; background: var(--panel);
  box-shadow: 0 30px 60px -36px rgba(1,40,60,.55);
}
/* Depth: a lit top-left, and the logo's smile arc as a big quiet shape. */
.showcase__panel::before {
  content: ''; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background:
    radial-gradient(90% 70% at 18% 0%, rgba(255,255,255,.32), rgba(255,255,255,0) 60%),
    radial-gradient(60% 35% at 50% 100%, rgba(0,0,0,.14), rgba(0,0,0,0) 100%);
}
.showcase__panel::after {
  content: ''; position: absolute; z-index: -1; left: 8%; right: 8%; top: 12%; aspect-ratio: 2 / 1; pointer-events: none;
  border: 26px solid rgba(255,255,255,.16); border-top: 0; border-radius: 0 0 999px 999px;
}
.showcase--green { --panel: var(--green); }
@media (max-width: 479px) { .showcase__panel .phone { zoom: .8; } .showcase__panel { padding: 24px 14px 22px; } }
@media (max-width: 699px) { .showcase--amber figcaption { display: none; } .split__art figcaption { margin-top: 10px; } }
.showcase--amber { --panel: var(--amber); }
@media (min-width: 700px) { .showcase__panel { padding: 40px 32px 36px; } }

.showcase__buddies { display: none; position: relative; flex: none; }
.showcase__img img { width: 100%; height: 100%; object-fit: contain; position: relative; z-index: 1; }
.bubble--show { top: -13%; right: -6%; width: 200px; font-size: 17px; }
/* Beside the phone when both fit: 292px of phone, the rest for them. */
@container (min-width: 508px) {
  .showcase__buddies {
    display: block; margin-left: -6px;
    --bh: clamp(300px, calc((100cqi - 286px) * 1.35), 400px);
    height: var(--bh); width: calc(var(--bh) * .7407);
  }
}

/* ----------------------------------------------------------- the phone --- */
/* Drawn in the learner app's own navy. */
.phone {
  position: relative; z-index: 1; width: min(292px, 100%); flex: none; padding: 10px; border-radius: 44px; background: #0a111c;
  box-shadow: inset 0 0 0 2px #26344a, 0 40px 70px -30px rgba(1,30,50,.7);
}
.phone__screen {
  border-radius: 35px; padding: 12px 14px 12px; color: #fff; overflow: hidden;
  background: radial-gradient(120% 60% at 50% 0%, #1a3050, var(--navy-2) 45%, var(--navy));
  display: flex; flex-direction: column; gap: 12px;
}
.phone__bar { display: flex; justify-content: space-between; align-items: center; font: 700 11px/1 var(--f-head); color: rgba(255,255,255,.8); padding: 2px 6px 0; }
.phone__notch { width: 76px; height: 20px; border-radius: 12px; background: #0a111c; }
.phone__top { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
.phone__hi { font: 600 24px/1.1 var(--f-voice); }
.phone__q { font: 700 15px/1.3 var(--f-body); color: rgba(255,255,255,.88); margin-top: -4px; }
.moods { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.mood {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 8px 0 7px; min-height: 60px;
  border: 0; border-radius: 14px; cursor: pointer; color: #fff; background: rgba(255,255,255,.07);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); font: 800 10.5px/1 var(--f-body);
  transition: transform .15s cubic-bezier(.3,1.6,.5,1), background-color .15s;
}
.mood span { font-size: 22px; line-height: 1; }
.mood:hover { transform: translateY(-2px); background: rgba(255,255,255,.12); }
.mood[aria-pressed="true"] { background: rgba(6,214,160,.2); box-shadow: inset 0 0 0 2px #06d6a0; transform: translateY(-2px); }
.phone__reply { min-height: 40px; font: 700 13.5px/1.4 var(--f-body); color: #06d6a0; }
.phone__reply .is-low { color: #ffd366; }
/* Real helplines, shown with a low answer: links that really call. */
.phone__help { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.phone__help[hidden] { display: none; }
.phone__help a { display: inline-flex; align-items: center; min-height: 32px; padding: 0 8px; border-radius: 10px;
  font: 800 12px/1 var(--f-body); color: var(--ink); background: #ffd366; text-decoration: none; white-space: nowrap; }
.phone__help a:hover { background: #ffe08f; }
.phone__tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tile { border-radius: 16px; padding: 12px 10px; font-size: 11.5px; line-height: 1.3; color: rgba(255,255,255,.78); }
.tile b { display: block; color: #fff; font: 700 13px/1.2 var(--f-head); margin-bottom: 3px; }
.tile--epoch { background: rgba(79,195,247,.12); box-shadow: inset 0 0 0 1px rgba(79,195,247,.45); }
.tile--check { background: rgba(6,214,160,.12); box-shadow: inset 0 0 0 1px rgba(6,214,160,.45); }
.phone__streak { display: flex; justify-content: space-between; padding: 10px 12px; border-radius: 14px;
  background: rgba(255,211,102,.08); box-shadow: inset 0 0 0 1px rgba(255,211,102,.3); font-size: 12px; color: rgba(255,255,255,.82); }
.phone__streak b { color: #ffd366; }
.phone__nav { display: flex; justify-content: space-between; margin-top: 2px; padding: 10px 6px 4px; border-top: 1px solid rgba(255,255,255,.08);
  font: 700 11px/1 var(--f-head); color: rgba(255,255,255,.65); }
.phone__nav .on { color: #06d6a0; }
.phone__nav .sos { color: #fff; background: #d93a3f; padding: 5px 8px; border-radius: 8px; margin-top: -5px; }

/* ------------------------------------------------------- the dashboard --- */
/* The staff app's own navy and chart colours, so it looks like the real thing. */
.dash {
  width: 100%; border-radius: 18px; overflow: hidden; color: #fff; background: var(--navy);
  box-shadow: 0 0 0 1px rgba(13,24,40,.1), 0 40px 80px -40px rgba(60,30,0,.7);
  font-family: var(--f-body);
}
.dash__chrome { display: flex; align-items: center; gap: 7px; padding: 10px 12px; background: var(--navy-2);
  border-bottom: 1px solid rgba(255,255,255,.06); }
.dash__chrome i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,.18); }
.dash__chrome span { margin-left: 6px; font: 700 12px/1 var(--f-head); color: rgba(255,255,255,.75);
  padding: 6px 10px; border-radius: 999px; background: rgba(255,255,255,.06); }
.dash__chrome .mock-tag { margin-left: auto; }
.dash__chrome span { white-space: nowrap; }
/* A narrow phone drops the window dots so the title stays on one line. */
@media (max-width: 379px) { .dash__chrome i { display: none; } .dash__chrome span { margin-left: 0; } }
.dash__body { padding: 12px; display: grid; gap: 10px;
  background: radial-gradient(90% 60% at 80% 0%, rgba(26,58,94,.6), rgba(13,24,40,0) 70%); }
.dash__stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.stat { padding: 10px 4px; text-align: center; border-radius: 12px; background: rgba(255,255,255,.04);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.09); }
.stat b { display: block; font: 600 22px/1 var(--f-voice); }
.stat span { display: block; margin-top: 5px; font: 800 8.5px/1.2 var(--f-body); letter-spacing: .06em; text-transform: uppercase; color: rgba(255,255,255,.78); }
.dash__panels { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.panel { padding: 10px; border-radius: 12px; background: rgba(255,255,255,.035); box-shadow: inset 0 0 0 1px rgba(255,255,255,.08); }
.panel__tag { display: inline-block; font: 800 8.5px/1.1 var(--f-body); letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255,255,255,.82); padding: 5px 8px; border-radius: 999px; box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); }
.panel__tag--coral { color: #ff8a8a; box-shadow: inset 0 0 0 1px rgba(255,138,138,.5); }
.bars { display: flex; align-items: flex-end; gap: 6px; height: 72px; margin-top: 10px; padding-bottom: 16px; }
.bars span { flex: 1; height: calc(var(--v) * 100%); border-radius: 6px 6px 3px 3px; position: relative;
  background: linear-gradient(to bottom, var(--c), color-mix(in srgb, var(--c) 40%, #0d1828)); }
.bars em { position: absolute; bottom: -15px; left: 0; right: 0; text-align: center; font: 800 9.5px/1 var(--f-body); font-style: normal; color: rgba(255,255,255,.72); }
.spark { display: flex; align-items: flex-end; gap: 3px; height: 72px; margin-top: 10px; padding-bottom: 16px; }
.spark span { flex: 1; height: calc(var(--v) * 100%); border-radius: 3px 3px 2px 2px;
  background: linear-gradient(to bottom, #06d6a0, #0a7f6a); }
.panel--list { display: grid; gap: 10px; }
.who { display: flex; align-items: center; gap: 10px; }
.who p { flex: 1; font-size: 12.5px; color: rgba(255,255,255,.78); line-height: 1.25; }
.who b { color: #fff; font-weight: 800; }
.who small { display: block; color: #ffb74d; font-size: 11.5px; font-weight: 700; }
.av { width: 32px; height: 32px; flex: none; border-radius: 50%; display: grid; place-items: center;
  font: 800 11.5px/1 var(--f-body); background: #06d6a0; color: #06222d; }
.chip { font: 800 10.5px/1 var(--f-body); color: #ffb74d; padding: 6px 9px; border-radius: 999px; background: rgba(255,183,77,.12);
  box-shadow: inset 0 0 0 1px rgba(255,183,77,.5); white-space: nowrap; }
@media (min-width: 480px) {
  .dash__chrome { padding: 11px 14px; }
  .dash__body { padding: 14px; gap: 12px; }
  .dash__stats { gap: 10px; }
  .stat { padding: 12px 8px; border-radius: 14px; }
  .stat b { font-size: 26px; }
  .stat span { font-size: 9.5px; }
  .panel { padding: 12px; border-radius: 14px; }
  .panel__tag { font-size: 9.5px; padding: 6px 9px; }
  .bars, .spark { height: 112px; padding-bottom: 18px; }
  .bars { gap: 8px; } .spark { gap: 4px; }
}

/* --------------------------------------------------------------- join ---- */
/* The characters' world again, with a floor to stand on, so they are always
   seen whole (never cut off at the waist by the band's edge). */
.join {
  position: relative; isolation: isolate; overflow: clip; color: #fff; padding: 40px 0 28px;
  background:
    radial-gradient(50% 60% at 50% 88%, rgba(12,112,160,.9), rgba(10,106,152,0) 70%),
    radial-gradient(120% 120% at 50% 0%, var(--wall), var(--wall-edge) 60%, var(--deep));
}
.join__grid { display: grid; gap: 20px; }
.join__copy { text-align: center; max-width: 600px; margin-inline: auto; }
.join h2 { font-size: clamp(30px, 4.4vw, 50px); line-height: 1.05; font-weight: 800; text-wrap: balance; }
.join__copy > p { margin-top: 14px; font-size: 17px; color: rgba(255,255,255,.92); text-wrap: pretty; }
@media (max-width: 559px) { .join__lede, .join .btn--ghost { display: none; } }
.join .cta-row { margin-top: 24px; justify-content: center; }
.join .cta-row .btn { flex: 1 1 220px; }

/* "All you'll need": three things, so nobody starts and then gets stuck. */
.needs { margin-top: 18px; text-align: left; padding: 14px 16px 16px; border-radius: 18px;
  background: rgba(0,24,40,.34); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.needs h3 { font: 800 12.5px/1 var(--f-body); letter-spacing: .14em; text-transform: uppercase; color: #ffd366; }
.needs ul { margin-top: 12px; display: grid; gap: 8px; }
.needs li { display: flex; gap: 12px; align-items: flex-start; font-size: 14.5px; line-height: 1.45; font-weight: 700; color: rgba(255,255,255,.92); }
.needs__ic { width: 20px; height: 20px; color: var(--green-lt); margin-top: 1px; }

.join__stage { display: flex; justify-content: center; padding-top: 26px; }
.join__figure { position: relative; height: 244px; aspect-ratio: 800 / 1080; margin-right: 60px; }
.join__img img { width: 100%; height: 100%; object-fit: contain; position: relative; z-index: 1; }
.bubble--join { left: 56%; top: -12%; width: 168px; }
@media (min-width: 700px) {
  .join { padding-top: 72px; }
  .join__figure { height: 380px; margin-right: 0; }
  .bubble--join { width: 210px; left: 58%; font-size: 17px; }
}
@media (min-width: 1024px) {
  .join { padding: 92px 0 44px; }
  .join__grid { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); align-items: end; gap: 40px; }
  .join__copy { text-align: left; margin: 0 0 40px; }
  .join .cta-row { justify-content: flex-start; }
  .join .cta-row .btn { flex: 0 0 auto; }
  .needs { max-width: 520px; }
  .join__stage { padding-top: 0; justify-content: flex-end; padding-right: 70px; }
  .join__figure { height: 460px; }
  .bubble--join { left: 60%; top: -6%; width: 220px; font-size: 18px; }
}

/* ------------------------------------------------------------ support --- */
.support { padding-block: 32px; }
.support__card {
  display: grid; gap: 16px; padding: 22px 18px 18px 22px; border-radius: 24px; background: #fff;
  box-shadow: inset 0 0 0 1px var(--line), inset 6px 0 0 #ffd366;
}
.support h2 { font-size: clamp(26px, 3.4vw, 36px); }
.support__text p { margin-top: 8px; color: var(--ink-2); font-size: 16.5px; }
.support__lines { display: grid; gap: 8px; }
.line {
  display: flex; gap: 12px; align-items: center;
  padding: 11px 14px; border-radius: 16px; text-decoration: none; background: var(--mist);
  box-shadow: inset 0 0 0 1px var(--line); transition: box-shadow .15s, transform .15s;
}
.line:hover { box-shadow: inset 0 0 0 2px var(--sun); transform: translateY(-1px); }
.line__text { display: block; line-height: 1.25; }
.line__ic { width: 40px; height: 40px; padding: 9px; border-radius: 12px; background: #fff; color: var(--blue-t); }
.line__num { display: block; font: 800 22px/1.15 var(--f-head); letter-spacing: -0.01em; white-space: nowrap; }
.line__label { display: block; font-weight: 800; font-size: 14.5px; }
.line__sub { display: block; font-size: 13px; color: var(--ink-2); font-weight: 600; }
@media (max-width: 699px) {
  .support__text p { font-size: 15.5px; margin-top: 6px; }
  .line { padding: 10px 14px; }
  .line__ic { width: 36px; height: 36px; padding: 8px; }
  .line__num { display: inline; font-size: 20px; margin-right: 8px; }
  .line__label { display: inline-block; }
}
@media (min-width: 700px) { .support__card { padding: 34px 36px 34px 42px; } }
@media (min-width: 1100px) {
  .support { padding-block: 72px; }
  .support__card { grid-template-columns: minmax(0, .8fr) minmax(0, 2fr); align-items: center; gap: 36px; }
  .support__lines { grid-template-columns: repeat(3, 1fr); }
}

/* ------------------------------------------------------------- footer ---- */
.foot { background: var(--navy); color: rgba(255,255,255,.8); padding: 32px 0 68px; font-size: 14px; }
.foot__grid { display: grid; gap: 18px; }
.foot__logo { width: 150px; height: auto; }
@media (min-width: 700px) { .foot { padding: 48px 0 88px; font-size: 14.5px; } .foot__logo { width: 170px; } }
.foot__love { margin-top: 12px; font: 600 16px/1.3 var(--f-voice); color: #fff; }
.foot__brand { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.foot__brand .foot__love { margin-top: 0; }
@media (min-width: 900px) { .foot__brand { display: block; } .foot__brand .foot__love { margin-top: 12px; } }
.foot__text { display: grid; gap: 12px; max-width: 640px; }
@media (max-width: 699px) { .foot__text { font-size: 13.5px; line-height: 1.55; } .greets { font-size: 17.5px; } }
/* Hello in some of Mzansi's languages, once, in the logo's letter colours
   (the blue and indigo lifted a shade so they read on the navy). */
.greets { display: flex; flex-wrap: wrap; gap: 2px 16px; font: 600 19px/1.35 var(--f-voice); }
.greets span:nth-child(5n+1) { color: #2f9bff; }
.greets span:nth-child(5n+2) { color: #ff6a4f; }
.greets span:nth-child(5n+3) { color: #53bc96; }
.greets span:nth-child(5n+4) { color: #fda002; }
.greets span:nth-child(5n+5) { color: #8f97ff; }
.foot__links { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.foot__links a { color: #fff; font-weight: 800; text-underline-offset: 4px; }
.foot__legal { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-weight: 700; color: rgba(255,255,255,.74); }
@media (min-width: 900px) { .foot__grid { grid-template-columns: 1fr 2fr; align-items: start; } .foot__text { justify-self: end; } }

/* A calm, always-there route to help. Dark so it reads on light and dark
   bands. It waits in the wings while the top bar's own link is on screen. */
.help-now {
  position: fixed; left: 14px; bottom: 14px; z-index: 40;
  display: inline-flex; align-items: center; gap: 8px; padding: 11px 16px 11px 13px; border-radius: 999px;
  font: 800 14px/1 var(--f-body); color: #fff; text-decoration: none;
  background: rgba(7,42,65,.94); box-shadow: inset 0 0 0 1px rgba(255,255,255,.22), 0 10px 26px -10px rgba(0,0,0,.5);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: opacity .25s ease, transform .25s ease, visibility .25s;
}
.help-now .ic { width: 17px; height: 17px; color: #ffd366; fill: #ffd366; stroke: none; }
.help-now:hover { background: var(--deep); }
/* Its focus ring is two-tone (yellow, then a dark edge), so it shows on the
   white and mist bands as well as on the dark ones. */
.help-now:focus-visible { outline: 3px solid #ffd366; outline-offset: 0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.22), 0 0 0 5px #072a41, 0 10px 26px -10px rgba(0,0,0,.5); }
.help-now.is-managed:not(.is-shown) { opacity: 0; visibility: hidden; transform: translateY(18px); }
/* Where the browser can tie an animation to the scroll position, CSS does it
   (no script, no scroll handler): hidden at the very top, where the top bar's
   own link is on screen, and in by the time the top bar has scrolled away.
   Elsewhere assets/landing.js switches the pill with a class instead. */
@keyframes help-in { from { opacity: 0; visibility: hidden; transform: translateY(18px); } to { opacity: 1; visibility: visible; transform: none; } }
@keyframes help-in-still { from { opacity: 0; visibility: hidden; } to { opacity: 1; visibility: visible; } }
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .help-now { animation: help-in linear both; animation-timeline: scroll(root); animation-range: 30px 90px; }
  }
}

/* Motion is a nicety. Turned off, everything simply appears where it lives. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
/* ...except that the help pill still steps aside while the top bar's own
   link is on screen. It only fades (nothing moves), so it is kept for
   everyone who asked for less motion too. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: reduce) {
    .help-now { animation: help-in-still linear both !important; animation-timeline: scroll(root) !important;
                animation-range: 30px 90px !important; }
  }
}
