/* =====================================================================
   Let's Talk — public marketing pages (index.php, about.php)

   Loaded after app.css and reuses its tokens, so the marketing site and
   the portal stay recognisably the same product. Everything here is
   additional: nothing in this file is needed by a signed-in student.

   Motion policy: every animation is decorative. app.css already reduces
   all durations to ~0 under prefers-reduced-motion, and landing.js
   reveals all content immediately in that case, so the page is complete
   and readable with no motion at all.
   ===================================================================== */

:root {
  /* Illustration palette — ink, stone and gold, the same family the rest of
     the site is painted in.

     There is no second hue in here on purpose. Gold lives in --brand-*, and
     it is the only colour in a drawing that is allowed to be loud: the
     child's shirt, the star, one speech bubble. Everything the gold is
     standing next to is a warm neutral, which is what makes it read as gold
     rather than as yellow.

     Two neutrals is enough. A third dark tone looked like a mistake rather
     than a decision — at badge size nobody can tell two near-blacks apart. */
  --c-wear:  #26221c;   /* clothing. Lifts in dark mode; see below. */
  --c-stone: #6d6353;   /* the second figure, a speech bubble, a letter block */
  --c-cream: #fff6e2;
  --c-skin:  #f3c8a2;
  --c-hair:  #2a2119;
  --c-blush: #f7a8a0;
  --c-ink:   #241f1a;

  /* Outlines get their own token because they are the one thing that must
     lift in dark mode. Clothing cannot lift as far — it carries white badge
     text — and the labels drawn inside the art must not lift at all, since
     they sit on a white or gold bubble that stays light in both themes.
     One token could not have done all three jobs. */
  --c-line:  #26221c;
}

.landing { background: var(--bg); }

/* Sinhala runs alongside English throughout. Windows and Android both
   ship a Sinhala face, but neither is first in the default stack, and
   Sinhala needs more line height than Latin to stay legible. */
.si {
  font-family: "Noto Sans Sinhala", "Iskoola Pota", "Nirmala UI", var(--font-sans);
  line-height: 1.9;
}

.lede { color: var(--text-muted); font-size: var(--text-lg); max-width: 52ch; }

/* ---------------------------------------------------------------------
   Motion primitives
   --------------------------------------------------------------------- */
@keyframes lt-rise    { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes lt-drift   { 0%, 100% { transform: translate(0, 0) scale(1); } 33% { transform: translate(30px, -24px) scale(1.08); } 66% { transform: translate(-22px, 18px) scale(.95); } }
@keyframes lt-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes lt-words {
  0%,  18%  { transform: translateY(0); }
  23%, 41%  { transform: translateY(-1.3em); }
  46%, 64%  { transform: translateY(-2.6em); }
  69%, 87%  { transform: translateY(-3.9em); }
  92%, 100% { transform: translateY(-5.2em); }
}

/* Scroll reveal. Gated on .lt-anim, which the inline script in the page
   head adds — so if scripting is off the class never appears and every
   section is simply visible. */
.lt-anim .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .65s var(--ease) var(--d, 0ms),
              transform .65s var(--ease) var(--d, 0ms);
  will-change: opacity, transform;
}
.lt-anim .reveal.is-in { opacity: 1; transform: none; }

/* ---------------------------------------------------------------------
   Navigation
   --------------------------------------------------------------------- */
.site-nav {
  position: sticky; top: 0; z-index: 50;
  padding-block: var(--sp-3);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--t-base), box-shadow var(--t-base);
}
.site-nav.is-stuck {
  border-bottom-color: var(--border-soft);
  box-shadow: var(--shadow-sm);
}

.site-logo {
  display: inline-flex; align-items: center; gap: var(--sp-3);
  font-weight: 700; letter-spacing: -0.02em; text-decoration: none;
  color: var(--text);
}

.nav-links { display: none; gap: var(--sp-6); }
.nav-links a {
  position: relative;
  font-size: var(--text-sm); font-weight: 550;
  color: var(--text-muted); text-decoration: none;
  transition: color var(--t-fast);
}
.nav-links a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -6px;
  height: 2px; border-radius: 2px; background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-base);
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::after,
.nav-links a[aria-current]::after { transform: scaleX(1); }
@media (min-width: 860px) { .nav-links { display: flex; } }

/* ---------------------------------------------------------------------
   Hero
   --------------------------------------------------------------------- */
.hero {
  /* overflow is clipped here rather than on .landing: hiding overflow on an
     ancestor of the header would turn it into a scroll container and break
     the sticky navigation. */
  position: relative; isolation: isolate; overflow: hidden;
  padding-block: var(--sp-16) var(--sp-12);
  background:
    radial-gradient(900px 420px at 12% -10%, var(--brand-100), transparent 62%),
    radial-gradient(700px 380px at 92% 0%, var(--brand-50), transparent 58%);
}
.hero-compact { padding-block: var(--sp-12); }

