/* ============================================================
   presentation.nxtatlas.com

   One road from top to bottom. No slides, no counters, no arrows:
   the chapter rail on the right is the only navigation, and it
   only names things — it never numbers them.

   Every scene owns one looping animation. They are built out of
   DOM and CSS rather than recorded, so they stay sharp on a
   projector, weigh nothing, and can be paused when off-screen —
   which is the whole reason fifteen of them can coexist.
   ============================================================ */

:root{
  --ink:#08090b; --ink-raise:#0d0f13; --glass:#12151b; --glass-2:#0b0d11;
  --paper:#ece8e1; --paper-soft:rgba(236,232,225,.66);
  --paper-dim:rgba(236,232,225,.42); --paper-faint:rgba(236,232,225,.12);
  --brass:#d1a05a; --brass-lit:#efc98d;
  --brass-soft:rgba(209,160,90,.32); --brass-glow:rgba(209,160,90,.2);
  --green:#63d39c;
  --line:rgba(236,232,225,.09); --line-strong:rgba(236,232,225,.16);
  --display:"Sora",system-ui,sans-serif;
  --body:"Manrope",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
  --ease:cubic-bezier(.2,.95,.25,1);
  --rail-w:clamp(46px,5vw,72px);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ink); color:var(--paper);
  font-family:var(--body); font-weight:400; line-height:1.6;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
}
/* Lenis drives the scroll; these two are what it asks of the page. */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}

/* ── the ground: one low warm key, one cold fill ────────────────── */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(120% 90% at 50% 118%, rgba(209,160,90,.14), transparent 58%),
    radial-gradient(80% 60% at 10% -10%, rgba(140,170,220,.05), transparent 62%),
    linear-gradient(180deg, var(--ink-raise), var(--ink) 52%);
}

/* ── scenes ─────────────────────────────────────────────────────── */
main{position:relative; z-index:2}
.scene{
  min-height:100svh; display:grid; align-content:center;
  padding:clamp(84px,11vh,132px) var(--rail-w) clamp(84px,11vh,132px) clamp(24px,6vw,96px);
}
.inner{width:100%; max-width:1180px; margin-inline:auto}

/* ── type ───────────────────────────────────────────────────────── */
h1,h2{font-family:var(--display); font-weight:500; margin:0; letter-spacing:-.038em}
h1{font-size:clamp(2.3rem,5.4vw,4.3rem); line-height:1.03}
h2{font-size:clamp(1.75rem,3.8vw,2.9rem); line-height:1.08}
.tag{
  display:inline-flex; align-items:center; gap:12px;
  font-size:10.5px; font-weight:500; letter-spacing:.2em;
  text-transform:uppercase; color:var(--paper-dim);
}
.tag::before{content:""; width:26px; height:1px; background:var(--brass-soft)}
.lede{
  color:var(--paper-soft); font-size:clamp(14.5px,1.15vw,16.5px);
  line-height:1.72; max-width:46ch; font-weight:300;
}
.br{color:var(--brass)}
.wm{font-family:var(--display); font-weight:600; letter-spacing:.15em}
.wm i{font-style:normal; color:var(--brass)}

/* ── entrance ───────────────────────────────────────────────────── */
.r{opacity:0; transform:translateY(22px)}
.live .r{
  opacity:1; transform:none;
  transition:opacity .85s ease, transform .85s var(--ease);
  transition-delay:calc(var(--i,0) * 95ms);
}

/* ══════════════════════════════════════════════════════════════════
   CHAPTER RAIL — names, never numbers. Collapsed it is a column of
   hairlines; hovering the rail (or focusing a chapter) opens the
   names out to the left of it.
   ══════════════════════════════════════════════════════════════════ */
.rail{
  position:fixed; z-index:20; top:50%; right:clamp(14px,2vw,30px);
  transform:translateY(-50%);
  display:flex; flex-direction:column; align-items:flex-end; gap:3px;
  padding:10px 6px;
}
.rail a{
  --w:15px;
  display:flex; align-items:center; justify-content:flex-end; gap:11px;
  height:19px; text-decoration:none; color:var(--paper-dim);
  font-size:11px; font-weight:500; letter-spacing:.02em; white-space:nowrap;
}
.rail a::after{
  content:""; width:var(--w); height:1px; background:var(--line-strong); flex:none;
  transition:width .42s var(--ease), background .42s ease;
}
.rail a span{
  opacity:0; transform:translateX(10px);
  transition:opacity .34s ease, transform .42s var(--ease);
  pointer-events:none;
}
.rail:hover a span,.rail:focus-within a span{opacity:1; transform:none}
.rail a:hover{color:var(--paper)}
.rail a:hover::after{--w:26px; background:var(--paper-dim)}
.rail a.on{color:var(--brass)}
.rail a.on::after{--w:30px; background:var(--brass)}
.rail a.on span{opacity:1; transform:none}

@media (max-width:820px){
  .rail{right:8px; gap:2px; padding:6px 3px}
  .rail a{height:15px}
  .rail a span{display:none}
  .scene{padding-right:clamp(30px,7vw,54px); padding-left:clamp(22px,6vw,54px)}
}

/* ── fixed chrome ───────────────────────────────────────────────── */
.mark{
  position:fixed; z-index:20; top:clamp(20px,3vh,32px); left:clamp(24px,6vw,96px);
  display:flex; align-items:center; gap:10px; pointer-events:none;
}
.mark img{width:22px; height:22px; flex:none; border-radius:6px}
.mark .wm{font-size:13px}
.mark .word{
  font-family:var(--display); font-weight:300; font-size:12.5px;
  color:var(--paper-dim); letter-spacing:.02em;
}
@media (max-width:820px){ .mark{left:22px} }

/* ══════════════════════════════════════════════════════════════════
   THE STAGE — device frames, drawn rather than screenshotted
   ══════════════════════════════════════════════════════════════════ */
.stage{position:relative; perspective:1600px; perspective-origin:50% 42%;
       display:flex; align-items:flex-end; justify-content:center}
.stage::after{
  content:""; position:absolute; left:6%; right:6%; bottom:-5%; height:32%;
  background:radial-gradient(60% 100% at 50% 0%, var(--brass-glow), transparent 72%);
  filter:blur(30px); pointer-events:none; z-index:0;
}

.mac{
  position:relative; z-index:2;
  width:clamp(290px,38vw,520px); aspect-ratio:16/10.4;
  border-radius:13px; overflow:hidden;
  background:linear-gradient(168deg,var(--glass),var(--glass-2));
  border:1px solid var(--line-strong);
  box-shadow:0 1px 0 rgba(236,232,225,.07) inset,
             0 40px 90px -28px rgba(0,0,0,.85),
             0 0 74px -18px var(--brass-glow);
  transform:rotateY(13deg) rotateX(4deg);
  transform-origin:right center;
}
.mac-bar{
  height:clamp(23px,2.2vw,29px); display:flex; align-items:center; gap:6px;
  padding:0 clamp(9px,1vw,13px); border-bottom:1px solid var(--line);
  background:rgba(236,232,225,.022);
}
.dot{width:7px; height:7px; border-radius:50%; background:var(--paper-faint)}
.mac-bar .sp{flex:1}
.mac-bar .ttl{font-family:var(--display); font-size:9px; font-weight:600;
              letter-spacing:.15em; color:var(--paper-dim)}
.mac-bar .ttl i{font-style:normal; color:var(--brass)}
.mac-body{height:calc(100% - clamp(23px,2.2vw,29px)); padding:clamp(12px,1.5vw,20px);
          display:grid; align-content:center; position:relative}
/* The row, the code and the confirmation are three moments of ONE place, so
   they share a single grid cell and cross-fade there. Stacked in flow they
   each held their own space, and the last of them was pushed off the window. */
.states{display:grid; width:100%}
.states > *{grid-area:1 / 1; align-self:center}

