/* ══════════════════════════════════════════════════════════════════
   scenes.css — the four animated feature scenes under the tab bar
   Loaded by index.html only. The legal pages never touch this.
   ══════════════════════════════════════════════════════════════════

   ONE STAGE SIZE. All four scenes are 980×620. They live under a tab
   bar, and a tab bar whose panel changes height moves the page under
   the reader's cursor every time they switch — the cheapest way to
   make a considered site feel unfinished.

   ONE CLOCK PER SCENE. Each declares a single --loop; every moving
   part is keyframed as a percentage of it.

   POSITIONS ARE COMPUTED. The block between the GENERATED sentinels
   comes from tools/gen_choreography.py — scatter, flight paths,
   spirals and the search masonry, with the no-overlap conditions
   asserted rather than eyeballed. Edit the generator, not the block.
   ══════════════════════════════════════════════════════════════════ */

.scene-wrap{width:100%;max-width:980px;margin:40px auto 0}
.scene{
  position:relative;width:980px;height:620px;
  border-radius:22px;overflow:hidden;
  border:1px solid rgba(0,0,0,.07);
  box-shadow:0 1px 2px rgba(0,0,0,.04),0 18px 48px -24px rgba(0,0,0,.22);
  text-align:left;contain:paint;
}
.scene *{box-sizing:border-box}
.tab-pane:not(.active) .scene *{animation-play-state:paused!important}

/* Between 760 and 1040 the stage is SCALED as a whole rather than
   reflowed, so every computed coordinate stays true — the wrapper
   holds the height the scaled box now occupies. Below 760 it is
   replaced outright; see SMALL SCREENS at the foot of this file. */
@media (max-width:1040px){
  /* min(1, …) — WITHOUT IT THIS SCALES UP. The query fires at 1040px,
     where (100vw − 44) / 980 is 1.016, so the stage was being enlarged
     past its natural size for the first 60px below the breakpoint and
     everything in it was soft. The wrapper's height has to follow the
     same expression, because a scaled box still reserves its original
     layout size and the difference is the gap. */
  .scene-wrap{height:calc(620px * min(1, (100vw - 44px)/980))}
  .scene{transform:scale(min(1, calc((100vw - 44px)/980)));transform-origin:top left}
}

.sc-chrome{display:flex;align-items:center;gap:10px;padding:0 14px;height:38px;flex:none;
  background:rgba(250,250,252,.94);border-bottom:1px solid rgba(0,0,0,.07)}