/* Gold over near-black goes khaki long before it goes warm. The light-mode
   values, dropped straight onto a dark page, read as a stain in the corner
   rather than as light — and the top-left gradient and the first orb both
   land in that same corner, so whatever each one does it does twice. Dark
   mode gets roughly a third of the strength. */
:root[data-theme="dark"] .hero {
  background:
    radial-gradient(900px 420px at 12% -10%, #1b1605, transparent 62%),
    radial-gradient(700px 380px at 92% 0%, #141104, transparent 58%);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero {
    background:
      radial-gradient(900px 420px at 12% -10%, #1b1605, transparent 62%),
      radial-gradient(700px 380px at 92% 0%, #141104, transparent 58%);
  }
}

/* Slow-drifting colour blobs behind the hero. */
.hero-orb {
  position: absolute; z-index: -1;
  border-radius: 50%; filter: blur(60px); opacity: .5;
  pointer-events: none;
  animation: lt-drift 22s var(--ease) infinite;
}
.hero-orb-1 { width: 340px; height: 340px; top: -80px; left: -80px;  background: var(--brand-300); }
/* Both blooms are gold. The second is the deeper end of the ramp at a lower
   opacity, so it reads as distance rather than as a second colour. */
.hero-orb-2 { width: 300px; height: 300px; bottom: -110px; right: -60px; background: var(--brand-500); opacity: .16; animation-duration: 28s; animation-direction: reverse; }

/* Half-opacity light gold works on a white page — it is a soft cream wash. On
   a near-black one the same value mixes to khaki, and it lands in the same
   corner as the hero gradient, so the two compound into a stain. At a seventh
   of the strength it goes back to reading as light falling on the page.
   Written twice: once for the toggle, once for the operating-system setting. */
:root[data-theme="dark"] .hero-orb-1 { opacity: .12; }
:root[data-theme="dark"] .hero-orb-2 { opacity: .08; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero-orb-1 { opacity: .12; }
  :root:not([data-theme="light"]) .hero-orb-2 { opacity: .08; }
}

.hero-grid { display: grid; gap: var(--sp-10); align-items: center; }
@media (min-width: 960px) { .hero-grid { grid-template-columns: 1.02fr 0.98fr; gap: var(--sp-12); } }

.eyebrow {
  display: inline-block;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--brand-700); margin-bottom: var(--sp-4);
}
:root[data-theme="dark"] .eyebrow { color: var(--brand-300); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .eyebrow { color: var(--brand-300); }
}
.eyebrow-on-dark { color: var(--brand-300) !important; }

.hero h1 {
  font-size: var(--text-4xl);
  letter-spacing: -0.038em; line-height: 1.06;
  margin-bottom: var(--sp-5);
}

/* Rotating word. The stack slides up one line at a time; the first word
   is repeated at the end so the loop back to the top is invisible. */
.word-rotate {
  display: inline-block; vertical-align: bottom;
  height: 1.3em; line-height: 1.3em; overflow: hidden;
}
.word-rotate-slot { display: block; animation: lt-words 12s var(--ease) infinite; }
.word-rotate-slot > span {
  display: block; height: 1.3em; line-height: 1.3em;
  color: var(--brand-600); white-space: nowrap;
}
:root[data-theme="dark"] .word-rotate-slot > span { color: var(--brand-400); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .word-rotate-slot > span { color: var(--brand-400); }
}
@media (prefers-reduced-motion: reduce) {
  .word-rotate { height: auto; }
  .word-rotate-slot { animation: none; }
  .word-rotate-slot > span:not(:first-child) { display: none; }
}

.hero-lede {
  font-size: var(--text-lg); color: var(--text-muted);
  max-width: 48ch; margin-bottom: var(--sp-8);
}
.hero-actions { gap: var(--sp-3); flex-wrap: wrap; }
@media (max-width: 480px) {
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
}

.hero-trust {
  list-style: none; padding: 0; margin-top: var(--sp-8);
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-6);
  font-size: var(--text-sm); color: var(--text-muted);
}
.hero-trust li { display: flex; align-items: center; gap: var(--sp-2); }
.hero-trust span { color: var(--accent); font-size: 10px; }

.hero-visual { display: flex; justify-content: center; }

/* ---------------------------------------------------------------------
   Talkie in the hero
   ---------------------------------------------------------------------
   The mascot is cut out, so on this page he stands in the page rather than on
   a tile. There is no picture of a background anywhere in here — what is
   behind him is the hero itself, gold blooms and all.

   Three files make him: one JPEG of the cat as a rectangle, and two PNGs whose
   alpha channels are his outline, used as CSS masks. See illustrations.php for
   why. The masks are named here rather than in the markup because a mask is a
   painting instruction, and because the same JPEG has to be able to wear two
   different ones.

   Both layers are the full canvas at the same coordinates, which is what keeps
   the arm attached to the shoulder at every screen width: there is no
   arithmetic to get wrong, the two files were cut from one image and are drawn
   over each other exactly. */
.talkie-stage {
  position: relative;
  width: 100%;
  max-width: 430px;
  aspect-ratio: 580 / 790;
}
@media (max-width: 640px) { .talkie-stage { max-width: 320px; } }

/* A pool of warm light for him to stand in — on the LIGHT theme only. He is a
   cream cat on a near-white page and without this he has almost no edge.
   Not a drop-shadow: a filter is applied before the mask, so the shadow would
   be cut away by the very outline that is meant to cast it.
   On black the same gold mixes to brown and reads as a smudge round him rather
   than as light, which is the same trap the hero orbs above are turned down
   for. There it is simply not drawn: the page is dark, his fur is cream, and he
   already has all the edge he needs. */
.talkie-stage::before {
  content: '';
  position: absolute; inset: -6% -8% -3%;
  border-radius: 50%;
  background: radial-gradient(ellipse at 52% 58%,
              rgba(242, 169, 0, .20), rgba(242, 169, 0, 0) 68%);
  pointer-events: none;
}
:root[data-theme="dark"] .talkie-stage::before { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .talkie-stage::before { display: none; }
}

.talkie-layer {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;  mask-size: 100% 100%;
}
.talkie-body {
  -webkit-mask-image: url(../img/art-talkie-mask.png);
          mask-image: url(../img/art-talkie-mask.png);
}

/* The origin is the wrist, measured off the render itself — 93px across and
   215px down in a 580x790 canvas. It is written as a percentage so it stays on
   the wrist whatever size the picture is drawn at. */
/* Deliberately NOT var(--ease). That curve is cubic-bezier(.4,0,.2,1), which
   leaves fast and arrives slow — right for a panel sliding in, wrong for
   something swinging back and forth, because the arm creeps into each extreme
   and then jumps out of it. A wave is a pendulum: it should slow down at both
   ends and be quickest through the middle, which is what the symmetric
   ease-in-out gives.

   will-change asks for the masked arm to be rasterised once and then simply
   moved, instead of the mask being reapplied on every frame. Without it this is
   the one animation on the page heavy enough to stutter. */
.talkie-arm {
  -webkit-mask-image: url(../img/art-talkie-arm.png);
          mask-image: url(../img/art-talkie-arm.png);
  transform-origin: 16.03% 27.22%;
  animation: lt-wave 6s ease-in-out infinite;
  will-change: transform;
}

/* He waves for about two and a half seconds and then rests, on the same six-
   second cycle as the speech bubbles, so the wave lands with the greeting. A
   mascot that waves without pause for as long as the page is open stops reading
   as a greeting and starts reading as a fault.

   The swings get smaller and slightly slower as they go, the way a real arm
   runs out of momentum, and the last one returns to rest rather than stopping
   dead at an angle. */
@keyframes lt-wave {
  0%,  4%   { transform: rotate(0deg); }
  11%       { transform: rotate(-15deg); }
  18%       { transform: rotate(11deg); }
  25%       { transform: rotate(-12deg); }
  32%       { transform: rotate(8deg); }
  39%       { transform: rotate(-7deg); }
  46%, 100% { transform: rotate(0deg); }
}

/* Three things a beginner can say on day one, appearing one at a time. They sit
   in the empty corners of the canvas — above the raised paw, and to the right
   of the head and shoulder — so none of them ever covers his face. Nothing is
   positioned outside the stage, which is what stops a narrow phone from
   gaining a sideways scrollbar. */
.talkie-say {
  position: absolute;
  padding: var(--sp-2) var(--sp-4);
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  box-shadow: var(--shadow-md);
  font-size: var(--text-sm); font-weight: 600;
  color: var(--text); white-space: nowrap;
  opacity: 0;
  animation: lt-say 6s var(--ease) infinite;
  /* These carry a soft shadow, and a shadow that is scaled has to be redrawn
     rather than just moved. Promoted, like the arm, so it is drawn once. */
  will-change: transform, opacity;
}
.talkie-say::after {
  content: '';
  position: absolute; left: 22px; bottom: -5px;
  width: 9px; height: 9px;
  background: inherit;
  border-right: inherit; border-bottom: inherit;
  transform: rotate(45deg);
}
.talkie-say-1 { top: 0;   left: 0;  animation-delay: 0s; }
.talkie-say-2 { top: 15%; right: 0; animation-delay: 2s; }
.talkie-say-3 { top: 46%; right: 0; animation-delay: 4s; }

/* The second one is the gold one. One in three keeps gold as the accent it is
   meant to be; all three in gold would make the corner louder than the
   headline it sits beside. */
.talkie-say-2 {
  background: var(--brand-400);
  border-color: transparent;
  color: #1a1408;
}

/* The scale range is kept narrow on purpose. A bubble that grows from a tenth
   of its size is a bigger pop, but the text inside is drawn once and stretched,
   so on the way up it arrives blurred and then sharpens — which looks like a
   rendering fault rather than a flourish. From .84 the softening is not
   noticeable and it still reads as popping in. */
@keyframes lt-say {
  0%        { opacity: 0; transform: scale(.84) translateY(8px); }
  5%        { opacity: 1; transform: scale(1.04) translateY(0); }
  9%, 30%   { opacity: 1; transform: scale(1) translateY(0); }
  37%, 100% { opacity: 0; transform: scale(.96) translateY(-8px); }
}

/* app.css cuts every animation to nothing under reduced motion, which for a
   loop that ends invisible would mean the bubbles never appear at all. So they
   are stated here as finished: all three showing, nothing moving. */
@media (prefers-reduced-motion: reduce) {
  .talkie-arm { animation: none; will-change: auto; }
  .talkie-say { animation: none; opacity: 1; transform: none; will-change: auto; }
}

/* Without CSS masking there is no cut-out and no arm to turn — the JPEG is a
   rectangle with cream where the cat is not. Rounded off, that is exactly the
   four pictures further down this page, so the fallback is not a broken hero,
   just a plainer one. */
@supports not ((-webkit-mask-image: none) or (mask-image: none)) {
  .talkie-arm { display: none; }
  .talkie-body { border-radius: 7%; }
  .talkie-say { display: none; }
}

/* ---------------------------------------------------------------------
   Illustrations
   --------------------------------------------------------------------- */
/* Five 3D renders, every one square and laid on the same cream-to-gold wash.
   How big each one gets is decided by the block holding it — .hero-visual,
   .course-art, .teacher-art, .who-art — so all this rule does is the look they
   share.

   The radius is a percentage rather than pixels on purpose. These appear at
   460px in the hero and at 200px on the About page, and a fixed 24px that looks
   right on the big one looks like a rounded button on the small one. A
   percentage keeps the corner in proportion to the picture. */
.art {
  display: block;
  max-width: 100%;
  border-radius: 7%;
  box-shadow: 0 18px 40px -26px rgba(0, 0, 0, .45);
}

/* The wash inside these files is cream, and a cream square is the brightest
   thing on a near-black page by a wide margin — brighter than the gold, which
   is meant to be what the eye lands on. The picture is a flat file and cannot
   answer the theme any other way, so dark mode dims it and pushes a little more
   colour back in to stop the dimming reading as grey.

   Written twice: once for the toggle, once for the operating-system setting. */
:root[data-theme="dark"] .art { filter: brightness(.84) saturate(1.08); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .art { filter: brightness(.84) saturate(1.08); }
}

/* --c-wear and --c-line were mixed for the old drawings and lifted here so
   near-black clothing would not sink into a dark card. The drawings are gone,
   but --c-wear still ends the accent stripe on the .pain cards, so the lift
   stays — without it that stripe fades into the card it sits on. */
:root[data-theme="dark"] { --c-wear: #8a8071; --c-line: #8f8779; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --c-wear: #8a8071; --c-line: #8f8779; }
}

/* ---------------------------------------------------------------------
   Benefit ticker
   --------------------------------------------------------------------- */
.marquee {
  overflow: hidden;
  padding-block: var(--sp-4);
  background: var(--ink-900);
  border-block: 1px solid var(--ink-800);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
:root[data-theme="dark"] .marquee { background: var(--surface); border-color: var(--border-soft); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .marquee { background: var(--surface); border-color: var(--border-soft); }
}
.marquee-track {
  display: flex; align-items: center; gap: var(--sp-5);
  width: max-content;
  animation: lt-marquee 38s linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-item {
  font-size: var(--text-sm); font-weight: 650;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--ink-50); white-space: nowrap;
}
.marquee-sep { color: var(--brand-400); font-size: var(--text-xs); }
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* ---------------------------------------------------------------------
   Sections
   --------------------------------------------------------------------- */
.section { padding-block: var(--sp-16); }
.section-alt { background: var(--surface-2); }

.section-head { max-width: 58ch; margin-bottom: var(--sp-10); }
.section-head-center { margin-inline: auto; text-align: center; }
.section-head h2 {
  font-size: var(--text-3xl); letter-spacing: -0.032em;
  line-height: 1.15; margin-bottom: var(--sp-3);
}
.section-head p { color: var(--text-muted); }

/* ---------------------------------------------------------------------
   Problem cards
   --------------------------------------------------------------------- */
.pain-grid {
  display: grid; gap: var(--sp-4);
  grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .pain-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5); } }