.phone{
  position:relative; z-index:3; margin-left:clamp(12px,1.8vw,30px);
  align-self:flex-end; margin-bottom:clamp(-24px,-2.2vw,-10px);
  width:clamp(124px,14.6vw,196px); aspect-ratio:9/19;
  border-radius:clamp(19px,2.3vw,30px); padding:clamp(4px,.5vw,7px);
  background:linear-gradient(158deg,#2a2d34,#0e1014 42%,#20242b);
  box-shadow:0 1px 0 rgba(236,232,225,.1) inset,
             0 34px 68px -22px rgba(0,0,0,.9),
             0 0 58px -14px var(--brass-glow);
  transform:rotateY(-10deg) rotateX(3deg) translateZ(50px);
}
.screen{
  height:100%; border-radius:clamp(15px,1.9vw,25px); overflow:hidden; position:relative;
  background:linear-gradient(178deg,#12151b,#080a0d);
  display:flex; flex-direction:column; padding:clamp(6px,.7vw,10px);
  gap:clamp(4px,.5vw,7px);
}
.island{position:absolute; top:clamp(5px,.6vw,8px); left:50%; transform:translateX(-50%);
        width:29%; height:clamp(8px,.9vw,12px); border-radius:99px; background:#040507; z-index:4}

/* ══════════════════════════════════════════════════════════════════
   THE LOOPS

   Every animated element shares one 10.5s master period, so the whole
   scene is a single choreographed take that closes on itself. Where
   a stagger is wanted, the element takes a positive `animation-delay`:
   with equal durations and infinite repetition that is a permanent
   phase offset, not a drift.

   Nothing animates while its scene is off-screen. Fifteen scenes of
   this could not otherwise share one page.
   ══════════════════════════════════════════════════════════════════ */
.anim{animation-duration:10.5s; animation-iteration-count:infinite;
      animation-timing-function:var(--ease); animation-play-state:paused}
.live .anim{animation-play-state:running}

/* ── the pointer, treated as a character ────────────────────────── */
.cursor{
  position:absolute; width:15px; height:21px; z-index:6; pointer-events:none;
  filter:drop-shadow(0 3px 7px rgba(0,0,0,.75));
}
.cursor svg{display:block; width:100%; height:100%}
.click-ring{
  position:absolute; left:-9px; top:-9px; width:32px; height:32px;
  border-radius:50%; border:1px solid var(--brass); opacity:0;
}

/* ══ SCENE: link Telegram ═════════════════════════════════════════ */
.tg-row{
  display:flex; align-items:center; gap:10px; padding:9px 11px;
  border:1px solid var(--line); border-radius:9px;
  background:rgba(236,232,225,.022);
}
.tg-row .ico{width:17px; height:17px; flex:none; color:var(--brass)}
.tg-row .nm{font-size:11.5px; font-weight:500}
.tg-row .st{margin-left:auto; font-size:10px; letter-spacing:.13em;
            text-transform:uppercase; color:var(--paper-dim)}
.link-btn{
  margin-left:auto; font-family:var(--body); font-size:10.5px; font-weight:600;
  letter-spacing:.06em; padding:6px 13px; border-radius:99px;
  background:var(--brass); color:#14100a; border:none; flex:none;
}
.panel{
  border:1px solid var(--brass-soft); border-radius:11px;
  background:linear-gradient(180deg,rgba(209,160,90,.085),rgba(209,160,90,.025));
  padding:clamp(11px,1.3vw,16px); display:grid; gap:10px; justify-items:center;
}
.panel .cap{font-size:9.5px; letter-spacing:.17em; text-transform:uppercase;
            color:var(--brass); text-align:center}
.digits{display:flex; gap:clamp(4px,.5vw,7px)}
.digits b{
  font-family:var(--mono); font-weight:500;
  font-size:clamp(15px,1.75vw,23px); line-height:1;
  width:clamp(17px,2vw,26px); padding:clamp(5px,.6vw,8px) 0; text-align:center;
  border:1px solid var(--brass-soft); border-radius:6px;
  background:rgba(0,0,0,.3); color:var(--brass-lit);
}
.panel .ttl{font-size:10px; color:var(--paper-dim); text-align:center}
.done{
  display:flex; align-items:center; justify-content:center; gap:9px;
  border:1px solid rgba(99,211,156,.4); border-radius:11px;
  background:rgba(99,211,156,.07); padding:clamp(13px,1.6vw,20px);
  font-size:12px; font-weight:500; color:var(--green);
}
.done .tick{width:16px; height:16px; flex:none}

/* the three states of the left half, on one timeline */
.st-idle{animation-name:k-idle}
.st-code{animation-name:k-code}
.st-done{animation-name:k-done}
@keyframes k-idle{
  0%,14%{opacity:1; transform:none}
  17%,95%{opacity:0; transform:translateY(-7px)}
  99%,100%{opacity:1; transform:none}
}
@keyframes k-code{
  0%,15%{opacity:0; transform:translateY(9px)}
  19%,64%{opacity:1; transform:none}
  68%,100%{opacity:0; transform:translateY(-7px)}
}
@keyframes k-done{
  0%,65%{opacity:0; transform:translateY(9px) scale(.97)}
  69%,92%{opacity:1; transform:none}
  96%,100%{opacity:0; transform:translateY(-6px) scale(.98)}
}
.digit{animation-name:k-digit; animation-delay:calc(var(--n) * 70ms)}
@keyframes k-digit{
  0%,17%{opacity:0; transform:translateY(7px) rotateX(-70deg)}
  22%,64%{opacity:1; transform:none}
  68%,100%{opacity:0; transform:translateY(-5px)}
}

/* cursor: an arc to the button, a press, then out of the way */
.tg-cursor{left:86%; top:50%; animation-name:k-cursor}
@keyframes k-cursor{
  0%,3%{opacity:0; transform:translate(-96px,104px)}
  6%{opacity:1; transform:translate(-96px,104px)}
  12%{opacity:1; transform:translate(-14px,22px)}
  14%{opacity:1; transform:translate(0,0)}
  15%{opacity:1; transform:translate(1px,2px) scale(.9)}
  17%{opacity:1; transform:translate(0,0)}
  26%{opacity:1; transform:translate(-40px,74px)}
  30%,100%{opacity:0; transform:translate(-70px,96px)}
}
.tg-ring{animation-name:k-ring}
@keyframes k-ring{
  0%,14%{opacity:0; transform:scale(.4)}
  15%{opacity:.9; transform:scale(.5)}
  20%{opacity:0; transform:scale(1.5)}
  100%{opacity:0; transform:scale(1.5)}
}
.btn-press{animation-name:k-press}
@keyframes k-press{
  0%,14%{transform:none; filter:none}
  15.5%{transform:scale(.94); filter:brightness(1.18)}
  17.5%,100%{transform:none; filter:none}
}

/* ── the phone half: Telegram's own skin, not ours ───────────────
   The point of the scene is that the assistant turns up somewhere you
   already are. Dressing that half in our brass would have said the
   opposite, so the phone uses Telegram's dark palette, its bubble
   shapes and its habit of announcing "typing…" in the header rather
   than in the thread. Only the bot's avatar is ours. */
.tg{
  --tg-head:#17212b; --tg-bg:#0e1621; --tg-in:#182533; --tg-out:#2b5278;
  --tg-text:#ffffff; --tg-sub:#708499; --tg-accent:#2ea6ff; --tg-link:#64b5ef;
  background:var(--tg-bg) !important; padding:0 !important; gap:0 !important;
}
.tg-bar{
  background:var(--tg-head); padding:clamp(13px,1.5vw,18px) 7px 6px;
  display:flex; align-items:center; gap:6px; flex:none;
}
.tg-back{width:8px; height:8px; border-left:1.4px solid var(--tg-link);
         border-bottom:1.4px solid var(--tg-link); transform:rotate(45deg); flex:none;
         margin-right:1px}
.tg-av{width:clamp(15px,1.7vw,21px); height:clamp(15px,1.7vw,21px);
       border-radius:50%; flex:none; background:#0a0b0d}
.tg-who{display:grid; gap:1px; min-width:0}
.tg-who .nm{font-family:var(--body); font-size:8px; font-weight:600; color:var(--tg-text)}
.tg-who .sub{font-size:6.5px; color:var(--tg-sub); position:relative; height:8px}
.tg-who .sub span{position:absolute; left:0; top:0; white-space:nowrap}
.tg-who .sub .live-t{color:var(--tg-link)}

/* Telegram's faint chat wallpaper, drawn rather than shipped as an image */
.tg-thread{
  flex:1; display:flex; flex-direction:column; justify-content:flex-end;
  gap:4px; padding:8px 7px;
  background-image:
    radial-gradient(circle at 20% 25%, rgba(255,255,255,.022) 0 8%, transparent 8%),
    radial-gradient(circle at 74% 62%, rgba(255,255,255,.02) 0 7%, transparent 7%),
    radial-gradient(circle at 46% 88%, rgba(255,255,255,.018) 0 9%, transparent 9%);
}
.bub{
  position:relative; padding:5px 7px 8px; font-size:7.5px; line-height:1.5;
  max-width:82%; font-family:var(--body); color:var(--tg-text);
}
.bub time{
  position:absolute; right:6px; bottom:2px; font-size:5.5px;
  color:rgba(255,255,255,.45); letter-spacing:.02em;
}
.bub.me{
  align-self:flex-end; background:var(--tg-out);
  border-radius:11px 11px 3px 11px; font-family:var(--mono); padding-right:26px;
}
.bub.me time{color:rgba(255,255,255,.55)}
.bub.bot{
  align-self:flex-start; background:var(--tg-in);
  border-radius:11px 11px 11px 3px; padding-right:24px;
}
.bub.bot b{color:var(--tg-link); font-weight:600}

.tg-compose{
  background:var(--tg-head); display:flex; align-items:center; gap:6px;
  padding:6px 8px; flex:none; min-height:19px;
}
/* The field and the action both stack two things in one place. Grid does
   that without absolute positioning, which matters because the send button
   is scaled by its keyframes — an absolute centring transform would be
   overwritten the moment the animation took hold. */
.tg-field{position:relative; flex:1; min-width:0; display:grid}
.tg-field > *{grid-area:1 / 1; align-self:center}
.tg-act{width:15px; height:15px; flex:none; display:grid; place-items:center}
.tg-act > *{grid-area:1 / 1}
.tg-clip{width:9px; height:9px; flex:none; color:var(--tg-sub)}
.tg-cmd{
  flex:1; font-family:var(--mono); font-size:7.5px; color:var(--tg-text);
  white-space:pre; overflow:hidden; width:0;
  border-right:1px solid var(--tg-accent);
  animation-name:k-type;
}
@keyframes k-type{
  0%,30%{width:0; border-right-color:transparent}
  31%{width:0; border-right-color:var(--tg-accent)}
  47%{width:13ch; border-right-color:var(--tg-accent)}
  50%{width:13ch; border-right-color:transparent}
  50.1%,100%{width:0; border-right-color:transparent}
}
.tg-ph{font-size:7.5px; color:var(--tg-sub); pointer-events:none; animation-name:k-ph}
@keyframes k-ph{
  0%,30%{opacity:1} 33%,50%{opacity:0} 50.5%,100%{opacity:1}
}
/* mic while the field is empty, send arrow once there is something to send —
   exactly the swap Telegram does. */
.tg-mic{width:9px; height:12px; color:var(--tg-sub); justify-self:center;
        align-self:center; animation-name:k-mic}
@keyframes k-mic{0%,32%{opacity:1} 35%,50%{opacity:0} 51%,100%{opacity:1}}
.tg-send{
  width:15px; height:15px; border-radius:50%;
  background:var(--tg-accent); display:grid; place-items:center;
  animation-name:k-send;
}
.tg-send svg{width:8px; height:8px; color:#fff}
@keyframes k-send{
  0%,33%{opacity:0; transform:scale(.6)}
  37%,48%{opacity:1; transform:scale(1)}
  49.5%{opacity:1; transform:scale(.84)}
  51%,100%{opacity:0; transform:scale(.6)}
}
.msg-sent{animation-name:k-sent}
@keyframes k-sent{
  0%,49%{opacity:0; transform:translateY(9px) scale(.94)}
  53%,92%{opacity:1; transform:none}
  96%,100%{opacity:0; transform:translateY(-5px)}
}
.msg-reply{animation-name:k-reply}
@keyframes k-reply{
  0%,61%{opacity:0; transform:translateY(9px) scale(.94)}
  65%,92%{opacity:1; transform:none}
  96%,100%{opacity:0; transform:translateY(-5px)}
}
/* the header subtitle, Telegram's real place for "typing…" */
.sub-bot{animation-name:k-subbot}
@keyframes k-subbot{0%,53%{opacity:1} 56%,61%{opacity:0} 64%,100%{opacity:1}}
.sub-typing{animation-name:k-subtyping}
@keyframes k-subtyping{0%,53%{opacity:0} 56%,61%{opacity:1} 64%,100%{opacity:0}}

.tg-phone{animation-name:k-wake}
@keyframes k-wake{
  0%,24%{filter:brightness(.5) saturate(.7)}
  30%,93%{filter:none}
  98%,100%{filter:brightness(.5) saturate(.7)}
}

/* ══ SCENE: title ═════════════════════════════════════════════════ */
.hero{display:grid; gap:clamp(24px,3.4vh,42px); justify-items:start}
.sphere-wrap{position:relative; width:clamp(150px,17vw,230px); aspect-ratio:1}
.sphere-wrap video,.sphere-wrap img{
  width:100%; height:100%; object-fit:contain; display:block;
  mix-blend-mode:screen; position:relative; z-index:2;
  /* The render's background is near-black rather than black, and `screen`
     lifts it just enough to draw a visible square. Feathering the corners
     away costs nothing and leaves only the sphere. */
  -webkit-mask-image:radial-gradient(circle at 50% 50%, #000 56%, transparent 73%);
  mask-image:radial-gradient(circle at 50% 50%, #000 56%, transparent 73%);
}
.sphere-wrap::after{
  content:""; position:absolute; inset:-14%; border-radius:50%; z-index:1;
  background:radial-gradient(circle, rgba(209,160,90,.3), transparent 66%);
  animation:breathe 7.5s ease-in-out infinite;
}
@keyframes breathe{0%,100%{opacity:.5; transform:scale(.94)} 50%{opacity:1; transform:scale(1.06)}}
.ways{display:flex; flex-wrap:wrap; gap:8px}
.chip{
  display:inline-flex; align-items:center; gap:8px; padding:7px 14px;
  border:1px solid var(--line-strong); border-radius:99px;
  font-size:11.5px; font-weight:500; color:var(--paper-soft);
}
.chip::before{content:""; width:5px; height:5px; border-radius:50%; background:var(--brass)}

/* ── placeholder scenes, until each gets its own loop ───────────── */
.todo{
  border:1px dashed var(--line-strong); border-radius:14px;
  padding:clamp(22px,3vh,34px); margin-top:26px; max-width:640px;
  color:var(--paper-dim); font-size:13px; font-weight:300;
}
.todo b{display:block; color:var(--brass); font-weight:500; font-size:10.5px;
        letter-spacing:.18em; text-transform:uppercase; margin-bottom:8px}

.split{display:grid; grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);
       gap:clamp(26px,4vw,60px); align-items:center}
@media (max-width:900px){
  .split{grid-template-columns:1fr; gap:clamp(22px,4vh,38px)}
  .phone{display:none}
  .mac{transform:none; width:100%}
}

@media (prefers-reduced-motion:reduce){
  .anim,.sphere-wrap::after,.typing i{animation:none !important}
  .r{opacity:1; transform:none}
  .st-idle,.tg-cursor,.tg-ring,.msg-typing{opacity:0}
  .st-done,.msg-sent,.msg-reply{opacity:1}
  .tg-cmd{width:13ch; border-right-color:transparent}
}

/* ══ SCENE: four ways in ══════════════════════════════════════════
   Three real surfaces rather than three boxes: a browser with its
   address, our app on a phone, and the Telegram chat — each with the
   chrome that identifies it at a glance. One question is asked on the
   first and the thread simply continues on the next two, timestamps
   and all, which is the whole claim of the chapter.
   ══════════════════════════════════════════════════════════════════ */
/* Four columns, because the chapter is called "four ways in" and showing
   three of them invited exactly the question it did. */
.trio{position:relative; display:grid; grid-template-columns:repeat(4,1fr);
      gap:clamp(8px,1.3vw,20px); align-items:stretch; margin-top:clamp(16px,2.4vh,28px)}
.trio::before{
  content:""; position:absolute; left:11%; right:11%; top:50%; height:1px;
  background:linear-gradient(90deg,transparent,var(--line-strong) 10%,
             var(--line-strong) 90%,transparent); z-index:0;
}
.pulse{
  position:absolute; top:50%; left:11%; width:7px; height:7px; margin-top:-3.5px;
  border-radius:50%; background:var(--brass); z-index:1;
  box-shadow:0 0 14px 3px var(--brass-glow); animation-name:k-pulse;
}
/* `left` rather than a transform: the distance has to be a share of the
   rail's own width, and a viewport-based guess landed in the wrong place
   at every other window size. One dot, so the cost is nothing. */
@keyframes k-pulse{
  0%,8%{opacity:0; left:11%}
  12%{opacity:1; left:11%}
  27%{opacity:1; left:37%}
  31%{opacity:1; left:37%}
  46%{opacity:1; left:63%}
  50%{opacity:1; left:63%}
  65%{opacity:1; left:89%}
  71%,100%{opacity:0; left:89%}
}
.surf{
  position:relative; z-index:2; border-radius:11px; overflow:hidden;
  border:1px solid var(--line); background:linear-gradient(168deg,var(--glass),var(--glass-2));
  display:flex; flex-direction:column; min-height:clamp(138px,17vh,192px);
}
.surf-glow{animation-name:k-surf}
@keyframes k-surf{
  0%,12%{border-color:var(--line); box-shadow:none}
  18%,86%{border-color:var(--brass-soft); box-shadow:0 0 40px -14px var(--brass-glow)}
  92%,100%{border-color:var(--line); box-shadow:none}
}
/* browser chrome */
.br-bar{display:flex; align-items:center; gap:6px; padding:7px 9px;
        border-bottom:1px solid var(--line); background:rgba(236,232,225,.025)}
.br-bar .d{width:5px; height:5px; border-radius:50%; background:var(--paper-faint); flex:none}
.br-bar .url{
  flex:1; margin-left:4px; padding:2.5px 8px; border-radius:99px; font-size:7px;
  background:rgba(0,0,0,.35); color:var(--paper-dim); border:1px solid var(--line);
  font-family:var(--mono); white-space:nowrap; overflow:hidden;
}
/* mac chrome — it sat next to the browser wearing the same grey dots and no
   address, so it read as "a browser with something missing". Two things tell
   a Mac window apart at a glance: the coloured traffic lights, and the app's
   own sidebar. It now has both. */
.mc-bar{display:flex; align-items:center; gap:4px; padding:7px 9px;
        border-bottom:1px solid var(--line);
        background:linear-gradient(180deg,rgba(236,232,225,.06),rgba(236,232,225,.02))}
.mc-bar .d{width:5.5px; height:5.5px; border-radius:50%; flex:none}
.mc-bar .d:nth-child(1){background:#ff5f57}
.mc-bar .d:nth-child(2){background:#febc2e}
.mc-bar .d:nth-child(3){background:#28c840}
.mc-bar .t{flex:1; text-align:center; font-family:var(--display); font-size:7px;
           font-weight:600; letter-spacing:.12em; color:var(--paper-dim);
           margin-right:16px}
.mc-bar .t i{font-style:normal; color:var(--brass)}

/* A sidebar was tried here and taken out again: at four columns each panel is
   under 200px, and a third of that spent on chrome squeezed the messages into
   a slot too narrow to read. The coloured lights carry the Mac on their own. */
.surf-body.mac{position:relative}
.surf-body.mac::before{
  content:""; position:absolute; left:0; right:0; top:0; height:1px;
  background:rgba(236,232,225,.08); pointer-events:none;
}
.mc-main{display:contents}

/* our phone chrome */
.ph-bar{display:flex; align-items:center; justify-content:space-between; padding:8px 9px 5px;
        font-size:6.5px; font-weight:600; color:var(--paper-soft);
        border-bottom:1px solid var(--line)}
.ph-bar .mid{font-family:var(--display); font-size:7.5px; letter-spacing:.1em; font-weight:600}
.ph-bar .mid i{font-style:normal; color:var(--brass)}
/* telegram chrome */
.tgm-bar{display:flex; align-items:center; gap:6px; padding:8px 9px;
         background:#17212b; border-bottom:1px solid rgba(0,0,0,.4)}
.tgm-bar img{width:13px; height:13px; border-radius:50%; flex:none}
.tgm-bar b{font-size:7.5px; font-weight:600; color:#fff}
.tgm-bar span{font-size:6px; color:#708499}
/* `min-width:0` is the whole fix: a flex item defaults to min-width:auto and
   refuses to shrink below its content, so one long word blew this body out to
   512px inside a 281px panel and pushed the right-aligned bubble clean out of
   the frame, where the panel's overflow:hidden ate it. */
/* `width:100%` rather than relying on stretch: in a column flex container the
   cross size is stretched, but the used width still cannot fall below the
   item's min-content width — so one long word blew this body out to 512px
   inside a 281px panel and pushed the right-aligned bubble out of the frame,
   where the panel's overflow:hidden ate it. An explicit width does not care
   what the content wants. */
.surf-body{flex:1; width:100%; min-width:0; min-height:0; box-sizing:border-box;
           display:flex; flex-direction:column; gap:4px; padding:7px}
.surf-body.tgm{background:#0e1621}
.msg{
  border-radius:8px; padding:5px 6px 7px; font-size:7px; line-height:1.5;
  max-width:92%; position:relative;
  /* Armenian words are long and these columns are narrow; without this a
     single word pushes the bubble past the edge of its own panel. */
  overflow-wrap:anywhere;
}
.msg time{position:absolute; right:5px; bottom:1px; font-size:5px; opacity:.5}
.msg.q{align-self:flex-end; background:rgba(209,160,90,.16); border:1px solid var(--brass-soft);
       color:var(--brass-lit); padding-right:20px}
.msg.a{align-self:flex-start; background:rgba(236,232,225,.05); border:1px solid var(--line);
       color:var(--paper-soft); padding-right:20px}
.surf-body.tgm .msg.q{background:#2b5278; border:none; color:#fff; border-radius:9px 9px 3px 9px}
.surf-body.tgm .msg.a{background:#182533; border:none; color:#fff; border-radius:9px 9px 9px 3px}
.w-a{animation-name:k-wa} .w-b{animation-name:k-wb}
.w-c{animation-name:k-wc} .w-d{animation-name:k-wd}
@keyframes k-wa{0%,9%{opacity:0; transform:translateY(6px)} 15%,88%{opacity:1; transform:none} 93%,100%{opacity:0}}
@keyframes k-wb{0%,27%{opacity:0; transform:translateY(6px)} 33%,88%{opacity:1; transform:none} 93%,100%{opacity:0}}
@keyframes k-wc{0%,46%{opacity:0; transform:translateY(6px)} 52%,88%{opacity:1; transform:none} 93%,100%{opacity:0}}
@keyframes k-wd{0%,65%{opacity:0; transform:translateY(6px)} 71%,88%{opacity:1; transform:none} 93%,100%{opacity:0}}
.dim-b{animation-name:k-db} .dim-c{animation-name:k-dc} .dim-d{animation-name:k-dd}
@keyframes k-db{0%,25%{opacity:.3} 33%,88%{opacity:1} 93%,100%{opacity:.3}}
@keyframes k-dc{0%,44%{opacity:.3} 52%,88%{opacity:1} 93%,100%{opacity:.3}}
@keyframes k-dd{0%,63%{opacity:.3} 71%,88%{opacity:1} 93%,100%{opacity:.3}}
.same-acct{
  margin-top:clamp(12px,1.8vh,20px); display:flex; align-items:center; gap:11px;
  font-size:11.5px; color:var(--paper-soft); animation-name:k-same;
}
.same-acct b{color:var(--brass); font-weight:500}
@keyframes k-same{
  0%,74%{opacity:0; transform:translateY(6px)} 80%,92%{opacity:1; transform:none}
  96%,100%{opacity:0}
}

/* ══ SCENE: images ════════════════════════════════════════════════ */
.compose{
  display:flex; align-items:center; gap:8px; border-radius:99px;
  border:1px solid var(--line-strong); background:rgba(0,0,0,.3);
  padding:7px 8px 7px 13px;
}
.compose .txt{
  flex:1; font-family:var(--mono); font-size:10px; color:var(--paper);
  white-space:pre; overflow:hidden; width:0; border-right:1px solid var(--brass);
}
.compose .go{width:19px; height:19px; border-radius:50%; background:var(--brass); flex:none}
.prompt-img{animation-name:k-typeimg}
@keyframes k-typeimg{
  0%,4%{width:0; border-right-color:transparent}
  6%{width:0; border-right-color:var(--brass)}
  26%{width:34ch; border-right-color:var(--brass)}
  29%{width:34ch; border-right-color:transparent}
  29.1%,100%{width:0; border-right-color:transparent}
}
.canvas{
  margin-top:11px; border-radius:11px; overflow:hidden; position:relative;
  aspect-ratio:16/9; border:1px solid var(--line);
  background:radial-gradient(120% 90% at 30% 20%, #1b2029, #0b0d11);
}
/* while it works: a light sweeping across an empty frame */
.sweep{
  position:absolute; inset:0; animation-name:k-sweep;
  background:linear-gradient(105deg, transparent 34%, rgba(209,160,90,.22) 50%, transparent 66%);
  background-size:260% 100%;
}
@keyframes k-sweep{
  0%,29%{opacity:0; background-position:130% 0}
  32%{opacity:1; background-position:130% 0}
  56%{opacity:1; background-position:-130% 0}
  60%,100%{opacity:0; background-position:-130% 0}
}
/* and then a picture, composed rather than claimed: it is plainly a
   representation, not a fake screenshot of a specific result. */
.art{position:absolute; inset:0; animation-name:k-art}
@keyframes k-art{
  0%,54%{opacity:0; filter:blur(13px) saturate(.5); transform:scale(1.05)}
  62%,90%{opacity:1; filter:none; transform:none}
  95%,100%{opacity:0; filter:blur(9px)}
}
.art img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block;
}
.chip-done{
  position:absolute; right:9px; bottom:9px; display:flex; align-items:center; gap:6px;
  padding:4px 9px; border-radius:99px; font-size:8.5px; letter-spacing:.1em;
  text-transform:uppercase; background:rgba(8,9,11,.72); border:1px solid var(--line-strong);
  color:var(--paper-soft); backdrop-filter:blur(6px); animation-name:k-art;
}
.chip-done b{color:var(--green); font-weight:600}

/* ══ SCENE: video ═════════════════════════════════════════════════ */
.prompt-vid{animation-name:k-typevid}
@keyframes k-typevid{
  0%,3%{width:0; border-right-color:transparent}
  5%{width:0; border-right-color:var(--brass)}
  22%{width:31ch; border-right-color:var(--brass)}
  25%{width:31ch; border-right-color:transparent}
  25.1%,100%{width:0; border-right-color:transparent}
}
.queue{
  margin-top:11px; border:1px solid var(--line); border-radius:11px;
  padding:clamp(10px,1.2vw,15px); display:grid; gap:9px; animation-name:k-queue;
}
@keyframes k-queue{
  0%,25%{opacity:0; transform:translateY(7px)}
  29%,62%{opacity:1; transform:none}
  66%,100%{opacity:0; transform:translateY(-6px)}
}
.queue .lbl{display:flex; align-items:center; gap:8px; font-size:9.5px;
            letter-spacing:.15em; text-transform:uppercase; color:var(--paper-dim)}
.queue .lbl b{color:var(--brass); font-weight:500; letter-spacing:.06em; text-transform:none}
.queue .lbl .pct{margin-left:auto; font-family:var(--mono); letter-spacing:0;
                 color:var(--paper-soft); position:relative; width:34px; height:11px}
.queue .lbl .pct span{position:absolute; right:0; animation-name:k-pct;
                      animation-delay:calc(var(--p) * 1.05s)}
@keyframes k-pct{0%,0.1%{opacity:0} 1%,10%{opacity:1} 11.5%,100%{opacity:0}}
.queue .meta{display:flex; gap:13px; font-size:8.5px; color:var(--paper-dim);
             font-family:var(--mono)}
.queue .meta b{color:var(--paper-soft); font-weight:400}
.vdone{
  position:absolute; left:9px; bottom:9px; display:flex; align-items:center; gap:7px;
  padding:3px 9px; border-radius:99px; font-size:8px; letter-spacing:.1em;
  text-transform:uppercase; background:rgba(8,9,11,.7); border:1px solid var(--line-strong);
  color:var(--paper-soft); backdrop-filter:blur(6px); animation-name:k-player;
}
.vdone b{color:var(--green); font-weight:600}
.bar-track{height:3px; border-radius:99px; background:rgba(236,232,225,.09); overflow:hidden}
.bar-fill{display:block; height:100%; border-radius:99px;
          background:var(--brass); width:0; animation-name:k-fill}
@keyframes k-fill{
  0%,29%{width:2%} 60%{width:100%} 100%{width:100%}
}
.strip{display:flex; gap:5px; margin-top:11px}
.strip i{
  flex:1; aspect-ratio:16/10; border-radius:5px; font-style:normal;
  border:1px solid var(--line); background:linear-gradient(160deg,#20293a,#0d1017);
  animation-name:k-frame; animation-delay:calc(var(--n) * 80ms);
}
@keyframes k-frame{
  0%,32%{opacity:0; transform:translateY(6px) scale(.92)}
  38%,90%{opacity:1; transform:none}
  95%,100%{opacity:0}
}
.player{margin-top:11px; border-radius:11px; overflow:hidden; position:relative;
        aspect-ratio:16/9; border:1px solid var(--line);
        background:linear-gradient(200deg,#25304a,#0c0f16); animation-name:k-player}
@keyframes k-player{
  0%,62%{opacity:0; transform:scale(.97)}
  68%,90%{opacity:1; transform:none}
  95%,100%{opacity:0}
}
.player .scrub{position:absolute; left:10px; right:10px; bottom:10px; height:3px;
               border-radius:99px; background:rgba(255,255,255,.16); overflow:hidden}
.player .scrub b{display:block; height:100%; width:0; background:var(--paper);
                 animation-name:k-scrub}
@keyframes k-scrub{0%,66%{width:0} 90%{width:78%} 100%{width:78%}}
.player .play{
  position:absolute; inset:0; margin:auto; width:34px; height:34px; border-radius:50%;
  background:rgba(8,9,11,.55); border:1px solid rgba(255,255,255,.28);
  display:grid; place-items:center; backdrop-filter:blur(4px);
}
.player .play::after{content:""; border-left:9px solid var(--paper);
  border-top:6px solid transparent; border-bottom:6px solid transparent; margin-left:3px}

/* ── a window whose content fills it exactly ─────────────────────
   The canvas and the player are 16:9 inside a 16:10.4 window that
   also carries a composer, so laying them out in normal flow pushed
   the last of them through the bottom edge. The pane gives the
   remaining height to one stretch area, and anything that shares
   that area stacks in it rather than below it. */
.pane{
  display:flex !important; align-content:initial !important;
  flex-direction:column; gap:clamp(7px,.9vw,11px); height:100%;
}
.fill{flex:1; min-height:0; display:grid}
.fill > *{grid-area:1 / 1; min-height:0}
.fill .canvas,.fill .player{aspect-ratio:auto; height:100%; margin-top:0}
.fill .queue{align-self:center; margin-top:0}

/* ══ SCENE: voice ═════════════════════════════════════════════════
   Rebuilt against the Telegram scene's standard: a real screen doing a
   real thing, step by step, with something to read at every moment.
   The orb alone said nothing — now the phone carries the call state,
   a running timer, the transcript arriving word by word as you speak,
   and the answer arriving the same way. Every word is its own element
   with its own phase, which is what makes it look spoken rather than
   pasted.
   ══════════════════════════════════════════════════════════════════ */
.vphone{
  --vg:#0c0e12;
  background:radial-gradient(120% 80% at 50% 8%, #17202b, var(--vg)) !important;
  padding:0 !important; gap:0 !important;
}
.v-status{
  display:flex; align-items:center; justify-content:space-between;
  padding:clamp(12px,1.4vw,17px) 11px 3px; font-size:6.5px; font-weight:600;
  color:var(--paper-soft); letter-spacing:.03em; flex:none;
}
.v-status .bars{display:flex; align-items:flex-end; gap:1.5px}
.v-status .bars i{width:2px; background:var(--paper-soft); border-radius:1px; font-style:normal}
.v-status .bars i:nth-child(1){height:3px} .v-status .bars i:nth-child(2){height:4.5px}
.v-status .bars i:nth-child(3){height:6px}  .v-status .bars i:nth-child(4){height:7.5px}
.v-status .batt{width:13px; height:6.5px; border:1px solid var(--paper-dim); border-radius:2px;
                position:relative; display:inline-block}
.v-status .batt::after{content:""; position:absolute; inset:1px; right:4px;
                       background:var(--paper-soft); border-radius:1px}

.v-head{display:grid; justify-items:center; gap:2px; padding:9px 0 4px; flex:none}
.v-head .nm{font-family:var(--display); font-size:8.5px; font-weight:600; letter-spacing:.05em}
.v-head .state{position:relative; height:9px; width:100%; display:grid; place-items:center}
.v-head .state span{
  position:absolute; font-size:7px; letter-spacing:.16em; text-transform:uppercase;
}
.st-listen{color:var(--green); animation-name:k-vlisten}
.st-think{color:var(--paper-dim); animation-name:k-vthink}
.st-speak{color:var(--brass); animation-name:k-vspeak}
@keyframes k-vlisten{0%,6%{opacity:0} 10%,38%{opacity:1} 41%,100%{opacity:0}}
@keyframes k-vthink{0%,38%{opacity:0} 41%,49%{opacity:1} 52%,100%{opacity:0}}
@keyframes k-vspeak{0%,49%{opacity:0} 52%,86%{opacity:1} 91%,100%{opacity:0}}
.v-timer{position:relative; height:10px; width:100%; display:grid; place-items:center}
.v-timer span{position:absolute; left:50%; transform:translateX(-50%);
              font-family:var(--mono); font-size:8px; color:var(--paper-soft);
              animation-name:k-tick; animation-delay:calc(var(--t) * 1.9s)}
/* Each reading has to still be up when the next one starts, or the timer
   blinks out between seconds. The windows overlap by design. */
@keyframes k-tick{0%,0.1%{opacity:0} 1.5%,19.5%{opacity:1} 21%,100%{opacity:0}}

/* the orb, with rings that only travel while it is listening */
.v-orb-wrap{flex:1; display:grid; place-items:center; position:relative; min-height:0}
.v-orb{
  width:clamp(46px,5.4vw,72px); aspect-ratio:1; border-radius:50%; position:relative;
  background:radial-gradient(circle at 36% 32%, #f2dcb4, #d1a05a 44%, #6b4d24 78%, #221a0d);
  animation-name:k-vorb;
}
@keyframes k-vorb{
  0%,8%{transform:scale(.9); box-shadow:0 0 24px -6px var(--brass-glow)}
  14%{transform:scale(1); box-shadow:0 0 40px -4px rgba(99,211,156,.4)}
  36%{transform:scale(.97); box-shadow:0 0 34px -6px rgba(99,211,156,.3)}
  44%{transform:scale(.86); box-shadow:0 0 20px -8px var(--brass-glow)}
  54%{transform:scale(1.06); box-shadow:0 0 52px -4px var(--brass-glow)}
  70%{transform:scale(.98); box-shadow:0 0 40px -6px var(--brass-glow)}
  86%{transform:scale(1.02); box-shadow:0 0 46px -5px var(--brass-glow)}
  95%,100%{transform:scale(.9); box-shadow:0 0 24px -6px var(--brass-glow)}
}
.v-ring{
  position:absolute; inset:0; margin:auto; width:clamp(46px,5.4vw,72px); aspect-ratio:1;
  border-radius:50%; border:1px solid rgba(99,211,156,.5);
  animation-name:k-vring; animation-delay:calc(var(--r) * 700ms);
}
@keyframes k-vring{
  0%,10%{opacity:0; transform:scale(1)}
  14%{opacity:.75; transform:scale(1)}
  34%{opacity:0; transform:scale(2.3)}
  100%{opacity:0; transform:scale(2.3)}
}
/* while it thinks, a single arc turns */
.v-spin{
  position:absolute; inset:0; margin:auto; width:clamp(58px,6.8vw,90px); aspect-ratio:1;
  border-radius:50%; border:1px solid transparent; border-top-color:var(--brass);
  animation-name:k-vspin;
}
@keyframes k-vspin{
  0%,38%{opacity:0; transform:rotate(0deg)}
  42%{opacity:1; transform:rotate(120deg)}
  48%{opacity:1; transform:rotate(430deg)}
  52%,100%{opacity:0; transform:rotate(560deg)}
}
/* speaking: bars under the orb, brass, each with its own amplitude */
.v-bars{position:absolute; bottom:8%; left:0; right:0; display:flex;
        justify-content:center; align-items:flex-end; gap:2px; height:16px}
.v-bars i{
  width:2px; border-radius:99px; background:var(--brass); height:8%; font-style:normal;
  animation-name:k-vbar; animation-delay:calc(var(--n) * 58ms);
}
@keyframes k-vbar{
  0%,50%{height:6%; opacity:0}
  55%{height:calc(10% + var(--a,.5) * 80%); opacity:1}
  62%{height:calc(8% + var(--a,.5) * 34%); opacity:1}
  69%{height:calc(10% + var(--a,.5) * 72%); opacity:1}
  76%{height:calc(8% + var(--a,.5) * 40%); opacity:1}
  83%{height:calc(9% + var(--a,.5) * 58%); opacity:1}
  88%{height:6%; opacity:.4}
  92%,100%{height:6%; opacity:0}
}

/* the transcript — the part that carries the information */
.v-script{padding:0 10px 8px; display:grid; gap:5px; align-content:end; flex:none;
          min-height:clamp(52px,6vw,78px)}
.v-line{font-size:8px; line-height:1.6; display:block}
.v-line.you{color:var(--paper)}
.v-line.it{color:var(--brass-lit)}
.v-line b{font-weight:400; opacity:0; display:inline-block}
.v-line.you b{animation-name:k-wyou; animation-delay:calc(var(--w) * 92ms)}
.v-line.it b{animation-name:k-wit; animation-delay:calc(var(--w) * 78ms)}
@keyframes k-wyou{
  0%,11%{opacity:0; transform:translateY(3px)}
  15%,86%{opacity:1; transform:none}
  91%,100%{opacity:0}
}
@keyframes k-wit{
  0%,50%{opacity:0; transform:translateY(3px)}
  54%,86%{opacity:1; transform:none}
  91%,100%{opacity:0}
}

/* the controls, so it reads as a call and not a diagram */
.v-controls{display:flex; justify-content:center; gap:9px; padding:0 0 clamp(11px,1.3vw,16px);
            flex:none}
.v-btn{width:clamp(17px,2vw,26px); aspect-ratio:1; border-radius:50%;
       background:rgba(236,232,225,.1); display:grid; place-items:center; color:var(--paper-soft)}
.v-btn svg{width:52%; height:52%}
.v-btn.end{background:#e5484d; color:#fff}
.v-muted{animation-name:k-vmute}
@keyframes k-vmute{
  0%,20%{background:rgba(236,232,225,.1)}
  24%,86%{background:rgba(236,232,225,.1)}
  100%{background:rgba(236,232,225,.1)}
}

/* ══ SCENE: memory ════════════════════════════════════════════════
   Two acts in one window, replacing each other in place: the moment a
   fact is stored, and the moment weeks later when it is used. The badge
   on the second answer is the point — you can see where the fact came
   from and when, which is the difference between memory and a guess.
   ══════════════════════════════════════════════════════════════════ */
.mem-thread{display:flex; flex-direction:column; gap:7px; height:100%; justify-content:center}
.mb{
  border-radius:9px; padding:7px 9px; font-size:9.5px; line-height:1.55; max-width:82%;
  position:relative;
}
.mb.me{align-self:flex-end; background:rgba(209,160,90,.15);
       border:1px solid var(--brass-soft); color:var(--brass-lit)}
.mb.ai{align-self:flex-start; background:rgba(236,232,225,.05);
       border:1px solid var(--line); color:var(--paper-soft)}
.saved{
  align-self:flex-start; display:inline-flex; align-items:center; gap:6px;
  padding:3px 9px; border-radius:99px; font-size:8px; letter-spacing:.11em;
  text-transform:uppercase; background:rgba(99,211,156,.1);
  border:1px solid rgba(99,211,156,.3); color:var(--green);
}
.from-mem{
  display:inline-flex; align-items:center; gap:5px; margin-top:5px; padding:2px 7px;
  border-radius:99px; font-size:7.5px; letter-spacing:.1em; text-transform:uppercase;
  background:rgba(209,160,90,.14); border:1px solid var(--brass-soft); color:var(--brass);
}
.mem-when{
  display:flex; align-items:center; gap:11px; font-size:8px; letter-spacing:.19em;
  text-transform:uppercase; color:var(--paper-dim); padding:2px 0;
}
.mem-when::before,.mem-when::after{content:""; height:1px; flex:1;
  background:linear-gradient(90deg,transparent,var(--line-strong),transparent)}
.act-1{animation-name:k-act1} .act-2{animation-name:k-act2}
@keyframes k-act1{
  0%,6%{opacity:0; transform:translateY(8px)}
  13%,44%{opacity:1; transform:none}
  50%,100%{opacity:0; transform:translateY(-7px)}
}
@keyframes k-act2{
  0%,48%{opacity:0; transform:translateY(8px)}
  56%,88%{opacity:1; transform:none}
  94%,100%{opacity:0; transform:translateY(-7px)}
}
.mem-w1{animation-name:k-mw1} .mem-w2{animation-name:k-mw2} .mem-w3{animation-name:k-mw3}
@keyframes k-mw1{0%,10%{opacity:0; transform:translateY(6px)} 16%,44%{opacity:1; transform:none} 50%,100%{opacity:0}}
@keyframes k-mw2{0%,20%{opacity:0; transform:translateY(6px)} 26%,44%{opacity:1; transform:none} 50%,100%{opacity:0}}
@keyframes k-mw3{0%,30%{opacity:0; transform:scale(.9)} 36%,44%{opacity:1; transform:none} 50%,100%{opacity:0}}
.mem-x1{animation-name:k-mx1} .mem-x2{animation-name:k-mx2}
@keyframes k-mx1{0%,52%{opacity:0; transform:translateY(6px)} 58%,88%{opacity:1; transform:none} 94%,100%{opacity:0}}
@keyframes k-mx2{0%,64%{opacity:0; transform:translateY(6px)} 70%,88%{opacity:1; transform:none} 94%,100%{opacity:0}}

/* ══ SCENE: games ═════════════════════════════════════════════════
   The blocks are Scratch's real shapes — the notch on top and bottom is
   what makes a block read as a block — and the stage runs an actual
   little platformer: parallax hills, drifting clouds, a character with
   squash and stretch, coins that pop, and a score that counts them.
   A crude sprite on a flat rectangle undersold the feature; this is
   what the generated project actually looks like when it runs.
   ══════════════════════════════════════════════════════════════════ */
.game{display:grid; grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);
      gap:clamp(14px,2.4vw,34px); margin-top:clamp(16px,2.4vh,28px); align-items:center}

/* ── the script ─────────────────────────────────────────────────── */
.blocks{display:grid; gap:3px; justify-items:start}
.blk{
  position:relative; font-family:var(--mono);
  font-size:clamp(9px,.9vw,11px); line-height:1;
  padding:8px 13px; border-radius:5px; color:#10131a; font-weight:500;
  white-space:nowrap; animation-name:k-blk; animation-delay:calc(var(--n) * 80ms);
  box-shadow:0 2px 0 rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.28);
}
/* Scratch's puzzle notch: a dimple under each block and a matching bump
   on the one below it. Without these the stack reads as coloured pills. */
.blk::after{
  content:""; position:absolute; left:13px; bottom:-3px; width:13px; height:5px;
  border-radius:0 0 4px 4px; background:inherit; box-shadow:0 2px 0 rgba(0,0,0,.3);
}
.blk-hat{border-radius:12px 12px 5px 5px; padding-top:11px}
.blk-e{background:#ffbf00} .blk-m{background:#4c97ff; color:#f2f7ff}
.blk-c{background:#ffab19} .blk-l{background:#cf63cf; color:#fff}
.blk-in{margin-left:15px}
@keyframes k-blk{
  0%,4%{opacity:0; transform:translate(-14px,-5px) rotate(-2.5deg)}
  11%,94%{opacity:1; transform:none}
  99%,100%{opacity:0}
}

/* ── the stage ──────────────────────────────────────────────────── */
.stagebox{
  position:relative; aspect-ratio:4/3; width:100%; max-width:420px; justify-self:end;
  border-radius:12px; overflow:hidden; border:1px solid var(--line-strong);
  box-shadow:0 26px 64px -26px rgba(0,0,0,.85);
  background:linear-gradient(180deg,#ffd9a8 0%,#ffc48a 22%,#a8d8e8 58%,#cbe8ef 100%);
  animation-name:k-stage;
}
@keyframes k-stage{
  0%,24%{opacity:0; transform:scale(.975)}
  32%,94%{opacity:1; transform:none}
  99%,100%{opacity:0}
}
.sun{
  position:absolute; left:16%; top:13%; width:15%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle,#fff6de,#ffd48a 62%,rgba(255,196,120,0) 74%);
  filter:blur(.3px);
}
.cloud{
  position:absolute; height:5.5%; border-radius:99px; background:rgba(255,255,255,.9);
  animation:k-cloud 24s ease-in-out infinite alternate; animation-play-state:paused;
}
.live .cloud{animation-play-state:running}
.cloud::before,.cloud::after{content:""; position:absolute; bottom:0; border-radius:50%;
       background:inherit}
.cloud::before{left:16%; width:44%; height:180%}
.cloud::after{right:14%; width:34%; height:140%}
.c1{width:24%; top:16%; left:52%}
.c2{width:17%; top:27%; left:26%; opacity:.75; animation-duration:31s}
.c3{width:20%; top:9%; left:78%; opacity:.6; animation-duration:19s}
@keyframes k-cloud{
  0%{transform:translateX(0)} 100%{transform:translateX(-14%)}
}
.hill{position:absolute; left:-6%; right:-6%; border-radius:50% 50% 0 0}
.hill-far{bottom:22%; height:26%; background:#8fc98a; opacity:.75}
.hill-mid{bottom:20%; height:19%; left:-24%; right:34%; background:#79bd77}
.hill-near{bottom:20%; height:15%; left:38%; right:-22%; background:#6cb26c}
.ground{
  position:absolute; left:0; right:0; bottom:0; height:20%;
  background:linear-gradient(180deg,#7cc36f 0 26%,#5b9c52 26% 100%);
}
.ground::after{
  content:""; position:absolute; inset:0;
  background-image:radial-gradient(circle at 12% 62%, rgba(0,0,0,.06) 0 6%, transparent 6%),
                   radial-gradient(circle at 48% 78%, rgba(0,0,0,.05) 0 5%, transparent 5%),
                   radial-gradient(circle at 82% 58%, rgba(0,0,0,.06) 0 6%, transparent 6%);
}

/* ── the character ──────────────────────────────────────────────────
   Named `.sprite`, not `.hero`: the title chapter's container is
   `<div class="inner hero">`, and when this rule was called `.hero` it
   applied to that too — absolute, 13% wide, pinned 20% up from the
   bottom of a 12 000px page. The whole opening screen was thrown nine
   thousand pixels down the document as a 187px column, which is why
   the deck opened black. */
.sprite{
  position:absolute; bottom:20%; left:9%; width:13%; aspect-ratio:1;
  animation-name:k-sprite;
}
.sprite .body{
  position:absolute; inset:0; border-radius:34% 34% 42% 42%;
  background:linear-gradient(165deg,#ff9a4d,#f2702a 58%,#d1541a);
  box-shadow:inset 0 -14% 0 rgba(0,0,0,.1), inset 0 3px 0 rgba(255,255,255,.4);
  animation-name:k-squash;
}
.sprite .ear{position:absolute; top:-19%; width:30%; height:30%; background:#f9853a;
           border-radius:44% 44% 6% 6%}
.sprite .ear.l{left:8%; transform:rotate(-14deg)}
.sprite .ear.r{right:8%; transform:rotate(14deg)}
.sprite .eye{position:absolute; top:36%; width:15%; aspect-ratio:1; border-radius:50%;
           background:#2a1a10}
.sprite .eye.l{left:26%} .hero .eye.r{right:26%}
.sprite .eye::after{content:""; position:absolute; left:16%; top:12%; width:42%; height:42%;
                  border-radius:50%; background:#fff; opacity:.9}
.sprite .cheek{position:absolute; top:52%; width:13%; aspect-ratio:1; border-radius:50%;
             background:rgba(255,120,80,.55)}
.sprite .cheek.l{left:14%} .hero .cheek.r{right:14%}
.sprite .smile{position:absolute; left:41%; top:56%; width:18%; height:9%;
             border-bottom:1.6px solid #2a1a10; border-radius:0 0 60% 60%}
.sprite .shadow{
  position:absolute; left:12%; right:12%; bottom:-9%; height:11%; border-radius:50%;
  background:rgba(0,0,0,.22); filter:blur(1.4px); animation-name:k-shadow;
}
@keyframes k-sprite{
  0%,34%{left:9%; transform:translateY(0)}
  44%{left:30%; transform:translateY(-34%)}
  49%{left:38%; transform:translateY(0)}
  58%{left:54%; transform:translateY(-38%)}
  63%{left:62%; transform:translateY(0)}
  76%,100%{left:78%; transform:translateY(0)}
}
@keyframes k-squash{
  0%,34%{transform:scale(1,1)}
  37%{transform:scale(1.14,.86)}
  44%{transform:scale(.92,1.1)}
  49%{transform:scale(1.14,.86)}
  53%{transform:scale(1,1)}
  56%{transform:scale(1.12,.88)}
  58%{transform:scale(.93,1.09)}
  63%{transform:scale(1.13,.87)}
  67%,100%{transform:scale(1,1)}
}
@keyframes k-shadow{
  0%,34%{opacity:.24; transform:scaleX(1)}
  44%{opacity:.1; transform:scaleX(.66)}
  49%{opacity:.24; transform:scaleX(1)}
  58%{opacity:.1; transform:scaleX(.62)}
  63%,100%{opacity:.24; transform:scaleX(1)}
}

/* ── coins ──────────────────────────────────────────────────────── */
.coin{
  position:absolute; width:7.5%; aspect-ratio:1; border-radius:50%;
  background:radial-gradient(circle at 34% 30%,#ffe9a8,#ffc93c 52%,#e09a12);
  box-shadow:0 0 12px rgba(255,201,60,.55), inset 0 -2px 0 rgba(0,0,0,.16);
  display:grid; place-items:center; animation-name:k-coin;
}
.coin::after{content:"★"; font-size:.62em; color:#b9760a; line-height:1}
.k1{left:31%; bottom:41%; animation-name:k-coin1}
.k2{left:55%; bottom:44%; animation-name:k-coin2}
.k3{left:71%; bottom:32%; animation-name:k-coin3}
/* A keyframe selector has to be a literal percentage — calc() and var()
   are not allowed there, and a rule written that way is dropped whole.
   Each coin therefore gets its own timings, popping as the character
   actually reaches it. */
@keyframes k-coin1{
  0%,31%{opacity:0; transform:scale(.5) translateY(6px)}
  35%,43%{opacity:1; transform:none}
  46%{opacity:0; transform:scale(1.8) translateY(-42%)}
  100%{opacity:0; transform:scale(1.8) translateY(-42%)}
}
@keyframes k-coin2{
  0%,31%{opacity:0; transform:scale(.5) translateY(6px)}
  35%,57%{opacity:1; transform:none}
  60%{opacity:0; transform:scale(1.8) translateY(-42%)}
  100%{opacity:0; transform:scale(1.8) translateY(-42%)}
}
@keyframes k-coin3{
  0%,31%{opacity:0; transform:scale(.5) translateY(6px)}
  35%,67%{opacity:1; transform:none}
  70%{opacity:0; transform:scale(1.8) translateY(-42%)}
  100%{opacity:0; transform:scale(1.8) translateY(-42%)}
}
/* the flag, and the score it is worth */
.goal{position:absolute; right:9%; bottom:20%; width:2.4%; height:24%;
      background:linear-gradient(90deg,#7a5a3a,#c39a6b 50%,#7a5a3a); border-radius:2px;
      animation-name:k-stage}
.goal::after{
  content:""; position:absolute; left:100%; top:4%; width:340%; height:44%;
  background:
    repeating-conic-gradient(#e5484d 0 25%, #fff 0 50%) 0 0 / 50% 50%;
  clip-path:polygon(0 0,100% 30%,0 60%);
  animation:k-wave 2.6s ease-in-out infinite; animation-play-state:paused;
}
.live .goal::after{animation-play-state:running}
@keyframes k-wave{
  0%,100%{transform:skewY(0deg)} 50%{transform:skewY(-4deg)}
}
.score{
  position:absolute; right:5%; top:5%; display:flex; align-items:center; gap:5px;
  padding:3px 9px; border-radius:99px; background:rgba(255,255,255,.82);
  border:1px solid rgba(0,0,0,.08); font-family:var(--display); font-weight:600;
  font-size:clamp(8px,.85vw,10.5px); color:#3a2a16; animation-name:k-stage;
}
.score .n{position:relative; width:8px; height:11px; display:grid; place-items:center}
.score .n span{position:absolute}
.sc0{animation-name:k-sc0} .sc1{animation-name:k-sc1}
.sc2{animation-name:k-sc2} .sc3{animation-name:k-sc3}
@keyframes k-sc0{0%,31%{opacity:0} 34%,44%{opacity:1} 46%,100%{opacity:0}}
@keyframes k-sc1{0%,45%{opacity:0} 47%,57%{opacity:1} 60%,100%{opacity:0}}
@keyframes k-sc2{0%,58%{opacity:0} 60%,67%{opacity:1} 70%,100%{opacity:0}}
@keyframes k-sc3{0%,68%{opacity:0} 71%,94%{opacity:1} 98%,100%{opacity:0}}
.win{
  position:absolute; inset:0; display:grid; place-items:center; animation-name:k-win;
}
.win b{
  font-family:var(--display); font-weight:600; font-size:clamp(13px,1.5vw,19px);
  color:#fff; text-shadow:0 2px 0 #e09a12, 0 0 22px rgba(255,201,60,.85);
  letter-spacing:.02em;
}
@keyframes k-win{
  0%,74%{opacity:0; transform:scale(.7)}
  79%,94%{opacity:1; transform:scale(1)}
  98%,100%{opacity:0; transform:scale(1.08)}
}

/* ══ SCENE: models ════════════════════════════════════════════════
   The picker is real and these are the names it actually lists. The
   chapter's claim is that you rarely have to open it: the request is
   read, the right model is already selected, and the label under the
   list says which and why.
   ══════════════════════════════════════════════════════════════════ */
.pickbar{
  display:flex; align-items:center; gap:8px; padding:6px 11px; border-radius:8px;
  border:1px solid var(--line-strong); background:rgba(236,232,225,.04);
  font-size:10.5px; color:var(--paper); align-self:flex-start;
}
.pickbar .cv{width:9px; height:9px; opacity:.55}
.picklist{
  margin-top:6px; border-radius:11px; border:1px solid var(--line-strong);
  background:#12151b; overflow:hidden; box-shadow:0 26px 60px -24px rgba(0,0,0,.9);
  animation-name:k-picklist;
}
@keyframes k-picklist{
  0%,16%{opacity:0; transform:translateY(-7px) scale(.985)}
  23%,88%{opacity:1; transform:none}
  94%,100%{opacity:0; transform:translateY(-5px)}
}
.pk{
  display:flex; align-items:center; gap:9px; padding:7px 11px; font-size:10px;
  border-bottom:1px solid rgba(236,232,225,.05);
}
.pk:last-child{border-bottom:none}
.pk .nm{flex:1; font-family:var(--mono); font-size:9.5px; color:var(--paper-soft)}
.pk .tier{font-size:7.5px; letter-spacing:.13em; text-transform:uppercase;
          padding:2px 7px; border-radius:99px; border:1px solid var(--line);
          color:var(--paper-dim)}
.pk .tick{width:11px; opacity:0; color:var(--brass)}
.pk-on{animation-name:k-pkon}
@keyframes k-pkon{
  0%,40%{background:transparent}
  48%,88%{background:rgba(209,160,90,.11)}
  94%,100%{background:transparent}
}
.pk-on .nm{color:var(--brass-lit)}
.pk-on .tick{animation-name:k-pktick}
@keyframes k-pktick{0%,44%{opacity:0} 52%,88%{opacity:1} 94%,100%{opacity:0}}
.why{
  display:block; margin-top:clamp(11px,1.6vh,17px);
  font-size:11.5px; line-height:1.6; color:var(--paper-soft); animation-name:k-why;
}
.why b{color:var(--brass); font-weight:500}
@keyframes k-why{
  0%,54%{opacity:0; transform:translateY(6px)} 62%,88%{opacity:1; transform:none}
  94%,100%{opacity:0}
}
.askbar{
  padding:clamp(10px,1.2vw,14px) clamp(12px,1.4vw,16px); border-radius:10px;
  border:1px solid var(--brass-soft); background:rgba(209,160,90,.07);
  font-family:var(--mono); font-size:clamp(10px,1vw,12px); color:var(--brass-lit);
  animation-name:k-ask;
}
@keyframes k-ask{
  0%,4%{opacity:0; transform:translateY(8px)} 11%,88%{opacity:1; transform:none}
  94%,100%{opacity:0}
}
.route{display:grid; gap:clamp(11px,1.6vh,18px); margin-top:clamp(16px,2.4vh,28px);
       max-width:560px}

/* ══ SCENE: access ════════════════════════════════════════════════
   Invite-only is a decision, not a limitation, so the scene shows the
   decision being made: a request arrives, a person answers it, and the
   door opens. The approval happens in Telegram because that is where
   it actually happens.
   ══════════════════════════════════════════════════════════════════ */
.gate{display:grid; gap:clamp(12px,1.8vh,20px); margin-top:clamp(16px,2.4vh,28px);
      max-width:600px}
.req{
  position:relative;
  display:grid; gap:9px; padding:clamp(12px,1.5vw,17px); border-radius:12px;
  border:1px solid var(--line); background:linear-gradient(168deg,var(--glass),var(--glass-2));
  animation-name:k-req;
}
@keyframes k-req{
  0%,5%{opacity:0; transform:translateY(11px)}
  13%,90%{opacity:1; transform:none}
  95%,100%{opacity:0}
}
.req .top{display:flex; align-items:center; gap:9px; font-size:9.5px;
          letter-spacing:.17em; text-transform:uppercase; color:var(--paper-dim)}
.req .top b{color:var(--brass); font-weight:500}
.req .nm{font-family:var(--display); font-size:clamp(13px,1.3vw,16px); font-weight:500}
.req .rs{font-size:12px; color:var(--paper-soft); line-height:1.55}
/* The buttons and what replaces them share one cell, so the card keeps its
   height when they go — a fading row that still held its space left an
   obvious hole under the request. */
.act-slot{display:grid; margin-top:3px}
.act-slot > *{grid-area:1 / 1}
.answers{display:flex; gap:9px}
.answered{
  display:flex; align-items:center; justify-content:center; gap:8px;
  padding:8px 0; border-radius:8px; font-size:11px; font-weight:600;
  background:rgba(99,211,156,.1); border:1px solid rgba(99,211,156,.35);
  color:var(--green); animation-name:k-answered;
}
@keyframes k-answered{
  0%,48%{opacity:0; transform:scale(.97)}
  53%,90%{opacity:1; transform:none}
  95%,100%{opacity:0}
}
.ans-btn{
  flex:1; text-align:center; padding:8px 0; border-radius:8px; font-size:11px;
  font-weight:600; letter-spacing:.04em; animation-name:k-ansbtn;
}
.ans-yes{background:#2ea6ff; color:#fff}
.ans-no{background:rgba(236,232,225,.07); border:1px solid var(--line-strong); color:var(--paper-dim)}
@keyframes k-ansbtn{
  0%,20%{opacity:0; transform:translateY(6px)}
  26%,44%{opacity:1; transform:none}
  46%{opacity:1; transform:scale(.95)}
  50%,100%{opacity:0; transform:translateY(-4px)}
}
.gate-cursor{left:34%; top:76%; animation-name:k-gatecur}
@keyframes k-gatecur{
  0%,26%{opacity:0; transform:translate(-70px,68px)}
  30%{opacity:1; transform:translate(-70px,68px)}
  42%{opacity:1; transform:translate(0,0)}
  45%{opacity:1; transform:translate(1px,2px) scale(.9)}
  48%{opacity:1; transform:translate(0,0)}
  56%,100%{opacity:0; transform:translate(-40px,52px)}
}
.granted{
  display:flex; align-items:center; gap:10px; padding:clamp(12px,1.5vw,17px);
  border-radius:12px; border:1px solid rgba(99,211,156,.4);
  background:rgba(99,211,156,.07); color:var(--green); font-size:12.5px; font-weight:500;
  animation-name:k-granted;
}
.granted svg{width:16px; height:16px; flex:none}
@keyframes k-granted{
  0%,50%{opacity:0; transform:translateY(10px) scale(.97)}
  57%,90%{opacity:1; transform:none}
  95%,100%{opacity:0}
}
.gate-note{font-size:11.5px; color:var(--paper-dim); animation-name:k-granted}

/* ══ SCENE: architecture ══════════════════════════════════════════
   One claim carries this scene: the machine never listens outward.
   So the packet is drawn arriving at Cloudflare, and the connection
   it rides is drawn leaving the box — the arrow points the way the
   tunnel actually goes, which is the opposite of what people expect.
   ══════════════════════════════════════════════════════════════════ */
.arch{position:relative; display:grid; gap:clamp(9px,1.3vh,15px);
      margin-top:clamp(14px,2vh,24px); max-width:760px}
/* A request drawn travelling the path it really takes. It runs down the
   left margin so it never sits on top of a label. */
.packet{
  position:absolute; left:-15px; width:8px; height:8px; border-radius:50%;
  background:var(--brass); box-shadow:0 0 15px 3px var(--brass-glow);
  z-index:3; animation-name:k-packet;
}
@keyframes k-packet{
  0%,6%{opacity:0; top:4%}
  11%{opacity:1; top:4%}
  24%{opacity:1; top:24%}
  38%{opacity:1; top:47%}
  52%{opacity:1; top:68%}
  64%{opacity:1; top:88%}
  70%,100%{opacity:0; top:88%}
}
.nd .badge{
  float:right; font-size:7.5px; letter-spacing:.1em; text-transform:uppercase;
  padding:1px 6px; border-radius:99px; border:1px solid var(--line-strong);
  color:var(--paper-dim); margin-left:8px;
}
.nd .badge.ok{border-color:rgba(99,211,156,.35); color:var(--green)}
.tier{display:flex; gap:clamp(7px,1vw,12px)}
.nd{
  flex:1; padding:clamp(9px,1.1vw,14px) clamp(10px,1.2vw,15px); border-radius:10px;
  border:1px solid var(--line); background:rgba(236,232,225,.022); min-width:0;
}
.nd b{display:block; font-family:var(--display); font-size:clamp(11px,1.05vw,12.5px);
      font-weight:500; margin-bottom:3px}
/* Direct children only: the port sits inside these lines, and a descendant
   selector was turning it into a block of its own — which put every port
   number on a line by itself. */
.nd > span{display:block; font-size:10px; color:var(--paper-dim); line-height:1.45}
.nd .port{display:inline; color:var(--brass); font-family:var(--mono)}
.hit{animation-name:k-hit; animation-delay:calc(var(--n) * 620ms)}
@keyframes k-hit{
  0%,7%{border-color:var(--line); background:rgba(236,232,225,.022); box-shadow:none}
  11%,14%{border-color:var(--brass); background:rgba(209,160,90,.1);
          box-shadow:0 0 34px -12px var(--brass-glow)}
  22%,100%{border-color:var(--line-strong); background:rgba(236,232,225,.03); box-shadow:none}
}
.link-row{
  display:flex; align-items:center; gap:11px; padding-left:4px;
  font-size:10px; letter-spacing:.15em; text-transform:uppercase; color:var(--paper-dim);
}
.link-row .arrow-out{
  color:var(--brass); font-size:13px; letter-spacing:0; animation-name:k-out;
}
@keyframes k-out{
  0%,14%{opacity:.25; transform:translateY(0)}
  20%{opacity:1; transform:translateY(-5px)}
  30%{opacity:.25; transform:translateY(0)}
  100%{opacity:.25; transform:translateY(0)}
}
.no-port{
  margin-top:clamp(10px,1.5vh,16px); display:flex; align-items:center; gap:11px;
  border-left:1px solid var(--brass); padding:3px 0 3px 14px;
  font-size:12.5px; color:var(--paper-soft); animation-name:k-noport;
}
.no-port b{color:var(--brass); font-weight:500}
@keyframes k-noport{
  0%,60%{opacity:0; transform:translateX(-6px)}
  68%,92%{opacity:1; transform:none}
  97%,100%{opacity:0}
}

/* ══ text chapters ════════════════════════════════════════════════ */
.claims{display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr));
        gap:clamp(16px,2.4vw,34px); margin-top:clamp(22px,3.2vh,40px)}
.claim{border-top:1px solid var(--line); padding-top:15px}
.claim b{display:block; font-family:var(--display); font-size:clamp(13px,1.25vw,15.5px);
         font-weight:500; margin-bottom:7px}
.claim span{display:block; font-size:12.5px; color:var(--paper-soft); line-height:1.65;
            font-weight:300}
.claim-lit{border-top-color:var(--brass-soft)}
.claim-lit b{color:var(--brass)}

.figs{display:grid; grid-template-columns:repeat(auto-fit,minmax(158px,1fr));
      column-gap:clamp(18px,2.5vw,44px); border-top:1px solid var(--line);
      margin-top:clamp(24px,3.4vh,44px)}
.fg{padding:clamp(16px,2.3vh,26px) 0; border-bottom:1px solid var(--line); min-width:0}
.fg b{display:block; font-family:var(--display); font-weight:200;
      font-size:clamp(1.6rem,2.8vw,2.4rem); line-height:1; letter-spacing:-.035em;
      font-variant-numeric:tabular-nums}
.fg s{display:block; text-decoration:none; margin-top:8px; font-size:10px;
      letter-spacing:.16em; text-transform:uppercase; color:var(--paper-dim); font-weight:500}
.fg-lit b{color:var(--brass)} .fg-lit s{color:var(--brass-soft)}

.who-grid{display:grid; grid-template-columns:auto minmax(0,1fr);
          gap:clamp(20px,3vw,44px); align-items:start; margin-top:clamp(20px,3vh,34px)}
.who-facts{display:grid; gap:13px; align-content:start; min-width:190px}
.who-facts div{display:grid; gap:2px}
.who-facts dt{font-size:9.5px; letter-spacing:.17em; text-transform:uppercase;
              color:var(--paper-dim)}
.who-facts dd{margin:0; font-size:13px; color:var(--paper)}
.who-say p{margin:0 0 13px; color:var(--paper-soft); font-size:clamp(13.5px,1.2vw,15.5px);
           line-height:1.7; font-weight:300; max-width:52ch}
.who-say p:last-child{margin-bottom:0}
.ends{margin-top:clamp(26px,4vh,50px); display:flex; align-items:center; gap:14px;
      font-size:12px; letter-spacing:.16em; text-transform:uppercase; color:var(--paper-dim)}
.ends::before{content:""; width:34px; height:1px; background:var(--brass-soft)}
@media (max-width:780px){ .who-grid{grid-template-columns:1fr} }

/* The request carries a name, a Telegram handle and — when they were signed
   in — the address on the account. It does not carry a reason: there is no
   such field, and inventing one on a slide is the kind of detail somebody
   checks. */
.req .nm em{font-style:normal; color:var(--paper-dim); font-weight:400;
            font-family:var(--body); font-size:.78em; margin-left:7px}
.req .rs b{color:var(--paper); font-weight:500; font-family:var(--mono); font-size:.94em}

/* The mark block ignores the pointer so it never sits between the reader and
   the page; the language link inside it has to opt back in. */
.mark{pointer-events:none}
.mark .lang{
  pointer-events:auto; margin-left:14px; padding:3px 9px; border-radius:99px;
  border:1px solid var(--line-strong); font-size:10px; letter-spacing:.14em;
  color:var(--paper-dim); text-decoration:none;
  transition:color .25s ease, border-color .25s ease;
}
.mark .lang:hover{color:var(--brass); border-color:var(--brass-soft)}