.sc-dots{display:flex;gap:6px}
.sc-dots i{width:10px;height:10px;border-radius:50%;display:block}
.sc-dots i:nth-child(1){background:#ff5f57}
.sc-dots i:nth-child(2){background:#febc2e}
.sc-dots i:nth-child(3){background:#28c840}
.sc-title{font-size:12.5px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.sc-meta{font-size:11px;color:var(--dim);margin-left:auto}
/* ══════════════════════════════════════════════════════════════════
   1 · NOTES — the editor, on one page
   ══════════════════════════════════════════════════════════════════
   ONE PAGE, ANNOTATED IN PLACE. An earlier version put the poem in one
   column and the thinking in another, which is two documents side by
   side — the opposite of the claim. The notes are now written BETWEEN
   the lines and out in the margin, on the same page, which is what a
   marked-up page actually is and what the product actually does.

   THE PAGE IS 680 WIDE, not the full stage. A document editor shows a
   page, not a wall; the earlier full-bleed sheet read as a spreadsheet.
   The verse only runs to ~300px of it, and the 290px of margin left
   over is not waste — it is where the hand goes.

   GEOMETRY IS FIXED IN PX, because the pen's flight path is derived
   from it:
       toolbar    y 0…60
       title      y 66…104
       sheet      (150,112) 680×492, padding 44 / 30
       INK ORIGIN (194,142) — sheet-inner (0,0)
       pen         X = ix + 184   Y = iy + 80   (nib 10,62 of a 72 box)
       highlighter X = ix + 182   Y = iy + 82   (chisel 12,60)

   Verse: starts inner y 44, line-height 24, and lines 4, 8 and 12 carry
   a 14px gap so there is real room to write underneath them. Every
   annotation is placed against those numbers, listed beside ed-fly.

   ONE CLOCK: --loop. The pen is AT a mark for exactly the window in
   which that mark draws, asserted by tools/check_scene.py.
   ══════════════════════════════════════════════════════════════════ */
.sc-notes{
  --loop:28s;
  background:linear-gradient(180deg,#f6f6f8,#eceef1);
}
.ed{position:absolute;inset:0}

/* ── Toolbar. A round button hard left, the tools dead centre, the
      actions hard right. The centre capsule is absolutely positioned
      so it centres on the STAGE and not on whatever space is left over
      between the other two. ── */
.ed-bar{
  position:absolute;left:0;right:0;top:0;height:60px;
  display:flex;align-items:center;padding:0 28px;
}
.ed-round{
  width:34px;height:34px;border-radius:50%;flex:none;
  background:#fff;border:1px solid rgba(0,0,0,.08);
  box-shadow:0 1px 2px rgba(0,0,0,.05);
  display:grid;place-items:center;color:#3a3a42;
}
.ed-round svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}

.ed-cap{
  display:flex;align-items:center;gap:1px;height:38px;padding:0 5px;
  border-radius:19px;background:#fff;border:1px solid rgba(0,0,0,.08);
  box-shadow:0 1px 2px rgba(0,0,0,.05);
}
.ed-cap-mid{position:absolute;left:50%;transform:translateX(-50%)}
.ed-cap-right{margin-left:auto}

.ed-i{
  width:30px;height:30px;border-radius:15px;flex:none;
  display:grid;place-items:center;color:#3a3a42;background:transparent;
}
/* fill:none on the SHAPES, not just the <svg>. Renderers disagree about
   whether a presentation attribute inherits through, and a shapes icon
   arriving as a solid black blob is the failure. */
.ed-i svg{width:16px;height:16px;stroke-width:1.45;
  stroke-linecap:round;stroke-linejoin:round}
.ed-i svg path,.ed-i svg rect,.ed-i svg circle{fill:none;stroke:currentColor}
.ed-i svg .f{fill:currentColor;stroke:none}
.ed-i svg .f2{fill:currentColor;opacity:.16;stroke:none}

/* The tool doing the work lights up. Two small truths that make the
   toolbar part of the demonstration rather than decoration above it. */
.ed-i.on-pen{animation:ed-actA var(--loop) step-end infinite}
.ed-i.on-rec{animation:ed-actB var(--loop) step-end infinite}
@keyframes ed-actA{
  0%,3%   {color:#3a3a42;background:transparent}
  4%,84%  {color:#0071e3;background:rgba(0,113,227,.11)}
  86%,100%{color:#3a3a42;background:transparent}
}
@keyframes ed-actB{
  0%,19%  {color:#3a3a42;background:transparent}
  20%,90% {color:#ff3b30;background:rgba(255,59,48,.10)}
  92%,100%{color:#3a3a42;background:transparent}
}

/* nowrap: an absolutely positioned box with only `left` set is
   shrink-to-fit and will break the title onto a second line that then
   collides with the page. */
.ed-title{
  position:absolute;left:150px;top:66px;white-space:nowrap;
  font-size:23px;font-weight:660;letter-spacing:-.024em;color:#1a1a1f;line-height:32px;
}

/* ── The page ── */
.ed-sheet{
  position:absolute;left:150px;top:112px;width:680px;height:492px;
  background:#fff;border-radius:14px;border:1px solid rgba(0,0,0,.07);
  box-shadow:0 1px 2px rgba(0,0,0,.04),0 20px 40px -26px rgba(20,24,40,.30);
  overflow:hidden;
}
/* A stacking context of its own. Everything positioned inside is placed
   against this box's origin, and nothing can escape behind the page. */
.ed-inner{position:absolute;left:44px;top:30px;width:592px;height:432px;
  isolation:isolate}

.ed-h{font-size:15px;font-weight:680;letter-spacing:-.018em;color:#1a1a1f;
  line-height:22px;margin:0}
.ed-by{font-size:10px;color:#a0a0a8;line-height:14px;margin:0 0 8px}

.ed-v{font-size:13px;line-height:24px;color:#2c2c33;margin:0;white-space:nowrap}
.ed-v.gap{margin-bottom:14px}
.ed-v.in{padding-left:18px}
.ed-v b{font-weight:660;color:#141418}
.ed-v i{font-style:italic}

/* ── Highlighter ──────────────────────────────────────────────────
   A BACKGROUND ON THE SPAN, not a pseudo-element behind it.

   The previous version used ::before with z-index:-1, which works only
   until something up the tree makes a stacking context — and .scene
   carries `contain:paint`, which makes one. The pseudo-element was
   therefore painting behind the white page and the highlighter did
   nothing at all. A background-size sweep needs no stacking games and
   cannot be broken from above. ── */
.ed-hl{
  padding:1px 3px;margin:0 -3px;border-radius:3px;
  background-repeat:no-repeat;background-position:left center;
  background-size:0% 100%;
}
.ed-hl.h1{background-image:linear-gradient(90deg,rgba(255,226,122,.95),rgba(255,212,86,.85));
  animation:ed-sw1 var(--loop) linear infinite}
.ed-hl.h2{background-image:linear-gradient(90deg,rgba(166,231,203,.95),rgba(140,222,188,.85));
  animation:ed-sw2 var(--loop) linear infinite}
/* Same windows as the highlighter's traverse in ed-mfly. Retime one,
   retime both. */
@keyframes ed-sw1{0%,4%{background-size:0% 100%} 12%{background-size:100% 100%}
  93%{background-size:100% 100%} 96%,100%{background-size:0% 100%}}
@keyframes ed-sw2{0%,24%{background-size:0% 100%} 31%{background-size:100% 100%}
  93%{background-size:100% 100%} 96%,100%{background-size:0% 100%}}

/* ── Handwriting, in the leading and in the margin ── */
.ed-hand{
  position:absolute;z-index:6;pointer-events:none;
  font-family:"Bradley Hand","Segoe Print","Snell Roundhand","Chalkboard SE",cursive;
  font-weight:600;letter-spacing:.01em;white-space:nowrap;
  clip-path:inset(0 100% 0 0);
}
/* a1 sits in the 14px gap under line 4, a2 in the gap under line 8 —
   smaller than the margin hand, because writing between lines means
   writing small. */
.ed-hand.a1{left:30px;top:139px;font-size:12px;color:#1f7a5a;transform:rotate(-1.5deg);
  animation:ed-a1 var(--loop) ease-out infinite}
.ed-hand.a2{left:30px;top:249px;font-size:12px;color:#2f6fd0;transform:rotate(1deg);
  animation:ed-a2 var(--loop) ease-out infinite}
.ed-hand.m1{left:356px;top:264px;font-size:15px;color:#d5453b;transform:rotate(-4deg);
  animation:ed-m1 var(--loop) ease-out infinite}
@keyframes ed-a1{0%,32%{clip-path:inset(0 100% 0 0)} 37%{clip-path:inset(0 0 0 0)}
  93%{clip-path:inset(0 0 0 0)} 96%,100%{clip-path:inset(0 100% 0 0)}}
@keyframes ed-a2{0%,38%{clip-path:inset(0 100% 0 0)} 43%{clip-path:inset(0 0 0 0)}
  93%{clip-path:inset(0 0 0 0)} 96%,100%{clip-path:inset(0 100% 0 0)}}
@keyframes ed-m1{0%,17%{clip-path:inset(0 100% 0 0)} 23%{clip-path:inset(0 0 0 0)}
  93%{clip-path:inset(0 0 0 0)} 96%,100%{clip-path:inset(0 100% 0 0)}}

/* ── Ink ──────────────────────────────────────────────────────────
   pathLength="1" normalises every path whatever its real length, so
   dasharray:1 / dashoffset 1→0 draws it end to end at a rate we choose
   rather than one the geometry chooses. Width and height are set in
   CSS rather than as attributes; an <svg> carrying both, inside an
   absolutely positioned box, can resolve to zero height. ── */
.ed-ink{position:absolute;left:0;top:0;width:592px;height:432px;
  z-index:5;pointer-events:none;overflow:visible}
.ed-ink path{fill:none;stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:1;stroke-dashoffset:1}
.ed-ink .k1{stroke:#d5453b;stroke-width:1.6;animation:ed-k1 var(--loop) ease-out infinite}
@keyframes ed-k1{0%,13%{stroke-dashoffset:1} 17%{stroke-dashoffset:0}
  93%{stroke-dashoffset:0} 96%,100%{stroke-dashoffset:1}}

/* The sketch. Eleven strokes drawn in the order a person would draw
   them, each one starting where the last finished, spread across the
   window with nth-child delays rather than eleven hand-written
   keyframe blocks. */
.ed-ink .k4 path{stroke:#3a3a42;stroke-width:1.3;
  animation:ed-k4 var(--loop) ease-out infinite}
.ed-ink .k4 path:nth-child(1){animation-delay:calc(var(--loop) * .00)}
.ed-ink .k4 path:nth-child(2){animation-delay:calc(var(--loop) * .014)}
.ed-ink .k4 path:nth-child(3){animation-delay:calc(var(--loop) * .028)}
.ed-ink .k4 path:nth-child(4){animation-delay:calc(var(--loop) * .042)}
.ed-ink .k4 path:nth-child(5){animation-delay:calc(var(--loop) * .056)}
.ed-ink .k4 path:nth-child(6){animation-delay:calc(var(--loop) * .066)}
.ed-ink .k4 path:nth-child(7){animation-delay:calc(var(--loop) * .078)}
.ed-ink .k4 path:nth-child(8){animation-delay:calc(var(--loop) * .092)}
.ed-ink .k4 path:nth-child(9){animation-delay:calc(var(--loop) * .104)}
.ed-ink .k4 path:nth-child(10){animation-delay:calc(var(--loop) * .118)}
.ed-ink .k4 path:nth-child(11){animation-delay:calc(var(--loop) * .132)}
@keyframes ed-k4{0%,64%{stroke-dashoffset:1} 68%{stroke-dashoffset:0}
  93%{stroke-dashoffset:0} 96%,100%{stroke-dashoffset:1}}

/* ── Handwriting becoming typed text ─────────────────────────────
   Written in the person's own hand between lines 12 and 13, scanned,
   wiped away left to right, and replaced by the typed line rising into
   its place. Showing the conversion is the only honest way to claim
   it, and doing it interlinearly rather than in a floating card keeps
   it part of the document. ── */
.ed-conv{position:absolute;left:40px;top:357px;width:300px;height:20px;z-index:7}
.ed-conv .ink,.ed-conv .txt{position:absolute;left:0;top:0;white-space:nowrap}
.ed-conv .ink{
  font-family:"Bradley Hand","Segoe Print","Snell Roundhand","Chalkboard SE",cursive;
  font-size:14px;font-weight:600;color:#7a4fd0;
  clip-path:inset(0 100% 0 0);
  animation:ed-ci var(--loop) ease-out infinite;
}
.ed-conv .txt{
  font-size:11.5px;font-weight:560;color:#7a4fd0;
  opacity:0;transform:translateY(6px);
  animation:ed-ct var(--loop) cubic-bezier(.2,.8,.3,1) infinite;
}
.ed-conv .scan{
  position:absolute;top:-4px;bottom:-4px;width:30px;pointer-events:none;
  background:linear-gradient(90deg,transparent,rgba(0,113,227,.32),transparent);
  opacity:0;animation:ed-cs var(--loop) linear infinite;
}
@keyframes ed-ci{0%,44%{clip-path:inset(0 100% 0 0)} 56%,58%{clip-path:inset(0 0 0 0)}
  63%,100%{clip-path:inset(0 0 0 100%)}}
@keyframes ed-cs{0%,57%{opacity:0;transform:translateX(-34px)} 58%{opacity:1}
  63%{opacity:1;transform:translateX(230px)} 64%,100%{opacity:0}}
@keyframes ed-ct{0%,61%{opacity:0;transform:translateY(6px)} 65%{opacity:1;transform:translateY(0)}
  93%{opacity:1;transform:translateY(0)} 96%,100%{opacity:0;transform:translateY(6px)}}

/* ── Imported PDF, clipped to the margin ─────────────────────────
   Inline in the document rather than a badge floating over it. A badge
   reads as chrome; a filename and a page number read as work. ── */
.ed-pdf{
  position:absolute;left:320px;top:44px;width:272px;height:46px;z-index:6;
  display:flex;align-items:center;gap:10px;padding:0 11px;
  border:1px solid rgba(0,0,0,.09);border-radius:9px;background:#fbfbfd;
  opacity:0;animation:ed-pdfin var(--loop) cubic-bezier(.2,.8,.3,1) infinite;
}
.ed-pdf .pg{width:22px;height:28px;border-radius:2.5px;background:#fff;flex:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);position:relative}
.ed-pdf .pg i{position:absolute;left:4px;right:4px;top:6px;height:2px;border-radius:1px;
  background:rgba(0,0,0,.18);box-shadow:0 5px 0 rgba(0,0,0,.18),0 10px 0 rgba(0,0,0,.11)}
.ed-pdf .t{font-size:10.5px;font-weight:640;color:#1a1a1f;letter-spacing:-.006em;
  white-space:nowrap}
.ed-pdf .s{font-size:9.5px;color:#9a9aa2;margin-top:2px}
.ed-pdf .ck{margin-left:auto;width:16px;height:16px;border-radius:50%;flex:none;
  background:#34c759;display:grid;place-items:center}
.ed-pdf .ck svg{width:10px;height:10px;fill:none;stroke:#fff;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
@keyframes ed-pdfin{
  0%,5%{opacity:0;transform:translateY(8px)} 8%{opacity:1;transform:translateY(0)}
  93%{opacity:1;transform:translateY(0)} 96%,100%{opacity:0;transform:translateY(8px)}
}

/* ── The recorder, floating in the lower margin ── */
.ed-rec{
  position:absolute;left:312px;top:300px;width:280px;height:112px;z-index:12;
  background:rgba(255,255,255,.97);
  border:1px solid rgba(0,0,0,.08);border-radius:13px;
  box-shadow:0 2px 5px rgba(20,24,40,.07),0 18px 34px -18px rgba(20,24,40,.36);
  padding:11px 13px;
  opacity:0;animation:ed-recin var(--loop) cubic-bezier(.2,.8,.3,1) infinite;
}
@keyframes ed-recin{
  0%,17%{opacity:0;transform:translateY(10px) scale(.98)}
  20%{opacity:1;transform:translateY(0) scale(1)}
  90%{opacity:1;transform:translateY(0) scale(1)}
  93%,100%{opacity:0;transform:translateY(10px) scale(.98)}
}
.ed-rec .hd{display:flex;align-items:center;gap:8px}
.ed-rec .dot{width:8px;height:8px;border-radius:50%;background:#ff3b30;flex:none;
  animation:ed-pulse 2.4s ease-in-out infinite}
@keyframes ed-pulse{0%,100%{opacity:1}50%{opacity:.35}}
.ed-rec .tm{font-size:12.5px;font-weight:640;color:#1a1a1f;
  font-variant-numeric:tabular-nums;display:inline-flex;align-items:baseline}
.ed-rec .tick{height:1em;line-height:1em;overflow:hidden;display:inline-block}
.ed-rec .tick span{display:block;height:1em;line-height:1em;
  animation:ed-roll 10s steps(10) infinite}
@keyframes ed-roll{to{transform:translateY(-10em)}}
.ed-rec .lb{font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:#9a9aa2}
.ed-rec .stop{margin-left:auto;width:20px;height:20px;border-radius:50%;flex:none;
  background:rgba(0,0,0,.06);display:grid;place-items:center}
.ed-rec .stop::after{content:"";width:7px;height:7px;border-radius:1.5px;background:#ff3b30}
.ed-rec .mtr{display:flex;align-items:center;gap:2px;height:22px;margin:8px 0 0}
.ed-rec .mtr i{display:block;width:3px;border-radius:2px;flex:none;height:14%;
  background:#c8c8d2;animation:ed-swell 3.4s ease-in-out infinite}
/* One swell travelling left to right, not twenty-four independent
   jitters. That is what a level meter actually looks like. */
@keyframes ed-swell{
  0%,100%{height:14%;background:#c8c8d2}
  18%{height:84%;background:#0071e3}
  36%{height:22%;background:#c8c8d2}
}
.ed-rec .tr{font-size:11px;line-height:16px;color:#5a5a64;margin-top:7px;
  border-left:2px solid rgba(0,113,227,.35);padding-left:8px;min-height:32px}
.ed-rec .tr span{display:block;overflow:hidden;white-space:nowrap;width:0;
  animation:ed-say1 var(--loop) steps(26,end) infinite}
.ed-rec .tr span:nth-child(2){animation-name:ed-say2}
@keyframes ed-say1{0%,23%{width:0} 38%{width:26ch} 90%{width:26ch} 93%,100%{width:0}}
@keyframes ed-say2{0%,44%{width:0} 58%{width:24ch} 90%{width:24ch} 93%,100%{width:0}}

/* ── The two tools ────────────────────────────────────────────────
   SYNC RULE: the tool is AT a mark for exactly the window in which
   that mark draws, and somewhere else at every other moment. Each is
   hidden while the other works, which is the only time either may
   teleport.

     highlight line 9    mark 4→12%    ed-sw1  4→12
     arrow into line 9   pen 13→17%    ed-k1   13→17
     "the volta"         pen 17→23%    ed-m1   17→23
     highlight l.12      mark 24→31%   ed-sw2  24→31
     "legal term!"       pen 32→37%    ed-a1   32→37
     "all subtraction"   pen 38→43%    ed-a2   38→43
     "= verse + lineage" pen 44→56%    ed-ci   44→56
     the sketch          pen 64→82%    ed-k4   64→68 (+ per-stroke delay)
   ────────────────────────────────────────────────────────────────── */
.ed-pen,.ed-mark{
  position:absolute;left:0;top:0;width:72px;height:72px;z-index:20;
  filter:drop-shadow(0 12px 12px rgba(20,24,40,.26));
  opacity:0;
}
.ed-pen{animation:ed-fly var(--loop) cubic-bezier(.5,.05,.25,1) infinite,
                  ed-penvis var(--loop) step-end infinite}
.ed-mark{animation:ed-mfly var(--loop) cubic-bezier(.5,.05,.25,1) infinite,
                   ed-markvis var(--loop) step-end infinite}

@keyframes ed-penvis{
  0%,12%{opacity:0} 13%,23%{opacity:1} 23.5%,31.5%{opacity:0}
  32%,56%{opacity:1} 58%,63%{opacity:0} 64%,82%{opacity:1} 84%,100%{opacity:0}
}
@keyframes ed-markvis{
  0%,3%{opacity:0} 4%,12%{opacity:1} 12.5%,23.5%{opacity:0}
  24%,31%{opacity:1} 31.5%,100%{opacity:0}
}

@keyframes ed-fly{
  0%,12%  {transform:translate3d(760px,500px,0) rotate(-14deg)}
  13%     {transform:translate3d(534px,356px,0) rotate(-20deg)}  /* k1 arrow, tail   */
  17%     {transform:translate3d(490px,358px,0) rotate(-18deg)}  /* k1 arrow, head   */
  17.5%   {transform:translate3d(540px,348px,0) rotate(-22deg)}  /* m1 "the volta"   */
  23%     {transform:translate3d(600px,348px,0) rotate(-20deg)}
  23.5%,31.5%{transform:translate3d(760px,500px,0) rotate(-14deg)}
  32%     {transform:translate3d(214px,227px,0) rotate(-23deg)}  /* a1 "legal term!" */
  37%     {transform:translate3d(276px,227px,0) rotate(-21deg)}
  38%     {transform:translate3d(214px,337px,0) rotate(-23deg)}  /* a2 "all subtr…"  */
  43%     {transform:translate3d(300px,337px,0) rotate(-21deg)}
  44%     {transform:translate3d(224px,447px,0) rotate(-23deg)}  /* the written line */
  56%     {transform:translate3d(384px,447px,0) rotate(-20deg)}
  58%,63% {transform:translate3d(700px,500px,0) rotate(-14deg)}
  64%     {transform:translate3d(566px,232px,0) rotate(-22deg)}  /* the sketch       */
  73%     {transform:translate3d(584px,233px,0) rotate(-18deg)}
  82%     {transform:translate3d(607px,276px,0) rotate(-19deg)}
  84%,100%{transform:translate3d(760px,500px,0) rotate(-14deg)}
}
@keyframes ed-mfly{
  0%,3%   {transform:translate3d(140px,500px,0) rotate(-12deg)}
  4%      {transform:translate3d(182px,358px,0) rotate(-18deg)}  /* line 9           */
  12%     {transform:translate3d(478px,358px,0) rotate(-18deg)}
  12.5%,23.5%{transform:translate3d(140px,500px,0) rotate(-12deg)}
  24%     {transform:translate3d(233px,430px,0) rotate(-18deg)}  /* "eternal lines"  */
  31%     {transform:translate3d(316px,430px,0) rotate(-18deg)}
  31.5%,100%{transform:translate3d(140px,500px,0) rotate(-12deg)}
}

/* ══════════════════════════════════════════════════════════════════
   2 · TASKS — the list assembles itself
   ══════════════════════════════════════════════════════════════════
   The right panel is EMPTY at 0%. Thirteen scraps leave the left one
   at a time and each becomes a row. 15s, not 26 — at the old pace the
   scene read as buffering rather than as sorting.
   ══════════════════════════════════════════════════════════════════ */
.sc-tasks{--loop:15s;background:linear-gradient(180deg,#fdfcfa,#f4f2ef)}
.tk-mess{position:absolute;left:0;top:0;width:46%;height:100%}

/* THE DIVIDER IS THE ARGUMENT. Before and after need a hard edge or
   the eye reads one continuous surface and the comparison collapses.
   Full-bleed, with a narrow shadow on the ledger side so the right
   panel reads as sitting on top rather than beside. */
.tk-rule{position:absolute;left:46%;top:0;bottom:0;width:1px;z-index:5;background:rgba(0,0,0,.15)}
.tk-rule::after{content:"";position:absolute;left:1px;top:0;bottom:0;width:26px;
  background:linear-gradient(90deg,rgba(0,0,0,.055),transparent)}

.tk-panel{position:absolute;right:0;top:0;width:54%;height:100%;
  padding:18px 26px 18px 30px;overflow:hidden}
/* The add bar, above the list, exactly where it is in the app. It is
   the first thing you see and the first thing you touch, so a task
   panel without it is a screenshot of the second half of the screen. */
.tk-add{
  display:flex;align-items:center;gap:9px;height:36px;padding:0 14px;
  border-radius:11px;background:rgba(120,110,100,.09);margin:0 4px 10px;
}
.tk-add .pl{font-size:16px;color:#a8a49f;line-height:1;font-weight:300;flex:none}
.tk-add .ph{font-size:13px;color:#a8a49f;letter-spacing:-.005em}

.tk-count{font-size:12.5px;color:#9a9aa2;margin:0 0 6px 4px}
.tk-card{background:#fff;border-radius:18px;padding:10px 18px 4px;
  box-shadow:0 1px 2px rgba(0,0,0,.05),0 14px 34px -20px rgba(0,0,0,.30)}
/* SCOPED TO THE DESKTOP SCENE ON PURPOSE.
   The reveal that makes a section appear with its first task lives on
   .tk-card.s0/.s1/.s2, which only the desktop markup carries. Putting
   the opacity:0 on the bare .tk-card put the PHONE scene's cards at
   zero too — and nothing there animates them back, so the scraps flew
   in and landed on an empty panel. A base class shared by two scenes
   must not hold one scene's starting state. */
.sc-tasks .tk-card{opacity:0}
.tk-card + .tk-card{margin-top:8px}
.tk-shead{display:flex;align-items:center;gap:8px;height:24px}
.tk-shead .nm{font-size:14px;font-weight:700;color:#111114;letter-spacing:-.014em;
  flex:none;white-space:nowrap}
.tk-shead .dots{color:#c4c4cc;font-size:13px;letter-spacing:1px;line-height:1}
.tk-shead .n{margin-right:auto;flex:none;font-size:12px;color:#b8b8c0;
  font-variant-numeric:tabular-nums;height:1em;line-height:1em;overflow:hidden}
.tk-shead .cv{flex:none;display:grid;place-items:center;width:11px;height:11px;
  color:#8e8e96}
.tk-shead .cv svg{width:11px;height:11px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
/* A counter that steps rather than counts: a column of numerals moved
   up one line each time a row lands. Exact, and free. */
.tk-roll{display:inline-block}
.tk-roll span{display:block;height:1em;line-height:1em}
.tk-count .tk-roll{height:1em;line-height:1em;overflow:hidden;vertical-align:-.06em}

.tk-row{display:flex;align-items:center;gap:13px;height:0;overflow:hidden;opacity:0;
  font-size:13.5px;color:#111114;letter-spacing:-.012em}
.tk-box{width:19px;height:19px;border-radius:5.5px;flex:none;border:1.6px solid #c8c8d2;background:#fff}
.tk-doc{width:19px;height:19px;flex:none;position:relative;
  border:1.4px solid #b4b4be;border-radius:3px;background:#fff}
.tk-doc::after{content:"";position:absolute;left:3.5px;right:3.5px;top:3.5px;height:1.3px;
  border-radius:1px;background:#b4b4be;box-shadow:0 3.2px 0 #b4b4be,0 6.4px 0 rgba(180,180,190,.7)}
.tk-tx{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tk-when{font-size:11px;font-weight:500;color:#e0453b;flex:none;white-space:nowrap}
.tk-when.red{color:#e0453b}

.tk-bit{position:absolute;font-size:11.5px;line-height:1.35;color:#3a3a40;
  padding:9px 11px;border-radius:5px;background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.08),0 10px 20px -12px rgba(0,0,0,.42)}
.tk-bit b{font-weight:650;display:block}
.tk-bit .sub{display:block;font-size:10px;color:#9a9aa2;margin-top:2px}
.tk-bit.sticky{background:#fff6b8;border-radius:2px}
.tk-bit.sticky.pink{background:#ffd9e2}
.tk-bit.sticky.blue{background:#d6ecff}
.tk-bit.sticky.green{background:#d8f5df}
.tk-bit.napkin{background:#fdfdf7;border-radius:2px;color:#4a4a52;
  font-family:"Bradley Hand","Segoe Print","Snell Roundhand",cursive;font-size:15px;font-weight:600}
.tk-bit.scrap{clip-path:polygon(0 3%,100% 0,99% 96%,2% 100%)}
.tk-bit.phone{background:rgba(26,26,30,.93);color:#f2f2f5;border-radius:12px;font-size:10.5px}
.tk-bit.phone .sub{color:#8e8e96}
.tk-bit.phone::before{content:"REMINDER";display:block;font-size:8px;letter-spacing:.1em;
  color:#8e8e96;margin-bottom:3px;font-weight:700}
.tk-bit.mail{border-left:3px solid #ff9500}
.tk-bit.mail::before{content:"INBOX";display:block;font-size:8px;letter-spacing:.1em;
  color:#ff9500;margin-bottom:3px;font-weight:700}


/* ══════════════════════════════════════════════════════════════════
   3 · CALENDAR — a pro board that reads as a quiet week
   ══════════════════════════════════════════════════════════════════
   The tab's claim is that the interface is simple and the system under
   it is not. A board stripped of all its controls does not make that
   argument — it dodges it. So the chrome is back, but flat and in the
   same vocabulary as the editor tab: the same round button, the same
   capsule, the same icon weight, reusing .ed-round / .ed-cap / .ed-i
   rather than a near-copy that drifts.

   THE HEIGHTS ARE LOAD-BEARING. Every event's landing slot is measured
   from the top of .cm-body by tools/gen_choreography.py, which knows
   this stack as HEAD = 156:
       .cm-top     60   toolbar
       .cm-bar     44   month + Today
       .cm-days    30   day headers
       .cm-allday  22   all-day rail
       .cm-body   464   10 rows of 46, with 4px to spare
   Change any of them and re-run the generator, or twelve events land
   in the wrong hour.
   ══════════════════════════════════════════════════════════════════ */
.sc-cal{--loop:26s;background:#fff;display:flex;flex-direction:column}

.cm-top{display:flex;align-items:center;height:60px;padding:0 22px;flex:none;position:relative}
.cm-views{position:absolute;left:50%;transform:translateX(-50%);gap:2px;padding:0 4px}
.cm-views span{font-size:12px;font-weight:500;color:#7a7a84;padding:6px 13px;border-radius:15px;
  line-height:1}
.cm-views span.on{background:rgba(0,0,0,.055);color:#111114;font-weight:620}
.cm-right{margin-left:auto}

.cm-bar{display:flex;align-items:center;height:44px;padding:0 22px;flex:none}
.cm-bar h5{font-size:22px;font-weight:650;color:#111114;letter-spacing:-.022em;margin:0;
  line-height:1}
.cm-bar h5 span{color:#b0b0b8;font-weight:500}
.cm-nav{margin-left:auto;display:flex;align-items:center;gap:6px}
.cm-arrow{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  background:rgba(0,0,0,.05);color:#5a5a64}
.cm-arrow svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.cm-today{font-size:12px;font-weight:560;color:#1a1a1f;padding:6px 14px;border-radius:15px;
  background:rgba(0,0,0,.05);line-height:1}

.cm-days{display:grid;grid-template-columns:64px repeat(5,1fr);flex:none;height:30px}
.cm-days > span{font-size:11px;font-weight:500;color:#9a9aa2;padding-left:7px;align-self:center}
.cm-days > span b{color:#26262b;font-weight:650;margin-left:4px}
.cm-days > span.now b{background:#e0453b;color:#fff;border-radius:6px;padding:2px 6px}

/* Shown even when empty. Chrome that appears and disappears with the
   data is chrome you cannot learn the position of. */
.cm-allday{display:grid;grid-template-columns:64px repeat(5,1fr);flex:none;height:22px;
  border-top:1px solid rgba(0,0,0,.055);border-bottom:1px solid rgba(0,0,0,.09)}
.cm-allday > span{border-right:1px solid rgba(0,0,0,.04)}
.cm-allday > span:last-child{border-right:0}
.cm-allday .lb{font-size:9px;color:#b0b0b8;text-align:right;padding-right:8px;
  align-self:center;border-right:1px solid rgba(0,0,0,.06)}

.cm-body{flex:1;position:relative;overflow:hidden}

/* Current time. Column 2 of five, which is the day headed .now, at
   14:20 — 6.33 rows of 46 down from the 8 AM origin. */
.cm-now{position:absolute;left:calc(64px + (100% - 64px) * 1 / 5);
  width:calc((100% - 64px) / 5);top:291px;height:0;z-index:16;
  border-top:1.5px solid #e0453b}
.cm-now i{position:absolute;left:-4px;top:-4.5px;width:8px;height:8px;border-radius:50%;
  background:#e0453b;display:block}
.cm-grid{position:absolute;inset:0;display:grid;grid-template-columns:64px repeat(5,1fr)}
.cm-rail{border-right:1px solid rgba(0,0,0,.06)}
.cm-rail span{display:block;height:46px;font-size:9.5px;color:#b8b8c0;text-align:right;
  padding-right:9px;transform:translateY(-5px)}
.cm-col{border-right:1px solid rgba(0,0,0,.04);
  background-image:linear-gradient(rgba(0,0,0,.045) 1px,transparent 1px);background-size:100% 46px}
.cm-col:last-child{border-right:0}

.cm-layer{position:absolute;inset:0;z-index:4;pointer-events:none}
.cv{position:absolute;left:0;top:0;border-radius:7px;padding:5px 8px;color:#fff;
  font-size:9.5px;line-height:1.25;overflow:hidden;opacity:0;
  box-shadow:0 2px 8px -2px rgba(0,0,0,.30)}
.cv b{display:block;font-weight:650;font-size:10.5px;margin-bottom:1px}
.cv.blue  {background:linear-gradient(160deg,#4c8ef7,#2f6fd0)}
.cv.violet{background:linear-gradient(160deg,#9b7dff,#7d5cff)}
.cv.green {background:linear-gradient(160deg,#4fc08a,#2fa471)}
.cv.amber {background:linear-gradient(160deg,#f0a44a,#dd8a2c)}
.cv.red   {background:linear-gradient(160deg,#f2685f,#e0453b)}
.cv.grey  {background:linear-gradient(160deg,#a8a8b4,#8e8e9c)}
/* A ring, not a colour change, so the calendar an event belongs to is
   still legible while it is selected. */
.cv.sel::after{content:"";position:absolute;inset:-3px;border-radius:10px;opacity:0;
  box-shadow:0 0 0 2px #fff,0 0 0 4px #1a84ff;animation:cv-ring var(--loop) ease-out infinite}
@keyframes cv-ring{0%,40%{opacity:0} 44%,88%{opacity:1} 92%,100%{opacity:0}}

.ci{position:absolute;right:18px;top:24px;width:230px;z-index:20;
  background:rgba(255,255,255,.97);
  backdrop-filter:saturate(180%) blur(20px);-webkit-backdrop-filter:saturate(180%) blur(20px);
  border:1px solid rgba(0,0,0,.07);border-radius:14px;padding:13px 14px;
  box-shadow:0 2px 8px rgba(0,0,0,.08),0 28px 52px -22px rgba(0,0,0,.42);
  opacity:0;transform:translateY(8px) scale(.97);transform-origin:top right;
  animation:ci-in var(--loop) cubic-bezier(.2,.8,.3,1) infinite}
@keyframes ci-in{0%,41%{opacity:0;transform:translateY(8px) scale(.97)}
  46%,86%{opacity:1;transform:translateY(0) scale(1)}
  91%,100%{opacity:0;transform:translateY(8px) scale(.97)}}
.ci-k{font-size:9px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;color:#9a9aa2}
.ci-t{font-size:14px;font-weight:650;color:#111114;letter-spacing:-.015em;margin:5px 0 10px;
  white-space:nowrap;overflow:hidden;border-right:1.5px solid #1a84ff;width:0;
  animation:ci-type var(--loop) steps(22,end) infinite,ci-caret .9s step-end infinite}
@keyframes ci-type{0%,48%{width:0} 58%{width:20ch} 86%{width:20ch} 91%,100%{width:0}}
@keyframes ci-caret{50%{border-color:transparent}}
.ci-f{display:flex;align-items:baseline;gap:8px;padding:6px 0;border-top:1px solid rgba(0,0,0,.06)}
.ci-f .l{font-size:10px;color:#9a9aa2;width:62px;flex:none}
.ci-f .v{font-size:11.5px;color:#26262b;font-weight:500}
/* Cross-fades on the frame the block lands in its new slot. */
.ci-swap{position:relative;display:inline-block;min-width:104px;height:15px}
.ci-swap span{position:absolute;left:0;top:0;white-space:nowrap;font-size:11.5px;
  color:#26262b;font-weight:500}
.ci-swap span:nth-child(1){animation:ci-old var(--loop) ease-out infinite}
.ci-swap span:nth-child(2){animation:ci-new var(--loop) ease-out infinite;opacity:0;color:#1a84ff}
@keyframes ci-old{0%,68%{opacity:1} 72%,100%{opacity:0}}
@keyframes ci-new{0%,68%{opacity:0} 72%,86%{opacity:1} 91%,100%{opacity:0}}
.ci-dot{width:8px;height:8px;border-radius:50%;background:#7d5cff;display:inline-block;
  margin-right:5px;vertical-align:-1px}


/* ══════════════════════════════════════════════════════════════════
   4 · SEARCH — the indexing pass, as a wireframe
   ══════════════════════════════════════════════════════════════════
   NO DATA. The reference is placeholder geometry, and that is the
   whole point of it: it shows an index reading STRUCTURE, not any
   particular record. Filling the cards with real titles answered a
   question the picture does not ask, and turned a dense field into a
   list of files.

   Seven primitives, packed on shelves, cut by the frame on all four
   sides. Grey bars at ragged widths give the look of text with no text
   present.

   THE GLOW MUST NOT BE CLIPPED, AND THE PREVIOUS ONE WAS.
   It used a blurred pseudo-element inside the card — but .w-card sets
   overflow:hidden so the gradient band keeps its rounded corners, and
   overflow clips that blur to the card's own box. Instead of light
   bleeding outward from the edge, the whole rectangle filled with
   blue. It was never going to work.

   A box-shadow is drawn outside the border box and is NOT subject to
   overflow, so the perimeter glows and the card stays white. Four
   layers on both keyframes so the list interpolates rather than
   snapping — a box-shadow only animates between lists of equal length.
   ══════════════════════════════════════════════════════════════════ */
.sc-search{
  --loop:26s;
  /* The sweep runs on its own, much shorter clock. At one pass per
     26s loop the field looked idle — an index that takes half a minute
     to cross the screen reads as a screensaver. Three passes and a
     wider pulse put four or five cards in flight at any moment. */
  --isweep:8.4s;
  background:
    radial-gradient(70% 60% at 50% 40%,#fbfbfd,transparent 70%),
    linear-gradient(180deg,#f2f2f5,#e9e9ee);
}
.w-card{
  position:absolute;overflow:hidden;background:#fff;border-radius:13px;
  padding:11px 13px;display:flex;flex-direction:column;gap:7px;
  box-shadow:0 0 0 0 rgba(0,113,227,0),0 0 0 0 rgba(0,113,227,0),
             0 1px 2px rgba(20,24,40,.05),0 8px 20px -10px rgba(20,24,40,.22);
  animation:w-drift ease-in-out infinite,w-glow var(--isweep) linear infinite;
}
@keyframes w-drift{0%,100%{translate:0 0}50%{translate:0 -5px}}

/* One pulse per sweep. Gentler than the first cut: a 1px ring at .45
   and a 14px bloom at .22, rather than 1.5px at .85 with an 18px bloom
   — which lit up like a selection rather than like something being
   read. The pulse is 14% of the sweep, so roughly five of the
   thirty-six cards are lit at any moment. */
@keyframes w-glow{
  0%     {box-shadow:0 0 0 0 rgba(0,113,227,0),0 0 0 0 rgba(0,113,227,0),
                     0 1px 2px rgba(20,24,40,.05),0 8px 20px -10px rgba(20,24,40,.22)}
  4%     {box-shadow:0 0 0 1px rgba(0,113,227,.45),0 0 14px 1px rgba(0,113,227,.22),
                     0 1px 2px rgba(20,24,40,.05),0 8px 20px -10px rgba(20,24,40,.22)}
  10%    {box-shadow:0 0 0 1px rgba(0,113,227,.45),0 0 14px 1px rgba(0,113,227,.22),
                     0 1px 2px rgba(20,24,40,.05),0 8px 20px -10px rgba(20,24,40,.22)}
  16%,100%{box-shadow:0 0 0 0 rgba(0,113,227,0),0 0 0 0 rgba(0,113,227,0),
                     0 1px 2px rgba(20,24,40,.05),0 8px 20px -10px rgba(20,24,40,.22)}
}

/* ── The lines inside get indexed too ────────────────────────────
   A card lighting as one block says the index found a file. Reading
   its contents is the actual claim, so each grey bar tints in turn a
   fraction behind its card — the card's --gd plus a per-line offset,
   which is why --gd is a custom property rather than a bare delay. */
.w-card .l{animation:w-line var(--isweep) linear infinite;
  animation-delay:calc(var(--gd, 0s) + var(--ln, 0) * .055s)}
@keyframes w-line{
  0%      {background:#e2e2e8}
  5%      {background:#bcd8f6}
  11%     {background:#bcd8f6}
  18%,100%{background:#e2e2e8}
}
/* --ln is the bar's position in its own stack. Written out rather than
   computed because CSS cannot read an element's index. */
.w-card .l:nth-child(1){--ln:1}
.w-card .l:nth-child(2){--ln:2}
.w-card .l:nth-child(3){--ln:3}
.w-card .l:nth-child(4){--ln:4}
.w-card .l:nth-child(5){--ln:5}
.w-card .l:nth-child(6){--ln:6}
.w-card .l:nth-child(7){--ln:7}
.w-card .l:nth-child(8){--ln:8}

/* The focal record. Bigger, with a tall banner and a footer block, so
   the eye has somewhere to land in a field of equal-weight cards. */
.w-focal{gap:9px;padding:13px 15px}
.w-focal .band.tall{height:74px;border-radius:9px}
.w-focal .bd.pad{gap:7px}
.w-focal .foot{display:flex;gap:11px;flex:none;margin-top:2px}
.w-focal .foot .thumb{width:86px;min-height:66px;flex:none}
.w-focal .foot .bd{gap:6px}

/* ── The grey vocabulary ── */
.w-card .l{display:block;height:6px;border-radius:99px;background:#e2e2e8}
.w-card .bd{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.w-card .av{width:26px;height:26px;border-radius:50%;background:#1e2438;flex:none}
.w-card .av.sm{width:20px;height:20px}
.w-card .bub{flex:1;background:#f0f0f4;border-radius:12px;padding:10px 12px;
  display:flex;flex-direction:column;gap:6px;justify-content:center}
.w-bubble{flex-direction:row;align-items:center;gap:10px;background:#fff}
.w-card .band{height:26px;border-radius:7px;flex:none;
  background:linear-gradient(100deg,#12162e,#1d2a56 34%,#2f6fd0 62%,#c58fd6 88%,#f0c9a8 100%)}
.w-card .thumb{flex:1;min-height:34px;border-radius:8px;background:#d8d8e0;position:relative}
.w-card .thumb::before{content:"";position:absolute;left:16%;top:22%;width:16%;
  padding-top:16%;border-radius:50%;background:#b4b4c0}
.w-card .thumb::after{content:"";position:absolute;left:8%;right:8%;bottom:14%;height:42%;
  background:#b4b4c0;clip-path:polygon(0 100%,32% 34%,54% 66%,72% 44%,100% 100%)}
.w-card .face{width:40px;height:40px;border-radius:50%;background:#1e2438;flex:none;
  position:relative;align-self:center}
.w-card .face::before{content:"";position:absolute;left:50%;top:24%;width:32%;padding-top:32%;
  border-radius:50%;background:#fff;translate:-50% 0}
.w-card .face::after{content:"";position:absolute;left:50%;bottom:14%;width:56%;height:28%;
  border-radius:99px 99px 0 0;background:#fff;translate:-50% 0}
.w-card .pips{display:flex;gap:5px;margin-top:2px}
.w-card .pips i{width:11px;height:11px;border-radius:50%;background:#d4d4dc;display:block}
.w-card .hdr{display:flex;gap:4px;flex:none}
.w-card .hdr i{width:5px;height:5px;border-radius:50%;background:#dcdce4;display:block}
.w-card .glyph{width:26px;height:26px;border-radius:8px;background:#1e2438;flex:none;
  position:relative}
.w-card .glyph::after{content:"";position:absolute;inset:6px;border-radius:2px;
  background:
    linear-gradient(90deg,#fff 33%,transparent 0) 0 0/4.6px 4.6px,
    linear-gradient(#fff 33%,transparent 0) 0 0/4.6px 4.6px;
  opacity:.9}
.w-card .row{display:flex;align-items:center;gap:9px;flex:none}
.w-card .tags{display:flex;gap:5px;margin-left:auto;flex:none}
.w-card .tags i{width:22px;height:7px;border-radius:99px;background:#e6e6ec;display:block}
.w-profile{flex-direction:row;align-items:center;gap:11px}
.w-media{gap:8px}
.w-cal{flex-direction:row;align-items:center;gap:10px}
/* The three column primitives. They inherit the base card's flex
   column, but they are declared rather than left implicit — an
   undefined class in the markup is indistinguishable from a typo, and
   the audit cannot tell me which one it is. */
.w-doc{gap:9px}
.w-mini{gap:8px;padding-top:9px}
.w-wide{gap:10px}

/* ── The focal record ── */
.sx-focal{
  position:absolute;z-index:20;background:#fff;border-radius:16px;overflow:hidden;
  display:flex;flex-direction:column;
  box-shadow:0 2px 6px rgba(20,24,40,.08),0 44px 76px -30px rgba(20,24,40,.5);
}
.sx-focal::before{
  content:"";position:absolute;inset:3px;border-radius:inherit;z-index:-1;
  background:#0071e3;filter:blur(22px);opacity:0;
  animation:w-glow 10s ease-in-out infinite 2s;
}
.f-top{display:flex;align-items:center;gap:10px;padding:14px 16px;flex:none}
.f-top .av{width:26px;height:26px;border-radius:50%;background:#1e2438;flex:none}
.f-top .bd{display:flex;flex-direction:column;gap:6px;flex:1}
.f-top .tags{display:flex;gap:6px;flex:none}
.f-top .tags i{width:26px;height:7px;border-radius:99px;background:#e6e6ec;display:block}
.f-band{height:96px;flex:none;margin:0 14px;border-radius:4px;
  background:linear-gradient(100deg,#0d1128,#1b2a58 30%,#2f6fd0 58%,#b98fd6 82%,#f2cba6 100%)}
.f-body{padding:16px;display:flex;flex-direction:column;gap:9px;flex:1}
.f-body .l{display:block;height:7px;border-radius:99px;background:#e2e2e8}
.f-body .l.hd{height:11px;width:56%;background:#d6d6de;margin:0 auto 6px}
.f-foot{display:flex;gap:12px;padding:14px 16px;border-top:1px solid rgba(0,0,0,.06);
  flex:none}
.f-foot .th{width:78px;height:78px;border-radius:6px;background:#d8d8e0;flex:none}
.f-foot .bd{display:flex;flex-direction:column;gap:7px;flex:1;padding-top:4px}
.f-foot .l{display:block;height:6px;border-radius:99px;background:#e2e2e8}

/* ══════════════════════════════════════════════════════════════════
   SMALL SCREENS — four different scenes, not four smaller ones
   ══════════════════════════════════════════════════════════════════
   A 980px stage on a 375px phone is 5px type. Below 780 the desktop
   stages are switched off and these take over. They are NOT
   miniatures — each answers what a phone can actually show:

     Notes     an editor, with the sonnet TYPING ITSELF, then getting
               marked up. No tool constellation: on a phone the tools
               would be the whole screen and the writing would be a
               detail, which inverts the point.
     Tasks     ONE THING AT A TIME. The desktop version shows the mess
               and the ledger side by side; at this width that is two
               half-legible columns. So it is sequential: tasks hover,
               then in a single move they all fly into a list, then the
               list stands alone. You never see both states at once.
     Calendar  the same board at phone proportion — one narrow column
               of days rather than a squashed week.
     Search    the desktop field, honestly scaled: fewer cards, same
               wireframe, same halo.

   Fluid throughout, so it holds from 320px to 779px with one set of
   rules.
   ══════════════════════════════════════════════════════════════════ */
.scene-sm{display:none}

@media (max-width:780px){
  .scene-wrap{display:none}
  /* THE PHONE SCENES ARE DRAWN IN FIXED PIXELS. Every one of them —
     the 42px editor bar, the 21px verse line, the 26px task row, the
     44px calendar hour — is a constant, while the card itself was
     `width:100%` with `aspect-ratio:340/470`. The two only agree at one
     width.

     Above it the card grows and the contents do not: at a 700px-wide
     window, still under the 780px breakpoint, the editor card is 968px
     tall holding 402px of sonnet, and the rest is blank white. That is
     what "the Notes tab isn't working on smaller screens" looks like on
     a narrowed desktop window.

     Below it the card shrinks and the contents do not: at 276px the
     card is 381px tall holding the same 402px, and overflow:hidden
     takes the last line off.

     So the card is capped near a real phone's width and floored at the
     height the contents actually need. Anything laid out in fixed px
     needs both ends pinned, not one. */
  .scene-sm{
    display:block;position:relative;width:100%;
    max-width:360px;min-height:470px;
    margin:22px auto 0;
    border-radius:18px;overflow:hidden;text-align:left;
    border:1px solid rgba(0,0,0,.07);
    box-shadow:0 1px 2px rgba(0,0,0,.04),0 14px 30px -18px rgba(0,0,0,.26);
  }
  .scene-sm *{box-sizing:border-box}
  .tab-pane:not(.active) .scene-sm *{animation-play-state:paused!important}

  /* ── NOTES · the sonnet types itself ────────────────────────────
     Each line is revealed by its own steps() width animation, in
     sequence, with a caret riding the live line. `ch` units make the
     caret land on the character rather than near it. */
  .m-notes{--loop:22s;background:#fff;display:flex;flex-direction:column;
    aspect-ratio:340/470}
  .m-ebar{display:flex;align-items:center;gap:9px;padding:0 14px;height:42px;flex:none;
    border-bottom:1px solid rgba(0,0,0,.07)}
  .m-ebar .bk{font-size:15px;color:#1a84ff;line-height:1}
  .m-ebar .ti{font-size:12.5px;font-weight:600;color:#111114;letter-spacing:-.01em}
  .m-ebar .rt{margin-left:auto;display:flex;gap:9px}
  .m-ebar .rt i{width:16px;height:16px;border-radius:4px;background:rgba(0,0,0,.07);display:block}
  .m-epage{flex:1;position:relative;padding:16px 18px;overflow:hidden}
  .m-h1{font-size:17px;font-weight:700;letter-spacing:-.022em;color:#111114;
    line-height:24px;margin:0 0 4px;white-space:nowrap;overflow:hidden;width:0;
    animation:mt-h var(--loop) steps(26,end) infinite}
  .m-by{font-size:10px;color:#a0a0a8;margin-bottom:10px;opacity:0;
    animation:mt-by var(--loop) ease-out infinite}
  /* One stepped clip over the whole block: fourteen steps, fourteen
     lines. The step boundaries land on the line boxes because every
     .m-v is exactly 21px tall and there is no margin between them —
     change the line-height, or the number of lines in index.html, and
     the reveal stops landing on the lines. */
  .m-verses{clip-path:inset(0 0 100% 0);
    animation:mt-vs var(--loop) steps(14,end) infinite}
  @keyframes mt-vs{0%,13%{clip-path:inset(0 0 100% 0)}
    60%,94%{clip-path:inset(0 0 0 0)} 98%,100%{clip-path:inset(0 0 100% 0)}}
  .m-v{position:relative;font-size:12px;line-height:21px;color:#26262b;
    white-space:nowrap;margin:0}
  .m-v.i{padding-left:16px}
  .m-hl{position:relative}
  .m-hl::before{content:"";position:absolute;left:-3px;right:-3px;top:1px;bottom:1px;
    border-radius:3px;z-index:-1;background:rgba(255,224,110,.9);
    transform:scaleX(0);transform-origin:left center;
    animation:mt-hl var(--loop) ease-out infinite}
  .m-hand{position:absolute;right:14px;color:#d5453b;transform:rotate(-5deg);
    font-family:"Bradley Hand","Segoe Print","Snell Roundhand",cursive;
    font-size:13.5px;font-weight:600;white-space:nowrap;clip-path:inset(0 100% 0 0);
    animation:mt-hand var(--loop) ease-out infinite}
  .m-ink{position:absolute;inset:0;pointer-events:none;overflow:visible}
  .m-ink path{fill:none;stroke:#d5453b;stroke-width:1.5;stroke-linecap:round;
    stroke-dasharray:1;stroke-dashoffset:1;animation:mt-ink var(--loop) ease-out infinite}
  @keyframes mt-h{0%,2%{width:0} 10%{width:26ch} 94%{width:26ch} 98%,100%{width:0}}
  @keyframes mt-by{0%,10%{opacity:0} 13%,94%{opacity:1} 98%,100%{opacity:0}}
  @keyframes mt-hl{0%,62%{transform:scaleX(0)} 70%{transform:scaleX(1)}
    94%{transform:scaleX(1)} 98%,100%{transform:scaleX(0)}}
  @keyframes mt-hand{0%,74%{clip-path:inset(0 100% 0 0)} 82%{clip-path:inset(0 0 0 0)}
    94%{clip-path:inset(0 0 0 0)} 98%,100%{clip-path:inset(0 100% 0 0)}}
  @keyframes mt-ink{0%,80%{stroke-dashoffset:1} 88%{stroke-dashoffset:0}
    94%{stroke-dashoffset:0} 98%,100%{stroke-dashoffset:1}}

  /* ── TASKS · one state at a time ────────────────────────────────
     Hover 0–34%, fly 34–46%, list 46–92%. The two layers cross-fade
     rather than sharing the screen: .m-cloud is gone before .m-sheet
     arrives, which is the whole difference from the desktop scene. */
  .m-tasks{--loop:16s;background:linear-gradient(180deg,#fdfcfa,#f4f2ef);
    position:relative;aspect-ratio:340/470}
  .m-cloud{position:absolute;inset:0;z-index:2}
  .m-cloud .tk-bit{font-size:10.5px;padding:8px 10px;width:52%;
    animation:mc-bob 6s ease-in-out infinite,mc-fly var(--loop) cubic-bezier(.5,0,.2,1) infinite}
  .m-cloud .tk-bit b{font-size:11px}
  .m-cloud .tk-bit .sub{font-size:9px}
  @keyframes mc-bob{0%,100%{translate:0 0}50%{translate:0 -6px}}
  @keyframes mc-fly{
    0%,34%  {transform:rotate(var(--r)) scale(1);opacity:1}
    40%     {transform:translate(var(--cx),var(--cy)) rotate(0deg) scale(.8);opacity:.85}
    46%,96% {transform:translate(var(--cx),var(--cy)) rotate(0deg) scale(.3);opacity:0}
    100%    {transform:rotate(var(--r)) scale(1);opacity:1}
  }
  .m-sheet{position:absolute;inset:0;z-index:3;padding:16px;opacity:0;
    animation:ms-in var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
  @keyframes ms-in{
    0%,42%  {opacity:0;transform:translateY(14px) scale(.97)}
    50%,90% {opacity:1;transform:translateY(0) scale(1)}
    96%,100%{opacity:0;transform:translateY(14px) scale(.97)}
  }
  /* The same panel as the desktop, at phone size: the add bar on top,
     then three section cards. The count line is the one thing dropped
     — 340×470 does not have room for both it and the add bar, and the
     add bar is the more recognisable of the two. */
  .m-sheet .tk-add{height:32px;padding:0 12px;gap:8px;border-radius:10px;
    margin:0 0 10px}
  .m-sheet .tk-add .pl{font-size:15px}
  .m-sheet .tk-add .ph{font-size:12px}
  .m-sheet .tk-card{border-radius:15px;padding:10px 14px 4px;opacity:0;
    animation:msc var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
  .m-sheet .tk-card + .tk-card{margin-top:9px}
  /* Each section lands a beat after the one above it, so the list
     assembles top-down rather than appearing whole. */
  .m-sheet .tk-card.ms0{animation-delay:0s}
  .m-sheet .tk-card.ms1{animation-delay:calc(var(--loop) * .022)}
  .m-sheet .tk-card.ms2{animation-delay:calc(var(--loop) * .044)}
  @keyframes msc{0%,44%{opacity:0;transform:translateY(8px) scale(.99)}
    50%,88%{opacity:1;transform:none} 94%,100%{opacity:0;transform:translateY(8px) scale(.99)}}
  .m-sheet .tk-shead{height:20px;gap:7px}
  .m-sheet .tk-shead .nm{font-size:13px}
  .m-sheet .tk-shead .n{font-size:11.5px}
  .m-sheet .tk-shead .cv{width:10px;height:10px}
  .m-sheet .tk-shead .cv svg{width:10px;height:10px}
  .m-sheet .tk-row{font-size:12px;gap:10px;height:26px;opacity:1;
    animation:msr var(--loop) ease-out infinite}
  .m-sheet .tk-when{font-size:10.5px}
  .m-sheet .tk-box,.m-sheet .tk-doc{width:16px;height:16px}
  @keyframes msr{0%,44%{opacity:0;transform:translateX(8px)}
    52%,88%{opacity:1;transform:none} 94%,100%{opacity:0}}

  /* ── CALENDAR · phone proportion ────────────────────────────── */
  .m-cal{--loop:20s;background:#fff;display:flex;flex-direction:column;
    aspect-ratio:340/470}
  .m-cbar{display:flex;align-items:center;height:44px;padding:0 15px;flex:none}
  .m-cbar h5{font-size:16px;font-weight:650;color:#111114;letter-spacing:-.02em;margin:0}
  .m-cbar h5 span{color:#b0b0b8;font-weight:500}
  .m-cbar .seg{margin-left:auto;font-size:10px;font-weight:600;color:#111114;
    background:rgba(0,0,0,.05);border-radius:7px;padding:4px 10px}
  .m-cdays{display:grid;grid-template-columns:34px repeat(3,1fr);height:26px;flex:none;
    border-bottom:1px solid rgba(0,0,0,.09)}
  .m-cdays span{font-size:10px;color:#9a9aa2;align-self:center;padding-left:6px}
  .m-cdays span b{color:#26262b;font-weight:650}
  .m-cdays span.now b{background:#e0453b;color:#fff;border-radius:5px;padding:1px 5px}
  .m-cbody{flex:1;position:relative;overflow:hidden}
  .m-cgrid{position:absolute;inset:0;display:grid;grid-template-columns:34px repeat(3,1fr)}
  .m-cgrid .rail{border-right:1px solid rgba(0,0,0,.06)}
  .m-cgrid .rail span{display:block;height:44px;font-size:8.5px;color:#b8b8c0;
    text-align:right;padding-right:6px;transform:translateY(-4px)}
  .m-cgrid .col{border-right:1px solid rgba(0,0,0,.04);
    background-image:linear-gradient(rgba(0,0,0,.045) 1px,transparent 1px);
    background-size:100% 44px}
  .m-clayer{position:absolute;inset:0;z-index:4}
  .m-clayer .cv{font-size:8.5px;padding:4px 6px}
  .m-clayer .cv b{font-size:9.5px}

  /* ── SEARCH · the same field, fewer cards ───────────────────── */
  /* --isweep has to be redeclared here. .w-card's animation shorthand
     reads `w-glow var(--isweep) linear infinite`, and --isweep was set
     only on .sc-search, the DESKTOP scene. An unresolvable var makes the
     whole shorthand invalid at computed-value time — not just that one
     duration — so the phone search field had no glow, no drift and no
     line-by-line indexing. It was not a slow animation; it was no
     animation, and a static render cannot tell those apart. */
  .m-search{--loop:14s;--isweep:8.4s;aspect-ratio:340/470;
    background:radial-gradient(70% 60% at 50% 40%,#fbfbfd,transparent 70%),
               linear-gradient(180deg,#f2f2f5,#e9e9ee)}
  .m-search .w-card{border-radius:11px;padding:9px 10px;gap:6px}
  .m-search .w-card .l{height:5px}
  .m-search .w-card .av{width:20px;height:20px}
  .m-search .w-card .face{width:30px;height:30px}
  .m-search .w-card .band{height:20px}
  .m-search .w-card .glyph{width:20px;height:20px}
  .m-focal{position:absolute;left:50%;top:23%;translate:-50% 0;width:52%;height:46%;
    z-index:20;background:#fff;border-radius:13px;overflow:hidden;
    display:flex;flex-direction:column;
    box-shadow:0 2px 6px rgba(20,24,40,.08),0 30px 50px -24px rgba(20,24,40,.5)}
  .m-focal .f-top{padding:9px 10px;gap:7px}
  .m-focal .f-top .av{width:18px;height:18px}
  .m-focal .f-band{height:44px;margin:0 9px}
  .m-focal .f-body{padding:10px;gap:6px}
  .m-focal .f-body .l{height:5px}
  .m-focal .f-body .l.hd{height:8px}
}

/* ══════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════
   Not `animation:none` — that resets every scene to its 0% keyframe,
   which is the EMPTY state: no ink, no rows, no events on the board.
   Four blank rectangles. Each scene is pinned to a frame from the end
   of its story instead, so stillness still shows the finished picture.
   ══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  .scene *,.scene *::before,.scene *::after,
  .scene-sm *,.scene-sm *::before,.scene-sm *::after{
    animation-duration:1ms!important;animation-iteration-count:1!important;
    animation-delay:0ms!important;animation-fill-mode:forwards!important;
    transition-duration:1ms!important;
  }
  /* The notes scene, pinned to its finished state: every mark laid
     down, the handwriting already converted, and the two tools out of
     shot — a stationary pen hovering over a page it is not touching is
     the one frame that looks like a bug rather than a still. */
  .ed-hl{background-size:100% 100%!important}
  .m-hl::before{transform:scaleX(1)!important}
  .ed-hand,.m-hand{clip-path:inset(0 0 0 0)!important}
  .ed-ink path{stroke-dashoffset:0!important}
  .ed-pen,.ed-mark{display:none!important}
  .ed-conv .ink,.m-conv .ink{opacity:0!important}
  .ed-conv .txt,.m-conv .txt{opacity:1!important;transform:none!important}
  .ed-pdf,.ed-rec{opacity:1!important;transform:none!important}
  .ed-rec .tr span{width:auto!important}
  .tk-bit{opacity:0!important}
  .tk-row{opacity:1!important;height:30px!important}
  /* The section cards and the phone sheet fade IN, so their keyframes
     end at opacity 0 — pinning only the rows inside them left a
     reduced-motion visitor looking at an empty panel on both layouts,
     which is the exact failure this block exists to prevent. Rows are
     26px on the phone, and twelve of them at 30px overflows the sheet
     by more than it has to give. */
  .tk-card,.m-sheet{opacity:1!important;transform:none!important}
  .m-sheet .tk-row{height:26px!important}
  /* The counters roll by stepping a column of numerals up; with the
     animation collapsed to 1ms the column sits at 0. Park it on the
     finished count instead — the numbers next to a full list have to
     agree with it. */
  .tk-n0 span{transform:translateY(-5em)!important}
  .tk-n1 span{transform:translateY(-4em)!important}
  .tk-n2 span{transform:translateY(-4em)!important}
  .tk-nall span{transform:translateY(-13em)!important}
  /* Phone notes: the page is built by three reveals, none of which the
     desktop selectors above reach. */
  .m-h1{width:26ch!important}
  .m-by{opacity:1!important}
  .m-verses{clip-path:none!important}
  .m-ink path{stroke-dashoffset:0!important}
  .cv{opacity:1!important;transform:translate(var(--fx),var(--fy))!important}
  .cv.sel::after{opacity:1!important}
  .ci{opacity:1!important;transform:none!important}
  .ci-t{width:20ch!important;border-color:transparent!important}
  .ci-swap span:nth-child(1){opacity:0!important}
  .ci-swap span:nth-child(2){opacity:1!important}
}

/* ===== GENERATED — tools/gen_choreography.py — DO NOT EDIT BELOW ===== */

/* ── Tasks · scrap flights ───────────────────────────────────── */
@keyframes tkf0{
  0%,6.00%{transform:translate(0,0) rotate(-5.0deg) scale(1);opacity:1}
  6.60%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  7.70%{transform:translate(219px,120px) rotate(0deg) scale(.78);opacity:.92}
  8.80%,95%{transform:translate(398px,258px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-5.0deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-5.0deg) scale(1);opacity:1}
}
.tk-bit.b0{left:161px;top:24px;width:160px;animation:tkf0 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr0{
  0%,7.70%{height:0;opacity:0;transform:translateX(10px)}
  9.60%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r0{animation:tkr0 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf1{
  0%,11.38%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:1}
  11.98%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  13.08%{transform:translate(226px,-279px) rotate(0deg) scale(.78);opacity:.92}
  14.18%,95%{transform:translate(411px,-468px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:1}
}
.tk-bit.b1{left:148px;top:548px;width:184px;animation:tkf1 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr1{
  0%,13.08%{height:0;opacity:0;transform:translateX(10px)}
  14.98%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r1{animation:tkr1 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf2{
  0%,16.77%{transform:translate(0,0) rotate(11.4deg) scale(1);opacity:1}
  17.37%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  18.47%{transform:translate(278px,-228px) rotate(0deg) scale(.78);opacity:.92}
  19.57%,95%{transform:translate(506px,-375px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(11.4deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(11.4deg) scale(1);opacity:1}
}
.tk-bit.b2{left:54px;top:485px;width:132px;animation:tkf2 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr2{
  0%,18.47%{height:0;opacity:0;transform:translateX(10px)}
  20.37%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r2{animation:tkr2 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf3{
  0%,22.15%{transform:translate(0,0) rotate(-6.9deg) scale(1);opacity:1}
  22.75%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  23.85%{transform:translate(165px,174px) rotate(0deg) scale(.78);opacity:.92}
  24.95%,95%{transform:translate(301px,357px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-6.9deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-6.9deg) scale(1);opacity:1}
}
.tk-bit.b3{left:258px;top:97px;width:148px;animation:tkf3 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr3{
  0%,23.85%{height:0;opacity:0;transform:translateX(10px)}
  25.75%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r3{animation:tkr3 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf4{
  0%,27.54%{transform:translate(0,0) rotate(5.4deg) scale(1);opacity:1}
  28.14%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  29.24%{transform:translate(300px,68px) rotate(0deg) scale(.78);opacity:.92}
  30.34%,95%{transform:translate(546px,164px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(5.4deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(5.4deg) scale(1);opacity:1}
}
.tk-bit.b4{left:13px;top:148px;width:160px;animation:tkf4 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr4{
  0%,29.24%{height:0;opacity:0;transform:translateX(10px)}
  31.14%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r4{animation:tkr4 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf5{
  0%,32.92%{transform:translate(0,0) rotate(1.3deg) scale(1);opacity:1}
  33.52%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  34.62%{transform:translate(140px,-202px) rotate(0deg) scale(.78);opacity:.92}
  35.72%,95%{transform:translate(255px,-328px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(1.3deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(1.3deg) scale(1);opacity:1}
}
.tk-bit.b5{left:304px;top:468px;width:132px;animation:tkf5 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr5{
  0%,34.62%{height:0;opacity:0;transform:translateX(10px)}
  36.52%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r5{animation:tkr5 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf6{
  0%,38.31%{transform:translate(0,0) rotate(-0.7deg) scale(1);opacity:1}
  38.91%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  40.01%{transform:translate(183px,15px) rotate(0deg) scale(.78);opacity:.92}
  41.11%,95%{transform:translate(332px,68px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-0.7deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-0.7deg) scale(1);opacity:1}
}
.tk-bit.b6{left:227px;top:274px;width:172px;animation:tkf6 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr6{
  0%,40.01%{height:0;opacity:0;transform:translateX(10px)}
  41.91%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r6{animation:tkr6 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf7{
  0%,43.69%{transform:translate(0,0) rotate(9.1deg) scale(1);opacity:1}
  44.29%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  45.39%{transform:translate(178px,48px) rotate(0deg) scale(.78);opacity:.92}
  46.49%,95%{transform:translate(324px,127px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(9.1deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(9.1deg) scale(1);opacity:1}
}
.tk-bit.b7{left:235px;top:357px;width:172px;animation:tkf7 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr7{
  0%,45.39%{height:0;opacity:0;transform:translateX(10px)}
  47.29%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r7{animation:tkr7 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf8{
  0%,49.08%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:1}
  49.68%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  50.78%{transform:translate(308px,44px) rotate(0deg) scale(.78);opacity:.92}
  51.88%,95%{transform:translate(560px,120px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-6.4deg) scale(1);opacity:1}
}
.tk-bit.b8{left:-1px;top:50px;width:148px;animation:tkf8 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr8{
  0%,50.78%{height:0;opacity:0;transform:translateX(10px)}
  52.68%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r8{animation:tkr8 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf9{
  0%,54.46%{transform:translate(0,0) rotate(-2.6deg) scale(1);opacity:1}
  55.06%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  56.16%{transform:translate(268px,15px) rotate(0deg) scale(.78);opacity:.92}
  57.26%,95%{transform:translate(486px,66px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-2.6deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-2.6deg) scale(1);opacity:1}
}
.tk-bit.b9{left:73px;top:306px;width:132px;animation:tkf9 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr9{
  0%,56.16%{height:0;opacity:0;transform:translateX(10px)}
  58.06%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r9{animation:tkr9 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf10{
  0%,59.85%{transform:translate(0,0) rotate(8.9deg) scale(1);opacity:1}
  60.45%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  61.55%{transform:translate(154px,-11px) rotate(0deg) scale(.78);opacity:.92}
  62.65%,95%{transform:translate(279px,21px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(8.9deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(8.9deg) scale(1);opacity:1}
}
.tk-bit.b10{left:280px;top:179px;width:148px;animation:tkf10 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr10{
  0%,61.55%{height:0;opacity:0;transform:translateX(10px)}
  63.45%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r10{animation:tkr10 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf11{
  0%,65.23%{transform:translate(0,0) rotate(-9.6deg) scale(1);opacity:1}
  65.83%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  66.93%{transform:translate(300px,51px) rotate(0deg) scale(.78);opacity:.92}
  68.03%,95%{transform:translate(545px,133px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(-9.6deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(-9.6deg) scale(1);opacity:1}
}
.tk-bit.b11{left:14px;top:381px;width:172px;animation:tkf11 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr11{
  0%,66.93%{height:0;opacity:0;transform:translateX(10px)}
  68.83%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r11{animation:tkr11 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tkf12{
  0%,70.62%{transform:translate(0,0) rotate(1.4deg) scale(1);opacity:1}
  71.22%{transform:translate(3px,-10px) rotate(0deg) scale(1.07);opacity:1}
  72.32%{transform:translate(254px,162px) rotate(0deg) scale(.78);opacity:.92}
  73.42%,95%{transform:translate(461px,335px) rotate(0deg) scale(.38);opacity:0}
  99%{transform:translate(0,0) rotate(1.4deg) scale(1);opacity:0}
  100%{transform:translate(0,0) rotate(1.4deg) scale(1);opacity:1}
}
.tk-bit.b12{left:98px;top:209px;width:148px;animation:tkf12 var(--loop) cubic-bezier(.45,0,.25,1) infinite}
@keyframes tkr12{
  0%,72.32%{height:0;opacity:0;transform:translateX(10px)}
  74.22%{height:30px;opacity:1;transform:translateX(0)}
  90%{height:30px;opacity:1}
  94%,100%{height:0;opacity:0}
}
.tk-row.r12{animation:tkr12 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}

/* ── Tasks · counters that step as their rows land ───────────── */
@keyframes tkc0{
  0%{transform:translateY(0)}
  14.98%{transform:translateY(-1em)}
  20.37%{transform:translateY(-2em)}
  36.52%{transform:translateY(-3em)}
  52.68%{transform:translateY(-4em)}
  63.45%{transform:translateY(-5em)}
  94%{transform:translateY(-5em)}
  100%{transform:translateY(0)}
}
.tk-n0 span{animation:tkc0 var(--loop) steps(1,end) infinite}
@keyframes tkc1{
  0%{transform:translateY(0)}
  9.60%{transform:translateY(-1em)}
  31.14%{transform:translateY(-2em)}
  41.91%{transform:translateY(-3em)}
  58.06%{transform:translateY(-4em)}
  94%{transform:translateY(-4em)}
  100%{transform:translateY(0)}
}
.tk-n1 span{animation:tkc1 var(--loop) steps(1,end) infinite}
@keyframes tkc2{
  0%{transform:translateY(0)}
  25.75%{transform:translateY(-1em)}
  47.29%{transform:translateY(-2em)}
  68.83%{transform:translateY(-3em)}
  74.22%{transform:translateY(-4em)}
  94%{transform:translateY(-4em)}
  100%{transform:translateY(0)}
}
.tk-n2 span{animation:tkc2 var(--loop) steps(1,end) infinite}
@keyframes tkc-all{
  0%{transform:translateY(0)}
  9.60%{transform:translateY(-1em)}
  14.98%{transform:translateY(-2em)}
  20.37%{transform:translateY(-3em)}
  25.75%{transform:translateY(-4em)}
  31.14%{transform:translateY(-5em)}
  36.52%{transform:translateY(-6em)}
  41.91%{transform:translateY(-7em)}
  47.29%{transform:translateY(-8em)}
  52.68%{transform:translateY(-9em)}
  58.06%{transform:translateY(-10em)}
  63.45%{transform:translateY(-11em)}
  68.83%{transform:translateY(-12em)}
  74.22%{transform:translateY(-13em)}
  94%{transform:translateY(-13em)}
  100%{transform:translateY(0)}
}
.tk-nall span{animation:tkc-all var(--loop) steps(1,end) infinite}

/* ── Tasks · a section appears with its first task ───────────── */
@keyframes tks0{
  0%,13.78%{opacity:0;transform:translateY(8px) scale(.985)}
  15.58%{opacity:1;transform:translateY(0) scale(1)}
  90%{opacity:1;transform:translateY(0) scale(1)}
  94%,100%{opacity:0;transform:translateY(8px) scale(.985)}
}
.tk-card.s0{animation:tks0 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tks1{
  0%,8.40%{opacity:0;transform:translateY(8px) scale(.985)}
  10.20%{opacity:1;transform:translateY(0) scale(1)}
  90%{opacity:1;transform:translateY(0) scale(1)}
  94%,100%{opacity:0;transform:translateY(8px) scale(.985)}
}
.tk-card.s1{animation:tks1 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}
@keyframes tks2{
  0%,24.55%{opacity:0;transform:translateY(8px) scale(.985)}
  26.35%{opacity:1;transform:translateY(0) scale(1)}
  90%{opacity:1;transform:translateY(0) scale(1)}
  94%,100%{opacity:0;transform:translateY(8px) scale(.985)}
}
.tk-card.s2{animation:tks2 var(--loop) cubic-bezier(.2,.9,.3,1) infinite}

/* ── Calendar · the tornado ──────────────────────────────────── */
@keyframes cvf0{
  0%,4.00%{transform:translate(676px,334px) rotate(14deg) scale(.5);opacity:0}
  5.20%{opacity:1}
  6.68%{transform:translate(172px,302px) rotate(14deg) scale(0.62);opacity:1}
  9.36%{transform:translate(387px,105px) rotate(6deg) scale(0.71);opacity:1}
  12.04%{transform:translate(505px,241px) rotate(-2deg) scale(0.80);opacity:1}
  14.71%{transform:translate(372px,237px) rotate(-10deg) scale(0.89);opacity:1}
  19.00%,88%{transform:translate(69px,46px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(69px,46px) scale(1);opacity:0}
}
.cv.e0{--fx:69px;--fy:46px;width:173px;height:42px;animation:cvf0 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf1{
  0%,5.40%{transform:translate(546px,402px) rotate(4deg) scale(.5);opacity:0}
  6.60%{opacity:1}
  8.08%{transform:translate(135px,219px) rotate(14deg) scale(0.62);opacity:1}
  10.76%{transform:translate(480px,115px) rotate(6deg) scale(0.71);opacity:1}
  13.44%{transform:translate(473px,269px) rotate(-2deg) scale(0.80);opacity:1}
  16.11%{transform:translate(361px,225px) rotate(-10deg) scale(0.89);opacity:1}
  20.40%,88%{transform:translate(69px,184px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(69px,184px) scale(1);opacity:0}
}
.cv.e1{--fx:69px;--fy:184px;width:173px;height:65px;animation:cvf1 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf2{
  0%,6.80%{transform:translate(378px,422px) rotate(-6deg) scale(.5);opacity:0}
  8.00%{opacity:1}
  9.48%{transform:translate(170px,136px) rotate(14deg) scale(0.62);opacity:1}
  12.16%{transform:translate(553px,152px) rotate(6deg) scale(0.71);opacity:1}
  14.84%{transform:translate(422px,284px) rotate(-2deg) scale(0.80);opacity:1}
  17.51%{transform:translate(361px,211px) rotate(-10deg) scale(0.89);opacity:1}
  21.80%,88%{transform:translate(69px,345px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(69px,345px) scale(1);opacity:0}
}
.cv.e2{--fx:69px;--fy:345px;width:173px;height:42px;animation:cvf2 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf3{
  0%,8.20%{transform:translate(217px,387px) rotate(-16deg) scale(.5);opacity:0}
  9.40%{opacity:1}
  10.88%{transform:translate(268px,75px) rotate(14deg) scale(0.62);opacity:1}
  13.56%{transform:translate(586px,208px) rotate(6deg) scale(0.71);opacity:1}
  16.24%{transform:translate(367px,281px) rotate(-2deg) scale(0.80);opacity:1}
  18.91%{transform:translate(373px,199px) rotate(-10deg) scale(0.89);opacity:1}
  23.20%,68%{transform:translate(252px,115px) rotate(0deg) scale(1);opacity:1}
  70%{transform:translate(344px,168px) rotate(-1.5deg) scale(1.05);opacity:.94}
  73%,88%{transform:translate(435px,253px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(435px,253px) scale(1);opacity:0}
}
.cv.e3{--fx:252px;--fy:115px;width:173px;height:88px;animation:cvf3 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf4{
  0%,9.60%{transform:translate(106px,306px) rotate(14deg) scale(.5);opacity:0}
  10.80%{opacity:1}
  12.28%{transform:translate(401px,52px) rotate(14deg) scale(0.62);opacity:1}
  14.96%{transform:translate(570px,266px) rotate(6deg) scale(0.71);opacity:1}
  17.64%{transform:translate(321px,261px) rotate(-2deg) scale(0.80);opacity:1}
  20.31%{transform:translate(392px,192px) rotate(-10deg) scale(0.89);opacity:1}
  24.60%,88%{transform:translate(252px,276px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(252px,276px) scale(1);opacity:0}
}
.cv.e4{--fx:252px;--fy:276px;width:173px;height:42px;animation:cvf4 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf5{
  0%,11.00%{transform:translate(74px,202px) rotate(3deg) scale(.5);opacity:0}
  12.20%{opacity:1}
  13.68%{transform:translate(536px,73px) rotate(14deg) scale(0.62);opacity:1}
  16.36%{transform:translate(509px,311px) rotate(6deg) scale(0.71);opacity:1}
  19.04%{transform:translate(297px,230px) rotate(-2deg) scale(0.80);opacity:1}
  21.71%{transform:translate(415px,192px) rotate(-10deg) scale(0.89);opacity:1}
  26.00%,88%{transform:translate(435px,46px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(435px,46px) scale(1);opacity:0}
}
.cv.e5{--fx:435px;--fy:46px;width:173px;height:42px;animation:cvf5 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf6{
  0%,12.40%{transform:translate(131px,102px) rotate(-7deg) scale(.5);opacity:0}
  13.60%{opacity:1}
  15.08%{transform:translate(635px,134px) rotate(14deg) scale(0.62);opacity:1}
  17.76%{transform:translate(420px,331px) rotate(6deg) scale(0.71);opacity:1}
  20.44%{transform:translate(302px,195px) rotate(-2deg) scale(0.80);opacity:1}
  23.11%{transform:translate(434px,199px) rotate(-10deg) scale(0.89);opacity:1}
  27.40%,88%{transform:translate(435px,368px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(435px,368px) scale(1);opacity:0}
}
.cv.e6{--fx:435px;--fy:368px;width:173px;height:42px;animation:cvf6 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf7{
  0%,13.80%{transform:translate(261px,34px) rotate(-17deg) scale(.5);opacity:0}
  15.00%{opacity:1}
  16.48%{transform:translate(672px,217px) rotate(14deg) scale(0.62);opacity:1}
  19.16%{transform:translate(326px,321px) rotate(6deg) scale(0.71);opacity:1}
  21.84%{transform:translate(334px,167px) rotate(-2deg) scale(0.80);opacity:1}
  24.51%{transform:translate(446px,211px) rotate(-10deg) scale(0.89);opacity:1}
  28.80%,88%{transform:translate(619px,92px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(619px,92px) scale(1);opacity:0}
}
.cv.e7{--fx:619px;--fy:92px;width:173px;height:111px;animation:cvf7 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf8{
  0%,15.20%{transform:translate(429px,14px) rotate(13deg) scale(.5);opacity:0}
  16.40%{opacity:1}
  17.88%{transform:translate(637px,300px) rotate(14deg) scale(0.62);opacity:1}
  20.56%{transform:translate(253px,284px) rotate(6deg) scale(0.71);opacity:1}
  23.24%{transform:translate(385px,152px) rotate(-2deg) scale(0.80);opacity:1}
  25.91%{transform:translate(445px,225px) rotate(-10deg) scale(0.89);opacity:1}
  30.20%,88%{transform:translate(619px,322px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(619px,322px) scale(1);opacity:0}
}
.cv.e8{--fx:619px;--fy:322px;width:173px;height:42px;animation:cvf8 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf9{
  0%,16.60%{transform:translate(590px,49px) rotate(3deg) scale(.5);opacity:0}
  17.80%{opacity:1}
  19.28%{transform:translate(539px,361px) rotate(14deg) scale(0.62);opacity:1}
  21.96%{transform:translate(221px,228px) rotate(6deg) scale(0.71);opacity:1}
  24.64%{transform:translate(440px,155px) rotate(-2deg) scale(0.80);opacity:1}
  27.31%{transform:translate(434px,237px) rotate(-10deg) scale(0.89);opacity:1}
  31.60%,88%{transform:translate(802px,46px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(802px,46px) scale(1);opacity:0}
}
.cv.e9{--fx:802px;--fy:46px;width:173px;height:42px;animation:cvf9 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf10{
  0%,18.00%{transform:translate(701px,130px) rotate(-7deg) scale(.5);opacity:0}
  19.20%{opacity:1}
  20.68%{transform:translate(405px,384px) rotate(14deg) scale(0.62);opacity:1}
  23.36%{transform:translate(237px,170px) rotate(6deg) scale(0.71);opacity:1}
  26.04%{transform:translate(486px,175px) rotate(-2deg) scale(0.80);opacity:1}
  28.71%{transform:translate(415px,244px) rotate(-10deg) scale(0.89);opacity:1}
  33.00%,88%{transform:translate(802px,230px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(802px,230px) scale(1);opacity:0}
}
.cv.e10{--fx:802px;--fy:230px;width:173px;height:65px;animation:cvf10 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes cvf11{
  0%,19.40%{transform:translate(732px,234px) rotate(-18deg) scale(.5);opacity:0}
  20.60%{opacity:1}
  22.08%{transform:translate(271px,363px) rotate(14deg) scale(0.62);opacity:1}
  24.76%{transform:translate(298px,125px) rotate(6deg) scale(0.71);opacity:1}
  27.44%{transform:translate(510px,206px) rotate(-2deg) scale(0.80);opacity:1}
  30.11%{transform:translate(392px,244px) rotate(-10deg) scale(0.89);opacity:1}
  34.40%,88%{transform:translate(802px,414px) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(802px,414px) scale(1);opacity:0}
}
.cv.e11{--fx:802px;--fy:414px;width:173px;height:42px;animation:cvf11 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}

/* ── Search · 36 wireframe cards, shelf-packed ─────────── */
.w-card.sx-focal{left:334px;top:138px;width:306px;height:348px}
.w-card.k0{left:-30px;top:-34px;width:178px;height:62px;--gd:calc(var(--isweep) * 0.0578);animation-duration:11.0s,var(--isweep);animation-delay:0.0s,var(--gd)}
.w-card.k1{left:160px;top:-34px;width:134px;height:62px;--gd:calc(var(--isweep) * 0.1869);animation-duration:12.3s,var(--isweep);animation-delay:8.7s,var(--gd)}
.w-card.k2{left:306px;top:-34px;width:178px;height:62px;--gd:calc(var(--isweep) * 0.2629);animation-duration:13.6s,var(--isweep);animation-delay:6.4s,var(--gd)}
.w-card.k3{left:496px;top:-34px;width:178px;height:62px;--gd:calc(var(--isweep) * 0.2818);animation-duration:14.9s,var(--isweep);animation-delay:4.1s,var(--gd)}
.w-card.k4{left:686px;top:-34px;width:200px;height:62px;--gd:calc(var(--isweep) * 0.4622);animation-duration:16.2s,var(--isweep);animation-delay:1.8s,var(--gd)}
.w-card.k5{left:898px;top:-34px;width:112px;height:62px;--gd:calc(var(--isweep) * 0.5126);animation-duration:17.6s,var(--isweep);animation-delay:10.5s,var(--gd)}
.w-card.k6{left:-30px;top:40px;width:112px;height:96px;--gd:calc(var(--isweep) * 0.1367);animation-duration:11.9s,var(--isweep);animation-delay:8.2s,var(--gd)}
.w-card.k7{left:94px;top:40px;width:134px;height:96px;--gd:calc(var(--isweep) * 0.0791);animation-duration:13.2s,var(--isweep);animation-delay:5.9s,var(--gd)}
.w-card.k8{left:240px;top:40px;width:156px;height:96px;--gd:calc(var(--isweep) * 0.1602);animation-duration:14.5s,var(--isweep);animation-delay:3.6s,var(--gd)}
.w-card.k9{left:408px;top:40px;width:178px;height:96px;--gd:calc(var(--isweep) * 0.2818);animation-duration:15.8s,var(--isweep);animation-delay:1.3s,var(--gd)}
.w-card.k10{left:598px;top:40px;width:200px;height:96px;--gd:calc(var(--isweep) * 0.3957);animation-duration:17.1s,var(--isweep);animation-delay:10.0s,var(--gd)}
.w-card.k11{left:810px;top:40px;width:156px;height:96px;--gd:calc(var(--isweep) * 0.5481);animation-duration:11.4s,var(--isweep);animation-delay:7.7s,var(--gd)}
.w-card.k12{left:978px;top:40px;width:178px;height:96px;--gd:calc(var(--isweep) * 0.5817);animation-duration:12.7s,var(--isweep);animation-delay:5.4s,var(--gd)}
.w-card.k13{left:-30px;top:148px;width:178px;height:118px;--gd:calc(var(--isweep) * 0.2356);animation-duration:14.0s,var(--isweep);animation-delay:3.1s,var(--gd)}
.w-card.k14{left:160px;top:148px;width:162.0px;height:118px;--gd:calc(var(--isweep) * 0.3062);animation-duration:15.3s,var(--isweep);animation-delay:0.8s,var(--gd)}
.w-card.k15{left:654px;top:148px;width:200px;height:118px;--gd:calc(var(--isweep) * 0.5318);animation-duration:16.7s,var(--isweep);animation-delay:9.5s,var(--gd)}
.w-card.k16{left:866px;top:148px;width:134px;height:118px;--gd:calc(var(--isweep) * 0.5814);animation-duration:18.0s,var(--isweep);animation-delay:7.2s,var(--gd)}
.w-card.k17{left:-30px;top:278px;width:156px;height:74px;--gd:calc(var(--isweep) * 0.2777);animation-duration:12.3s,var(--isweep);animation-delay:4.9s,var(--gd)}
.w-card.k18{left:138px;top:278px;width:184.0px;height:74px;--gd:calc(var(--isweep) * 0.3810);animation-duration:13.6s,var(--isweep);animation-delay:2.6s,var(--gd)}
.w-card.k19{left:654px;top:278px;width:200px;height:74px;--gd:calc(var(--isweep) * 0.6295);animation-duration:14.9s,var(--isweep);animation-delay:0.3s,var(--gd)}
.w-card.k20{left:866px;top:278px;width:134px;height:74px;--gd:calc(var(--isweep) * 0.7059);animation-duration:16.2s,var(--isweep);animation-delay:9.0s,var(--gd)}
.w-card.k21{left:-30px;top:364px;width:134px;height:104px;--gd:calc(var(--isweep) * 0.4189);animation-duration:17.5s,var(--isweep);animation-delay:6.7s,var(--gd)}
.w-card.k22{left:116px;top:364px;width:156px;height:104px;--gd:calc(var(--isweep) * 0.3897);animation-duration:11.8s,var(--isweep);animation-delay:4.4s,var(--gd)}
.w-card.k23{left:654px;top:364px;width:156px;height:104px;--gd:calc(var(--isweep) * 0.7270);animation-duration:13.1s,var(--isweep);animation-delay:2.1s,var(--gd)}
.w-card.k24{left:822px;top:364px;width:156px;height:104px;--gd:calc(var(--isweep) * 0.7775);animation-duration:14.4s,var(--isweep);animation-delay:10.8s,var(--gd)}
.w-card.k25{left:-30px;top:480px;width:200px;height:84px;--gd:calc(var(--isweep) * 0.5168);animation-duration:15.8s,var(--isweep);animation-delay:8.5s,var(--gd)}
.w-card.k26{left:182px;top:480px;width:134px;height:84px;--gd:calc(var(--isweep) * 0.5569);animation-duration:17.1s,var(--isweep);animation-delay:6.2s,var(--gd)}
.w-card.k27{left:654px;top:480px;width:178px;height:84px;--gd:calc(var(--isweep) * 0.7699);animation-duration:11.4s,var(--isweep);animation-delay:3.9s,var(--gd)}
.w-card.k28{left:844px;top:480px;width:134px;height:84px;--gd:calc(var(--isweep) * 0.8979);animation-duration:12.7s,var(--isweep);animation-delay:1.6s,var(--gd)}
.w-card.k29{left:-30px;top:576px;width:178px;height:132px;--gd:calc(var(--isweep) * 0.4920);animation-duration:14.0s,var(--isweep);animation-delay:10.3s,var(--gd)}
.w-card.k30{left:160px;top:576px;width:134px;height:132px;--gd:calc(var(--isweep) * 0.6276);animation-duration:15.3s,var(--isweep);animation-delay:8.0s,var(--gd)}
.w-card.k31{left:306px;top:576px;width:112px;height:132px;--gd:calc(var(--isweep) * 0.7500);animation-duration:16.6s,var(--isweep);animation-delay:5.7s,var(--gd)}
.w-card.k32{left:430px;top:576px;width:156px;height:132px;--gd:calc(var(--isweep) * 0.7756);animation-duration:17.9s,var(--isweep);animation-delay:3.4s,var(--gd)}
.w-card.k33{left:598px;top:576px;width:112px;height:132px;--gd:calc(var(--isweep) * 0.7665);animation-duration:12.2s,var(--isweep);animation-delay:1.1s,var(--gd)}
.w-card.k34{left:722px;top:576px;width:134px;height:132px;--gd:calc(var(--isweep) * 0.9665);animation-duration:13.5s,var(--isweep);animation-delay:9.8s,var(--gd)}
.w-card.k35{left:868px;top:576px;width:200px;height:132px;--gd:calc(var(--isweep) * 0.9850);animation-duration:14.9s,var(--isweep);animation-delay:7.5s,var(--gd)}
.w-card.sx-focal{--gd:calc(var(--isweep) * 0.52);animation-duration:15.3s,var(--isweep);animation-delay:-4.0s,var(--gd)}

/* ── Phone · calendar tornado, as decaying offsets ───────────── */
@keyframes ms-cal0{
  0%,4.0%{transform:translate(138px,43px) rotate(3deg) scale(.5);opacity:0}
  5.4%{opacity:1}
  7.2%{transform:translate(-96px,27px) rotate(9deg) scale(0.73);opacity:1}
  10.4%{transform:translate(24px,-39px) rotate(0deg) scale(0.86);opacity:1}
  13.5%{transform:translate(9px,16px) rotate(-9deg) scale(0.99);opacity:1}
  20.0%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms0{animation:ms-cal0 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes ms-cal1{
  0%,6.2%{transform:translate(18px,109px) rotate(-17deg) scale(.5);opacity:0}
  7.6%{opacity:1}
  9.4%{transform:translate(-81px,-45px) rotate(9deg) scale(0.73);opacity:1}
  12.6%{transform:translate(60px,-5px) rotate(0deg) scale(0.86);opacity:1}
  15.7%{transform:translate(-15px,14px) rotate(-9deg) scale(0.99);opacity:1}
  22.2%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms1{animation:ms-cal1 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes ms-cal2{
  0%,8.4%{transform:translate(-120px,66px) rotate(2deg) scale(.5);opacity:0}
  9.8%{opacity:1}
  11.6%{transform:translate(15px,-71px) rotate(9deg) scale(0.73);opacity:1}
  14.8%{transform:translate(36px,34px) rotate(0deg) scale(0.86);opacity:1}
  17.9%{transform:translate(-24px,-2px) rotate(-9deg) scale(0.99);opacity:1}
  24.4%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms2{animation:ms-cal2 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes ms-cal3{
  0%,10.6%{transform:translate(-138px,-44px) rotate(-18deg) scale(.5);opacity:0}
  12.0%{opacity:1}
  13.8%{transform:translate(96px,-27px) rotate(9deg) scale(0.73);opacity:1}
  17.0%{transform:translate(-24px,39px) rotate(0deg) scale(0.86);opacity:1}
  20.1%{transform:translate(-9px,-16px) rotate(-9deg) scale(0.99);opacity:1}
  26.6%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms3{animation:ms-cal3 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes ms-cal4{
  0%,12.8%{transform:translate(-17px,-109px) rotate(2deg) scale(.5);opacity:0}
  14.2%{opacity:1}
  16.0%{transform:translate(81px,45px) rotate(9deg) scale(0.73);opacity:1}
  19.2%{transform:translate(-61px,5px) rotate(0deg) scale(0.86);opacity:1}
  22.3%{transform:translate(15px,-14px) rotate(-9deg) scale(0.99);opacity:1}
  28.8%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms4{animation:ms-cal4 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}
@keyframes ms-cal5{
  0%,15.0%{transform:translate(121px,-65px) rotate(-18deg) scale(.5);opacity:0}
  16.4%{opacity:1}
  18.2%{transform:translate(-16px,71px) rotate(9deg) scale(0.73);opacity:1}
  21.4%{transform:translate(-36px,-34px) rotate(0deg) scale(0.86);opacity:1}
  24.5%{transform:translate(24px,3px) rotate(-9deg) scale(0.99);opacity:1}
  31.0%,88%{transform:translate(0,0) rotate(0deg) scale(1);opacity:1}
  95%,100%{transform:translate(0,0) scale(1);opacity:0}
}
.m-clayer .cv.ms5{animation:ms-cal5 var(--loop) cubic-bezier(.32,.02,.2,1) infinite}

/* ===== END GENERATED ===== */