@media (min-width: 1080px) { .pain-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.pain {
  position: relative; overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
  transition: transform var(--t-base), box-shadow var(--t-base), border-color var(--t-base);
}
.pain::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 4px;
  background: linear-gradient(180deg, var(--brand-400), var(--c-wear));
  transform: scaleY(0); transform-origin: top;
  transition: transform var(--t-base);
}
.pain:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--border);
}
.pain:hover::before { transform: scaleY(1); }

.pain-icon {
  display: grid; place-items: center;
  width: 38px; height: 38px; margin-bottom: var(--sp-4);
  border-radius: var(--radius);
  background: var(--brand-100); color: var(--brand-800);
  font-size: var(--text-lg);
}
:root[data-theme="dark"] .pain-icon { background: var(--brand-900); color: var(--brand-200); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .pain-icon { background: var(--brand-900); color: var(--brand-200); }
}
.pain-en { font-weight: 600; line-height: 1.5; }
.pain-si {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px dashed var(--border);
  font-size: var(--text-sm); color: var(--text-muted);
}

.pain-close {
  margin-top: var(--sp-10); text-align: center;
  display: flex; flex-direction: column; gap: var(--sp-1);
  align-items: center;
}
.pain-close .si { font-size: var(--text-lg); font-weight: 600; }

