/* ============================================================
   Fluentade — "Two Voices"
   Dreamy iridescent 3D. Dark, luminous, glass.
   ============================================================ */

@font-face{font-family:'Manrope';src:url('../fonts/manrope-wght.woff2') format('woff2');
  font-weight:200 800;font-style:normal;font-display:swap}
@font-face{font-family:'Plex Mono';src:url('../fonts/plex-mono-400.woff2') format('woff2');
  font-weight:400;font-style:normal;font-display:swap}
/* Pretendard, subset to the Hangul this site actually sets (2.0MB -> 126KB).
   The unicode-range keeps English pages from ever fetching it. OFL 1.1,
   licence vendored beside the file. Regenerate the subset with:
     python -m fontTools.subset assets/fonts/pretendard-full.woff2 \
       --text-file=<chars> --flavor=woff2 --output-file=pretendard-ko.woff2 */
@font-face{font-family:'Pretendard';src:url('../fonts/pretendard-ko.woff2') format('woff2');
  font-weight:45 930;font-style:normal;font-display:swap;
  unicode-range:U+1100-11FF,U+3130-318F,U+A960-A97F,U+AC00-D7A3,U+D7B0-D7FF}

:root{
  --green:#8ede7a; --sea:#48a774; --sky:#7bc1ec;
  --grad-light:linear-gradient(115deg,#8ede7a 0%,#5fd0b2 45%,#7bc1ec 100%);

  --bg-0:#04080e;
  --text:#eef6fa;
  --text-2:#cfe0ea;
  --text-3:#a7bfcd;
  --line:rgba(255,255,255,.10);
  --glass:rgba(8,16,26,.55);
  --glass-strong:rgba(7,14,23,.72);

  /* the site's motion curve: it used to leave at four times its average
     speed, which read as a snap. Easing the departure (initial slope 4.1
     down to 1.9) keeps the soft landing but lets things get under way. */
  --ease:cubic-bezier(.34,.66,.22,1);
  --ease-soft:cubic-bezier(.4,.06,.15,1);

  --step-0:1rem;
  --step-1:clamp(1.1rem,1rem + .5vw,1.3rem);
  --step-2:clamp(1.45rem,1.2rem + 1.2vw,2.05rem);
  --step-3:clamp(2rem,1.5rem + 2.4vw,3.3rem);
  --step-4:clamp(2.7rem,1.8rem + 4.6vw,5.4rem);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  /* Manrope leads so Latin keeps its shape; Hangul falls through to the
     first Korean face available, Pretendard preferred where installed */
  font-family:'Manrope','Pretendard','Apple SD Gothic Neo','Malgun Gothic',
    system-ui,-apple-system,sans-serif;
  font-size:var(--step-0);
  line-height:1.7;
  color:var(--text);
  /* A whisper of the palette under the whole scroll, so the dark reads as
     depth rather than flat ink. Blue sits upper-left and green lower-right,
     the sides their orbs take. Deliberately a third of the hero auras'
     strength: enough to feel, weak enough that no panel scrim (.rail::before,
     .hero-inner::before) ever shows itself as a box. */
  background:
    radial-gradient(72% 48% at 14% 14%, rgba(31,149,230,.07), transparent 70%),
    radial-gradient(68% 52% at 86% 78%, rgba(72,167,116,.06), transparent 72%),
    var(--bg-0);
  background-attachment:fixed;
  overflow-x:hidden;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

::selection{background:rgba(142,222,122,.32);color:#f2fff0}

:focus-visible{outline:2px solid var(--sky);outline-offset:3px;border-radius:4px}

/* ---------- atmosphere (lives behind everything, works with & without WebGL) ---------- */

/* One viewport tall, anchored to the top of the page: this is the hero's
   atmosphere, not a layer for the whole scroll. (Fixed would re-draw all
   five auras behind every section and wash the site out.)
   The seam on long pages came from `overflow:hidden` CUTTING the auras at
   the bottom edge, so the fix is to fade the box out instead of clipping
   it: below the fade there is only --bg-0, exactly as before. */
.sky-field{
  position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none;
  background:
    radial-gradient(120% 90% at 50% 0%, #0a1626 0%, #060d18 46%, #04080e 100%);
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 62%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 62%,transparent 100%);
}
.sky-field .aura{
  position:absolute;border-radius:50%;filter:blur(90px);opacity:.5;
}
/* the two hero auras sit under their own orb: blue left, green right,
   the order the eyebrow names them */
.aura-1{width:56vw;height:56vw;min-width:min(480px,88vw);min-height:min(480px,88vw);right:-14vw;top:4vh;
  background:radial-gradient(circle at 40% 40%, rgba(72,167,116,.42), rgba(72,167,116,0) 65%)}
.aura-2{width:52vw;height:52vw;min-width:min(440px,88vw);min-height:min(440px,88vw);left:-12vw;top:14vh;
  background:radial-gradient(circle at 55% 45%, rgba(31,149,230,.36), rgba(31,149,230,0) 65%)}
.aura-3{width:64vw;height:44vw;min-width:min(520px,88vw);min-height:min(380px,88vw);left:8vw;top:38%;
  background:radial-gradient(ellipse at 50% 50%, rgba(123,193,236,.16), rgba(123,193,236,0) 62%)}
.aura-4{width:50vw;height:50vw;min-width:min(420px,88vw);min-height:min(420px,88vw);right:-10vw;top:62%;
  background:radial-gradient(circle at 45% 50%, rgba(142,222,122,.20), rgba(142,222,122,0) 64%)}
.aura-5{width:58vw;height:58vw;min-width:min(460px,88vw);min-height:min(460px,88vw);left:-16vw;top:82%;
  background:radial-gradient(circle at 55% 45%, rgba(31,149,230,.30), rgba(31,149,230,0) 66%)}

.grain{
  position:fixed;inset:0;z-index:4;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px;
}

canvas#scene{
  position:fixed;inset:0;z-index:1;width:100%;height:100%;display:block;
  pointer-events:none;
}
html.mobile-fx canvas#scene{width:100dvw;height:100dvh}
.no-webgl canvas#scene{display:none}

/* CSS fallback orbs — only when WebGL is unavailable */
.gl-fallback{position:absolute;inset:0;z-index:0;pointer-events:none;display:none}
.no-webgl .gl-fallback{display:block}
.gl-fallback .orb{
  position:absolute;width:min(32vw,360px);height:min(32vw,360px);
  border-radius:50%;filter:blur(6px);
}
.gl-fallback .orb-a{
  right:8%;top:32%;filter:blur(6px) brightness(.9);
  background:radial-gradient(circle at 38% 34%, #d6ffc4 0%, #8ede7a 28%, #2d7a52 62%, rgba(20,60,45,0) 74%);
  box-shadow:0 0 140px 40px rgba(142,222,122,.25);
}
.gl-fallback .orb-b{
  left:9%;top:44%;
  background:radial-gradient(circle at 40% 34%, #dff2ff 0%, #7bc1ec 30%, #1c5f9e 64%, rgba(18,50,90,0) 75%);
  box-shadow:0 0 140px 40px rgba(123,193,236,.25);
}
.gl-fallback .wave{
  position:absolute;left:14%;right:14%;top:48%;height:22%;
  background:
    radial-gradient(60% 40% at 30% 55%, rgba(142,222,122,.25), transparent 70%),
    radial-gradient(60% 40% at 70% 45%, rgba(123,193,236,.28), transparent 70%);
  filter:blur(18px);
}

/* ---------- structure ---------- */

.page{position:relative;z-index:2}

.visually-hidden{
  position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
}

.skip-link{
  position:absolute;left:1rem;top:-3.5rem;z-index:50;
  background:var(--glass-strong);color:var(--text);padding:.6rem 1.1rem;border-radius:999px;
  border:1px solid var(--line);text-decoration:none;transition:top .3s var(--ease);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
}
.skip-link:focus-visible{top:1rem}

.wrap{max-width:72rem;margin-inline:auto;padding-inline:clamp(1.25rem,4vw,3rem)}

/* ---------- nav ---------- */

/* the header steps out of the cinema: hidden by JS while the film has
   the screen, back for the reading sections */
.site-nav.nav-hidden{
  opacity:0;transform:translateX(-50%) translateY(-16px);pointer-events:none;
}
.site-nav{
  position:fixed;top:1rem;left:50%;transform:translateX(-50%);z-index:20;
  transition:opacity .45s var(--ease-soft),transform .45s var(--ease-soft);
  width:min(72rem,calc(100% - 2rem));
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.55rem .65rem .55rem 1.1rem;border-radius:999px;
  background:var(--glass);border:1px solid var(--line);
  backdrop-filter:blur(20px) saturate(150%);-webkit-backdrop-filter:blur(20px) saturate(150%);
  box-shadow:0 12px 40px rgba(2,8,16,.45), inset 0 1px 0 rgba(255,255,255,.08);
}
.brand{display:inline-flex;align-items:center;gap:.6rem;text-decoration:none;color:var(--text)}
.brand img{width:30px;height:auto;display:block}
.brand .name{font-weight:600;font-size:1.02rem;letter-spacing:.01em}

.nav-links{display:flex;align-items:center;gap:.25rem;list-style:none;margin:0;padding:0}
.nav-links a{
  color:var(--text-2);text-decoration:none;font-size:.9rem;font-weight:500;
  padding:.45rem .85rem;border-radius:999px;transition:color .25s var(--ease),background .25s var(--ease);
}
.nav-links a:hover{color:var(--text);background:rgba(255,255,255,.07)}
.nav-links a[aria-current="page"]{color:var(--text);background:rgba(255,255,255,.08)}

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  border-radius:999px;text-decoration:none;cursor:pointer;
  font-family:inherit;font-size:.95rem;font-weight:700;letter-spacing:.01em;
  padding:.72rem 1.5rem;border:1px solid transparent;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),background .3s var(--ease);
}
.btn-primary{
  color:#06202b;background:var(--grad-light);
  box-shadow:0 6px 26px rgba(94,196,180,.28), inset 0 1px 0 rgba(255,255,255,.5);
}
.btn-primary:hover{transform:translateY(-2px);box-shadow:0 12px 34px rgba(94,196,180,.4), inset 0 1px 0 rgba(255,255,255,.5)}
.btn-primary:active{transform:translateY(0) scale(.985);box-shadow:0 4px 14px rgba(94,196,180,.24), inset 0 1px 0 rgba(255,255,255,.5)}
.btn-ghost{
  color:var(--text);background:rgba(255,255,255,.06);border-color:var(--line);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
}
.btn-ghost:hover{background:rgba(255,255,255,.11);border-color:rgba(255,255,255,.22);transform:translateY(-2px)}
.btn-ghost:active{transform:translateY(0) scale(.985)}
.nav-cta{padding:.55rem 1.15rem;font-size:.88rem;white-space:nowrap}
/* the pill never wraps: on phones it drops to the shorter label instead */
.nav-cta .cta-brief{display:none}

/* ---------- hero ---------- */

.hero{
  position:relative;min-height:100svh;display:flex;align-items:center;justify-content:center;
  text-align:center;padding-block:8rem 6rem;
  /* A near-transparent cool lift keeps the opening cinematic, while making
     the gate's move into the lesson register as a real tonal step. */
  background:linear-gradient(180deg,rgba(72,112,146,.045),rgba(52,88,116,.025));
  /* the scrim (::before, 118% wide) must not vote on the phone's layout
     viewport. Clip is safe here: nothing sticky lives in the hero. */
  overflow:clip;
}
.hero-inner{position:relative;max-width:48rem;margin-inline:auto;padding-inline:1.25rem}
.hero-inner::before{
  content:"";position:absolute;z-index:-1;
  left:50%;top:50%;transform:translate(-50%,-50%);
  width:118%;height:130%;
  background:radial-gradient(50% 48% at 50% 46%,
    rgba(3,7,12,.82) 0%, rgba(3,7,12,.62) 38%, rgba(3,7,12,.2) 68%, rgba(3,7,12,0) 100%);
  filter:blur(10px);pointer-events:none;
}

.eyebrow{
  display:inline-block;font-size:.76rem;font-weight:700;letter-spacing:.24em;
  text-transform:uppercase;color:var(--sky);margin:0 0 1.4rem;
}
/* the hero kicker stays neutral; only the two PEOPLE wear their colours —
   tutors blue, students green — the site's law, stated before the title */
.hero-inner .eyebrow{color:var(--text-2)}
.hero-inner .eyebrow .ey-t{color:var(--sky)}
.hero-inner .eyebrow .ey-s{color:var(--green)}
h1{
  margin:0 0 1.6rem;font-size:var(--step-4);font-weight:250;line-height:1.07;
  letter-spacing:.015em;text-wrap:balance;
  /* the scrim is small now, so legibility over an orb rides on this instead:
     a tight radius hugs the glyphs rather than darkening the whole hero */
  filter:drop-shadow(0 1px 10px rgba(3,8,14,.92)) drop-shadow(0 0 26px rgba(3,8,14,.55));
}
/* blue to green, left to right: the order the orbs now stand in */
.grad{
  background:linear-gradient(100deg,#bde6fb 4%,#a9edd6 46%,#bff5ac 92%);
  -webkit-background-clip:text;background-clip:text;color:transparent;
  font-weight:350;
}
/* The hero headline is a two-sentence line, much wider than a generic h1 — size it
   to sit inside the gap the orbs leave rather than at the full display scale.
   The cap holds "Progress both can see." on ONE line at desktop widths; below
   ~1060px the middle term takes over and it wraps gracefully. */
.hero h1{
  font-size:clamp(2.5rem,1.6rem + 3.6vw,4.3rem);
  letter-spacing:0;
}
.hero-sub{
  max-width:34rem;margin:0 auto 2.6rem;font-size:var(--step-1);font-weight:400;
  line-height:1.65;color:var(--text-2);text-wrap:pretty;
}
.hero-ctas{display:flex;gap:.9rem;justify-content:center;flex-wrap:wrap}
/* a quiet reassurance under the buttons — the promise in one line */
.hero-fine{
  margin:1.5rem auto 0;font-size:.9rem;color:var(--text-2);
  letter-spacing:.01em;text-wrap:balance;
}

.scroll-hint{
  position:absolute;left:50%;bottom:.75rem;transform:translateX(-50%);
  width:max-content;max-width:calc(100% - 2rem);margin:0;
  display:flex;flex-direction:column;align-items:center;gap:.5rem;
  color:var(--text-3);font-family:'Plex Mono',monospace;font-size:.66rem;
  font-weight:400;line-height:1;letter-spacing:.28em;
  text-transform:uppercase;text-decoration:none;
  transition:opacity .5s var(--ease),color .25s var(--ease),filter .25s var(--ease);
}
.scroll-hint:hover{color:var(--text-2);filter:brightness(1.12)}
.scroll-hint::after{
  content:"";width:1px;height:44px;
  background:linear-gradient(to bottom,rgba(123,193,236,.7),transparent);
  animation:drip 2.6s var(--ease-soft) infinite;
}
@keyframes drip{
  0%{transform:scaleY(0);transform-origin:top}
  45%{transform:scaleY(1);transform-origin:top}
  55%{transform:scaleY(1);transform-origin:bottom}
  100%{transform:scaleY(0);transform-origin:bottom}
}

/* ---------- sections ---------- */

section{position:relative}
.section{padding-block:clamp(5.5rem,12vh,9.5rem)}
#both-sides,#early-access,#faq{scroll-margin-top:6.25rem}

/* ---------- the seam ----------------------------------------------------
   Section 2's edge hides the orbs but does not remove them. Below it their
   light still falls, and the wave between them still runs — as transcription.
   Both sit in the fixed scene layer (z-index 1, behind the page) and are
   clipped to the far side of the seam, so they stay with the orbs as the
   page scrolls past. All four positions are written per frame from the orbs'
   real projected coordinates. */

/* No painted light below the seam. The veil blurs the real scene so hard that
   every shape — orb, filament, particle — smears into pure colour wash. What
   section 2 receives is the scene's actual light, with nothing recognisable
   left in it. Positioned each frame from the seam. */
.seam-veil{
  position:fixed;left:0;top:0;width:100%;height:0;z-index:1;pointer-events:none;
  backdrop-filter:blur(88px) saturate(152%);
  -webkit-backdrop-filter:blur(88px) saturate(152%);
}
/* Where the blur is genuinely unavailable, JS drops DIM_FLOOR to 0.16 in the
   same breath, so the scene below the seam is darkened almost to its light
   instead of smeared into it. Same story, cheaper telling.

   This is a capability fallback only. It was briefly extended to every coarse
   pointer to save frames on phones: it measured ~17% of the frame in the lab
   and made no difference anyone could feel, while the phone visibly lost the
   veil over the orbs and the glass under the pills. Not a trade worth making
   on the device with the smallest screen. Reverted. */
html.no-veil-blur .seam-veil{
  backdrop-filter:none;-webkit-backdrop-filter:none;
  background:linear-gradient(180deg,rgba(4,8,14,.55),rgba(4,8,14,.86));
}
html[data-theme="light"].no-veil-blur .seam-veil{
  background:linear-gradient(180deg,rgba(237,244,245,.55),rgba(237,244,245,.88));
}
/* full-viewport: the bars start on the wave's line but must reach every word */
.seam-wave{position:fixed;left:0;top:0;width:0;height:0;z-index:1;pointer-events:none}
/* The gate: a luminous hairline living on the seam whenever it is on screen,
   with a light-leak bleeding down like light under a door. JS charges its
   brightness while the wave is being born and flares it as you pass through. */
.seam-gate{
  position:fixed;left:0;top:0;width:0;height:2.5px;z-index:1;pointer-events:none;opacity:0;
  border-radius:2px;
  /* the gate is a door, not a voice: plain light end to end. It used to run
     green at 12% and blue at 88%, which was the orbs' old order and read as a
     green stain on the left once they swapped. */
  background:linear-gradient(90deg,
    rgba(234,246,255,0), rgba(234,246,255,.84) 14%, #fff 50%, rgba(234,246,255,.84) 86%,
    rgba(234,246,255,0));
  /* drop-shadow (not box-shadow) so the glow follows the line's own alpha:
     it tapers into nothing at both ends, exactly where the gradient fades,
     instead of stopping in a hard bar */
  filter:
    drop-shadow(0 0 14px rgba(234,246,255,.62))
    drop-shadow(0 0 40px rgba(226,240,255,.32));
}
.seam-gate::after{
  content:"";position:absolute;left:5%;right:5%;top:2px;height:58px;
  background:linear-gradient(180deg, rgba(234,246,255,.16), rgba(234,246,255,0));
  /* the light-leak fades at its ends too, so nothing cuts off square */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 16%,#000 84%,transparent);
}
/* A live 88px backdrop blur is a full-viewport repaint on a phone. The phone
   hard-masks WebGL at the gate and paints only diffuse replacement light below
   it, so the bodies disappear without re-filtering the viewport every frame. */
html.mobile-fx .seam-veil{
  backdrop-filter:none;-webkit-backdrop-filter:none;
  overflow:hidden;
  background:linear-gradient(180deg,rgba(4,8,14,.72),rgba(4,8,14,.94));
  --orb-a-x:25vw;--orb-a-y:20vh;
  --orb-b-x:75vw;--orb-b-y:48vh;
}
html[data-theme="light"].mobile-fx .seam-veil{
  background:linear-gradient(180deg,rgba(237,244,245,.72),rgba(237,244,245,.94));
}
/* Only soft light crosses the phone's gate. The actual WebGL canvas is hard
   masked by JS; these two small radial layers replace the colour wash without
   exposing either orb body or invoking a live backdrop filter. */
html.mobile-fx .seam-veil::before,
html.mobile-fx .seam-veil::after{
  content:"";position:absolute;left:0;top:0;
  width:min(92vw,430px);aspect-ratio:1;border-radius:50%;
  pointer-events:none;will-change:transform;
}
html.mobile-fx .seam-veil::before{
  transform:translate3d(var(--orb-a-x),var(--orb-a-y),0) translate(-50%,-50%);
  background:radial-gradient(circle,
    rgba(123,193,236,.42) 0%,rgba(76,166,224,.20) 34%,rgba(76,166,224,0) 72%);
}
html.mobile-fx .seam-veil::after{
  transform:translate3d(var(--orb-b-x),var(--orb-b-y),0) translate(-50%,-50%);
  background:radial-gradient(circle,
    rgba(142,222,122,.38) 0%,rgba(85,184,109,.18) 36%,rgba(85,184,109,0) 72%);
}
/* Keep the gate on one compositor layer. On phones JS moves this full-width
   strip with a transform; changing top/left/width forced a repaint of its two
   large drop shadows on every touch-scroll frame. */
html.mobile-fx .seam-gate{
  left:0;width:100vw;top:0;
  will-change:transform,opacity;
  contain:layout paint style;
}
.no-webgl .seam-wave,.no-webgl .seam-gate{display:none}

h2{
  margin:0 0 1.2rem;font-size:var(--step-3);font-weight:300;line-height:1.15;
  letter-spacing:.01em;text-wrap:balance;
}
h3{margin:0 0 .7rem;font-size:var(--step-2);font-weight:500;line-height:1.25}
.lede{max-width:38rem;font-size:var(--step-1);color:var(--text-2);line-height:1.68;text-wrap:pretty}
.section-head{max-width:44rem}
.section-head.center{margin-inline:auto;text-align:center}
.section-head.center .lede{margin-inline:auto}

/* glass card */
.glass{
  position:relative;border-radius:24px;
  background:var(--glass);
  border:1px solid var(--line);
  backdrop-filter:blur(22px) saturate(150%);-webkit-backdrop-filter:blur(22px) saturate(150%);
  box-shadow:0 24px 60px rgba(2,8,16,.5), inset 0 1px 0 rgba(255,255,255,.09);
}
/* gradient border light — lit from above, a whisper of green→sky at the base */
@supports ((mask-composite:exclude) or (-webkit-mask-composite:xor)){
  .glass{border-color:rgba(255,255,255,.05)}
  .glass::before{
    content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
    background:linear-gradient(168deg,
      rgba(255,255,255,.30) 0%, rgba(255,255,255,.10) 24%,
      rgba(255,255,255,.045) 50%, rgba(142,222,122,.10) 76%, rgba(123,193,236,.20) 100%);
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;
    mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    mask-composite:exclude;
    pointer-events:none;
  }
}

/* (the old section-head scrims are gone: the display titles carry their
   own weight, and the dimmed halo read as a smudge behind them) */

/* --- the lesson: a pinned film — the bars that crossed the gate become the conversation --- */
.lesson-film{
  position:relative;
  /* Just enough depth after the gate to separate the recording film from the
     hero without turning the boundary into a new painted panel. */
  background:rgba(0,2,6,.085);
}
.lesson-stage{
  min-height:100vh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(1.1rem,2.8vh,2rem);
  padding:clamp(4.5rem,9vh,6.5rem) clamp(1.2rem,4vw,2.5rem) clamp(3rem,7vh,5rem);
}
/* the runway exists only when JS can drive the film; otherwise a plain section */
html.js:not(.lesson-static) .lesson-film{height:600vh}
html.js:not(.lesson-static) .lesson-stage{
  position:sticky;top:0;height:100vh;min-height:0;overflow:hidden;
  justify-content:flex-start;
}
/* The phone film updates these two composite groups continuously. Give the
   compositor stable surfaces and keep the brain's internal layout changes
   from invalidating the rest of the pinned stage. */
html.mobile-fx.js:not(.lesson-static) .brain-core{
  contain:layout style;
  will-change:transform,opacity;
  /* The silhouette already has its violet stroke. Filtering the whole moving
     node forest made every internal node change re-raster a second surface. */
  filter:none;
}
/* the cinema sits right of centre and below the brain's band — first words
   nearest the mouth, so the filing keeps chronology without ever crossing
   standing text. The rail owns the left. The stage adds ~9vh padding above,
   so the first message lands ~40vh — level with the raised bar strip — and
   all five turns end inside the frame. */
html.js:not(.lesson-static) .convo{margin-top:28vh}

/* --- the rail: each act's title at the left hand of the cinema --- */
.lesson-rail{position:relative;z-index:1}
html.js:not(.lesson-static) .lesson-rail{position:absolute;left:clamp(2rem,10vw,11rem);top:36vh;width:min(25.5rem,28vw)}
html.js:not(.lesson-static) .rail{position:absolute;left:0;top:0;width:100%}
.rail-eyebrow{
  display:flex;align-items:center;gap:.6rem;margin:0 0 .9rem;
  font-family:'Plex Mono',monospace;font-size:.7rem;letter-spacing:.16em;
  text-transform:uppercase;color:var(--text-3);
}
.rail-eyebrow::before{
  content:"";width:20px;height:2px;border-radius:2px;
  background:linear-gradient(90deg,var(--green),var(--sky));
}
.rail h2,.rail .rail-h{
  margin:0 0 1rem;font-size:var(--step-3);font-weight:300;line-height:1.12;
}
/* the pattern title is a longer triad — a touch smaller, so each beat
   holds its own line inside the narrow rail. "Surfacing" leads quietly;
   the three findings wear the colours of the streams that deliver them:
   taught = blue to the student, stuck = green it keeps, focus = violet
   to the teacher. */
.rail-2 .rail-h{font-size:calc(var(--step-3)*.86)}
/* the triad may run wider than the rail itself — the brain stands at 56%,
   so there is clear air to borrow; narrow screens simply wrap again */
html.js:not(.lesson-static) .rail-2 .rail-h{width:max-content;max-width:min(30rem,36vw)}
.rail-h .rh-lead{
  display:block;font-size:.56em;font-weight:400;color:var(--text-2);
  letter-spacing:.04em;margin-bottom:.35rem;
}
.rail-h em{font-style:normal;font-weight:500}
.rail-h .rh-t{color:var(--sky)}
.rail-h .rh-s{color:var(--green)}
.rail-h .rh-v{color:#b794f7}
html[data-theme="light"] .rail-h .rh-v{color:#6d4fc4}
/* the beat-breaks are for the film's rail; in the static column the
   title flows like any sentence */
.rail-h br{display:none}
html.js:not(.lesson-static) .rail-h br{display:inline}
/* the rail stands still; its life is this WAVE — the logo's own fluent
   wave over the title, revealing left-to-right with the act's progress
   (JS drives --fill on the rail; the clip follows), so the reader can
   see the next scene coming. */
.rail-wave{
  display:block;width:148px;height:49px;margin-bottom:1rem;
  filter:drop-shadow(0 0 10px rgba(123,193,236,.30));
}
.rail-wave .rw{
  clip-path:inset(0 calc((1 - var(--fill,0)) * 100%) 0 0);
}
/* what was heard, tallied — rows assemble as their evidence plays */
.rail-tally{margin-top:1.35rem;display:flex;flex-direction:column;gap:.55rem;align-items:flex-start}
.tly{
  position:relative;display:flex;align-items:baseline;gap:.55rem;
  font-family:'Plex Mono',monospace;font-size:.78rem;letter-spacing:.03em;
  color:var(--text-2);opacity:0;
}
/* the counts wear amber — the same light as the marks in the bubbles and
   the nodes they become; the pace wears the student's green */
.tly b{font-size:1.08rem;font-weight:600;color:#f0c383}
.tly-wpm b{color:var(--green)}
.tly-sample{font-size:.62rem;color:var(--text-3);letter-spacing:.08em}
.tly-tip{
  position:absolute;left:0;top:calc(100% + 8px);z-index:5;width:max-content;max-width:19rem;
  padding:.5rem .75rem;border-radius:10px;
  font-family:'Manrope',sans-serif;font-size:.78rem;letter-spacing:0;line-height:1.5;
  color:var(--text-2);background:var(--glass-strong);border:1px solid var(--line);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 10px 30px rgba(2,8,16,.5);
  opacity:0;pointer-events:none;transition:opacity .25s var(--ease);
}
.tly:hover .tly-tip,.tly:focus-visible .tly-tip{opacity:1}
html.lesson-static .tly,html:not(.js) .tly{opacity:1;transform:none}
.rail{position:relative}
.rail::before{
  content:"";position:absolute;z-index:-1;inset:-1.8rem -2.4rem;
  background:radial-gradient(ellipse 78% 78% at 42% 50%,
    rgba(3,7,12,.74) 0%, rgba(3,7,12,.5) 48%, rgba(3,7,12,0) 100%);
  filter:blur(9px);pointer-events:none;
}

.convo{position:relative;z-index:1;width:min(41rem,100%);display:flex;flex-direction:column;gap:.95rem}
/* the cinema sits just past the rail — one composition, no dead corridor;
   left-anchored so the rail→dialogue gap stays constant at any width */
@media (min-width:980px){
  html.js:not(.lesson-static) .convo{
    width:min(38rem,52vw);align-self:flex-start;margin-left:clamp(19rem,39vw,46rem);
  }
}
/* act one's eyebrow IS the recording light: the live dot replaces the dash */
.rail-eyebrow-rec::before{content:none}
/* …and it lives at the gate's left hand, not on the rail — JS glues it to
   the ring and reveals it with the ring's own entrance */
.rec-cap{position:absolute;margin:0;opacity:0;white-space:nowrap;transform:translateY(-50%)}
.rec-dot{width:8px;height:8px;border-radius:50%;background:var(--green);box-shadow:0 0 10px rgba(142,222,122,.9);
  animation:rec-breathe 2.4s var(--ease-soft) infinite}
@keyframes rec-breathe{
  0%,100%{opacity:1;box-shadow:0 0 10px rgba(142,222,122,.9)}
  50%{opacity:.45;box-shadow:0 0 3px rgba(142,222,122,.35)}
}
.turn{max-width:86%}
/* the teacher's voice is the blue orb, the LEFT orb, so the teacher sits left
   and the student right under the green, in the order the eyebrow names them.
   No names, no times: the colours speak. */
.turn-t{align-self:flex-start}
.turn-s{align-self:flex-end}
.bubble{
  position:relative;margin:0;padding:.8rem 1.15rem;border-radius:18px;
  font-size:clamp(1rem,.94rem + .35vw,1.18rem);line-height:1.62;color:var(--text);
  background:rgba(11,26,42,.62);border:1px solid rgba(123,193,236,.28);
  backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
  box-shadow:0 14px 34px rgba(2,8,16,.35);
}
.turn-s .bubble{background:rgba(12,30,18,.58);border-color:rgba(142,222,122,.26)}
/* when JS runs it draws the WHOLE outline (body + tail) as one SVG path, so the
   CSS border must go — otherwise its straight bottom line cuts across the tail's
   mouth. isolation keeps the skin painting behind the text. (No-JS keeps the
   plain border above.) */
html.js .bubble{border:0;isolation:isolate}
/* the balloon's skin is ONE outline: the rounded body and the tail live on a
   single SVG path (JS-built per bubble, since they differ in size), so the
   bottom edge DIPS into the tail and back — a soft-pointed beak like the 💬
   emoji — with no straight border ever cutting across the tail's mouth. The
   rim strokes that whole path; bt-fill fills only the beak below the mouth (the
   body's own glass fills the rest). The skin rides behind the text and fades
   with the melt, exactly as the skin does. */
.bubble-skin{
  position:absolute;left:0;top:0;z-index:-1;overflow:visible;
  pointer-events:none;opacity:calc(1 - var(--melt,0));
}
.bt-rim{fill:none;stroke-width:1;vector-effect:non-scaling-stroke;
  stroke-linejoin:round;stroke-linecap:round}
/* --tail-fill/--tail-rim are driven by the film's melt loop so the tail always
   wears the exact skin the JS gives the body (the cinema forces the body dark
   in both themes); the fallbacks are the resting, themed colours for the static
   view where no JS runs */
.turn-t .bt-fill{fill:var(--tail-fill,rgba(11,26,42,.62))}
.turn-t .bt-rim{stroke:var(--tail-rim,rgba(123,193,236,.28))}
.turn-s .bt-fill{fill:var(--tail-fill,rgba(12,30,18,.58))}
.turn-s .bt-rim{stroke:var(--tail-rim,rgba(142,222,122,.26))}
/* the balloon pops up EMPTY (its bars still standing inside); the words
   arrive a beat later — JS drives --txt per row. Markers fade as one
   piece; their inner words stay at 1 so the fade never doubles. */
html.js:not(.lesson-static) .convo .bubble .w{opacity:var(--txt,1)}
html.js:not(.lesson-static) .convo .bubble :is(.mk-filler,.mk-pause,.mk-slip,.mk-fixed){opacity:var(--txt,1)}
html.js:not(.lesson-static) .convo .bubble :is(.mk-filler,.mk-pause,.mk-slip,.mk-fixed) .w{opacity:1}
/* melted state: the skin is gone, each word floats as a pill of its
   speaker's light (driven by --melt from JS). The two voices must read
   apart at a glance: the teacher's pills go deep azure, the student's
   stay leaf-green, each with its own rim */
.turn-t .bubble .w{border-radius:6px;background:rgba(41,132,208,calc(var(--melt,0)*.34))}
.turn-s .bubble .w{border-radius:6px;background:rgba(108,196,88,calc(var(--melt,0)*.27))}
.bubble :is(.mk-filler,.mk-pause,.mk-slip,.mk-fixed) .w{background:none}
/* what the lesson carried besides its words — amber, like the orange bars */
.mk-filler,.mk-pause{
  font-style:normal;
  background:rgba(232,162,61,.18);color:#f2c184;border-radius:6px;padding:.02em .3em;
}
.mk-slip{
  background:rgba(232,162,61,.14);color:#e9b47c;border-radius:6px;padding:.02em .3em;
  text-decoration:line-through;text-decoration-color:rgba(233,180,124,.75);text-decoration-thickness:1px;
}
.mk-fixed{
  background:linear-gradient(100deg,rgba(142,222,122,.24),rgba(123,193,236,.24));
  border-radius:6px;padding:.02em .28em;font-weight:600;
}
/* --- act two: the brain that takes the lesson in ---
   It condenses low in the stage where the two voices' light pools; the words
   file through a small gate of the same light and become its constellation. */
.brain{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  /* Where the brain stands and how wide it is, declared once. The thought
     chain climbs off its shoulder and the notes sit beside it, so all three
     have to agree; when the notes carried their own copy of the number and the
     brain moved, they slid over the chain and hid it. */
  --brain-x:calc(clamp(1.2rem,4vw,2.5rem) + clamp(19rem,39vw,46rem) + min(38rem,52vw) / 2);
  --brain-w:min(330px,36vw);
}
/* violet: the AI's own colour — a third presence, made from neither voice.
   The silhouette is a real brain (07's path); during the filing it sits low
   with only its crown in the clear band under the last bubble, then rises to
   centre stage for the finale. */
.brain-core{
  /* Over the dialogue's own centre, which is where the words leave from — so
     the flights stay short and even, and the descent stays purely vertical.

     It used to be a flat 56%, but the conversation is a fixed-width column set
     in from the left, so ITS centre moves as the window narrows while 56% did
     not: aligned at 1840px, 99px adrift at 1440, 126px at 1280. This is the
     same three terms .lesson-stage and .convo are built from — the stage's
     padding, the column's offset, half its width — so the two now move
     together at every width by construction rather than by a number that was
     right once. Below 980px the film stacks and the brain re-centres. */
  position:absolute;left:var(--brain-x);top:8vh;
  width:var(--brain-w);aspect-ratio:500/420;
  transform:translateX(-50%);opacity:0;
  filter:drop-shadow(0 0 26px rgba(146,108,230,.22));
}
@media (max-width:979px){.brain{--brain-x:50%}}
/* short windows: the ring would crowd the fold — shrink the brain and lift
   the conversation so all five turns stand fully on stage */
@media (max-height:820px){
  html.js:not(.lesson-static) .convo{margin-top:23vh}
  .brain{--brain-w:min(280px,32vw)}
  .brain-core{top:5vh}
}
/* named only once it settles — up top it would hide behind the nav */
.brain-tag{
  position:absolute;left:50%;top:-9%;transform:translateX(-50%);
  margin:0;padding:.22rem .7rem;border-radius:8px;white-space:nowrap;
  font-family:'Plex Mono',monospace;font-size:.68rem;letter-spacing:.08em;
  color:#c9b0f7;background:rgba(24,16,44,.66);border:1px solid rgba(183,148,247,.4);
  opacity:0;
}
.brain-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.brain-path{
  fill:rgba(16,11,32,.58);
  stroke:rgba(183,148,247,.55);stroke-width:2;vector-effect:non-scaling-stroke;
  stroke-linejoin:round;
  opacity:0;   /* revealed only when the gathered cloud settles */
}
.brain-edges line{
  stroke:rgba(157,123,240,.55);stroke-width:1;vector-effect:non-scaling-stroke;
  opacity:0;
}
/* Phone connections reveal as one network layer. This replaces 74 individual
   opacity writes with one composited group fade. */
html.mobile-fx .brain-edges{opacity:0}
html.mobile-fx .brain-edges line{opacity:1}
/* the brain's mouth: a precise ring on its underside — the thought-bubble
   tail — that tints with the colour of every node passing through it */
.brain-mouth{
  position:absolute;left:51.6%;top:89%;width:30px;height:30px;
  margin:-15px 0 0 -15px;border-radius:50%;opacity:0;
  border:1.5px solid rgba(183,148,247,.65);
  box-shadow:0 0 14px rgba(157,123,240,.35), inset 0 0 8px rgba(157,123,240,.22);
}
.brain-stars{position:absolute;inset:0}
/* nodes: a bright core in a soft halo ring — the 4200 styling */
.brain-star{
  position:absolute;width:6px;height:6px;margin:-3px 0 0 -3px;border-radius:50%;
  opacity:0;transform:scale(.2);
}
.star-dim{width:6px;height:6px}
.star-violet{
  width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  background:#b794f7;
  box-shadow:0 0 0 5px rgba(157,123,240,.16), 0 0 16px 3px rgba(157,123,240,.55);
}
html.mobile-fx .star-violet{box-shadow:0 0 9px 2px rgba(157,123,240,.58)}
/* one-shot rings: violet births and green refreshes announce themselves */
.star-bloom{
  width:22px;height:22px;margin:0;
  background:transparent;border:2px solid;
  transform:translate(-50%,-50%) scale(.35);
  pointer-events:none;
}
html.mobile-fx .star-bloom{box-shadow:none!important}
/* the thought chain: the brain is thinking, comic-balloon style */
.think-dot{
  position:absolute;border-radius:50%;opacity:0;
  background:rgba(157,123,240,.10);border:1px solid rgba(183,148,247,.45);
  box-shadow:0 0 12px rgba(157,123,240,.20);
}
/* a tight chain, climbing from the brain's shoulder straight to the thought */
.td-1{width:8px;height:8px;left:86%;top:12%}
.td-2{width:13px;height:13px;left:93%;top:4%}
.td-3{width:20px;height:20px;left:100%;top:-4%}
/* the thought itself: a left-aligned column at the brain's right hand,
   high enough that the chain lands on its first lines */
.brain-notes{
  /* Clear of the brain's right edge AND of the thought chain climbing past it.
     The gap has to be generous because the brain SCALES UP at the finale —
     about 1.3x — and the chain scales with it, so the largest bubble lands far
     further right than its unscaled 100%+20px suggests. Measured at the beat
     where both are lit: the chain ends at +137px from the silhouette's edge,
     not +20. A 6rem gap leaves it ~14px of air. */
  position:absolute;
  left:calc(var(--brain-x) + var(--brain-w) / 2 + 6rem);top:29vh;
  display:flex;flex-direction:column;align-items:flex-start;gap:.5rem;
  width:min(28rem,32vw);
}
.note{
  margin:0;display:flex;align-items:baseline;gap:.6rem;
  padding:.42rem .95rem;border-radius:999px;
  background:rgba(10,16,28,.68);border:1px solid rgba(255,255,255,.10);
  backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
  box-shadow:0 10px 26px rgba(2,8,16,.35);
  font-size:.88rem;color:var(--text-2);line-height:1.4;
  opacity:0;white-space:nowrap;
}
.nt{
  font-family:'Plex Mono',monospace;font-size:.64rem;letter-spacing:.13em;
  text-transform:uppercase;white-space:nowrap;
}
.nt::before{
  content:"";display:inline-block;width:7px;height:7px;border-radius:50%;
  background:currentColor;margin-right:.5rem;vertical-align:1px;
  box-shadow:0 0 8px currentColor;
}
.nt-b{color:#7bc1ec}
.nt-g{color:#8ede7a}
.nt-e{color:#7aa06d}
.nt-o{color:#e8a23d}
.nt-v{color:#b794f7}
/* Below this the column beside the brain runs off the stage. Anchoring it to
   the right edge instead is no good either — the brain now stands over the
   dialogue, far enough right that a right-anchored column lands on top of it —
   so the notes drop BENEATH the brain, the same shape the phone layout uses.
   Measured: with the wider gap the chain needs, the side-by-side survives to
   ~1500px, where the last pill still ends inside the frame. */
@media (max-width:1500px) and (min-width:701px){
  .brain-notes{
    left:var(--brain-x);right:auto;transform:translateX(-50%);
    top:auto;bottom:1vh;width:auto;max-width:min(34rem,86vw);
    align-items:center;
  }
  .brain-notes{gap:.35rem}
  .note{
    padding:.32rem .72rem;font-size:.78rem;line-height:1.3;
    white-space:normal;border-radius:18px;
  }
  .nt{font-size:.56rem}
}
/* Tablets and narrow laptops still have room for the film's two-column
   composition. Keep the title in a compact left rail and give the dialogue
   the right side instead of stacking both into the same coordinates. */
@media (min-width:701px) and (max-width:979px){
  html.js:not(.lesson-static) .lesson-stage{
    padding-inline:clamp(1.5rem,3.5vw,2rem);
  }
  html.js:not(.lesson-static) .lesson-rail{
    left:clamp(1.5rem,4.5vw,2.75rem);width:min(19rem,31vw);
  }
  html.js:not(.lesson-static) .convo{
    width:min(36rem,61vw);align-self:flex-end;margin-left:0;
  }
  html.js:not(.lesson-static) .turn{max-width:94%}
}
/* Short landscape screens have enough horizontal room for the full film but
   very little vertical room for five wrapped findings. Tighten that column
   so the last note stays inside the stage instead of grazing the fold. */
@media (min-width:701px) and (max-height:520px){
  html.js:not(.lesson-static) .lesson-rail{top:20vh}
  html.js:not(.lesson-static) .convo{margin-top:17vh;gap:.42rem}
  html.js:not(.lesson-static) .turn{max-width:96%}
  html.js:not(.lesson-static) .bubble{
    padding:.48rem .72rem;border-radius:14px;
    font-size:.84rem;line-height:1.32;
  }
  .brain-notes{top:23vh;gap:.3rem}
  .note{padding:.3rem .7rem;font-size:.78rem;line-height:1.3}
  .nt{font-size:.58rem}
}
@media (max-width:700px){
  html.mobile-fx.js:not(.lesson-static) .lesson-film{height:760vh}
  html.mobile-fx.js:not(.lesson-static) .lesson-stage{height:100dvh}
  html.js:not(.lesson-static) .lesson-stage{
    padding:4.5rem 1.15rem 2rem;
  }
  html.js:not(.lesson-static) .lesson-rail{
    left:1.25rem;right:1.25rem;top:6.8rem;width:auto;
  }
  html.js:not(.lesson-static) .rail-wave{
    width:82px;height:28px;margin-bottom:.35rem;
  }
  html.js:not(.lesson-static) .rail h2,
  html.js:not(.lesson-static) .rail .rail-h{
    margin-bottom:.45rem;font-size:clamp(1.55rem,7.4vw,2rem);
  }
  html.js:not(.lesson-static) .rail-2 .rail-h{
    width:auto;max-width:100%;font-size:clamp(1.35rem,6.5vw,1.75rem);
  }
  html.js:not(.lesson-static) .rail-h .rh-lead{margin-bottom:.15rem}
  html.js:not(.lesson-static) .rail-tally{
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:.25rem .7rem;margin-top:.45rem;
  }
  html.js:not(.lesson-static) .tly{gap:.35rem;font-size:.65rem}
  html.js:not(.lesson-static) .tly b{font-size:.86rem}
  html.js:not(.lesson-static) .rec-cap{display:none}
  html.js:not(.lesson-static) .convo{
    width:100%;margin-top:30vh;gap:.5rem;
  }
  html.js:not(.lesson-static) .turn{max-width:92%}
  html.js:not(.lesson-static) .bubble{
    padding:.62rem .82rem;font-size:.93rem;line-height:1.48;
  }
  html.js:not(.lesson-static) .brain-core{
    left:50%;top:12vh;width:min(260px,62vw);
  }
  /* At the finale the brain grows by 34%. Keep its label in the clean gap
     directly above the outline, instead of letting the scaled -9% offset
     climb back through the final line of the mobile heading. */
  html.mobile-fx .brain-tag{top:-1%}
  #both-sides{padding-top:clamp(11rem,25vh,13rem)}
  .note{white-space:normal;text-align:left;border-radius:18px}
  html.mobile-fx .note{
    backdrop-filter:none;-webkit-backdrop-filter:none;
    background:rgba(10,16,28,.88);
  }
  html[data-theme="light"].mobile-fx .note{background:rgba(255,255,255,.96)}
  /* Phones keep the brain's thought visible: the five findings condense into
     a shallow two-column result grid in the clean band below the silhouette.
     It is intentionally much smaller than the desktop pills, and the film
     fades it before the outbound nodes use this lane. */
  html.mobile-fx .brain-notes{
    left:.8rem;right:.8rem;top:auto;bottom:max(.85rem,2vh);width:auto;
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    align-items:stretch;gap:.28rem;
  }
  html.mobile-fx .note{
    min-width:0;padding:.28rem .45rem;gap:.3rem;border-radius:10px;
    font-size:.63rem;line-height:1.25;box-shadow:none;
  }
  html.mobile-fx .nt{
    flex:0 0 auto;font-size:.48rem;letter-spacing:.07em;
  }
  html.mobile-fx .nt::before{
    width:4px;height:4px;margin-right:.25rem;vertical-align:1px;
    box-shadow:0 0 5px currentColor;
  }
  html.mobile-fx .note:last-child{
    grid-column:1 / -1;justify-self:center;
    border-color:rgba(183,148,247,.26);
  }
  /* In the non-animated fallback, the thought still settles under the brain. */
  .brain-notes{left:1rem;right:1rem;top:auto;bottom:8vh;width:auto}
}

/* the film owns these entrances; without it (no JS / static) everything just shows */
html.js:not(.lesson-static) .rail,
html.js:not(.lesson-static) .convo .turn{opacity:0}
/* static pages never reach act two — its title stays out of the flow */
html.lesson-static .rail-2,html:not(.js) .rail-2{display:none}

/* --- both sides --- */
.sides-head{margin-bottom:clamp(2.2rem,5vh,3.6rem)}
.sides-head h2{margin-bottom:0}
.sides{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.2rem,2.6vw,2.2rem)}
.side{padding:clamp(1.6rem,3vw,2.6rem);display:flex;flex-direction:column;gap:.4rem}
.side-tag{
  /* inline-block so the delivery pulse (inline transform) can take hold */
  display:inline-block;
  align-self:flex-start;font-size:.72rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  padding:.35rem .8rem;border-radius:999px;margin-bottom:1.1rem;
}
.side-teacher .side-tag{color:#cfe8fa;background:rgba(123,193,236,.12);border:1px solid rgba(123,193,236,.4)}
.side-student .side-tag{color:#c9f3ba;background:rgba(142,222,122,.12);border:1px solid rgba(142,222,122,.35)}
/* each panel carries a breath of its voice's colour — the colours the film
   taught: teacher blue, student green. The orbs' glows arrive to match. */
.side-teacher{background:radial-gradient(130% 66% at 16% -10%, rgba(123,193,236,.13), rgba(123,193,236,0) 60%), var(--glass)}
.side-student{background:radial-gradient(130% 66% at 84% -10%, rgba(142,222,122,.12), rgba(142,222,122,0) 60%), var(--glass)}
.side p{margin:.2rem 0 1.2rem;color:var(--text-2)}
.side ul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:.85rem}
.side li{
  position:relative;padding-left:1.6rem;color:var(--text-2);font-size:1.06rem;line-height:1.6;
}
.side li::before{
  content:"";position:absolute;left:0;top:.52em;width:9px;height:9px;border-radius:50%;
}
.side-teacher li::before{background:radial-gradient(circle at 35% 35%,#dff2ff,#1f95e6)}
.side-student li::before{background:radial-gradient(circle at 35% 35%,#d6ffc4,#48a774)}
/* the bold lead of each point stands a shade brighter than its body */
.side li b{color:var(--text);font-weight:600}
/* --- the covenant beneath the panels: centered, quiet, and binding ---
   "Teachers" wears the teacher's blue, "AI" the AI's violet — the same
   law every scene has taught. */
.sides-creed{margin:clamp(3.5rem,8vh,6rem) auto 0;max-width:46rem;text-align:center}
.creed-h{margin:0 0 1.1rem;font-size:var(--step-2);font-weight:300;letter-spacing:.01em}
.creed-h .creed-t{color:var(--sky)}
.creed-h .creed-ai{color:#b794f7}
html[data-theme="light"] .creed-h .creed-ai{color:#6d4fc4}
.sides-creed p:not(.creed-h){
  margin:.45rem auto 0;max-width:41rem;
  font-size:1.06rem;color:var(--text-2);line-height:1.7;text-wrap:pretty;
}
/* --- the Word Universe -------------------------------------------------
   A pinned runway: the stage holds the viewport while the scroll scrubs
   the fourteen lessons. The scrubber's track IS the data — one stacked
   bar per lesson (new / given / reused), the hairline thumb the playhead. */

.uni{height:220vh}  /* brisk: the fourteen lessons pass in about a screen of scroll; the bars stay for anyone who wants a specific one */
.uni-stage{
  position:sticky;top:0;height:100vh;
  display:flex;align-items:center;overflow:hidden;
}
.uni-grid{
  display:grid;grid-template-columns:minmax(22rem,.92fr) 1.08fr;
  gap:clamp(22px,3.4vw,56px);align-items:center;width:100%;
  max-width:88rem; /* wider than the page wrap: the copy gets a two-line
                      title, and the plate reaches full size and sits
                      further right, using the empty margin */
  padding-top:2.5rem; /* the pinned stage starts under the fixed header */
}
/* the headline stays large but scales just enough to hold two lines beside
   the plate; the lede steps down one notch */
.uni-copy h2{font-size:clamp(2.4rem,.5rem + 2.5vw,3.05rem)}
.uni-copy .lede{font-size:clamp(1rem,.95rem + .3vw,1.14rem)}

.uni-read{margin-top:1.5rem;min-height:2.4rem}
.uni-stats{display:flex;flex-wrap:wrap;gap:.45rem}
.uni-stat{
  font-family:'Plex Mono',monospace;font-size:.72rem;color:var(--text-3);
  border:1px solid var(--line);border-radius:999px;padding:.26rem .7rem;
  background:rgba(255,255,255,.03);white-space:nowrap;
}
.uni-stat b{font-weight:400}
.uni-stat-new b{color:var(--green)}
.uni-stat-re b{color:#79c6b1}
.uni-stat-fg b{color:#f0c383}

.uni-scrub{position:relative;height:76px;margin-top:1.35rem;margin-bottom:1.25rem;border-bottom:1px solid var(--line)}
.uni-bars{position:absolute;inset:0;display:flex;align-items:flex-end;gap:4px;padding-bottom:1px}
.uni-bar{
  position:relative;
  flex:1;height:100%;display:flex;flex-direction:column;justify-content:flex-end;
  opacity:.34;transition:opacity .4s var(--ease);
}
/* each bar names its lesson, so the chart reads as the course, not decoration */
.uni-bar .b-n{
  position:absolute;left:0;right:0;bottom:-1.15rem;text-align:center;
  font-family:'Plex Mono',monospace;font-size:.62rem;font-weight:400;
  color:var(--text-3);
}
.uni-bar.lit{opacity:1}
.uni-bar i{display:block;border-radius:2px;margin-top:2px}
.uni-bar .b-re{background:rgba(94,196,180,.42)}
.uni-bar .b-new{background:var(--green);box-shadow:0 0 8px rgba(142,222,122,.35)}
.uni-bar .b-st{background:#f0c383;box-shadow:0 0 8px rgba(240,195,131,.4)}
.uni-scrub input[type=range]{
  position:absolute;inset:0;width:100%;height:100%;margin:0;
  -webkit-appearance:none;appearance:none;background:transparent;cursor:ew-resize;
}
.uni-scrub input[type=range]::-webkit-slider-runnable-track{background:transparent;height:100%}
.uni-scrub input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:3px;height:76px;border-radius:2px;border:none;
  background:linear-gradient(180deg,var(--green),var(--sky));
  box-shadow:0 0 12px rgba(123,193,236,.75);
}
.uni-scrub input[type=range]::-moz-range-track{background:transparent;height:76px}
.uni-scrub input[type=range]::-moz-range-thumb{
  width:3px;height:76px;border-radius:2px;border:none;
  background:linear-gradient(180deg,var(--green),var(--sky));
  box-shadow:0 0 12px rgba(123,193,236,.75);
}
/* the visitor's turn: mic + typed line, tucked under the bars */
.uni-mic{margin-top:1.35rem}
.uni-mic-line{display:flex;flex-wrap:wrap;align-items:center;gap:.6rem}
#uni-mic-btn{
  display:inline-flex;align-items:center;gap:.55rem;cursor:pointer;
  font-family:inherit;font-size:.85rem;font-weight:600;color:var(--text);
  padding:.6rem 1.15rem;border-radius:999px;
  background:rgba(255,255,255,.06);border:1px solid var(--line);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  transition:border-color .3s var(--ease),box-shadow .3s var(--ease);
}
#uni-mic-btn:hover{border-color:rgba(142,222,122,.55)}
/* a quiet standing invitation — the page's one interactive promise */
@keyframes mic-invite{
  0%,100%{box-shadow:0 0 0 0 rgba(142,222,122,0)}
  50%{box-shadow:0 0 0 5px rgba(142,222,122,.10),0 0 16px rgba(142,222,122,.20)}
}
#uni-mic-btn:not(.is-listening){animation:mic-invite 4.2s var(--ease-soft) infinite}
#uni-mic-btn.is-listening{
  border-color:var(--green);
  box-shadow:0 0 0 4px rgba(142,222,122,.16), 0 0 18px rgba(142,222,122,.25);
}
#uni-mic-btn .mic-ic{
  width:13px;height:13px;border-radius:3px 3px 6px 6px;
  border:1.6px solid currentColor;position:relative;
}
#uni-mic-btn .mic-ic::after{
  content:"";position:absolute;left:50%;top:100%;width:1.6px;height:4px;
  background:currentColor;transform:translateX(-50%);
}
#uni-typed{display:flex;gap:.45rem;flex:1;min-width:220px}
#uni-typed-input{
  flex:1;min-width:0;font-family:inherit;font-size:.85rem;color:var(--text);
  padding:.6rem .9rem;border-radius:999px;
  background:rgba(8,16,26,.5);border:1px solid var(--line);outline:none;
  transition:border-color .3s var(--ease);
}
#uni-typed-input::placeholder{color:var(--text-3)}
#uni-typed-input:focus{border-color:rgba(123,193,236,.5)}
.uni-light{
  cursor:pointer;font-family:inherit;font-size:.85rem;font-weight:600;color:var(--text);
  padding:.6rem 1rem;border-radius:999px;
  background:rgba(255,255,255,.06);border:1px solid var(--line);
  transition:border-color .3s var(--ease),background .3s var(--ease);
}
.uni-light:hover{border-color:rgba(123,193,236,.5);background:rgba(255,255,255,.09)}
#uni-live{
  margin:.6rem 0 0;min-height:1.3em;
  font-family:'Plex Mono',monospace;font-size:.74rem;color:var(--text-2);
}
#uni-reset{
  margin:.35rem 0 0;padding:0;cursor:pointer;background:none;border:none;
  font-family:'Plex Mono',monospace;font-size:.68rem;color:var(--text-3);
  text-decoration:underline;text-underline-offset:3px;
}
#uni-reset:hover{color:var(--text)}
/* quiet by default; only speaks when the mic is blocked or missing */
.uni-mic-note{
  margin:.6rem 0 0;font-family:'Plex Mono',monospace;font-size:.62rem;
  letter-spacing:.03em;line-height:1.7;color:var(--text-3);
}
.uni-mic-note:empty{display:none}

.uni-plate{
  position:relative;width:100%;max-width:min(84vh,720px);aspect-ratio:1;
  justify-self:end; /* hug the right of its cell on wide screens */
}
.uni-mobile-step{display:none}
#uni-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.uni-labels{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .6s var(--ease)}
.uni-ring-label{
  position:absolute;left:0;top:0;white-space:nowrap;
  font-family:'Plex Mono',monospace;font-size:.66rem;letter-spacing:.06em;
  color:rgba(196,214,228,.72);
}
.uni-v-label{
  position:absolute;left:0;top:0;white-space:nowrap;
  font-family:'Plex Mono',monospace;font-size:.76rem;color:#d9ffc9;
  text-shadow:0 1px 10px rgba(2,8,14,.9);
  opacity:0;transition:opacity .4s var(--ease);
}
.uni-v-label.show{opacity:1}
/* the band window: names the frequency section under the cursor and lists
   the lit words inside it, in order */
.uni-band-win{
  position:absolute;left:0;top:0;z-index:3;pointer-events:none;width:max-content;
  max-width:15rem;padding:.55rem .7rem;border-radius:11px;
  background:rgba(8,17,26,.93);border:1px solid rgba(123,193,236,.28);
  box-shadow:0 12px 30px rgba(2,8,16,.5);
  opacity:0;transition:opacity .2s var(--ease);
}
.uni-band-win.show{opacity:1}
.bw-head{
  margin:0 0 .4rem;font-family:'Plex Mono',monospace;font-size:.62rem;
  letter-spacing:.09em;text-transform:uppercase;color:#9cc7e6;
}
.bw-list{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:.18rem}
.bw-list li{
  display:flex;gap:.5rem;align-items:baseline;
  font-size:.86rem;color:var(--text);
}
.bw-n{font-family:'Plex Mono',monospace;font-size:.72rem;color:var(--text-3);min-width:3.4em;text-align:right;flex:none}
.bw-w{color:#cdeec0}
.bw-x{font-family:'Plex Mono',monospace;font-size:.72rem;color:var(--text-3);margin-left:auto;padding-left:.7rem}
.bw-more{color:var(--text-3);font-size:.72rem;font-style:italic;margin-top:.1rem}
.bw-empty{margin:0;font-size:.8rem;color:var(--text-3);font-style:italic}
/* the order-number badges that ride each lit dot in the hovered band */
.uni-dot-num{
  position:absolute;left:0;top:0;pointer-events:none;transform:translate(-50%,-50%);
  font-family:'Plex Mono',monospace;font-size:.6rem;color:#eafff0;
  text-shadow:0 0 6px rgba(2,10,16,.95),0 1px 3px rgba(2,10,16,.95);
  opacity:0;transition:opacity .22s var(--ease);white-space:nowrap;
}
.uni-dot-num.show{opacity:.95}
html[data-theme="light"] .uni-dot-num{color:#0c3d1c;text-shadow:0 0 6px rgba(244,250,248,.95)}

.uni-fallback{display:none;position:absolute;inset:0;width:100%;height:100%}
.uf-ring circle{stroke:rgba(140,165,185,.35)}
.uf-s{fill:var(--green)}
/* no WebGL (page-level or section-level) → the still map */
.no-webgl #uni-canvas,.uni-nogl #uni-canvas,
.no-webgl .uni-labels,.uni-nogl .uni-labels,
.no-webgl .uni-mic,.uni-nogl .uni-mic{display:none}
.no-webgl .uni-fallback,.uni-nogl .uni-fallback{display:block}
.no-webgl .uni,.uni-nogl.uni{height:auto}
.no-webgl .uni-stage,.uni-nogl .uni-stage{position:static;height:auto;padding-block:clamp(5.5rem,12vh,9.5rem)}
/* no JS at all: the map still stands, the controls (JS-built) bow out */
html:not(.js) .uni{height:auto}
html:not(.js) .uni-stage{position:static;height:auto;padding-block:clamp(5.5rem,12vh,9.5rem)}
html:not(.js) #uni-canvas,html:not(.js) .uni-labels,
html:not(.js) .uni-scrub,html:not(.js) .uni-read,
html:not(.js) .uni-mic{display:none}
html:not(.js) .uni-fallback{display:block}

/* --- languages + early access: the world it understands, the door in ---
   proportions mirror site 06's world section: 1.08fr/.92fr, globe 520 --- */
/* the card stands beside the GLOBE, not beside the headline — centred
   against the left column so it clears the section head */
.access-grid{
  display:grid;grid-template-columns:1.08fr .92fr;
  gap:clamp(26px,4vw,70px);align-items:start;
}
/* the door sits a step LOWER than the headline — the heading opens top-left,
   the card answers below it on the right, never shoulder to shoulder */
.access-col{margin-top:clamp(3rem,11vh,7.5rem)}
@media (max-width:979px){
  .access-grid{grid-template-columns:1fr}
  .globe-stage{margin-inline:auto}
  .access-col{margin-top:0}
}
.globe-stage{
  position:relative;width:100%;max-width:520px;aspect-ratio:1;margin-top:26px;
}
#globe-canvas{width:100%;height:100%;display:block;cursor:grab;touch-action:pan-y}
#globe-canvas:active{cursor:grabbing}
.globe-tip{
  position:absolute;left:0;top:0;transform:translate(-50%,calc(-100% - 14px));
  max-width:min(280px,74vw);padding:.45rem .7rem;border-radius:10px;
  white-space:normal;line-height:1.45;text-align:left;pointer-events:none;
  opacity:0;transition:opacity .18s var(--ease-soft);
  font-family:'Plex Mono',monospace;font-size:.72rem;letter-spacing:.04em;color:var(--text);
  background:rgba(8,16,26,.88);border:1px solid rgba(123,193,236,.30);
  box-shadow:0 8px 22px rgba(2,8,16,.5);
}
.globe-tip .c{display:block;color:var(--text-3);margin-top:.15rem}
/* the door: one card, wearing the two voices' light along its top edge —
   ONE bold line, so the glass's own top highlight stands down here */
.access-card{
  position:relative;overflow:hidden;padding:clamp(22px,2.6vw,36px);
  display:flex;flex-direction:column;gap:1rem;
  /* stand clear of the navy sky behind it — a real, near-solid window lifted
     off the section, not a tint the same colour as the space it floats on */
  background:rgba(18,31,48,.96);
  border-color:rgba(150,186,216,.22);border-top-color:transparent;
  box-shadow:0 34px 80px rgba(2,8,16,.72);
}
.access-card::before{
  content:"";position:absolute;inset:0 0 auto 0;height:5px;
  background:linear-gradient(90deg,var(--green),var(--sky));
  box-shadow:0 0 14px rgba(123,193,236,.45);
  /* the .glass border-light shares this pseudo-element: its ring MASK and
     1px padding cascade in and slice the bar into two hairlines. Stand
     them down — this is one bold line, nothing else. */
  padding:0;border-radius:0;
  -webkit-mask:none;mask:none;
}
.access-h{margin:0;font-size:var(--step-2)}
.access-lede{margin:0;color:var(--text-2);font-size:.95rem;line-height:1.65}
#access-form{display:flex;flex-direction:column;gap:1.1rem}
.role-pills{display:flex;gap:.5rem;flex-wrap:wrap}
.role-pills label{position:relative;cursor:pointer}
.role-pills input{position:absolute;opacity:0;pointer-events:none}
.role-pills span{
  display:inline-block;padding:8px 15px;border-radius:999px;cursor:pointer;
  font-family:'Plex Mono',monospace;font-size:.72rem;letter-spacing:.06em;color:var(--text-2);
  background:rgba(255,255,255,.04);border:1px solid var(--line);
  transition:border-color .2s var(--ease-soft),color .2s var(--ease-soft),background .2s var(--ease-soft);
}
.role-pills input:checked + span{
  color:var(--text);border-color:rgba(142,222,122,.6);
  background:rgba(142,222,122,.13);
}
.role-pills input:focus-visible + span{outline:2px solid var(--sky);outline-offset:2px}
.field{display:flex;flex-direction:column;gap:.45rem}
.field label{
  font-family:'Plex Mono',monospace;font-size:.68rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--text-3);
}
.field .field-opt{text-transform:lowercase;letter-spacing:.06em;opacity:.7}
.field input{
  padding:12px 14px;border-radius:11px;font:inherit;font-size:.9rem;color:var(--text);
  background:rgba(8,16,26,.6);border:1px solid var(--line);
  transition:border-color .2s var(--ease-soft);
}
.field input:focus{outline:none;border-color:rgba(123,193,236,.55)}
.field input::placeholder{color:var(--text-3)}
.language-combobox{position:relative}
.field .language-combobox input{width:100%;padding-right:46px}
.language-toggle{
  position:absolute;z-index:1;inset:1px 1px 1px auto;width:44px;
  display:grid;place-items:center;padding:0;border:0;border-radius:0 10px 10px 0;
  color:var(--text-2);background:transparent;cursor:pointer;
}
.language-toggle span{
  width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;
  border-top:7px solid currentColor;
  transition:transform .2s var(--ease-soft),color .2s var(--ease-soft);
}
.language-toggle:hover{color:var(--text)}
.language-toggle:focus-visible{outline:2px solid var(--sky);outline-offset:1px}
.language-combobox.is-open .language-toggle span{transform:rotate(180deg)}
.language-options{
  position:fixed;z-index:300;min-width:12rem;max-height:240px;
  margin:0;padding:6px;list-style:none;overflow-y:auto;overscroll-behavior:contain;
  color:var(--text);background:rgba(12,22,34,.985);
  border:1px solid rgba(150,186,216,.26);border-radius:12px;
  box-shadow:0 24px 54px rgba(2,8,16,.62),inset 0 1px 0 rgba(255,255,255,.05);
  backdrop-filter:blur(18px) saturate(120%);-webkit-backdrop-filter:blur(18px) saturate(120%);
  scrollbar-width:thin;scrollbar-color:rgba(123,193,236,.42) transparent;
}
.language-options[hidden]{display:none}
.language-option{
  padding:9px 11px;border-radius:8px;font-size:.86rem;line-height:1.25;
  color:var(--text-2);cursor:pointer;
}
.language-option + .language-option{margin-top:2px}
.language-option:hover,.language-option.is-active{
  color:var(--text);background:rgba(123,193,236,.13);
}
.language-option[aria-selected="true"]{
  color:var(--text);background:rgba(142,222,122,.13);
}
.language-option[aria-selected="true"].is-active{
  background:linear-gradient(90deg,rgba(142,222,122,.16),rgba(123,193,236,.16));
}
.language-empty{padding:11px;color:var(--text-3);font-size:.82rem}
.access-submit{
  width:100%;justify-content:center;text-align:center;
  border-radius:13px;padding:14px;font-weight:650;
  box-shadow:0 10px 30px -14px rgba(142,222,122,.7);
  transition:transform .2s var(--ease-soft),box-shadow .2s var(--ease-soft);
}
.access-submit:hover{
  transform:translateY(-1px);
  box-shadow:0 14px 36px -14px rgba(142,222,122,.85);
}
.access-msg{margin:0;font-size:.85rem;min-height:1.2em}
.access-msg.is-error{color:#f2c184}
/* the honest confirmation replaces the form beneath a quiet divider */
.access-done{display:none;margin-top:4px;border-top:1px solid var(--line);padding-top:16px}
.access-card.is-done form{display:none}
.access-card.is-done .access-done{display:block}
.access-done-line{margin:0;font-size:1rem;color:var(--text);line-height:1.6}
.access-done-more{margin:.7rem 0 0;font-size:.88rem;color:var(--text-2);line-height:1.7}
.access-done-more strong{color:var(--green);font-weight:600}

/* ---------- footer ---------- */

/* The footer is a surface, not more page: frosted and lifted off the
   near-black ground, so the site visibly ends somewhere. */
.site-footer{
  /* the same hairline the sub-footer carries, so both edges read alike; the
     tonal ramp below does the softening, the line just marks the boundary */
  position:relative;border-top:1px solid var(--line);isolation:isolate;
  /* one flat band, opaque, so nothing from the page shows through or gradates
     inside it: the hairline is the whole transition */
  background:#0e1b29;
  padding-block:3.6rem 0;
}
/* brand holds the left; the two named groups pin to the right as a pair,
   so the space between them reads as intent rather than as a gap */
.footer-row{
  display:grid;gap:2.6rem clamp(2rem,4vw,3.5rem);
  grid-template-columns:1.25fr 1fr 1.15fr;
  align-items:start;
}
.footer-brand{display:flex;align-items:flex-start;gap:.7rem}
.footer-brand img{width:34px;height:auto;flex:none}
.footer-id{display:flex;flex-direction:column;align-items:flex-start}
.footer-brand .name{font-weight:600}
.footer-brand .tag{display:block;margin-top:.4rem;font-size:.86rem;color:var(--text-3);line-height:1.62}
.footer-brand .tag-2{font-size:.84rem;opacity:.9}
.footer-h{
  margin:0 0 1rem;font-size:.71rem;font-weight:600;line-height:1;
  letter-spacing:.15em;text-transform:uppercase;color:var(--text-3);
}
.footer-links{display:flex;flex-direction:column;gap:.62rem;list-style:none;margin:0;padding:0}
.footer-links a{color:var(--text-2);text-decoration:none;font-size:.89rem;transition:color .25s var(--ease)}
.footer-links a:hover{color:var(--text)}
/* the sub-footer: a full-bleed band a shade deeper than the plane above it,
   so the copyright reads as a closing strip rather than more footer */
.footer-base{
  margin-top:3.2rem;border-top:1px solid var(--line);background:#08131f;
}
.footer-fine{
  margin:0;padding-block:1.35rem 1.5rem;
  font-size:.78rem;color:var(--text-3);text-align:center;text-wrap:pretty;
}

/* ---------- legal documents ---------- */
/* Paperwork, set to be read: one narrow column, numbered sections divided by
   a rule, and the three documents linked to each other at the top. */

.legal-main{padding-block:clamp(7rem,15vh,9.5rem) clamp(4rem,10vh,7rem)}
.legal-hero{max-width:46rem;margin-bottom:clamp(2.6rem,6vh,4rem)}
.legal-hero h1{margin:0 0 .75rem;font-size:var(--step-3);font-weight:300;line-height:1.12}
.legal-updated{margin:0;font-size:.85rem;color:var(--text-3)}
.legal-tabs{display:flex;flex-wrap:wrap;gap:.5rem;list-style:none;margin:1.9rem 0 0;padding:0}
.legal-tabs a{
  display:inline-block;padding:.42rem .9rem;border:1px solid var(--line);border-radius:999px;
  color:var(--text-2);text-decoration:none;font-size:.84rem;
  transition:color .25s var(--ease),border-color .25s var(--ease),background .25s var(--ease);
}
.legal-tabs a:hover{color:var(--text);border-color:rgba(255,255,255,.24)}
.legal-tabs a[aria-current="page"]{color:var(--text);border-color:transparent;background:rgba(255,255,255,.09)}

.legal-doc{max-width:44rem}
.legal-doc h2{
  margin:2.9rem 0 .95rem;padding-top:1.6rem;border-top:1px solid var(--line);
  font-size:var(--step-1);font-weight:500;line-height:1.3;
}
.legal-doc > h2:first-child{margin-top:0;padding-top:0;border-top:0}
.legal-doc h3{margin:1.9rem 0 .55rem;font-size:.97rem;font-weight:600;line-height:1.4;color:var(--text)}
.legal-doc p{margin:0 0 1rem;font-size:.95rem;line-height:1.75;color:var(--text-2);text-wrap:pretty}
.legal-doc ul{margin:0 0 1.15rem;padding-left:1.2rem}
.legal-doc li{margin-bottom:.42rem;font-size:.95rem;line-height:1.7;color:var(--text-2)}
.legal-doc li::marker{color:var(--sea)}
.legal-doc strong{color:var(--text);font-weight:600}
.legal-doc a{color:var(--sky);text-decoration:none;border-bottom:1px solid rgba(123,193,236,.38)}
.legal-doc a:hover{border-bottom-color:currentColor}
.legal-doc .legal-meta{
  margin:0 0 1.15rem;padding:1.05rem 1.25rem;border:1px solid var(--line);border-radius:14px;
  background:var(--glass);list-style:none;
}
.legal-doc .legal-meta li{margin-bottom:.35rem}
.legal-doc .legal-meta li:last-child{margin-bottom:0}

/* ---------- reveals ---------- */

html.js [data-reveal]{opacity:0;transform:translateY(20px);
  transition:opacity .75s var(--ease-soft),transform .75s var(--ease-soft)}
html.js [data-reveal].in{opacity:1;transform:none}

/* ---------- guide page ---------- */

.guide-main{padding-top:9rem}
.guide-hero{position:relative;max-width:46rem;margin-bottom:4rem}
.guide-hero::before{
  content:"";position:absolute;z-index:-1;inset:-2.5rem -3rem -2rem -3rem;
  background:radial-gradient(70% 74% at 32% 46%,
    rgba(3,7,12,.82) 0%, rgba(3,7,12,.6) 46%, rgba(3,7,12,.18) 76%, rgba(3,7,12,0) 100%);
  filter:blur(8px);pointer-events:none;
}
.guide-hero .eyebrow{margin-bottom:1rem}
.guide-hero h1{font-size:var(--step-3);font-weight:300;margin-bottom:1.2rem}
.guide-section{margin-bottom:3.2rem;padding:clamp(1.6rem,3vw,2.6rem)}
.guide-section h2{font-size:var(--step-2);font-weight:500;margin-bottom:1rem}
.guide-section p{color:var(--text-2);max-width:60ch}
.guide-section p strong{color:var(--text)}
.guide-section ul{color:var(--text-2);padding-left:1.2rem;max-width:60ch}
.guide-section li{margin-bottom:.55rem}
.guide-section li::marker{color:var(--sea)}
.guide-section code{
  font-family:'Plex Mono',monospace;font-size:.86em;color:#cfe8fa;
  background:rgba(123,193,236,.1);padding:.1em .4em;border-radius:6px;
}
pre{
  overflow-x:auto;margin:1.4rem 0 .4rem;padding:1.2rem 1.4rem;border-radius:16px;
  background:rgba(3,7,12,.72);border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05);
  font-family:'Plex Mono',monospace;font-size:.8rem;line-height:1.65;color:#c8dcec;
}
.guide-section pre code,pre code{background:none;padding:0;border-radius:0;color:inherit;font-size:1em}
.guide-back{margin:3rem 0 5rem}
.swatches{display:flex;gap:.7rem;flex-wrap:wrap;margin-top:1.2rem}
.swatch{
  display:flex;flex-direction:column;gap:.4rem;align-items:center;
  font-family:'Plex Mono',monospace;font-size:.68rem;color:var(--text-3);
}
.swatch i{display:block;width:58px;height:58px;border-radius:14px;border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.32), inset 0 -10px 18px rgba(4,10,18,.22), 0 6px 16px rgba(2,8,16,.35)}

/* ---------- epilogue: the last word before the footer ---------- */

.epilogue{padding-block:clamp(6rem,14vh,11rem) clamp(6rem,13vh,10rem)}
.epilogue-inner{display:flex;flex-direction:column;align-items:center;text-align:center;gap:2.4rem}
.epi-logo{
  width:clamp(74px,9.5vh,100px);height:auto;overflow:visible;
  filter:drop-shadow(0 0 22px rgba(94,196,180,.35));
}
.epilogue p{
  margin:0;font-size:var(--step-3);font-weight:300;line-height:1.28;
  letter-spacing:.01em;text-wrap:balance;
}
/* the formation plays only where the film can: JS + WebGL + motion.
   Everywhere else the mark and the line simply stand. */
html.js:not(.no-webgl):not(.lesson-static) .epi-b{opacity:0}
html.js:not(.no-webgl):not(.lesson-static) .epi-wave{
  clip-path:inset(-8% 105% -8% -5%);
  transition:clip-path .45s var(--ease);
}
/* formed: the voices are inside and the wave draws through the mark.
   The closing line never waits on any of it: it is the page's own thesis
   and the last thing anyone reads, so it is simply always there — the
   mark performs, the sentence stands. */
html.js:not(.no-webgl):not(.lesson-static) .epilogue.epi-formed .epi-wave{
  clip-path:inset(-8% -5% -8% -5%);
  transition:clip-path 1.05s var(--ease) .15s;
}
@media (max-width:600px){.ep-br{display:none}}

/* ---------- FAQ ---------- */

.section-faq{padding-top:clamp(4rem,9vh,7rem)}
.faq-wrap .section-head{margin-bottom:2.2rem}
.faq-contact{margin:.2rem 0 0;font-size:.9rem;color:var(--text-3)}
.faq-contact a{
  color:var(--text-2);text-decoration:underline;text-underline-offset:3px;
  transition:color .25s var(--ease);
}
.faq-contact a:hover{color:var(--sky)}
.faq-list{max-width:46rem;display:flex;flex-direction:column;gap:.65rem}
.faq-list details{
  border-radius:16px;background:var(--glass);border:1px solid var(--line);
  backdrop-filter:blur(18px) saturate(140%);-webkit-backdrop-filter:blur(18px) saturate(140%);
  transition:border-color .3s var(--ease);overflow:hidden;
}
.faq-list details[open]{border-color:rgba(123,193,236,.26)}
.faq-list summary{
  position:relative;cursor:pointer;list-style:none;
  padding:1.05rem 3rem 1.05rem 1.3rem;font-weight:600;font-size:.97rem;line-height:1.45;
}
.faq-list summary:focus-visible{
  outline:none;border-radius:15px;
  box-shadow:inset 0 0 0 2px var(--sky);
}
.faq-list details[open] summary:focus-visible{border-radius:15px 15px 0 0}
.faq-list summary::-webkit-details-marker{display:none}
.faq-list summary::after{
  content:"+";position:absolute;right:1.15rem;top:50%;transform:translateY(-50%);
  font-weight:300;font-size:1.35rem;color:var(--text-3);
  transition:transform .3s var(--ease),color .3s var(--ease);
}
.faq-list details[open] summary::after{transform:translateY(-50%) rotate(45deg);color:var(--sky)}
.faq-a{
  padding:0 1.3rem 1.3rem;color:var(--text-2);font-size:.92rem;line-height:1.72;
}
.faq-a p{margin:0;max-width:68ch;text-wrap:pretty}
.faq-a p + p,.faq-a p + ul,.faq-a ul + p{margin-top:.8rem}
.faq-a ul{
  margin:.85rem 0 0;padding:0;max-width:68ch;list-style:none;
  display:grid;gap:.7rem;
}
.faq-a li{position:relative;padding-left:1.15rem}
.faq-a li::before{
  content:"";position:absolute;left:0;top:.72em;width:6px;height:6px;border-radius:50%;
  background:linear-gradient(135deg,var(--green),var(--sky));
  box-shadow:0 0 10px rgba(123,193,236,.24);
}
.faq-a strong{color:var(--text);font-weight:650}
/* the answer settles in as the box glides open (faq.js drives the height) */
.faq-list details[open] .faq-a{animation:faq-a-in .42s var(--ease-soft) both}
@keyframes faq-a-in{
  from{opacity:0;transform:translateY(-5px)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){
  .faq-list details[open] .faq-a{animation:none}
}

/* ---------- responsive ---------- */

@media (max-width:900px){
  .sides{grid-template-columns:1fr}
}
@media (max-width:980px){
  .uni{height:auto}
  .uni-stage{position:static;height:auto;overflow:visible;padding-block:clamp(5.5rem,12vh,9.5rem)}
  .uni-grid{grid-template-columns:1fr;gap:2.1rem}
  .uni-plate{max-width:min(88vw,480px)}
  /* The compact map is scrubbed by page scroll. Name that interaction at the
     point where it matters—the map itself—because its full-size range input
     has already scrolled above by the time the plate fills the phone. */
  html.js .uni-mobile-step{
    display:block;position:absolute;left:50%;top:-1.8rem;z-index:4;
    transform:translateX(-50%);margin:0;white-space:nowrap;
    font-family:'Plex Mono',monospace;font-size:.64rem;letter-spacing:.08em;
    text-transform:uppercase;color:var(--text-3);
  }
}
/* short pinned viewports: the copy column tightens so the whole story
   still stands inside one screen */
@media (min-width:981px) and (max-height:860px){
  .uni-copy .lede{font-size:.95rem}
  .uni-read{margin-top:1.05rem;min-height:2.2rem}
  .uni-scrub{height:58px;margin-top:.9rem}
  .uni-scrub input[type=range]::-webkit-slider-thumb{height:58px}
  .uni-scrub input[type=range]::-moz-range-thumb{height:58px}
  .uni-mic{margin-top:.95rem}
}
@media (max-width:720px){
  .nav-links{display:none}
  .site-nav{padding:.5rem .55rem .5rem .9rem}
  .hero{padding-block:7.5rem 5.5rem}
  .hero-sub{font-size:1.02rem}
  .scroll-hint{bottom:1.4rem}
  /* On a phone the footer was eating two-thirds of the screen, so the mark
     and its closing line never shared the view with it. Everything here is
     spacing, nothing is dropped. */
  .footer-row{grid-template-columns:1fr 1fr;gap:1.9rem 1.4rem}
  .footer-brand{grid-column:1 / -1}
  .site-footer{padding-block:3.2rem 0}
  .footer-h{margin-bottom:.8rem}
  .footer-links{gap:.58rem}
  .footer-base{margin-top:2.2rem}
  .footer-fine{padding-block:1.2rem 1.3rem}
  /* the finale keeps its air above, and gives some back below */
  .epilogue{padding-block:clamp(4.5rem,11vh,7rem) clamp(3.4rem,7vh,5rem)}
  .epilogue-inner{gap:1.8rem}
}
/* phones: the whole nav row must fit 390px — tighten the CTA */
@media (max-width:480px){
  .nav-end{gap:.5rem}
  .site-nav .btn-primary{font-size:.78rem;padding:.5rem .85rem}
  .nav-cta .cta-full{display:none}
  .nav-cta .cta-brief{display:inline}
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion:reduce){
  html.js [data-reveal]{opacity:1;transform:none;transition:none}
  .scroll-hint::after{animation:none;transform:none}
  .rec-dot{animation:none}
  #uni-mic-btn:not(.is-listening){animation:none}
  .btn,.nav-links a,.footer-links a{transition:none}
  .btn-primary:hover,.btn-ghost:hover{transform:none}
  .btn-primary:active,.btn-ghost:active{transform:none}
  .uni{height:auto}
  .uni-stage{position:static;height:auto;overflow:visible;padding-block:clamp(5.5rem,12vh,9.5rem)}
  .uni-labels{opacity:1;transition:none}
  .uni-bar{transition:none}
}

/* ============================================================
   LIGHT — morning glass. Not an inversion: the same green→blue
   chroma turned from light into pigment, the night's glass into
   bright frosted paper. The WebGL layers re-dress themselves in
   JS; everything DOM re-dresses here.
   ============================================================ */

.nav-end{display:flex;align-items:center;gap:.5rem}
/* the language switch sits beside the theme switch, same quiet weight */
.lang-toggle{
  /* the switch names the other language in its own script. It borrows a system
     face so an English page never pulls the 126KB Korean webfont for two glyphs */
  font-family:'Manrope','Apple SD Gothic Neo','Malgun Gothic',system-ui,sans-serif;
  display:inline-flex;align-items:center;justify-content:center;
  height:38px;padding:0 .7rem;border-radius:999px;
  font-size:.78rem;font-weight:600;letter-spacing:.02em;
  color:var(--text-2);text-decoration:none;background:rgba(255,255,255,.06);
  transition:color .25s var(--ease),background .25s var(--ease);
}
.lang-toggle:hover{color:var(--text);background:rgba(255,255,255,.12)}
html[data-theme="light"] .lang-toggle{background:rgba(9,38,58,.05)}
html[data-theme="light"] .lang-toggle:hover{background:rgba(9,38,58,.1)}

/* Korean sets differently: never break inside a word, a little more
   leading, and none of the wide Latin tracking */
html[lang="ko"] body{word-break:keep-all;line-height:1.75}
html[lang="ko"] h1,html[lang="ko"] h2,html[lang="ko"] h3,
html[lang="ko"] .rail-h,html[lang="ko"] .epi-text,html[lang="ko"] .creed-h{
  word-break:keep-all;letter-spacing:-.005em;
}
/* Plex Mono carries no Hangul, so the small caps borrow the body face */
html[lang="ko"] .eyebrow,html[lang="ko"] .side-tag,html[lang="ko"] .footer-h,
html[lang="ko"] .scroll-hint{
  font-family:inherit;letter-spacing:.05em;
}
.theme-toggle{
  width:38px;height:38px;border-radius:50%;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:1.05rem;line-height:1;color:var(--text-2);
  background:rgba(255,255,255,.06);border:1px solid var(--line);
  transition:color .25s var(--ease),background .25s var(--ease),transform .4s var(--ease);
}
.theme-toggle:hover{color:var(--text);background:rgba(255,255,255,.12);transform:rotate(40deg)}

html[data-theme="light"]{
  --bg-0:#edf4f5;
  --text:#0d2130;
  --text-2:#294957;
  --text-3:#506e7d;
  --line:rgba(9,38,58,.18);
  --glass:rgba(252,254,255,.82);
  --glass-strong:rgba(255,255,255,.94);
  --green:#237a40;
  --sea:#1e6e54;
  --sky:#2b7fc0;
}
html[data-theme="light"] body{
  background:
    radial-gradient(72% 48% at 14% 14%, rgba(14,108,176,.05), transparent 70%),
    radial-gradient(68% 52% at 86% 78%, rgba(35,122,64,.045), transparent 72%),
    var(--bg-0);
  background-attachment:fixed;
}
/* The tonal step is a dark-mode storytelling device. Paper mode keeps its
   clean, continuous background through the demo. */
html[data-theme="light"] .hero,
html[data-theme="light"] .lesson-film{background:transparent}
html[data-theme="light"] .sky-field{
  background:
    radial-gradient(72% 28% at 18% 33%,rgba(78,178,126,.07),transparent 76%),
    radial-gradient(70% 32% at 90% 13%,rgba(55,145,207,.08),transparent 76%),
    linear-gradient(180deg,#f7fafa 0%,#edf4f5 34%,#e8f0f2 68%,#eef4f5 100%);
}
html[data-theme="light"] .sky-field .aura{opacity:.4}
html[data-theme="light"] .grain{opacity:.022}
html[data-theme="light"] ::selection{background:rgba(35,122,64,.22);color:#08331a}

/* type on paper */
html[data-theme="light"] h1{filter:drop-shadow(0 2px 16px rgba(228,240,244,.9))}
html[data-theme="light"] .grad{
  background:linear-gradient(100deg,#125e9e 4%,#15716a 46%,#1d7a44 92%);
  -webkit-background-clip:text;background-clip:text;
}
html[data-theme="light"] .hero-inner::before{
  background:radial-gradient(56% 52% at 50% 46%,
    rgba(247,250,251,.94) 0%, rgba(244,249,250,.80) 42%, rgba(240,247,248,.34) 72%, rgba(240,246,248,0) 100%);
}
/* the colophon's hero carries the same scrim and needs the same turn: on
   paper it lifts the type off the orbs instead of darkening it into them */
html[data-theme="light"] .guide-hero::before{
  background:radial-gradient(70% 74% at 32% 46%,
    rgba(247,250,251,.94) 0%, rgba(244,249,250,.78) 46%, rgba(240,247,248,.3) 76%, rgba(240,246,248,0) 100%);
}
html[data-theme="light"] .scroll-hint::after{
  background:linear-gradient(to bottom,rgba(14,108,176,.65),transparent);
}
html[data-theme="light"] .tly b{color:#875712}
html[data-theme="light"] .tly-wpm b{color:#237a40}
html[data-theme="light"] .site-footer{box-shadow:none;background:#e3edef}
html[data-theme="light"] .footer-base{background:#d6e4e8}
/* legal pages in daylight */
html[data-theme="light"] .legal-tabs a:hover{border-color:rgba(9,38,58,.3)}
html[data-theme="light"] .legal-tabs a[aria-current="page"]{background:rgba(9,38,58,.07)}
html[data-theme="light"] .legal-doc a{color:#0e6cb0;border-bottom-color:rgba(14,108,176,.36)}
html[data-theme="light"] .legal-doc .legal-meta{
  background:rgba(255,255,255,.72);box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
/* chrome */
html[data-theme="light"] .site-nav{
  background:rgba(252,254,255,.86);
  border-color:rgba(9,38,58,.16);
  backdrop-filter:blur(20px) saturate(112%);-webkit-backdrop-filter:blur(20px) saturate(112%);
  box-shadow:0 12px 34px rgba(30,60,80,.13), inset 0 1px 0 rgba(255,255,255,.9);
}
html[data-theme="light"] .nav-links a:hover{color:var(--text);background:rgba(9,38,58,.06)}
html[data-theme="light"] .theme-toggle{background:rgba(9,38,58,.05)}
html[data-theme="light"] .theme-toggle:hover{background:rgba(9,38,58,.1)}
html[data-theme="light"] .btn-ghost{color:var(--text);background:rgba(9,38,58,.05)}
html[data-theme="light"] .btn-ghost:hover{background:rgba(9,38,58,.09);border-color:rgba(9,38,58,.22)}
html[data-theme="light"] .glass{
  backdrop-filter:blur(20px) saturate(112%);-webkit-backdrop-filter:blur(20px) saturate(112%);
  box-shadow:0 22px 50px rgba(30,60,80,.13), inset 0 1px 0 rgba(255,255,255,.92);
}
/* the CTA window keeps its stand-clear opacity in light too */
html[data-theme="light"] .access-card{
  background:rgba(255,255,255,.94);border-color:rgba(9,38,58,.17);
  box-shadow:0 30px 68px rgba(30,60,80,.17),inset 0 1px 0 #fff;
}
html[data-theme="light"] .glass::before{
  background:linear-gradient(168deg,
    rgba(255,255,255,.9) 0%, rgba(255,255,255,.4) 24%,
    rgba(9,38,58,.06) 50%, rgba(35,122,64,.16) 76%, rgba(14,108,176,.22) 100%);
}

/* the film */
html[data-theme="light"] .bubble{
  background:rgba(250,253,255,.94);border-color:rgba(14,108,176,.34);
  backdrop-filter:blur(12px) saturate(106%);-webkit-backdrop-filter:blur(12px) saturate(106%);
  box-shadow:0 14px 32px rgba(30,60,80,.16),inset 0 1px 0 #fff;
}
html[data-theme="light"] .turn-s .bubble{background:rgba(244,250,245,.94);border-color:rgba(35,122,64,.34)}
html[data-theme="light"] .turn-t .bt-fill{fill:var(--tail-fill,rgba(250,253,255,.94))}
html[data-theme="light"] .turn-t .bt-rim{stroke:var(--tail-rim,rgba(14,108,176,.34))}
html[data-theme="light"] .turn-s .bt-fill{fill:var(--tail-fill,rgba(244,250,245,.94))}
html[data-theme="light"] .turn-s .bt-rim{stroke:var(--tail-rim,rgba(35,122,64,.34))}
html[data-theme="light"] .turn-t .bubble .w{background:rgba(14,108,176,calc(var(--melt,0)*.24))}
html[data-theme="light"] .turn-s .bubble .w{background:rgba(35,122,64,calc(var(--melt,0)*.19))}
html[data-theme="light"] .mk-filler,html[data-theme="light"] .mk-pause{
  background:rgba(196,124,20,.15);color:#875712;
}
html[data-theme="light"] .mk-slip{
  background:rgba(196,124,20,.11);color:#8f5e16;
  text-decoration-color:rgba(143,94,22,.75);
}
html[data-theme="light"] .mk-fixed{
  background:linear-gradient(100deg,rgba(35,122,64,.18),rgba(14,108,176,.16));
}
html[data-theme="light"] .rail::before{
  background:radial-gradient(ellipse 78% 78% at 42% 50%,
    rgba(238,244,246,.85) 0%, rgba(238,244,246,.55) 48%, rgba(238,244,246,0) 100%);
}
html[data-theme="light"] .brain-tag{
  color:#573ba9;background:rgba(249,247,254,.95);border-color:rgba(122,90,220,.48);
  box-shadow:0 8px 20px rgba(89,62,154,.12);
}
html[data-theme="light"] .brain-core{filter:drop-shadow(0 12px 28px rgba(100,72,174,.14))}
html[data-theme="light"] .brain-path{fill:rgba(242,238,252,.76);stroke:rgba(101,69,199,.72)}
html[data-theme="light"] .brain-edges line{stroke:rgba(101,69,199,.64)}
html[data-theme="light"] .brain-mouth{border-color:rgba(101,69,199,.72);box-shadow:0 0 12px rgba(101,69,199,.18),inset 0 0 7px rgba(101,69,199,.12)}
html[data-theme="light"] .note{
  background:rgba(255,255,255,.92);border-color:rgba(9,38,58,.16);
  box-shadow:0 10px 24px rgba(30,60,80,.12),inset 0 1px 0 #fff;
}
html[data-theme="light"] .nt::before{box-shadow:none}
html[data-theme="light"] .nt-b{color:#1465a8}
html[data-theme="light"] .nt-g{color:#237a40}
html[data-theme="light"] .nt-e{color:#4b7a44}
html[data-theme="light"] .nt-o{color:#a2670e}
html[data-theme="light"] .nt-v{color:#6b46c0}
/* the film's 2D light (bars, escort, traces) prints as ink on paper */
html[data-theme="light"] .seam-wave{mix-blend-mode:multiply;opacity:.9}
html[data-theme="light"] .seam-gate{opacity:.85;
  filter:drop-shadow(0 0 10px rgba(14,108,176,.30)) drop-shadow(0 0 26px rgba(14,108,176,.14));
}

/* the universe */
html[data-theme="light"] .uni-stat{
  color:#496877;background:rgba(255,255,255,.66);border-color:rgba(9,38,58,.17);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9);
}
/* these two counts carried hard-coded night pastels and vanished on paper */
html[data-theme="light"] .uni-stat-re b{color:#12705a}
html[data-theme="light"] .uni-stat-fg b{color:#96600f}
html[data-theme="light"] .uni-bar{opacity:.22}
html[data-theme="light"] .uni-bar.lit{opacity:1}
html[data-theme="light"] .uni-bar .b-re{background:#78aa9b}
html[data-theme="light"] .uni-bar .b-new{background:#4e9565;box-shadow:none}
html[data-theme="light"] .uni-bar .b-st{background:#c98a2e;box-shadow:none}
html[data-theme="light"] .uni-ring-label{color:rgba(50,80,100,.75);text-shadow:none}
html[data-theme="light"] .uni-dot-num{display:none}
html[data-theme="light"] .uni-v-label{
  color:#145f2b;background:rgba(247,251,249,.78);border-radius:4px;padding:0 3px;
  text-shadow:0 1px 2px rgba(255,255,255,.95);
  box-shadow:0 1px 5px rgba(42,77,59,.08);
}
html[data-theme="light"] .uni-scrub input[type=range]:focus-visible{outline:none}
html[data-theme="light"] .uni-scrub:has(input[type=range]:focus-visible){
  border-bottom-color:rgba(14,108,176,.5);
  box-shadow:0 4px 8px -7px rgba(14,108,176,.7);
}
html[data-theme="light"] .uni-scrub input[type=range]::-webkit-slider-thumb{box-shadow:0 0 0 1px rgba(14,108,176,.14)}
html[data-theme="light"] .uni-scrub input[type=range]::-moz-range-thumb{box-shadow:0 0 0 1px rgba(14,108,176,.14)}
html[data-theme="light"] .uni-band-win{
  background:rgba(252,254,255,.98);border-color:rgba(14,108,176,.3);
  box-shadow:0 14px 34px rgba(65,96,113,.22),inset 0 1px 0 #fff;
}
html[data-theme="light"] .bw-head{color:#1f6ba0}
html[data-theme="light"] .bw-w{color:#1d6a34}
html[data-theme="light"] .uf-ring circle{stroke:rgba(60,95,120,.4)}
html[data-theme="light"] #uni-mic-btn{background:rgba(255,255,255,.7)}
html[data-theme="light"] #uni-typed-input{background:rgba(255,255,255,.82)}
html[data-theme="light"] .uni-light{background:rgba(255,255,255,.68)}
html[data-theme="light"] .uni-light:hover{background:rgba(9,38,58,.09)}

/* the two panels */
html[data-theme="light"] .side-teacher .side-tag{color:#12629f;background:rgba(14,108,176,.09);border-color:rgba(14,108,176,.4)}
html[data-theme="light"] .side-student .side-tag{color:#1d7038;background:rgba(35,122,64,.09);border-color:rgba(35,122,64,.38)}
html[data-theme="light"] .side-teacher{background:radial-gradient(130% 66% at 16% -10%, rgba(14,108,176,.11), rgba(14,108,176,0) 60%), rgba(252,254,255,.86)}
html[data-theme="light"] .side-student{background:radial-gradient(130% 66% at 84% -10%, rgba(35,122,64,.10), rgba(35,122,64,0) 60%), rgba(252,254,255,.86)}

/* the world + the door */
html[data-theme="light"] .field input{background:rgba(255,255,255,.88)}
html[data-theme="light"] .field input:focus{border-color:rgba(14,108,176,.55)}
html[data-theme="light"] .language-options{
  color:#102737;background:rgba(251,253,254,.985);
  border-color:rgba(9,38,58,.18);
  box-shadow:0 24px 54px rgba(30,60,80,.2),inset 0 1px 0 #fff;
}
html[data-theme="light"] .language-option{color:#456274}
html[data-theme="light"] .language-option:hover,
html[data-theme="light"] .language-option.is-active{
  color:#102737;background:rgba(14,108,176,.09);
}
html[data-theme="light"] .language-option[aria-selected="true"]{
  color:#174f2a;background:rgba(71,169,99,.13);
}
html[data-theme="light"] .language-option[aria-selected="true"].is-active{
  background:linear-gradient(90deg,rgba(71,169,99,.14),rgba(14,108,176,.1));
}
html[data-theme="light"] .role-pills span{background:rgba(255,255,255,.72)}
html[data-theme="light"] .role-pills input:checked + span{
  color:#174f2a;background:rgba(71,169,99,.14);border-color:rgba(35,122,64,.5);
  box-shadow:0 3px 10px rgba(35,122,64,.08);
}
html[data-theme="light"] .globe-tip{background:rgba(255,255,255,.92);border-color:rgba(14,108,176,.35)}

/* answers should sit on paper, not disappear into the ambient colour field */
html[data-theme="light"] .faq-list details{
  background:rgba(252,254,255,.86);border-color:rgba(9,38,58,.17);
  backdrop-filter:blur(18px) saturate(108%);-webkit-backdrop-filter:blur(18px) saturate(108%);
  box-shadow:0 8px 22px rgba(30,60,80,.08),inset 0 1px 0 rgba(255,255,255,.95);
}
html[data-theme="light"] .faq-list details:hover{border-color:rgba(14,108,176,.3)}
html[data-theme="light"] .faq-list details[open]{
  background:rgba(255,255,255,.94);border-color:rgba(14,108,176,.34);
  box-shadow:0 12px 28px rgba(30,60,80,.11),inset 0 1px 0 #fff;
}

/* the close */
html[data-theme="light"] .epi-logo{filter:drop-shadow(0 0 18px rgba(35,122,64,.28))}