/* ---------------------------------------------------------------------
   Three-month promise
   --------------------------------------------------------------------- */
.promise {
  position: relative; isolation: isolate; overflow: hidden;
  background: var(--ink-950); color: var(--ink-50);
}
:root[data-theme="dark"] .promise { background: #121216; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .promise { background: #121216; }
}
.promise-glow {
  position: absolute; z-index: -1;
  width: 640px; height: 640px; top: -260px; left: 50%;
  margin-left: -320px; border-radius: 50%;
  background: radial-gradient(circle, rgba(242, 169, 0, .28), transparent 62%);
  animation: lt-drift 26s var(--ease) infinite;
}
.promise-inner { max-width: 760px; margin-inline: auto; text-align: center; }
.promise-si { font-size: var(--text-2xl); color: var(--brand-400); font-weight: 700; margin-bottom: var(--sp-2); }
.promise h2 {
  font-size: var(--text-4xl); letter-spacing: -0.038em;
  line-height: 1.08; color: #fff; margin-bottom: var(--sp-5);
}
.hl-guarantee {
  position: relative; white-space: nowrap;
  color: var(--brand-400);
}
.hl-guarantee::after {
  content: ''; position: absolute; left: -2%; right: -2%; bottom: .05em;
  height: .18em; border-radius: var(--radius-full);
  background: var(--brand-500); opacity: .35;
}
.promise-lede { color: var(--ink-200); font-size: var(--text-lg); max-width: 60ch; margin-inline: auto; }

.stat-row {
  display: grid; gap: var(--sp-6);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-top: var(--sp-12);
}
@media (min-width: 860px) { .stat-row { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.stat { text-align: center; }
.stat-value {
  display: block;
  font-size: clamp(2.4rem, 1.9rem + 2.4vw, 3.6rem);
  font-weight: 800; letter-spacing: -0.05em; line-height: 1;
  color: var(--brand-400);
  font-variant-numeric: tabular-nums;
}
.stat-label {
  display: block; margin-top: var(--sp-2);
  font-size: var(--text-sm); color: var(--ink-300);
  max-width: 22ch; margin-inline: auto;
}

.promise-tags {
  list-style: none; padding: 0; margin-top: var(--sp-12);
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3);
}
.promise-tags li {
  padding: var(--sp-2) var(--sp-5);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--radius-full);
  font-size: var(--text-sm); color: var(--ink-100);
  background: rgba(255, 255, 255, .04);
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.promise-tags li:hover { border-color: var(--brand-400); transform: translateY(-2px); }

/* ---------------------------------------------------------------------
   Courses
   --------------------------------------------------------------------- */
.course-grid {
  display: grid; gap: var(--sp-6);
  grid-template-columns: 1fr;
}
@media (min-width: 760px)  { .course-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .course-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.course {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  overflow: hidden;
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.course:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }

.course-art { padding: var(--sp-6) var(--sp-6) 0; }
.course-art .art { width: 100%; max-width: 260px; margin-inline: auto; height: auto; }
.course-art-kids     { background: linear-gradient(180deg, var(--brand-50), transparent); }
.course-art-everyday { background: linear-gradient(180deg, #e6f7f5, transparent); }
.course-art-work     { background: linear-gradient(180deg, #eaeff8, transparent); }
:root[data-theme="dark"] .course-art-kids,
:root[data-theme="dark"] .course-art-everyday,
:root[data-theme="dark"] .course-art-work { background: linear-gradient(180deg, var(--surface-2), transparent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .course-art-kids,
  :root:not([data-theme="light"]) .course-art-everyday,
  :root:not([data-theme="light"]) .course-art-work { background: linear-gradient(180deg, var(--surface-2), transparent); }
}

.course-body { padding: var(--sp-6); display: flex; flex-direction: column; flex: 1; }
.course-tag {
  align-self: flex-start;
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--radius-full);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  color: #fff; margin-bottom: var(--sp-4);
}
/* Three courses, three tones that are actually telling apart at badge size:
   the brand gold for the children's class, warm stone for the general one,
   ink for the professional one. The gold badge takes ink text — white on
   gold is 2.1:1 and unreadable. */
.course-tag-gold  { background: var(--brand-500); color: var(--c-ink); }
.course-tag-stone { background: var(--c-stone); }
.course-tag-ink   { background: var(--c-ink); }
.course h3 { font-size: var(--text-xl); letter-spacing: -0.02em; margin-bottom: var(--sp-3); }
.course-lede { font-size: var(--text-sm); color: var(--text-muted); margin-bottom: var(--sp-5); }

.ticks { list-style: none; padding: 0; display: grid; gap: var(--sp-3); margin-top: auto; }
.ticks li {
  position: relative; padding-left: var(--sp-8);
  font-size: var(--text-sm); line-height: 1.5;
}
.ticks li::before {
  content: '✓'; position: absolute; left: 0; top: 1px;
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--ok-bg); color: var(--ok-fg);
  font-size: 11px; font-weight: 800;
}
.ticks-lg li { font-size: var(--text-base); }

/* ---------------------------------------------------------------------
   What you get
   --------------------------------------------------------------------- */
.gain-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
@media (min-width: 620px)  { .gain-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 960px)  { .gain-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1240px) { .gain-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.gain {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.gain:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.gain-icon {
  display: grid; place-items: center;
  width: 48px; height: 48px; margin-bottom: var(--sp-4);
  border-radius: var(--radius);
  background: linear-gradient(135deg, var(--brand-300), var(--brand-500));
  color: var(--ink-900); font-size: var(--text-xl);
}
.gain h3 { font-size: var(--text-base); margin-bottom: var(--sp-2); }
.gain p { font-size: var(--text-sm); color: var(--text-muted); }

.chip-row {
  list-style: none; padding: 0; margin-top: var(--sp-10);
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-3);
}
.chip-row li {
  padding: var(--sp-2) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  font-size: var(--text-sm); color: var(--text-muted);
  transition: border-color var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.chip-row li:hover { border-color: var(--accent); color: var(--text); transform: translateY(-2px); }

/* ---------------------------------------------------------------------
   Steps
   --------------------------------------------------------------------- */
.steps { list-style: none; padding: 0; display: grid; gap: var(--sp-6); }
@media (min-width: 760px)  { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-8); } }
@media (min-width: 1100px) { .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.step { display: flex; gap: var(--sp-4); align-items: flex-start; }
.step-number {
  flex: 0 0 40px; width: 40px; height: 40px;
  border-radius: var(--radius-full);
  background: var(--ink-900); color: var(--brand-400);
  display: grid; place-items: center;
  font-weight: 800; font-size: var(--text-sm);
  transition: transform var(--t-base);
}
.step:hover .step-number { transform: scale(1.12) rotate(-6deg); }
:root[data-theme="dark"] .step-number { background: var(--brand-500); color: var(--ink-950); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .step-number { background: var(--brand-500); color: var(--ink-950); }
}
.step h3 { font-size: var(--text-base); margin-bottom: var(--sp-2); }
.step p { font-size: var(--text-sm); color: var(--text-muted); }

/* ---------------------------------------------------------------------
   Teacher
   --------------------------------------------------------------------- */
.teacher-grid { display: grid; gap: var(--sp-10); align-items: center; }
@media (min-width: 900px) { .teacher-grid { grid-template-columns: 0.8fr 1.2fr; gap: var(--sp-16); } }
.teacher-grid h2 { font-size: var(--text-3xl); letter-spacing: -0.03em; margin-bottom: var(--sp-3); }

.teacher-art { display: flex; justify-content: center; }
.teacher-art .art { width: 100%; max-width: 300px; height: auto; }
.teacher-art-lg .art { max-width: 340px; }

.cred-list { list-style: none; padding: 0; display: grid; gap: var(--sp-4); margin-top: var(--sp-6); }
.cred-list li {
  display: flex; gap: var(--sp-4); align-items: flex-start;
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  transition: border-color var(--t-fast), transform var(--t-fast);
}
.cred-list li:hover { border-color: var(--accent); transform: translateX(3px); }
.cred-mark { color: var(--accent); font-size: var(--text-lg); line-height: 1.4; }

/* ---------------------------------------------------------------------
   Portal preview
   --------------------------------------------------------------------- */
.portal-grid { display: grid; gap: var(--sp-10); align-items: center; }
@media (min-width: 960px) { .portal-grid { grid-template-columns: 1fr 1fr; gap: var(--sp-16); } }
.portal-grid h2 { font-size: var(--text-3xl); letter-spacing: -0.03em; margin-bottom: var(--sp-3); }

.hero-visual-portal { display: none; }
@media (min-width: 760px) { .hero-visual-portal { display: block; } }

.mock-card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  transform: perspective(1300px) rotateY(-8deg) rotateX(3deg);
  transition: transform .5s var(--ease);
}
.mock-card:hover { transform: perspective(1300px) rotateY(0deg) rotateX(0deg); }
.mock-head {
  display: flex; gap: 6px; padding: var(--sp-4);
  background: var(--surface-2); border-bottom: 1px solid var(--border-soft);
}
.mock-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ink-300); }
.mock-body { padding: var(--sp-6); }
.mock-stat { margin-bottom: var(--sp-6); }
.mock-label {
  display: block; font-size: var(--text-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: .06em; color: var(--text-subtle);
}
.mock-value {
  display: block; font-size: var(--text-3xl); font-weight: 700;
  letter-spacing: -0.03em; margin: var(--sp-1) 0 var(--sp-3);
}
.mock-bar { height: 7px; border-radius: var(--radius-full); background: var(--surface-3); overflow: hidden; }
.mock-bar > span {
  display: block; height: 100%; width: 0; border-radius: inherit;
  background: linear-gradient(90deg, var(--brand-400), var(--brand-500));
  transition: width 1.4s var(--ease);
}
.mock-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) 0; font-size: var(--text-sm);
  border-bottom: 1px solid var(--border-soft);
}
.mock-row:last-child { border-bottom: 0; }
.mock-row-pending { color: var(--text-subtle); }
.mock-tick {
  width: 22px; height: 22px; flex: 0 0 22px;
  border-radius: 50%; display: grid; place-items: center;
  background: var(--ok-bg); color: var(--ok-fg);
  font-weight: 700; font-size: var(--text-xs);
}
.mock-tick-open { background: var(--surface-3); color: var(--text-subtle); }

/* ---------------------------------------------------------------------
   Contact
   --------------------------------------------------------------------- */
.contact-grid { display: grid; gap: var(--sp-10); align-items: start; }
@media (min-width: 900px) { .contact-grid { grid-template-columns: 1.15fr 0.85fr; gap: var(--sp-16); } }
.contact-grid h2 { font-size: var(--text-3xl); letter-spacing: -0.03em; margin-bottom: var(--sp-3); }

.contact-list { display: flex; flex-direction: column; gap: var(--sp-3); }
.contact-item {
  display: flex; align-items: flex-start; gap: var(--sp-4);
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  text-decoration: none; color: var(--text); font-size: var(--text-sm);
  transition: border-color var(--t-fast), transform var(--t-fast);
}
a.contact-item:hover { border-color: var(--accent); transform: translateX(3px); }
.contact-icon {
  width: 36px; height: 36px; flex: 0 0 36px;
  border-radius: var(--radius-sm); display: grid; place-items: center;
  background: var(--surface-3); color: var(--text-muted);
}
.contact-label {
  display: block; font-size: var(--text-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-subtle); margin-bottom: 2px;
}

.cta-card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  padding: var(--sp-8);
  box-shadow: var(--shadow-md);
}
.cta-card h3 { font-size: var(--text-xl); }

/* ---------------------------------------------------------------------
   About page
   --------------------------------------------------------------------- */
.about-hero { display: grid; gap: var(--sp-8); align-items: center; }
@media (min-width: 860px) { .about-hero { grid-template-columns: 0.75fr 1.25fr; gap: var(--sp-12); } }
.about-name { font-size: var(--text-4xl); letter-spacing: -0.04em; line-height: 1.05; margin-bottom: var(--sp-5); }

.qual-grid { grid-template-columns: 1fr; gap: var(--sp-5); }
@media (min-width: 620px)  { .qual-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .qual-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.qual {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--sp-6);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.qual:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.qual-icon {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: var(--sp-4);
  border-radius: var(--radius);
  background: var(--brand-100); color: var(--brand-800); font-size: var(--text-lg);
}
:root[data-theme="dark"] .qual-icon { background: var(--brand-900); color: var(--brand-200); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .qual-icon { background: var(--brand-900); color: var(--brand-200); }
}
.qual h3 { font-size: var(--text-base); line-height: 1.35; margin-bottom: var(--sp-1); }
.qual-place { font-size: var(--text-sm); color: var(--accent); font-weight: 600; margin-bottom: var(--sp-3); }
.qual-body { font-size: var(--text-sm); color: var(--text-muted); }

.prose { max-width: 68ch; margin-inline: auto; }
.prose h2 { font-size: var(--text-3xl); letter-spacing: -0.03em; margin-bottom: var(--sp-6); }
.prose p { margin-bottom: var(--sp-5); color: var(--text-muted); }
.prose .lead-para { font-size: var(--text-lg); color: var(--text); }

.pull-quote {
  margin: var(--sp-8) 0;
  padding: var(--sp-6) var(--sp-8);
  border-left: 4px solid var(--accent);
  background: var(--surface);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}
.pull-quote .si { font-size: var(--text-xl); font-weight: 600; color: var(--text); margin-bottom: var(--sp-2); }
.pull-quote p:last-child { margin-bottom: 0; }

.who-grid { grid-template-columns: 1fr; gap: var(--sp-6); }
@media (min-width: 760px) { .who-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.who {
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  padding: var(--sp-6);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.who:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
.who-art .art { width: 100%; max-width: 200px; margin-inline: auto; height: auto; }
.who h3 { font-size: var(--text-lg); margin: var(--sp-4) 0 var(--sp-2); }

.about-cta {
  max-width: 640px; margin-inline: auto; text-align: center;
  padding: var(--sp-12) var(--sp-8);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
}
.about-cta h2 { font-size: var(--text-3xl); letter-spacing: -0.03em; margin-bottom: var(--sp-3); }
.about-cta-actions { justify-content: center; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-8); }
@media (max-width: 480px) {
  .about-cta-actions { flex-direction: column; align-items: stretch; }
  .about-cta-actions .btn { width: 100%; }
}

/* ---------------------------------------------------------------------
   Floating WhatsApp button
   --------------------------------------------------------------------- */
.wa-float {
  position: fixed; z-index: 60;
  right: var(--sp-5); bottom: var(--sp-5);
  width: 54px; height: 54px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: #25d366; color: #fff;
  box-shadow: 0 8px 24px rgba(37, 211, 102, .38);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.wa-float svg { width: 30px; height: 30px; fill: currentColor; }
.wa-float:hover { transform: scale(1.09); box-shadow: 0 12px 30px rgba(37, 211, 102, .5); }
.wa-float::after {
  content: ''; position: absolute; inset: 0;
  border-radius: 50%; border: 2px solid #25d366;
  animation: lt-pulse 2.6s var(--ease) infinite;
}
@keyframes lt-pulse {
  0%   { transform: scale(1);   opacity: .7; }
  100% { transform: scale(1.6); opacity: 0; }
}
@media (max-width: 480px) { .wa-float { width: 50px; height: 50px; right: var(--sp-4); bottom: var(--sp-4); } }

/* ---------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------- */
.site-footer {
  /* The extra bottom padding keeps the last row clear of the floating
     WhatsApp button, which is fixed over the bottom-right corner. */
  padding-block: var(--sp-12) var(--sp-12);
  background: var(--surface);
  border-top: 1px solid var(--border-soft);
}
.footer-col { display: grid; gap: var(--sp-2); align-content: start; }
.footer-grid {
  display: grid; gap: var(--sp-8);
  grid-template-columns: 1fr;
}
@media (min-width: 640px)  { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: var(--sp-10); } }

.footer-heading {
  display: block; font-size: var(--text-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--text-subtle);
}
.footer-slogan { font-weight: 700; color: var(--accent); letter-spacing: -0.01em; }
.site-footer a { color: var(--text-muted); text-decoration: none; }
.site-footer a:hover { color: var(--text); text-decoration: underline; }
.footer-base {
  margin-top: var(--sp-10); padding-top: var(--sp-6);
  /* Right inset so the right-hand tagline never slides under the floating
     WhatsApp button, which sits in the same corner. */
  padding-right: 72px;
  border-top: 1px solid var(--border-soft);
  gap: var(--sp-3); flex-wrap: wrap;
}
