/* ============================================================
   Nabhak, portfolio v4: article illustrations (HTML/SVG; the only rasters are the avatar + Momo).
   Style (owner picked 1 Oct 2026, docs/decisions.md): a soft, real-looking app window (.ilw: white
   surface, no outlines, layered soft shadow) on a cream ground (.il), with a hand-drawn layer on top:
   .il-ink pen lines generated by tools/build-articles.py (3 pre-wobbled frames = line boil),
   .il-hand labels in Mali, .il-mark underlines, plus my avatar (.il-duo-av, the Momo Whisper video one).
   26 Oct 2026: the article figures moved to the kit (css/article.css "Kit figures", tools/article_figures.py) and their
   runner in js/article.js was removed: nothing sets .is-playing / .is-live / data-seq / data-say / data-votes any more.
   The old figure rules below (boil, cursors, parking, vote replay, feed, .ip-*, .sl-*) are dead, kept until a purge. (The four back-room storyboard
   figures were cut 7 Oct 2026, owner pin: plain text there; recover from git before that date if ever wanted.)
   Motion spec (owner pick 1 Oct 2026, docs/boards/motion-proposal: B "warm editorial" base):
   one mover at a time; in 250-420 ms ease-out (--ease), out 150-200 ms; the arriving hero piece of a figure may
   use --il-spring (overshoot ~3%); <= 12 px travel, rotate <= 2 deg, never 360 / 3D; pen lines draw AFTER the UI has
   landed; base markup = the end frame (reduced motion / no JS). Loads after site.css on writing.html and v2 articles.
   ============================================================ */
/* illustration-local scale: article figures and covers are mock-ups with their own small sizes (out of the v6 UI type/radius scale) */
@font-face{font-family:"Silka";src:url("../fonts/silka-semibold-webfont.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}  /* illustrations only: the UI uses 400/500/700 */
:root{--il-fs-2xs:.625rem;--il-fs-xs:.75rem;--il-fs-sm:.875rem;--il-fs-md:1rem;--il-r-md:14px;--il-r-lg:22px;--il-line:#E8E8E8;--il-line-strong:#D9D7D5}


/* ---------- Ground ---------- */
.il{position:relative;overflow:hidden;min-width:0;padding:clamp(var(--s-4),3.5%,var(--s-6));border-radius:var(--il-r-lg);color:var(--ink);
  --il-pen:color-mix(in srgb,var(--ink) 86%,transparent);
  --il-spring:cubic-bezier(.22,1.2,.36,1);--il-carry:cubic-bezier(.4,0,.2,1);
  /* scale-only pop for a small delta (.86 -> 1): y2 1.9 overshoots ~21% of the delta = scale peaks ~1.03 at ~45% of the
     time, then settles from above. --il-spring's ~1.3% would be invisible on a .14 delta (measured: 1.002). */
  --il-pop:cubic-bezier(.3,1.9,.5,1);
  /* pen-stroke wipe, left to right. The SVGs overflow their box (round caps + the pen's overshoot), so the end state
     clips 12 px OUTSIDE the box: inset(0) chopped the tail of the "listening" underline flat (owner pin, 7 Oct). */
  --il-wipe-0:inset(-12px calc(100% + 12px) -12px -12px);--il-wipe-1:inset(-12px);
  --il-hand:"Mali","Sukhumvit Set","Thonburi",cursive;
  --il-line:color-mix(in srgb,var(--ink) 6%,transparent);
  --il-ring:0 0 0 1px var(--il-line);
  --il-sh:var(--il-ring),0 1px 2px color-mix(in srgb,var(--ink) 5%,transparent),0 26px 40px -22px color-mix(in srgb,var(--ink) 38%,transparent);
  --il-sh-sm:var(--il-ring),0 1px 2px color-mix(in srgb,var(--ink) 6%,transparent),0 8px 14px -9px color-mix(in srgb,var(--ink) 28%,transparent);
  background:
    radial-gradient(60% 80% at 12% 8%,color-mix(in srgb,var(--sun-art) 22%,transparent),transparent 70%),
    radial-gradient(50% 70% at 92% 100%,color-mix(in srgb,var(--teal) 14%,transparent),transparent 70%),
    linear-gradient(160deg,var(--white),var(--cream));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 5%,transparent)}
.fpost-visual .il{border-radius:0;box-shadow:none}

/* ---------- Window ---------- */
.ilw{position:relative;border-radius:var(--il-r-md);background:var(--white);box-shadow:var(--il-sh);overflow:hidden;min-width:0}
.ilw-bar{display:flex;align-items:center;gap:6px;height:36px;padding:0 12px;border-bottom:1px solid color-mix(in srgb,var(--ink) 7%,transparent);background:linear-gradient(var(--white),var(--cream));font-size:var(--il-fs-xs);font-weight:600;color:var(--muted)}
.ilw-bar i{width:9px;height:9px;border-radius:50%;background:color-mix(in srgb,var(--ink) 14%,transparent)}
.ilw-bar span:first-of-type{margin-left:var(--s-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ilw-ppl{margin-left:auto;display:flex;flex:none}
.ilw-ppl b{width:20px;height:20px;margin-left:-5px;border-radius:50%;display:grid;place-items:center;font-size:var(--il-fs-xs);font-weight:700;color:var(--white);box-shadow:0 0 0 2px var(--white)}
.ilw-ppl b:nth-child(1){background:var(--teal)}
.ilw-ppl b:nth-child(2){background:var(--tangerine)}
.ilw-ppl b:nth-child(3){background:var(--sun-art);color:var(--ink)}
.ilw-board{background-image:radial-gradient(circle,color-mix(in srgb,var(--ink) 9%,transparent) 1px,transparent 1.2px);background-size:22px 22px;background-position:11px 11px}
.ilw-board{position:relative;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;padding:14px;--il-nh:60px;--il-ng:10px}
.ilw-col{display:flex;flex-direction:column;gap:var(--il-ng);min-width:0}
.ilw-col small{display:block;height:18px;font-size:var(--il-fs-xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;line-height:18px;color:var(--muted);white-space:nowrap}
/* Cards (owner pin 1 Oct): a title row + a meta row, 60 px tall, so they read as cards, not thin bars */
.il-note{position:relative;display:flex;flex-direction:column;justify-content:center;gap:5px;box-sizing:border-box;height:var(--il-nh);padding:8px 12px;border-radius:10px;background:var(--white);box-shadow:var(--il-sh-sm);font-size:var(--il-fs-sm);font-weight:600;line-height:1.1;color:var(--ink);min-width:0}
.il-note-h{display:flex;align-items:center;gap:8px;min-width:0}
.il-note-t{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.il-note-m{display:flex;align-items:center;gap:8px;min-height:12px;padding-left:16px;font-size:var(--il-fs-xs);font-weight:500;line-height:1;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.il-dot{width:8px;height:8px;border-radius:50%;flex:none}
.il-ghost{background:transparent;box-shadow:none;outline:1.5px dashed color-mix(in srgb,var(--ink) 24%,transparent);outline-offset:-1.5px;color:var(--muted)}
.il-ghost .il-dot{opacity:.5}
.il-drop{display:block;height:var(--il-nh);border-radius:10px;background:color-mix(in srgb,var(--teal) 9%,transparent);outline:1.5px dashed color-mix(in srgb,var(--teal) 55%,transparent);outline-offset:-1.5px}
.d-teal{background:var(--teal)}
.d-sun{background:var(--sun-art)}
.d-tan{background:var(--tangerine)}
.il-dots{display:inline-flex;align-items:center;flex:0 0 auto;font-style:normal}
.il-dots b{width:10px;height:10px;border-radius:50%;margin-left:-3px;box-shadow:0 0 0 1.5px var(--white)}
.il-dots b:first-child{margin-left:0}
.il-dots .d-big,.ilw-legend .d-big{width:18px;height:18px;display:inline-grid;place-items:center;background:var(--ink);color:var(--white);font-size:var(--il-fs-xs);font-weight:700;line-height:1}
.ilw-legend{display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-4);padding:var(--s-2) 14px var(--s-3);border-top:1px solid color-mix(in srgb,var(--ink) 7%,transparent);font-size:var(--il-fs-xs);font-weight:600;color:var(--body)}
.ilw-legend li{display:inline-flex;align-items:center;gap:6px}
.ilw-legend b{width:10px;height:10px;border-radius:50%}

/* ---------- Hand-drawn layer ---------- */
.il-ink{position:absolute;inset:0;z-index:3;width:100%;height:100%;overflow:visible;pointer-events:none;fill:none;stroke:var(--il-pen);stroke-linecap:round;stroke-linejoin:round}
.il-boil-f{opacity:0}
.il-boil-f:first-child{opacity:1}
.is-playing .il-boil-f{animation:ilBoil .42s step-end infinite}
.is-playing .il-boil-f:nth-child(2){animation-delay:-.14s}
.is-playing .il-boil-f:nth-child(3){animation-delay:-.28s}
@keyframes ilBoil{0%,33.3%{opacity:1}33.4%,100%{opacity:0}}
.il-mark{position:relative;white-space:nowrap}
.il-ul{position:absolute;left:-3%;bottom:-.14em;width:106%;height:.36em;overflow:visible;pointer-events:none;fill:none;stroke:var(--sun-art);stroke-linecap:round;stroke-linejoin:round}
.il-hand{position:absolute;z-index:4;font-family:var(--il-hand);font-weight:600;font-size:clamp(.82rem,1.6vw,1.05rem);line-height:1.2;color:var(--il-pen);white-space:nowrap;transform:rotate(var(--rot,-3deg));transform-origin:0 50%;pointer-events:none}

/* ---------- Cursors ---------- */
.il-cur{position:absolute;z-index:5;display:flex;align-items:flex-start;pointer-events:none;color:var(--teal-text)}
.il-cur svg{width:18px;height:18px;flex:none;fill:currentColor;stroke:var(--white);stroke-width:1.4;stroke-linejoin:round;filter:drop-shadow(0 1px 1px color-mix(in srgb,var(--ink) 30%,transparent))}
.il-cur span{margin:13px 0 0 -3px;padding:3px 7px;border-radius:6px;font-size:var(--il-fs-xs);font-weight:700;line-height:1.2;color:var(--white);background:var(--teal-text);box-shadow:0 4px 10px -4px color-mix(in srgb,var(--ink) 40%,transparent)}
.il-cur-client{color:var(--tangerine)}
.il-cur-client span{background:var(--tangerine)}
.il-track{position:absolute;inset:0;z-index:5;pointer-events:none}
.il-track .il-cur{left:0;top:0}

/* ---------- Avatar + Momo ---------- */
.il-duo-av,.il-duo-big{position:relative;display:inline-block;flex:none}
.il-duo-av img,.il-duo-big img{display:block;width:100%;height:auto;border-radius:50%;background:var(--sun-art);box-shadow:var(--il-sh)}

/* ---------- Cursors that float on a cover (.is-playing came from the removed js/article.js runner; inert) ---------- */
.is-playing .il-cur-p1{animation:ilFloat var(--loop) var(--ease-inout) infinite alternate}
.is-playing .il-cur-p2{animation:ilFloat calc(var(--loop) * 1.3) var(--ease-inout) -1.3s infinite alternate-reverse}
@keyframes ilFloat{from{transform:none}to{transform:translate(-6px,5px)}}

/* ---------- Closing figure: my avatar + one chat bubble at a time (old runner, removed 26 Oct 2026) ----------
   Owner (1 Oct): "like the Slack one, a feed, a loop"; (7 Oct): no composer, the messages just pop in; (7 Oct, later):
   the article's three takeaways, one message on screen at a time, the avatar centred on the bubble, a shorter figure.
   Base markup = the three bubbles stacked (reduced motion / no JS), the avatar vertically centred against the stack.
   Live (.is-live): the list is one grid cell with all three bubbles on top of each other, centred, so the cell
   is as tall as the tallest line at any width (no layout shift during the loop) and the avatar's centre is the
   bubble's centre. The .is-on bubble pops in from its tail (scale .86 -> 1 on --il-pop, a 10 px rise; individual
   translate / scale so the bounce never drags the rise past its spot), the avatar tilts 2 deg (ilTilt), the pen
   underline draws 350 ms after it lands. The old one leaves first (.is-off: 10 px up, scale .96, fade, 200 ms) and is
   reset with no transition once invisible. Tail = a rotated square clipped to its outer half with the SAME ring
   box-shadow as the bubble, so the hairline matches with no seam; it reaches 8*sqrt2 = 11.3 px left of the bubble (ring
   included): nothing clips the list (no overflow:hidden) and its left padding keeps the tip off the avatar. */
.il-feed{--il-av:clamp(72px,14%,112px);--il-gap:var(--s-5);display:flex;align-items:center;justify-content:center;gap:var(--il-gap);padding:var(--s-6)}  /* avatar + bubble window = one pair, centred in the box; window = widest line, bubbles left-aligned beside the fixed avatar */
.il-duo-big{flex:none;width:var(--il-av);transform-origin:50% 90%}
.il-duo-big.is-tilt{animation:ilTilt var(--dur-2) var(--ease) both}
@keyframes ilTilt{0%{transform:none}45%{transform:rotate(-2deg)}100%{transform:none}}
.il-feed-win{flex:0 1 auto;max-width:520px;min-width:0}
.il-feed-list{display:flex;flex-direction:column;align-items:flex-start;gap:10px}
.il-feed.is-live .il-feed-list{display:grid;grid-template-columns:minmax(0,max-content);justify-items:start;align-items:center}
.il-bub{position:relative;flex:none;max-width:100%;padding:var(--s-3) var(--s-4);border-radius:var(--il-r-md);background:var(--white);box-shadow:var(--il-sh);font-size:clamp(.95rem,1.6vw,1.15rem);font-weight:600;line-height:1.4;letter-spacing:-.01em;color:var(--ink);overflow-wrap:anywhere;text-wrap:balance;transform-origin:0 50%}
.il-bub::before{content:"";position:absolute;z-index:1;left:-7px;top:50%;width:14px;height:14px;margin-top:-7px;background:var(--white);box-shadow:var(--il-ring);clip-path:polygon(-2px -2px,-2px 16px,16px 16px);transform:rotate(45deg)}
.il-feed.is-live .il-bub{grid-area:1/1;opacity:0;translate:0 10px;scale:.86;transition:none}
.il-feed.is-live .il-bub.is-on{opacity:1;translate:none;scale:none;transition:opacity .25s var(--ease),translate .35s var(--ease),scale .45s var(--il-pop)}
.il-feed.is-live .il-bub.is-off{translate:0 -10px;scale:.96;transition:opacity .18s var(--ease),translate .2s var(--ease),scale .2s var(--ease)}
.il-feed.is-live .il-bub .il-ul{clip-path:var(--il-wipe-0)}
.il-feed.is-live .il-bub:is(.is-on,.is-off) .il-ul{clip-path:var(--il-wipe-1)}
.il-feed.is-live .il-bub.is-on .il-ul{transition:clip-path .6s linear .35s}

/* ---------- Parking lot loop ----------
   10 s, all transform/opacity/clip-path, direction B: the board starts empty; the Client cursor places Search,
   Categories, Cart (ilPlace1-3) and Live video (ilPark), each arriving in 420 ms from 10 px up (--il-spring, ~3%
   overshoot); Me then lifts Live video (250 ms: scale 1.03, 1.5 deg, deeper shadow), carries it 850 ms (--il-carry),
   drops it (300 ms settle, no bounce; dot / ring / meta turn teal "Nice to have"), THEN the pen arrow draws (700 ms
   radial wipe from its start) and "parking lot" fades in; hold; quick fade; reset at the parked spot, never mid-drag.
   Every rest state is the END state, so reduced motion and no JS (animation:none from the page's <noscript>) show the
   finished board with the arrow. */
.ilw-park :is(.il-note,.il-cur,.il-track-client,.il-dot,.il-swap>span,.il-ink,.il-hand),.ilw-park .il-move::after{animation-duration:10s;animation-timing-function:var(--ease);animation-iteration-count:infinite;animation-play-state:paused}
.is-playing .ilw-park :is(.il-note,.il-cur,.il-track-client,.il-dot,.il-swap>span,.il-ink,.il-hand),.is-playing .ilw-park .il-move::after{animation-play-state:running}
.ilw-park .ilw-col:first-child .il-note:nth-child(2){animation-name:ilPlace1}
.ilw-park .ilw-col:first-child .il-note:nth-child(3){animation-name:ilPlace2}
.ilw-park .ilw-col:first-child .il-note:nth-child(4){animation-name:ilPlace3}
.ilw-park .il-park-ghost{animation-name:ilGhost}
.ilw-park .il-move{position:absolute;left:calc(50% + 6px);top:40px;width:calc(50% - 20px);z-index:5;--dx:calc(-100% - 12px);--dy:calc(3 * (var(--il-nh) + var(--il-ng)));box-shadow:var(--il-sh-sm),0 0 0 1.5px color-mix(in srgb,var(--teal) 55%,transparent);animation-name:ilPark,ilRing}
.ilw-park .il-move .il-dot{animation-name:ilDot}
.il-swap{display:inline-grid}
.il-swap>span{grid-area:1/1}
.ilw-park .il-swap>span:first-child{opacity:0;animation-name:ilMetaA}
.ilw-park .il-swap>span:last-child{animation-name:ilMetaB}
.ilw-park .il-move::after{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;box-shadow:0 22px 34px -14px color-mix(in srgb,var(--ink) 50%,transparent);opacity:0;animation-name:ilLift}
.ilw-park .il-move .il-cur{right:14px;bottom:-14px;animation-name:ilMe}
.ilw-park .il-track-client{transform:translate(70%,62%);animation-name:ilClient}  /* base = end of loop (reduced motion) */
.ilw-park .il-ink{animation-name:ilInk;animation-timing-function:linear}
.ilw-park .il-hand{animation-name:ilLabel}
@keyframes ilPlace1{0%,5%{opacity:0;transform:translateY(-10px) scale(.96);animation-timing-function:var(--il-spring)}9.2%,92%{opacity:1;transform:none}94%,100%{opacity:0;transform:none}}
@keyframes ilPlace2{0%,13%{opacity:0;transform:translateY(-10px) scale(.96);animation-timing-function:var(--il-spring)}17.2%,92%{opacity:1;transform:none}94%,100%{opacity:0;transform:none}}
@keyframes ilPlace3{0%,21%{opacity:0;transform:translateY(-10px) scale(.96);animation-timing-function:var(--il-spring)}25.2%,92%{opacity:1;transform:none}94%,100%{opacity:0;transform:none}}
@keyframes ilGhost{0%,42%{opacity:0}45%,92%{opacity:1}94%,100%{opacity:0}}
@keyframes ilPark{
  0%,29%{transform:translate(var(--dx),calc(var(--dy) - 10px)) scale(.96);opacity:0;animation-timing-function:var(--il-spring)}
  33.2%,42%{transform:translate(var(--dx),var(--dy));opacity:1;animation-timing-function:var(--ease)}
  44.5%{transform:translate(var(--dx),var(--dy)) scale(1.03) rotate(1.5deg);animation-timing-function:var(--il-carry)}
  53%{transform:translate(0,0) scale(1.03) rotate(1.5deg);animation-timing-function:var(--ease)}
  56%,92%{transform:none;opacity:1}
  94%{transform:none;opacity:0}
  95%,100%{transform:translate(var(--dx),calc(var(--dy) - 10px)) scale(.96);opacity:0}
}
@keyframes ilRing{0%,53%{box-shadow:var(--il-sh-sm),0 0 0 1.5px color-mix(in srgb,var(--sun-art) 70%,transparent)}56%,100%{box-shadow:var(--il-sh-sm),0 0 0 1.5px color-mix(in srgb,var(--teal) 55%,transparent)}}
@keyframes ilDot{0%,53%{background:var(--sun-art)}56%,94%{background:var(--teal)}95%,100%{background:var(--sun-art)}}
@keyframes ilMetaA{0%,53%{opacity:1}56%,94%{opacity:0}95%,100%{opacity:1}}
@keyframes ilMetaB{0%,53%{opacity:0}56%,94%{opacity:1}95%,100%{opacity:0}}
@keyframes ilLift{0%,42%{opacity:0}44.5%,53%{opacity:1}56%,100%{opacity:0}}
@keyframes ilMe{
  0%,37%{transform:translate(40px,38px)}
  41%,57%{transform:none}
  61%,92%{transform:translate(-12px,34px)}
  100%{transform:translate(40px,38px)}
}
@keyframes ilClient{
  0%,3%{transform:translate(30%,14%)}
  5%{transform:translate(29.5%,15.5%)}
  8%{transform:translate(30%,36%)}
  13%{transform:translate(29.5%,37.5%)}
  16%{transform:translate(30%,58%)}
  21%{transform:translate(29.5%,59.5%)}
  24%{transform:translate(30%,80%)}
  29%{transform:translate(29.5%,81.5%)}
  33%{transform:translate(30%,80%)}
  40%,94%{transform:translate(70%,62%)}
  100%{transform:translate(30%,14%)}
}
/* the pen arrow starts at its tail (448,266 of the 884 x 324 board = 50.7% 82%) and grows out from there, 700 ms */
@keyframes ilInk{0%,57%{clip-path:circle(0 at 50.7% 82%)}64%,92%{clip-path:circle(105% at 50.7% 82%)}94%,100%{clip-path:circle(0 at 50.7% 82%)}}
@keyframes ilLabel{0%,63%{opacity:0}66%,92%{opacity:1}94%,100%{opacity:0}}

/* ---------- Vote replay (old runner, removed 26 Oct 2026) ----------
   .is-live = JS is driving it: dots start hidden and pop in (.is-in) role by role; .is-scattered puts every
   card where it sat before the vote (--sx/--sy from the generator, transform only). The ring + label only
   make sense once sorted: hidden for the whole live loop until .is-sorted (set when the glide has ended),
   then the ink wipes in like a pen stroke and the label fades after it. Without JS or with reduced motion
   The MVP / Backlog headings are hidden too while the cards are shuffled (no categories yet) and write in,
   text fading and the sun underline wiping like a pen stroke, on .is-headed, before the cards move (owner pin).
   Without JS or with reduced motion none of these classes exist and the markup is the sorted end state. */
.il-votes .il-vcard{transition:transform .8s var(--ease)}
.il-votes.is-scattered .il-vcard{transform:translate(var(--sx,0px),var(--sy,0px))}
.il-votes.is-live .il-dots b{transform:scale(.6);opacity:0;transition:transform .42s var(--il-spring),opacity .2s var(--ease)}
.il-votes.is-live .il-dots b.is-in{transform:none;opacity:1}
.il-votes.is-live .il-ink:not(.il-ul){opacity:0;clip-path:var(--il-wipe-0);transition:clip-path .7s var(--ease),opacity .2s var(--ease)}
.il-votes.is-live .il-hand{opacity:0;transition:opacity .4s var(--ease)}
.il-votes.is-live .ilw-col small{opacity:0;transition:opacity .45s var(--ease)}
.il-votes.is-live .ilw-col .il-ul{clip-path:var(--il-wipe-0);transition:clip-path .5s var(--ease) .25s}
.il-votes.is-headed .ilw-col small{opacity:1}
.il-votes.is-headed .ilw-col .il-ul{clip-path:var(--il-wipe-1)}
.il-votes.is-sorted .il-ink:not(.il-ul){opacity:1;clip-path:var(--il-wipe-1)}
.il-votes.is-sorted .il-hand{opacity:1;transition-delay:.5s}

/* ---------- Small screens ---------- */
@media(max-width:480px){
  .il-note{font-size:var(--il-fs-xs);padding:6px 9px}
  .il-note-m{padding-left:14px}
  .il-note-h{gap:6px}
  .ilw-col small{letter-spacing:.02em}
  .il-hand{font-size:.75rem}
  .il-feed{--il-av:48px;padding:var(--s-4) var(--s-3)}
}

/* ---------- Reduced motion: frame 1 of the ink, card parked, votes sorted, cursors at rest ---------- */
@media(prefers-reduced-motion:reduce){
  .is-playing .il-boil-f,.ilw-park :is(.il-note,.il-cur,.il-track-client,.il-dot,.il-swap>span,.il-ink,.il-hand),.ilw-park .il-move::after,.is-playing .il-cur-p1,.is-playing .il-cur-p2{animation:none}
}

/* ---------- Cover (01 Momo Hop, tip 02, articles 07 + 11; _cover in the generator): feed card, home lead card, article top media ----------
   No headline (owner pin, 12 Oct: a bold line on the cover fought the card title right under it). The UI on the right,
   my pen note (Mali) with an arrow into it and my avatar on the left. 16:9 at every width: positions are % of the
   cover, the UI keeps the figures' px parts and is zoomed in steps to the cover's own width (it is the container).
   Loop (7 s, transform/opacity only): one keyframe set per role, staggered by delay; off screen .is-paused (data-pause,
   js/site.js) pauses it. Reduced motion: no animation, the base markup = the finished frame. */
.cover{aspect-ratio:16/9;padding:0;container-type:inline-size}
/* every cover is a .mesh surface (site.css): the pale white -> cream sheet is the base, the .il tints become its blobs */
.cover.mesh{background:linear-gradient(160deg,var(--white),var(--cream))}
/* the blob tints at zero specificity, so a .hue-* class on a cover (the Writing grid's tool covers + lead, css/site.css) wins */
:where(.cover.mesh){--m1:color-mix(in srgb,var(--sun-art) 22%,transparent);--m2:color-mix(in srgb,var(--teal) 14%,transparent);--m3:var(--sun-tint)}
.cover-ui{position:absolute;right:6%;top:50%;translate:0 -50%}
.cover-note{position:absolute;left:7%;top:24%;z-index:4;font-family:var(--il-hand);font-weight:600;font-size:clamp(.75rem,2.9cqi,1.35rem);line-height:1.25;color:var(--il-pen)}
.cover-note span{display:block;rotate:-3deg;transform-origin:0 50%}
.cover-note .il-ink{position:relative;display:block;width:4.4em;height:2.2em;margin:.35em 0 0 5.4em}
.cover .il-duo-av{position:absolute;left:7%;bottom:9%;z-index:4;width:clamp(36px,10cqi,76px)}
/* the article number on cards (owner, 12 Oct): the plain thumbs' badge (.nsq, untilted like .thumb .t-n), same corner */
.cover-n{position:absolute;left:var(--s-5);top:var(--s-5);z-index:5;--nsq-rot:0deg}
.cover-bars .cover-ui{width:380px;--tm-dx:14px;--tm-dy:46px}
.cover .tm-pile{margin:0}
.cover-board .cover-ui{width:400px;top:12%;translate:none}  /* the board is tall: it bleeds off the bottom edge */
.cover-board .il-cur-p1{left:36%;top:78%}
.cover-board .il-cur-p2{left:64%;top:24%}
.cover-pins .cover-ui{width:400px}
.cover-pins .ip{--ip-h:240px}
.cover-pins .ip-pop{left:-196px}
.cover-hop .cover-ui{width:400px}
.cover .hp-app :is(.hp-search,.hp-path,.hp-run,.hp-count){display:none}  /* a shorter window: the list and the Open bar */
/* Static covers (owner pin 15 Oct: "my face icon all over them"): every note but the newest shows ONLY its main component,
   centred on both axes in the tile, no note, no avatar, no loop. --cx / --cy = optical nudge in unzoomed px where the visible
   art is wider than its box (the PinPoint popover, the rewind arrow gutter); measured with scratchpad/motion/covers.mjs. */
.cover-static .cover-ui{right:auto;left:50%;top:50%;translate:calc(-50% + var(--cx,0px)) calc(-50% + var(--cy,0px))}
/* the three big 400 px windows are scaled down to the family's ~55-70 % tile width (the board is tall: it must not bleed) */
.cover-static.cover-board .cover-ui{width:360px;scale:.8}
.cover-static.cover-bars .cover-ui{scale:.85}
.cover-static.cover-pins .cover-ui{width:340px}
.cover-static.cover-pins .ip{--ip-h:200px}
@container (max-width:660px){.cover-ui{zoom:.88}}
@container (max-width:580px){.cover-ui{zoom:.78}}
@container (max-width:500px){.cover-ui{zoom:.68}}
@container (max-width:430px){.cover-ui{zoom:.6}}
@container (max-width:370px){.cover-ui{zoom:.52}}
@container (max-width:480px){.cover-note br{display:none}.cover-note span{max-width:7.2em}.cover-note .il-ink{margin-left:3.6em}.cover-n{--nsq:32px;left:var(--s-3);top:var(--s-3)}.cover:has(.cover-n) .cover-note{top:31%}}  /* phones: three short lines, clear of the UI and the badge */
@media(prefers-reduced-motion:no-preference){
  /* only a [data-loop] cover (the newest note) animates; static covers rest on the finished frame */
  .cover[data-loop] :is(.tm-new,.tm-old,.pin,.ip-pop,.hp-hl,.hp-n b,.cover-note){animation:7s var(--ease) infinite backwards}
  .cover.is-paused :is(.tm-new,.tm-old,.pin,.ip-pop,.hp-hl,.hp-n b,.cover-note){animation-play-state:paused}
  .cover .tm-new{animation-name:cvTag}
  .cover .tm-old{animation-name:cvStub}
  .cover .tm-a :is(.tm-new,.tm-old){animation-delay:.25s}  /* front to back */
  .cover .tm-w :is(.tm-new,.tm-old){animation-delay:.5s}
  .cover .pin{animation-name:cvPin}
  .cover .ip-pop{animation-name:cvRise}
  /* owner pin, 13 Oct: one row at a time, 1 -> 2 -> 3 (~.6 s apart), the count follows: Open, Open 1, Open 2, Open 3 */
  .cover .hp-row:nth-child(2) .hp-hl{animation-name:cvSel1}
  .cover .hp-row:nth-child(3) .hp-hl{animation-name:cvSel2}
  .cover .hp-row:nth-child(4) .hp-hl{animation-name:cvSel3}
  .cover .hp-n b:nth-child(1){animation-name:cvN0}
  .cover .hp-n b:nth-child(2){animation-name:cvN1}
  .cover .hp-n b:nth-child(3){animation-name:cvN2}
  .cover .hp-n b:nth-child(4){animation-name:cvN3}
  .cover .cover-note{animation-name:cvNote}
}
@keyframes cvTag{0%,12%{opacity:0;scale:.7;animation-timing-function:var(--il-pop)}18%,90%{opacity:1;scale:1}95%,100%{opacity:0;scale:1}}
@keyframes cvStub{0%,12%{opacity:1}16%,91%{opacity:0}96%,100%{opacity:1}}
@keyframes cvPin{0%,8%{opacity:0;transform:translateY(-10px) rotate(-45deg) scale(.6);animation-timing-function:var(--il-spring)}14%,90%{opacity:1;transform:rotate(-45deg) scale(1)}95%,100%{opacity:0;transform:rotate(-45deg) scale(1)}}
@keyframes cvRise{0%,30%{opacity:0;translate:0 10px;scale:.96;animation-timing-function:var(--il-spring)}36%,90%{opacity:1;translate:none;scale:none}95%,100%{opacity:0}}
@keyframes cvSel1{0%,12%{opacity:0}15%,90%{opacity:1}94%,100%{opacity:0}}
@keyframes cvSel2{0%,21%{opacity:0}24%,90%{opacity:1}94%,100%{opacity:0}}
@keyframes cvSel3{0%,30%{opacity:0}33%,90%{opacity:1}94%,100%{opacity:0}}
@keyframes cvN0{0%,12.9%{opacity:1}13%,93.9%{opacity:0}94%,100%{opacity:1}}
@keyframes cvN1{0%,12.9%{opacity:0}13%,21.9%{opacity:1}22%,100%{opacity:0}}
@keyframes cvN2{0%,21.9%{opacity:0}22%,30.9%{opacity:1}31%,100%{opacity:0}}
@keyframes cvN3{0%,30.9%{opacity:0}31%,93.9%{opacity:1}94%,100%{opacity:0}}
@keyframes cvNote{0%,44%{opacity:0;translate:-6px 0}50%,90%{opacity:1;translate:none}95%,100%{opacity:0}}

/* ---------- Article 07 step figures (.ip-*, old data-seq runner removed 26 Oct 2026) ----------
   A soft mock page (nav, hero, three cards) inside an .ilw window; pins = the site's .pin (same as the cover and the
   PinPoint case demo); note editor, area box + chip and the docked toolbar mirror the real Momo PinPoint UI. Live (.is-live, JS):
   every [data-at] is hidden until .is-on (.ip-keep = always shown, animates differently; .ip-tmp = only shown mid-sequence);
   .is-reset fades the stage, then everything is cleared with no transition. Base markup = the composed end frame.
   Windows do not clip (pins and the chip stand above their anchors; the section copy travels across the gap). */
.ip{--ip-pin:28px;--ip-gap:40px;--ip-ref:color-mix(in srgb,var(--ink) 62%,transparent);--brand:var(--ip-ref);--ip-bar:color-mix(in srgb,var(--ink) 88%,var(--white))}
.ip .ip-stage{transition:opacity .25s var(--ease)}
.ip.is-reset .ip-stage{opacity:0}
.ip .ilw{overflow:visible}
.ip .ilw-bar{border-radius:var(--il-r-md) var(--il-r-md) 0 0}
.ip-win{position:relative;height:var(--ip-h);border-radius:0 0 var(--il-r-md) var(--il-r-md)}
.ip-refsite{--ip-h:160px}
.ip-row{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:var(--s-5);align-items:start;position:relative}
.ip-row-2{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--ip-gap)}
.ip-labels{position:relative;height:30px;margin-top:var(--s-3)}
.ip-labels .il-hand{top:0}
.ip-lab-c{left:50%;translate:-50% 0}
/* the mock page */
.ip-pg{position:absolute;inset:0;display:flex;flex-direction:column;gap:10px;padding:12px;pointer-events:none}
.ip-pg i{box-sizing:border-box}
.ip-brand,.ip-lnk,.ip-btn,.ip-hbtn,.ip-h1,.ip-h2,.ip-cdot,.ip-cbar,.ip-card .ip-bar{display:block;position:relative}
.ip-nav{position:relative;display:flex;align-items:center;gap:8px;height:16px}
.ip-brand{width:34px;height:8px;border-radius:4px;background:var(--ip-ref)}
.ip-lnk{width:22px;height:6px;border-radius:3px;background:var(--il-line-strong)}
.ip-brand+.ip-lnk{margin-left:auto}
.ip-btn,.ip-hbtn{height:16px;width:40px;border-radius:8px;background:var(--brand)}
.ip-hero{position:relative;display:flex;flex-direction:column;align-items:center;gap:6px;padding:6px 0 2px}
.ip-h1{width:46%;height:10px;border-radius:5px;background:var(--ip-ref)}
.ip-h2{width:62%;height:6px;border-radius:3px;background:var(--il-line-strong)}
.ip-hbtn{width:48px;margin-top:4px}
.ip-cards{position:relative;flex:1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.ip-card{position:relative;display:flex;flex-direction:column;gap:5px;padding:8px;border-radius:8px;background:var(--cream);box-shadow:inset 0 0 0 1px var(--il-line-strong)}
.ip-cdot{width:10px;height:10px;border-radius:50%;background:var(--brand);margin-bottom:1px}
.ip-cbar{width:80%;height:5px;border-radius:3px;background:var(--brand);opacity:.55}
.ip-card .ip-bar{width:55%;height:5px;border-radius:3px;background:var(--il-line-strong)}
.ip-mine{--brand:var(--teal)}
/* .ip-pale (owner pins, 12 Oct: the mock page read too dark, the note editor did not stand out): article 07's figures
   and its cover. The mock page is a pale wireframe (headline / buttons / dots at 18% ink, bars and card edges at --line;
   "my project" keeps its teal) and the editor gets a deeper soft shadow, so pins, notes and the editor are the focus. */
.ip-pale .ip-pg{--ip-ref:color-mix(in srgb,var(--ink) 18%,transparent);--line-strong:var(--il-line)}
.ip-pale .ip-pg:not(.ip-mine){--brand:var(--ip-ref)}
.ip-pale .ip-pop{box-shadow:var(--il-sh),0 18px 32px -18px color-mix(in srgb,var(--ink) 30%,transparent)}
/* spots + pins: the site's .pin (tangerine, 2 px white ring, soft shadow, no ink stroke; owner 12 Oct). Live, a pin
   drops 10 px from above and settles on --il-spring (420 ms) while a tangerine ring pulses out from under it. */
.ip-spot{position:absolute;left:var(--x);top:var(--y);width:0;height:0;z-index:4}
.ip .pin{left:0;top:0;width:var(--ip-pin);height:var(--ip-pin);margin:calc(-1 * var(--ip-pin)) 0 0 calc(var(--ip-pin) / -2);animation-timing-function:var(--il-spring)}
.ip .pin::after{content:"";position:absolute;inset:-2px;border-radius:50%;box-shadow:0 0 0 2px var(--tangerine);opacity:0;pointer-events:none}
.ip.is-live .pin:not(.is-on){animation:none;transform:rotate(-45deg) scale(0)}
.ip.is-live .pin.is-on{animation:ipDrop .42s var(--il-spring) forwards}
.ip.is-live .pin.is-on::after{animation:ipRing .6s var(--ease) .12s both}
@keyframes ipDrop{from{opacity:0;transform:translateY(-10px) rotate(-45deg) scale(.6)}to{opacity:1;transform:rotate(-45deg) scale(1)}}
@keyframes ipRing{from{opacity:.7;scale:.8}to{opacity:0;scale:2.3}}
/* generic live visibility */
.ip.is-live [data-at]:not(.is-on):not(.ip-keep){opacity:0}
.ip.is-live [data-at].is-on{transition:opacity .22s var(--ease)}
.ip.is-live .ip-tmp{opacity:0}
.ip.is-live .ip-tmp.is-on:not(.is-off){opacity:1}
.ip.is-live [data-at].is-off{opacity:0;transition:opacity .2s var(--ease)}
.ip.is-live :is(.ip-pop,.ip-paste,.ip-chip,.ip-warn,.hp-dlg):not(.is-on){translate:0 10px;scale:.96}
.ip.is-live :is(.ip-pop,.ip-paste,.ip-chip,.ip-warn,.hp-dlg).is-on{translate:none;scale:none;transition:opacity .22s var(--ease),translate .42s var(--il-spring),scale .42s var(--il-spring)}
/* 1 · ten screenshots into an AI chat, then the wall (owner, 12 Oct: the pain only, no pins). A chat window: notice
   area, a ten-step context meter, the composer with a 5 x 2 tray of attachments + an empty input. Each attachment = the
   mock page shrunk (.ip-mini, scale --ip-k) under a thin browser strip, its one spot circled in sun (.ip-ring). Live:
   tiles drop in and light a meter step each; .is-full turns the meter tangerine, greys the overflow tiles (.ip-att-x,
   x badge), then the notice pops. Base markup = that full, failed end frame. */
.ip-shots{--ip-k:.3;--ip-cb:8px;--ip-rs:13px;--ip-rw:1.8px}
.ip-shots .ilw{max-width:520px;margin-inline:auto}
.ip-chat-b{display:flex;flex-direction:column;gap:var(--s-3);padding:var(--s-4);text-align:left}
.ip-warn{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border-radius:10px;background:var(--tangerine-tint);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--tangerine) 35%,transparent);font-size:var(--il-fs-xs);line-height:1.4;color:var(--body)}
.ip-warn i{flex:none;display:grid;place-items:center;width:20px;height:20px;border-radius:50%;background:var(--tangerine);color:var(--white);font-size:var(--il-fs-xs);font-style:normal;font-weight:700}
.ip-warn b{display:block;font-size:var(--il-fs-sm);font-weight:700;color:var(--ink)}
.ip-meter{display:flex;align-items:center;gap:var(--s-2);font-size:var(--il-fs-xs);line-height:1}
.ip-meter small{font-size:var(--il-fs-xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.ip-seg{flex:1;display:grid;grid-template-columns:repeat(10,minmax(0,1fr));gap:3px}
.ip-seg i{height:6px;border-radius:3px;background:var(--tangerine);transition:background .25s var(--ease)}
.ip-shots.is-live .ip-seg i:not(.is-on){background:var(--il-line)}
.ip-shots.is-live:not(.is-full) .ip-seg i.is-on{background:var(--sun-art)}
.ip-meter b{padding:3px 8px;border-radius:var(--pill);background:var(--tangerine);color:var(--white);font-weight:700}
.ip-comp{padding:8px;border-radius:12px;background:var(--white);box-shadow:var(--il-sh-sm)}
.ip-tray{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
.ip-att{position:relative;aspect-ratio:4/3;overflow:hidden;border-radius:6px;background:var(--white);box-shadow:var(--il-ring)}
.ip-att::before{content:"";position:absolute;inset:0 0 auto;height:var(--ip-cb);border-bottom:1px solid var(--il-line);
  background:radial-gradient(circle at 6px 50%,var(--il-line-strong) 1.5px,transparent 2px),radial-gradient(circle at 11px 50%,var(--il-line-strong) 1.5px,transparent 2px),radial-gradient(circle at 16px 50%,var(--il-line-strong) 1.5px,transparent 2px),var(--cream)}
.ip-mini{inset:var(--ip-cb) auto auto 0;width:calc(100% / var(--ip-k));height:calc((100% - var(--ip-cb)) / var(--ip-k));transform:scale(var(--ip-k));transform-origin:0 0}
.ip-ring{position:absolute;left:var(--x);top:var(--y);z-index:2;width:calc(var(--ip-rs) / var(--ip-k));height:calc(var(--ip-rs) / var(--ip-k));translate:-50% -50%;border-radius:50%;background:color-mix(in srgb,var(--sun-art) 18%,transparent);box-shadow:0 0 0 calc(var(--ip-rw) / var(--ip-k)) var(--sun-art)}
.ip-att-x{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--tangerine) 55%,transparent)}
.ip-att-x .ip-mini,.ip-att-x::before{opacity:.4;filter:grayscale(1);transition:opacity .3s var(--ease),filter .3s var(--ease)}
.ip-x{position:absolute;right:3px;top:3px;z-index:3;display:grid;place-items:center;width:15px;height:15px;border-radius:50%;background:var(--ink);color:var(--white);font-size:var(--il-fs-2xs);font-weight:700;line-height:1;transition:opacity .3s var(--ease)}
.ip-shots.is-live:not(.is-full) .ip-att-x{box-shadow:var(--il-ring)}
.ip-shots.is-live:not(.is-full) .ip-att-x .ip-mini,.ip-shots.is-live:not(.is-full) .ip-att-x::before{opacity:1;filter:none}
.ip-shots.is-live:not(.is-full) .ip-x{opacity:0}
.ip.is-live :is(.ip-att,.hp-term,.hp-tab):not(.is-on){translate:0 -10px;scale:.85}
.ip.is-live :is(.ip-att,.hp-term,.hp-tab).is-on{transition:opacity .2s var(--ease),translate .38s var(--il-spring),scale .38s var(--il-spring)}
.ip-input{display:flex;align-items:center;justify-content:space-between;gap:var(--s-2);margin-top:8px;padding:2px 0 0 6px;font-size:var(--il-fs-sm);color:var(--muted)}
.ip-send{flex:none;display:grid;place-items:center;width:26px;height:26px;border-radius:50%;background:var(--il-line-strong);color:var(--white);font-size:var(--il-fs-sm);font-style:normal;font-weight:700}
/* 2 · a long page (owner, 12 Oct): the mock page grows (split section, a second card row, a footer) and is cropped by
   the window (.ip-win clips here), a thin scrollbar on its right; the Momo PinPoint toolbar is docked to the window's
   bottom (outside the page, so it stays put while the page scrolls). Live: the page starts --ip-sy down and scrolls to
   the top on .is-top (650 ms, thumb follows). Editor (.ip-pop: grey "Comment · selector" head, the note with a teal
   focus ring + typing caret, bin / Cancel / Save foot), toolbar (grip, pin + brand, "Commenting…" teal, count, Copy for
   AI, Clear all, mint toast above) and the report mirror the real tool. Under it an AI chat (fig 1's window + composer):
   the report pastes into the composer and the send button lights. */
.ip-pointer{--ip-h:330px;--ip-sy:100px;--ip-st:68px}
.ip-pointer .ip-stage{display:flex;flex-direction:column;gap:var(--s-4)}
.ip-pointer .ip-win{overflow:hidden}
.ip-pg-long{bottom:auto;padding:22px 12px 12px}
.ip-pg-long .ip-hero{padding:10px 0 6px}
.ip-pg-long .ip-cards{flex:none}
.ip-pg-long .ip-card{min-height:64px}
.ip-split{position:relative;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:center;padding:8px 0}
.ip-img{display:block;height:84px;border-radius:8px;background:linear-gradient(135deg,color-mix(in srgb,var(--teal) 20%,var(--cream)),color-mix(in srgb,var(--sun-art) 26%,var(--cream)))}
.ip-txt{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.ip-txt .ip-h1{width:72%}
.ip-txt .ip-bar{display:block;width:94%;height:5px;border-radius:3px;background:var(--il-line-strong)}
.ip-txt .ip-bar+.ip-bar{width:66%}
.ip-foot{display:flex;align-items:center;gap:8px;height:34px;padding-top:10px;border-top:1px solid var(--il-line)}
.ip-sb{position:absolute;right:3px;top:6px;bottom:6px;z-index:4;width:4px;border-radius:2px}
.ip-sb i{position:absolute;inset:0 0 auto;height:70%;border-radius:2px;background:color-mix(in srgb,var(--ink) 16%,transparent)}
.ip-pointer.is-live :is(.ip-pg-long,.ip-sb i){transition:translate .65s var(--il-carry)}
.ip-pointer.is-live:not(.is-top) .ip-pg-long{translate:0 calc(-1 * var(--ip-sy))}
.ip-pointer.is-live:not(.is-top) .ip-sb i{translate:0 var(--ip-st)}
/* the note editor, anchored under its pin */
.ip-pop{position:absolute;left:-114px;top:12px;z-index:5;width:228px;border-radius:10px;overflow:hidden;background:var(--white);box-shadow:var(--il-sh);text-align:left;transform-origin:50% 0;font-style:normal;font-weight:500;white-space:nowrap}
.ip-pop-h{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 10px;background:var(--cream);font-size:var(--il-fs-xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.ip-pop-h code{padding:0;background:none;font-family:var(--mono);font-size:var(--il-fs-xs);font-weight:500;letter-spacing:0;text-transform:none;color:var(--teal-text)}
.ip-pop-t{display:block;min-height:calc(2.8em + 14px);padding:7px 10px;box-shadow:inset 0 0 0 2px var(--teal);font-size:var(--il-fs-xs);line-height:1.4;color:var(--ink);white-space:normal;overflow-wrap:anywhere}
.ip-caret{display:none;width:1.5px;height:1em;margin-left:1px;vertical-align:-.15em;background:var(--teal-text)}
.ip.is-live .ip-pop.is-on .ip-caret{display:inline-block;animation:blink 1s steps(2) infinite}
.ip-pop-f{display:flex;align-items:center;gap:6px;padding:7px 10px;border-top:1px solid var(--il-line)}
.ip-pop-bin{display:grid;place-items:center;width:22px;height:22px;margin-right:auto;color:var(--tangerine)}
.ip-pop-bin svg{width:14px;height:14px}
.ip-pop-b{display:grid;place-items:center;height:22px;padding:0 10px;border-radius:7px;background:color-mix(in srgb,var(--ink) 7%,transparent);font-size:var(--il-fs-xs);font-weight:600;color:var(--body);transition:background .15s var(--ease),scale .15s var(--ease)}
.ip-pop-save{background:var(--teal-text);color:var(--white)}
.ip.is-live .ip-pop-save.is-on{background:color-mix(in srgb,var(--teal-text) 78%,var(--ink));scale:.95}
/* the toolbar, docked */
.ip-tb{position:absolute;left:50%;bottom:10px;z-index:5;display:flex;align-items:center;gap:6px;padding:6px 8px;border-radius:12px;background:var(--ip-bar);color:var(--white);font-size:var(--il-fs-xs);font-weight:600;line-height:1;white-space:nowrap;translate:-50% 0;box-shadow:inset 0 1px 0 color-mix(in srgb,var(--white) 10%,transparent),0 12px 28px -8px color-mix(in srgb,var(--ink) 55%,transparent)}
.ip-tb-grip{width:10px;height:8px;margin:0 2px;opacity:.5;background:repeating-linear-gradient(to bottom,var(--white) 0 1.5px,transparent 1.5px 3.25px)}
.ip-tb b{display:inline-flex;align-items:center;gap:6px;margin-right:2px;font-weight:700;letter-spacing:.01em}
.ip-tb-pin{width:10px;height:10px;border-radius:50% 50% 50% 0;background:var(--tangerine);rotate:-45deg;box-shadow:0 0 0 1.5px var(--white)}
.ip-tb-on,.ip-tb-n,.ip-copy,.ip-tb-x{display:inline-grid;place-items:center;height:24px;padding:0 9px;border-radius:8px;background:color-mix(in srgb,var(--white) 14%,transparent)}
.ip-tb-on{background:var(--teal)}
.ip-tb-n{min-width:24px;padding:0 6px;font-weight:700}
/* a ticking count (fig 2 toolbar, fig 4 reaction, 01's Open button): stacked <b>s, the last one is the end frame; live, the latest .is-on shows */
:is(.ip-tb-n,.sl-n,.hp-n) b{grid-area:1/1}
:is(.ip-tb-n,.sl-n,.hp-n) b:not(:last-child){opacity:0}
.ip.is-live :is(.ip-tb-n,.sl-n,.hp-n) b{opacity:0}
.ip.is-live :is(.ip-tb-n,.sl-n,.hp-n) b:first-child:not(:has(~ .is-on)){opacity:1}  /* the first value until the next one lands */
.ip.is-live :is(.ip-tb-n,.sl-n,.hp-n) b.is-on:not(:has(~ .is-on)){opacity:1;animation:ipCount .35s var(--il-pop)}
@keyframes ipCount{from{scale:.5}to{scale:1}}
.ip-copy{background:var(--white);color:var(--ink);transition:background .15s var(--ease),color .15s var(--ease)}
.ip.is-live .ip-copy:not(.is-on){background:color-mix(in srgb,var(--white) 14%,transparent);color:var(--white)}
.ip-toast{position:absolute;left:50%;bottom:calc(100% + 8px);padding:6px 10px;border-radius:8px;background:var(--mint);color:var(--ink);font-size:var(--il-fs-xs);font-weight:700;translate:-50% 0;opacity:0}  /* live only: in the composed end frame it would sit on the editor */
.ip.is-live .ip-toast:not(.is-on){translate:-50% 6px}
.ip.is-live .ip-toast.is-on{opacity:1}
.ip.is-live .ip-toast.is-on{transition:opacity .2s var(--ease),translate .35s var(--il-spring)}
/* the AI chat: the report lands in the composer, the send button lights */
.ip-comp-2{display:flex;flex-direction:column;gap:4px}
.ip-paste{margin:0;padding:6px 6px 0;font-family:var(--mono);font-size:var(--il-fs-xs);line-height:1.55;color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere;text-align:left}
.ip-comp-2 .ip-input{margin-top:0}
.ip-comp-2 .ip-send{margin-left:auto}
.ip-ph{display:none}
.ip.is-live .ip-ph{display:block;transition:opacity .2s var(--ease)}
.ip.is-live .ip-paste.is-on~.ip-input .ip-ph{opacity:0}
.ip-pointer .ip-send{background:var(--teal-text);transition:background .25s var(--ease)}
.ip-pointer.is-live .ip-send:not(.is-on){background:var(--il-line-strong)}
/* cursor: hidden in the end frame; JS places it on real elements (left/top in px of .ip-stage) */
.ip-stage{position:relative}
.ip-cur{left:46%;top:30%;opacity:0;z-index:6;transition:left .5s var(--il-carry),top .5s var(--il-carry)}
.ip.is-live .ip-cur{opacity:1;transition:left .5s var(--il-carry),top .5s var(--il-carry),opacity .3s var(--ease)}
.ip-pointer.is-typing:not(.is-typed) .ip-cur{opacity:0}
/* 3 · area box, chip, the travelling section, the hop arrow */
.ip-area{position:absolute;inset:-4px;z-index:3;border-radius:6px;background:color-mix(in srgb,var(--teal) 10%,transparent);box-shadow:inset 0 0 0 1.5px var(--teal)}
.ip.is-live .ip-area:not(.is-on){clip-path:inset(0 100% 100% 0)}
.ip.is-live .ip-area.is-on{clip-path:inset(-1px);transition:clip-path .5s var(--il-carry)}
.ip-chip{position:absolute;left:-1.5px;bottom:100%;display:flex;align-items:center;gap:5px;height:20px;padding:0 7px 0 4px;border-radius:6px 6px 6px 0;background:var(--teal);color:var(--white);font-size:var(--il-fs-xs);font-weight:600;line-height:1;white-space:nowrap;transform-origin:0 100%}
.ip-chip b{display:grid;place-items:center;min-width:14px;height:14px;border-radius:4px;background:var(--white);color:var(--teal-text);font-size:11px;font-weight:700}
.ip-slot{position:absolute;inset:-4px;border-radius:6px;background:color-mix(in srgb,var(--teal) 9%,transparent);outline:1.5px dashed color-mix(in srgb,var(--teal) 55%,transparent);outline-offset:-1.5px}
.ip-fly{position:absolute;inset:0;z-index:4;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;--brand:var(--teal);--ip-dx:calc(100% + 24px + var(--ip-gap));translate:var(--ip-dx) 0}
.ip.is-live .ip-fly:not(.is-on){--brand:var(--ip-ref);translate:0 0}
.ip.is-live .ip-fly.is-on{translate:var(--ip-dx) 0;transition:translate .85s var(--il-carry) .25s;animation:ipLift 1.1s var(--ease) both}
.ip.is-live .ip-fly.is-on :is(.ip-cdot,.ip-cbar){transition:background .4s var(--ease) 1.15s}
@keyframes ipLift{0%{scale:1;filter:none}22%,78%{scale:1.03;filter:drop-shadow(0 10px 10px color-mix(in srgb,var(--ink) 22%,transparent))}100%{scale:1;filter:none}}
.ip-hop{position:absolute;left:50%;top:100px;width:84px;height:60px;z-index:5;translate:-50% 0;pointer-events:none}
.ip.is-live .ip-hop:not(.is-on) .il-ink{clip-path:var(--il-wipe-0)}
.ip.is-live .ip-hop.is-on .il-ink{clip-path:var(--il-wipe-1);transition:clip-path .7s linear}
/* 4 · show and tell, then four days (owner, 12 Oct, second pass): one chat channel (generic look, no chat-app branding).
   The window = a top piece (bar + first scene) over a drawer: .sl-dr clips at its top edge, the panel (.sl-pan: day
   divider + the CEO's message) starts pulled up behind the top with only its rounded bottom (--r-md) showing, so it reads
   as one short window; live, that window starts centred in the frame (half the panel's travel; --sl-ph was measured by
   the removed article runner), my message lands, the chip pops with a bounce (slPop: overshoot, small undershoot, scale only) and
   ticks, the thread reply lands; then .is-later slides it up to the top, .is-open pulls the panel down, the pen
   "4 days later" writes in, the CEO's message and the video card land, the heart chip pops and ticks.
   The frame is the final height from the first frame (no page jump). Base = the whole thread. */
.sl-w{position:relative;max-width:560px;margin-inline:auto}
.ilw.sl-top{z-index:2;border-radius:var(--il-r-md) var(--il-r-md) 0 0;box-shadow:var(--il-ring);clip-path:inset(-2px -2px 1px -2px)}
.sl-dr{position:relative;z-index:1;margin-top:-3px;clip-path:inset(1px -48px -64px -48px)}  /* tucked under the top piece, both clipped 1 px past the seam: no hairline from either ring */
.sl-pan{padding:0 var(--s-4) var(--s-4);border-radius:0 0 var(--il-r-md) var(--il-r-md);background:var(--white);box-shadow:var(--il-sh);text-align:left}
.sl-chat{padding:var(--s-4);text-align:left}
.sl-msg{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px}
.sl-av{display:grid;place-items:center;width:36px;height:36px;overflow:hidden;border-radius:10px;background:var(--sun-art);color:var(--white)}
.sl-av img{display:block;width:100%;height:100%}
.sl-av svg{width:70%;height:70%;margin-top:22%}
.sl-av-c{background:var(--teal)}
.sl-av-ceo{background:var(--tangerine)}
.sl-m{min-width:0}
.sl-h{font-size:var(--il-fs-sm);font-weight:700;line-height:1.3;color:var(--ink)}
.sl-t{margin-top:2px;font-size:var(--il-fs-sm);line-height:1.45;color:var(--ink)}
.sl-link{display:block;color:var(--teal-text);text-decoration:underline;text-underline-offset:2px;overflow-wrap:anywhere}
.sl-rx{display:flex;align-items:center;gap:6px;margin-top:10px}
.sl-chip{display:inline-flex;align-items:center;gap:5px;height:26px;padding:0 10px 0 7px;border-radius:var(--pill);background:var(--teal-tint);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--teal) 45%,transparent);font-size:var(--il-fs-xs);font-weight:700;line-height:1;color:var(--teal-text)}
.sl-emo{width:17px;height:18px;transform-origin:50% 90%}
.sl-emo-p{fill:var(--sun);stroke:color-mix(in srgb,var(--tangerine) 75%,var(--ink));stroke-width:.8;stroke-linejoin:round}
.sl-emo-c{fill:var(--teal-text)}
.sl-heart{width:16px;height:16px;fill:var(--tangerine)}
.sl-n{display:inline-grid;min-width:7px}
.sl-add{display:inline-grid;place-items:center;width:32px;height:26px;border-radius:var(--pill);background:var(--cream);box-shadow:inset 0 0 0 1px var(--il-line);color:var(--muted)}
.sl-add svg{width:16px;height:16px}
.sl-thr{display:grid;grid-template-columns:24px minmax(0,1fr);column-gap:8px;margin-top:12px;padding-left:10px;border-left:2px solid var(--il-line)}
.sl-thr .sl-av{grid-row:span 2;width:24px;height:24px;border-radius:7px}
.sl-thr .sl-h{line-height:24px;font-size:var(--il-fs-xs)}
.sl-thr .sl-t{margin-top:0}
/* the day divider, with the pen note on it */
.sl-day{display:flex;align-items:center;gap:12px;padding:2px 0 14px}
.sl-day::before,.sl-day::after{content:"";flex:1;height:1px;background:var(--il-line-strong)}
.sl-day .il-hand{position:relative;font-size:clamp(.95rem,1.9vw,1.15rem)}
/* the video card: a still of a generic ticket tool (a marked-up client page + a new-ticket panel), play, duration */
.sl-vid{position:relative;max-width:400px;margin-top:10px;overflow:hidden;border-radius:10px;box-shadow:var(--il-sh-sm)}
.sl-vid::before{content:"";position:absolute;inset:0;z-index:4;background:color-mix(in srgb,var(--ink) 8%,transparent)}
.sl-vid-ui{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:8px;align-items:center;aspect-ratio:16/9;padding:10px;background:linear-gradient(160deg,var(--cream),var(--sun-tint))}
.sl-att{--ip-k:.5;--ip-cb:10px}
.sl-box{position:absolute;left:25%;top:15.5%;z-index:3;width:50%;height:22%;border-radius:4px;background:color-mix(in srgb,var(--tangerine) 8%,transparent);box-shadow:inset 0 0 0 1.5px var(--tangerine)}
.sl-mk{position:absolute;inset:0;z-index:3;pointer-events:none}
.sl-mk .il-ink{stroke:var(--tangerine)}
.sl-form{display:flex;flex-direction:column;gap:5px;padding:8px;border-radius:6px;background:var(--white);box-shadow:var(--il-ring)}
.sl-form b{font-size:var(--il-fs-2xs);font-weight:700;line-height:1.2;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sl-form i{display:block;border-radius:3px}
.sl-f-l{width:60%;height:4px;background:var(--il-line-strong)}
.sl-f-in{height:12px;box-shadow:inset 0 0 0 1px var(--il-line-strong)}
.sl-f-tall{height:24px}
.sl-f-btn{width:55%;height:12px;margin-left:auto;background:var(--teal)}
.sl-play{position:absolute;left:50%;top:50%;z-index:5;display:grid;place-items:center;width:46px;height:46px;border-radius:50%;translate:-50% -50%;background:color-mix(in srgb,var(--ink) 80%,transparent);color:var(--white);box-shadow:0 0 0 2px color-mix(in srgb,var(--white) 70%,transparent),0 8px 18px -6px color-mix(in srgb,var(--ink) 50%,transparent)}
.sl-play svg{width:20px;height:20px;margin-left:3px}
.sl-dur{position:absolute;right:8px;bottom:8px;z-index:5;padding:3px 6px;border-radius:5px;background:color-mix(in srgb,var(--ink) 75%,transparent);color:var(--white);font-size:var(--il-fs-2xs);font-weight:700;line-height:1}
/* live */
.ip-share.is-live .sl-w{transition:translate .75s var(--il-carry)}
.ip-share.is-live:not(.is-later) .sl-w{translate:0 calc((var(--sl-ph,0px) - var(--il-r-md)) / 2)}
.ip-share.is-live .sl-pan{transition:translate .7s var(--il-carry)}
.ip-share.is-live:not(.is-open) .sl-pan{translate:0 calc(var(--il-r-md) - 100%)}
.ip-share.is-live :is(.sl-msg,.sl-thr,.sl-vid){transform-origin:0 0}
.ip-share.is-live :is(.sl-msg,.sl-thr,.sl-vid):not(.is-on){translate:0 10px;scale:.97}
.ip-share.is-live :is(.sl-msg,.sl-thr,.sl-vid).is-on{transition:opacity .22s var(--ease),translate .42s var(--il-spring),scale .42s var(--il-spring)}
.ip-share.is-live .sl-chip:not(.is-on){scale:.3}
.ip-share.is-live .sl-chip.is-on{animation:slPop .55s var(--ease) both}
.ip-share.is-two .sl-chip:not(.sl-chip-love) .sl-emo,.ip-share.is-love .sl-chip-love .sl-emo{animation:slBump .5s var(--ease)}
@keyframes slPop{0%{scale:.3}45%{scale:1.18}72%{scale:.94}100%{scale:1}}
@keyframes slBump{0%{scale:1}40%{scale:1.32}70%{scale:.92}100%{scale:1}}
.ip-share.is-live .sl-day:not(.is-on) .il-hand{clip-path:var(--il-wipe-0)}
.ip-share.is-live .sl-day.is-on .il-hand{clip-path:var(--il-wipe-1);transition:clip-path .6s linear}
/* reset: nothing moves while the stage is dark */
.ip.is-reset :is([data-at],.ip-cur,.hp-ball,.ip-seg i,.ip-att-x,.ip-att-x .ip-mini,.ip-x,.ip-hop .il-ink,.sl-w,.sl-pan,.sl-day .il-hand,.ip-pg-long,.ip-sb i,.ip-ph,.ip-send,.ip-copy),.ip.is-reset .ip-att-x::before{transition:none;animation:none}
@media(max-width:480px){
  .ip{--ip-gap:24px}
  .ip-pointer{--ip-h:320px}.ip-refsite{--ip-h:150px}
  /* fig 2: the toolbar keeps brand, count and Copy for AI (grip, Commenting…, Clear all go); smaller report type */
  .ip-pointer :is(.ip-tb-grip,.ip-tb-on,.ip-tb-x){display:none}
  .ip-paste{font-size:var(--il-fs-2xs)}
  /* fig 1: a smaller mock page inside each (narrower) attachment; tighter chat padding */
  .ip-shots{--ip-k:.17;--ip-cb:6px;--ip-rs:9px;--ip-rw:1.3px}
  .ip-chat-b{padding:var(--s-3);gap:10px}
  .ip-tray{gap:5px}
  .ip-x{width:13px;height:13px;right:2px;top:2px}
  .ip-row-2 .ilw-bar{padding:0 10px}
  .ip-row-2 .ilw-bar i{display:none}
  .ip-row-2 .ilw-bar span:first-of-type{margin-left:0}
  .ip-pg{padding:10px;gap:8px}
  .ip-cards{gap:6px}
  .ip-card{padding:6px;gap:4px}
  .ip-hop{top:92px;width:64px;height:48px}
  /* fig 4: tighter chat, a smaller page in the video still */
  .sl-chat{padding:var(--s-3)}
  .sl-pan{padding:0 var(--s-3) var(--s-3)}
  .sl-msg{grid-template-columns:30px minmax(0,1fr);gap:10px}
  .sl-msg>.sl-av{width:30px;height:30px;border-radius:8px}
  .sl-vid-ui{gap:6px;padding:7px}
  .sl-att{--ip-k:.34;--ip-cb:7px}
  .sl-form{gap:4px;padding:5px}
  .sl-play{width:38px;height:38px}
  .sl-play svg{width:16px;height:16px}
}

/* ---------- Tip 02: a pile of three terminal windows, a status line each (.tm-*; ill_hunt + ill_bars in the generator) ----------
   Two figures share it (owner, 12 Oct): .tm-hunt = "The moment", grey stubs only, the task in the wrong window, the hunt;
   the plain .tm = "The fix", the tags pop in and one click finds the right window. The 02 cover reuses the pile.
   The hero is the status line. Generic window chrome (.ilw, no terminal brand) around a little grey history, Claude
   Code's input box (> + the task) and its status line: an empty grey stub first (.tm-old, live only), then the project
   name in bold on its own colour + a grey ⎇ main (.tm-new; token colours: terracotta = tangerine deepened with ink, sun
   with ink text, teal). The pile is a cascade in one grid cell: --slot 0 = front (on top), each slot behind it shifted
   --tm-dy down and --tm-dx right, so the bottom strip of every window (its status line) peeks out under the one in
   front. A click (.is-o1 / .is-o2 / .is-o3 on the figure, later wins) re-sorts the slots: the clicked window is raised
   at once (z-index) and glides to the front while the others slide back (transform only). Live (data-seq + the .ip
   rules above): hunt = the wrong try, "oops" (.tm-tmp, live only), two clicks, "which one?"; fix = the bars pop front to
   back (scale .7 -> 1 on --il-pop from the left, the stub fades), one click, the task, the pen ring, the note. Base = each
   end frame (hunt: the wrong window in front, stubs; fix: MOMO-WHISPER in front).
   Desktop: the pen notes sit in a right margin with an arrow to the front window; phones: on its title bar, no arrow. */
.tm{--tm-dx:16px;--tm-dy:50px}  /* dy = status line + gap + padding: the strip shows the bar, not the input box edge */
.tm-pile{display:grid;margin-right:150px;padding-bottom:calc(2 * var(--tm-dy))}
.tm-win{grid-area:1/1;width:calc(100% - 2 * var(--tm-dx));min-width:0;z-index:calc(3 - var(--slot));transform:translate(calc(var(--slot) * var(--tm-dx)),calc(var(--slot) * var(--tm-dy)))}
.tm-m{--slot:0;--tm-c:color-mix(in srgb,var(--tangerine) 76%,var(--ink))}
.tm-a{--slot:1;--tm-c:var(--sun)}
.tm-w{--slot:2;--tm-c:var(--teal-text)}
.tm:is(.is-live,.tm-hunt) .tm-a{--slot:0}.tm:is(.is-live,.tm-hunt) .tm-w{--slot:1}.tm:is(.is-live,.tm-hunt) .tm-m{--slot:2}  /* live start; the hunt's end frame */
.tm.is-live.is-o1 .tm-w{--slot:0}.tm.is-live.is-o1 .tm-a{--slot:1}
.tm.is-live.is-o2 .tm-a{--slot:0}.tm.is-live.is-o2 .tm-w{--slot:1}
.tm.is-live.is-o3 .tm-m{--slot:0}.tm.is-live.is-o3 .tm-a{--slot:1}.tm.is-live.is-o3 .tm-w{--slot:2}
.tm.is-live .tm-win{transition:transform .55s var(--il-carry)}
.tm.is-reset .tm-win{transition:none}
.tm-body{display:flex;flex-direction:column;gap:10px;padding:12px;font-family:var(--mono);font-size:var(--il-fs-sm);line-height:1.5;color:var(--ink);text-align:left}
.tm-ln{display:flex;align-items:center;gap:6px;height:8px}
.tm-ln i{display:block;height:5px;border-radius:3px;background:var(--il-line-strong)}
.tm-ln i:first-child{width:6px;height:6px;border-radius:50%;background:var(--muted)}
.tm-ln i:last-child{width:58%}
.tm-ln+.tm-ln i:last-child{width:36%}
.tm-in{display:flex;gap:8px;min-height:calc(1.5em + 12px);padding:6px 10px;border-radius:8px;box-shadow:inset 0 0 0 1px var(--il-line-strong)}
.tm-in>b{color:var(--muted)}
.tm-q{min-width:0;overflow-wrap:anywhere}
.tm-sl{display:grid;align-items:center;height:28px}
.tm-sl>*{grid-area:1/1}
.tm-old{width:30%;height:8px;border-radius:4px;background:var(--il-line);opacity:0}
.tm-hunt .tm-old{opacity:1}  /* the moment: grey stubs only, no tags */
.tm-new{display:flex;align-items:center;gap:18px;min-width:0;font-size:var(--il-fs-md);white-space:nowrap;transform-origin:0 50%}
.tm-new b{position:relative;padding:2px 10px;border-radius:2px;background:var(--tm-c);color:var(--white);line-height:24px;letter-spacing:.02em}
.tm-a .tm-new b{color:var(--ink)}  /* white on sun is unreadable */
.tm-new span{color:var(--muted)}
.tm-ring{position:absolute;inset:-8px -11px;pointer-events:none}
.tm-note{position:absolute;right:0;top:44px;z-index:4;width:136px;pointer-events:none}
.tm-note .il-ink{position:relative;display:block;width:44px;height:24px}
.tm-note .il-hand{position:relative;display:block;margin:2px 0 0 16px;line-height:1.25}
.tm-tmp{opacity:0}
.tm.is-live .tm-old:not(.is-off){opacity:1}
.tm.is-live .tm-new:not(.is-on){scale:.7}
.tm.is-live .tm-new.is-on{transition:opacity .2s var(--ease),scale .5s var(--il-pop)}
.tm.is-live .tm-tmp.is-on:not(.is-off){opacity:1}
.tm.is-live .tm-caret.is-on:not(.is-off){display:inline-block;animation:blink 1s steps(2) infinite}
.tm.is-live .tm-note:not(.is-on){translate:-6px 0}
.tm.is-live .tm-note.is-on{transition:opacity .35s var(--ease),translate .45s var(--ease)}
.tm.is-live .tm-note:not(.is-on) .il-ink{clip-path:inset(-12px -12px -12px calc(100% + 12px))}  /* drawn from its tail, right to left */
.tm.is-live .tm-note.is-on .il-ink{clip-path:var(--il-wipe-1);transition:clip-path .45s linear}
.tm.is-live .tm-ring:not(.is-on) .il-ink{clip-path:var(--il-wipe-0)}
.tm.is-live .tm-ring.is-on .il-ink{clip-path:var(--il-wipe-1);transition:clip-path .6s linear}
@media(max-width:640px){
  .tm{--tm-dx:8px;--tm-dy:48px}
  .tm .ip-stage{padding-top:10px}
  .tm-pile{margin-right:0}
  .tm .ilw-bar{height:30px}
  .tm-body{padding:10px}
  .tm-ln{display:none}
  .tm-note{right:24px;top:-3px;width:auto}
  .tm-note .il-ink,.tm-note br{display:none}
  .tm-note .il-hand{margin:0;font-size:.875rem}  /* the house .75rem is too small for a whole sentence */
}

/* ---------- 01 Momo Hop: the restart scare (Fig A, .hp-restart) and the app (Fig B .hp-hop + the cover; .hp-*) ----------
   Fig A reuses the tip's terminal parts (.tm on the figure: .tm-body lines, the .tm-note pen note + its live rules): six
   identical windows, each an AI session with a blinking caret; live they pop in (with .ip-att), the cursor turns into a
   spinning beach ball (the slow Mac), the dialog pops (with .ip-pop), Restart lights under the cursor, the cursor backs
   off to Cancel, the note writes in. Fig B = a pale mock of the Momo Hop window (structure from momo-hop's screenshot:
   search, Recent, rows with folder, name, tool badges, Running, path, time; the "Open in / with / and" bar + Open N):
   selection = a soft teal row (.hp-hl, live: fades in at its ms), the button (--hp-orange, white text: 4.5:1, never dimmed) shows no number until the first pick, the count
   ticks 1 -> 3 (with .ip-tb-n), a shift chip rides on the cursor, the press scales it down (.hp-press marker; the button stays full tangerine), then a terminal
   opens under it and three tabs pop in. The cover uses the same window, shorter. Base = each end frame. */
/* Momo Hop's own orange (owner pin, 13 Oct: the token tangerine read muddy next to the real app): sampled from the real
   app (#D9643E, white text only 3.6:1), same hue a little deeper and more saturated so white bold text passes 4.5:1. */
.il{--hp-orange:#D1481B}
.hp-desk{position:relative;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-right:150px}
.hp-desk .ilw-bar{height:26px;gap:4px;padding:0 8px;font-size:var(--il-fs-2xs)}
.hp-desk .ilw-bar i{width:7px;height:7px}
.hp-desk .ilw-bar span:first-of-type{margin-left:var(--s-1)}
.hp-desk .tm-body{gap:7px;padding:8px;font-size:var(--il-fs-xs)}
.hp-prompt{display:flex;align-items:center;gap:6px;min-width:0}
.hp-prompt b{color:var(--muted)}
.hp-blink{display:inline-block;width:.55em;height:1.1em;background:color-mix(in srgb,var(--ink) 70%,transparent)}
.ip.is-live .hp-blink{animation:blink 1s steps(2) infinite}
.hp-dlg{position:absolute;inset:0;z-index:4;display:flex;flex-direction:column;align-items:center;gap:2px;width:236px;height:fit-content;margin:auto;padding:var(--s-4) var(--s-4) var(--s-3);border-radius:12px;background:var(--white);box-shadow:var(--il-sh),0 18px 32px -18px color-mix(in srgb,var(--ink) 30%,transparent);font-size:var(--il-fs-xs);line-height:1.4;color:var(--body);text-align:center}
.hp-dlg b{font-size:var(--il-fs-sm);color:var(--ink)}
.hp-dlg-ic{display:grid;place-items:center;width:30px;height:30px;margin-bottom:var(--s-1);border-radius:50%;background:var(--sun-tint);color:var(--ink);font-size:var(--il-fs-md);font-style:normal;font-weight:700}
.hp-btns{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;width:100%;margin-top:var(--s-2)}
.hp-btn{position:relative;display:grid;place-items:center;height:26px;overflow:hidden;border-radius:7px;background:color-mix(in srgb,var(--ink) 7%,transparent);font-weight:600;color:var(--ink)}
.hp-go{background:var(--teal-text);color:var(--white)}
.hp-hover{position:absolute;inset:0;background:color-mix(in srgb,var(--ink) 20%,transparent)}
:is(.hp-hover,.hp-ball,.hp-key){opacity:0}  /* live only (.ip-tmp shows them between their ms) */
.hp-ball{position:absolute;left:-1px;top:-1px;width:18px;height:18px;border-radius:50%;background:conic-gradient(var(--tangerine),var(--sun-art),var(--mint),var(--teal),var(--tangerine));box-shadow:0 0 0 1.5px var(--white),0 1px 2px color-mix(in srgb,var(--ink) 30%,transparent)}
.ip.is-live .hp-ball{animation:spin .7s linear infinite}
.ip-cur:has(.hp-ball.is-on:not(.is-off)) svg{opacity:0}
.hp-key{position:absolute;left:18px;top:-20px;padding:2px 6px;border-radius:5px;background:var(--white);box-shadow:var(--il-sh-sm);font-family:inherit;font-size:var(--il-fs-2xs);font-weight:700;line-height:1.4;color:var(--ink);white-space:nowrap}
/* the app window */
.hp-app .ilw-bar span:first-of-type{color:var(--ink)}
.hp-search{display:flex;align-items:center;gap:8px;height:30px;margin:10px 12px;padding:0 10px;border-radius:8px;background:color-mix(in srgb,var(--ink) 5%,transparent);font-size:var(--il-fs-sm);color:var(--muted)}
.hp-mag{position:relative;width:10px;height:10px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--muted)}
.hp-mag::after{content:"";position:absolute;left:8px;top:8px;width:5px;height:1.5px;border-radius:1px;background:var(--muted);rotate:45deg;transform-origin:0 50%}
.hp-sec{display:block;padding:2px 16px 6px;border-bottom:1px solid var(--il-line);font-size:var(--il-fs-xs);font-weight:700;color:var(--muted)}
.hp-list{margin:0;padding:6px 8px;list-style:none}
.hp-row{position:relative;display:grid;grid-template-columns:20px minmax(0,1fr) auto auto;align-items:center;gap:10px;padding:7px 8px;text-align:left}
.hp-row>:not(.hp-hl){position:relative}
.hp-hl{position:absolute;inset:1px 0;border-radius:8px;background:color-mix(in srgb,var(--teal) 13%,var(--white));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--teal) 35%,transparent)}
.hp-dir{width:18px;height:13px;margin-top:3px;border-radius:2px 3px 3px 3px;background:var(--hp-orange)}
.hp-dir::before{content:"";position:absolute;left:0;top:-3px;width:8px;height:4px;border-radius:2px 2px 0 0;background:inherit}
.hp-id{display:flex;flex-direction:column;gap:1px;min-width:0}
.hp-name{display:flex;align-items:center;gap:5px;min-width:0;white-space:nowrap}
.hp-name b{overflow:hidden;text-overflow:ellipsis;font-size:var(--il-fs-sm);color:var(--ink)}
.hp-tool{flex:none;padding:1px 6px;border-radius:5px;background:color-mix(in srgb,var(--ink) 7%,transparent);font-size:var(--il-fs-2xs);font-weight:600;line-height:1.5;color:var(--body)}
.hp-path{overflow:hidden;font-size:var(--il-fs-2xs);color:var(--muted);white-space:nowrap;text-overflow:ellipsis}
.hp-run{display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:var(--pill);background:color-mix(in srgb,var(--mint) 22%,var(--white));font-size:var(--il-fs-2xs);font-weight:700;color:var(--teal-text)}
.hp-run::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--teal)}
.hp-ago{grid-column:4;font-size:var(--il-fs-xs);color:var(--muted);white-space:nowrap}
.hp-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;padding:10px 12px;border-top:1px solid var(--il-line);font-size:var(--il-fs-xs);color:var(--body);text-align:left}
.hp-opts{display:flex;flex-wrap:wrap;align-items:center;gap:6px;flex:1 1 0;min-width:0}
.hp-sel{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 8px;border-radius:6px;background:color-mix(in srgb,var(--ink) 6%,transparent);font-weight:600;color:var(--ink);white-space:nowrap}
.hp-sel svg{width:7px;height:10px;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
.hp-open{position:relative;display:inline-grid;place-items:center;height:28px;overflow:hidden;padding:0 14px;border-radius:var(--pill);background:var(--hp-orange);font-size:var(--il-fs-sm);font-weight:700;color:var(--white);white-space:nowrap}
.hp-press{display:none}
.ip.is-live .hp-open{transition:scale .15s var(--ease)}
.ip.is-live .hp-open:has(.hp-press.is-on:not(.is-off)){scale:.9}
.hp-n{display:inline-grid;translate:0 .08em}  /* optical centring: the font's box sits high, this puts the cap height on the pill's centre */
.hp-n b{justify-self:center}  /* every label centred in the cell, the cell = the widest label (Open 3): no width jump */
.hp-count{flex-basis:100%;font-size:var(--il-fs-xs);color:var(--muted)}
/* the terminal it opens: one tab per project */
.hp-out{position:relative;margin:var(--s-4) 150px 0 0}
.hp-out .tm-note{right:-150px;top:2px}
.hp-tabs .ilw-bar{gap:6px}
.hp-tab{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;border-radius:6px;background:var(--white);box-shadow:var(--il-ring);font-size:var(--il-fs-xs);color:var(--ink);white-space:nowrap}
.hp-tab+.hp-tab{background:none;box-shadow:none;color:var(--muted)}
.hp-tab i{width:6px;height:6px;border-radius:50%;background:var(--teal)}
.hp-tabs .tm-body{gap:4px;font-size:var(--il-fs-xs)}
.hp-recap{color:var(--teal-text)}
@media(max-width:640px){
  .hp-desk{margin-right:0;gap:8px}
  .hp-desk .ilw-bar i{display:none}
  .hp-desk .ilw-bar span:first-of-type{margin-left:0}
  .hp-desk .tm-ln{display:flex}
  .hp-desk .tm-body{padding:7px}
  .hp-path,.hp-run,.hp-tool+.hp-tool{display:none}
  .hp-row{gap:8px;padding:7px 6px}
  .hp-out{margin-right:0}
  .hp-out .tm-note{position:relative;right:auto;top:auto;display:flex;justify-content:flex-end;margin:var(--s-2) var(--s-2) var(--s-1) 0}
  .hp-tabs .ilw-bar{gap:4px;padding:0 8px}
  .hp-tabs .ilw-bar i{display:none}
  .hp-tab{padding:0 6px;font-size:var(--il-fs-2xs)}
}

/* === v6 covers 03-15 (.cv-*; cover_undo … cover_tokens in tools/build-articles.py) ===
   The 01 / 02 / 07 / 11 cover anatomy (.cover above: badge, pen note + arrow, avatar, the UI cropped off the right edge) with
   the v6 rules: ONE pale tint per cover (--cv-tint, set inline by the generator; decoration, never a client colour), white
   windows on soft shadows, flat shapes, no outlines, illustration tokens only inside the UI, 1-3 words per label.
   Motion: at most ONE gentle loop per cover, 7 s, transform / opacity only (.cv-a), paused off screen (.is-paused via
   data-pause), reduced motion = no animation = the base markup, which is always the end frame. */
:where(.cover.cv){--m1:var(--cv-tint);--m2:color-mix(in srgb,var(--cv-tint) 55%,transparent);--m3:color-mix(in srgb,var(--cv-tint) 40%,var(--sun-tint))}   /* the one tint, as a soft mesh (.cover.mesh above) */
.cover.cv .cover-ui{width:360px}
.cover.cv .ilw-bar span:first-of-type{display:inline-flex;align-items:center;gap:6px}
.cover.cv .ilw-bar img{width:14px;height:14px;border-radius:3px}
.cover.cv ul,.cover.cv ol{margin:0;padding:0;list-style:none}
.cv-dots{background-image:radial-gradient(circle,color-mix(in srgb,var(--ink) 9%,transparent) 1px,transparent 1.2px);background-size:14px 14px;background-position:7px 7px}
.cv-ok{flex:none;display:grid;place-items:center;width:22px;height:22px;border-radius:50%;background:var(--teal);color:var(--white)}
.cv-ok svg{width:12px;height:12px}
.cv-no{background:var(--tangerine)}
/* 03 · the commit log: a save point, the bad AI change faded, the pen rewind arrow */
.cover.cv-undo .cover-ui{width:310px}
.cv-git{position:relative;padding:16px 16px 18px 58px}  /* the left gutter holds the rewind arrow */
.cv-log{position:relative;display:flex;flex-direction:column;gap:16px}
.cv-log::before{content:"";position:absolute;left:47px;top:6px;bottom:6px;width:2px;border-radius:1px;background:var(--il-line-strong)}
.cv-log li{position:relative;display:flex;align-items:center;gap:10px;font-size:var(--il-fs-sm);font-weight:600;line-height:1.2;color:var(--ink);white-space:nowrap}
.cv-dot{flex:none;width:12px;height:12px;border-radius:50%;background:var(--teal);box-shadow:0 0 0 3px var(--white)}
.cv-log small{font-size:var(--il-fs-xs);font-weight:500;color:var(--muted)}
.cv-chip{padding:3px 8px;border-radius:var(--pill);background:var(--sun-art);color:var(--ink);font-size:var(--il-fs-2xs);font-weight:700;line-height:1.2}
.cv-bad{opacity:.35}
.cv-bad .cv-dot{background:var(--tangerine)}
.cv-back{inset:auto auto auto 6px;top:48px;width:50px;height:52px;stroke-width:2.2px}
/* 04 · the SKILL.md file card */
.cover.cv-skill .cover-ui{width:300px}
.cv-file{border-radius:var(--il-r-md);background:var(--white);box-shadow:var(--il-sh);overflow:hidden}
.cv-tab{display:flex;align-items:center;gap:8px;height:36px;padding:0 14px;border-bottom:1px solid color-mix(in srgb,var(--ink) 7%,transparent);background:linear-gradient(var(--white),var(--cream));font-family:var(--mono);font-size:var(--il-fs-xs);font-weight:600;color:var(--ink)}
.cv-tab i{width:11px;height:14px;border-radius:2px 5px 2px 2px;background:color-mix(in srgb,var(--ink) 22%,transparent)}
.cv-pill{margin-left:2px;padding:3px 9px;border-radius:var(--pill);background:var(--sun-art);font-family:var(--font,inherit);font-size:var(--il-fs-2xs);font-weight:700;line-height:1.2;color:var(--ink)}
.cv-md{display:flex;flex-direction:column;gap:9px;padding:14px 16px 18px;font-family:var(--mono);font-size:var(--il-fs-sm);line-height:1.3;color:var(--body);white-space:nowrap}
.cv-md b{font-size:var(--il-fs-md);font-weight:700;color:var(--ink)}
/* 05 · the plug: a Claude window, a cable, a Figma window */
.cover.cv-mcp .cover-ui{width:352px}
.cv-link{position:relative;display:grid;grid-template-columns:146px 146px;gap:60px;align-items:center}
.cv-link .ilw{position:relative;z-index:1}
.cv-link .ilw-bar{height:30px;gap:4px;padding:0 10px}
.cv-link .ilw-bar i{width:7px;height:7px}
.cv-link .ilw-bar span:first-of-type{margin-left:4px}
.cv-link .ilw:last-child::before{content:"";position:absolute;left:0;top:50%;width:4px;height:16px;margin-top:-8px;border-radius:0 2px 2px 0;background:color-mix(in srgb,var(--ink) 30%,transparent)}
.cv-chat{display:flex;flex-direction:column;gap:7px;min-height:94px;padding:10px}
.cv-bub{align-self:flex-start;padding:5px 9px;border-radius:9px 9px 9px 3px;background:var(--cream);font-size:var(--il-fs-xs);font-weight:600;color:var(--ink);white-space:nowrap}
.cv-bub-me{align-self:flex-end;border-radius:9px 9px 3px 9px;background:var(--teal-tint);color:var(--teal-text)}
.cv-canvas{display:grid;place-items:center;height:94px}
.cv-frame{display:flex;flex-direction:column;gap:5px;width:78px;padding:8px;border-radius:6px;background:var(--white);box-shadow:var(--il-sh-sm)}
.cv-frame b{display:block;height:6px;border-radius:3px;background:var(--il-line-strong)}
.cv-frame b:first-child{height:18px;background:color-mix(in srgb,var(--teal) 22%,var(--white))}
.cv-frame b:last-child{width:60%}
.cv-cable{position:absolute;z-index:0;left:146px;top:50%;width:60px;height:20px;translate:0 -50%}
.cv-plug{position:absolute;right:0;top:0;width:26px;height:20px;border-radius:5px 2px 2px 5px;background:var(--ink)}
.cv-plug::before{content:"";position:absolute;right:100%;top:50%;width:140px;height:3px;margin-top:-1.5px;background:var(--ink)}  /* the wire, its tail under the Claude window */
.cv-plug b{position:absolute;left:100%;width:7px;height:3px;border-radius:0 2px 2px 0;background:var(--ink)}
.cv-plug b:first-child{top:5px}
.cv-plug b:last-child{bottom:5px}
/* 06 · three directions, one pick */
.cover.cv-mood .cover-ui{width:330px}
.cv-dirs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;padding:14px}
.cv-dir{position:relative;display:flex;flex-direction:column;gap:8px;padding:9px;border-radius:10px;background:var(--white);box-shadow:var(--il-sh-sm)}
.cv-pick{box-shadow:var(--il-sh)}
.cv-sw{display:grid;grid-template-columns:2fr 1fr;gap:4px;height:36px}
.cv-sw i{border-radius:6px}
.cv-sw-a i:first-child{background:var(--teal)}.cv-sw-a i:last-child{background:var(--teal-tint)}
.cv-sw-b i:first-child{background:var(--ink)}.cv-sw-b i:last-child{background:var(--tangerine)}
.cv-sw-c i:first-child{background:var(--tangerine-hl)}.cv-sw-c i:last-child{background:var(--sun-tint)}
.cv-aa{font-size:22px;line-height:1;color:var(--ink)}
.cv-aa-a{font-weight:400}.cv-aa-b{font-weight:700}.cv-aa-c{font-weight:500;color:color-mix(in srgb,var(--tangerine) 76%,var(--ink))}
.cv-dir small{font-size:var(--il-fs-xs);font-weight:600;color:var(--muted)}
.cv-tick{position:absolute;right:-7px;top:-7px;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;background:var(--sun-art);color:var(--ink);box-shadow:0 0 0 2px var(--white)}
.cv-tick svg{width:13px;height:13px}
/* 08 · the Momo Copy Review card in the review figure (ill_review; the Vibe Code #tone card: .tone-* in site.css) */
.cv-tone{gap:8px;padding:10px;border-radius:0;box-shadow:none}
.cv-tone .tone-row{padding:8px 12px}
.cv-tone .tone-label{margin-bottom:2px;font-size:var(--il-fs-2xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.cv-tone .tone-row p{font-size:var(--il-fs-sm);font-weight:600;line-height:1.45}
/* 08 · figure: "2 seats left" read word by word (the left seats lit) vs what it meant (two free seats) */
.st-fig{container-type:inline-size;display:grid;place-items:center;padding:clamp(var(--s-5),6%,var(--s-8)) var(--s-4)}
.st-card{display:flex;flex-direction:column;gap:10px;width:min(100%,460px);padding:14px}
.st-src{display:flex;align-items:baseline;gap:10px;margin:0;padding:2px 4px}
.st-fig small{display:block;font-size:var(--il-fs-2xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.st-src b{font-size:var(--il-fs-md);color:var(--ink)}
.st-row{display:flex;align-items:center;justify-content:space-between;gap:14px}
.st-row>span:first-child{display:flex;flex-direction:column;gap:2px;min-width:0}
.st-row b{font-size:var(--fs-title);line-height:1.35;color:var(--ink)}
.st-row em{font-style:normal;font-size:var(--il-fs-xs);font-weight:500;color:var(--body)}
.st-seats{flex:none;display:grid;grid-template-columns:repeat(6,14px);gap:5px}
.st-seats i{height:16px;border-radius:5px 5px 3px 3px;background:color-mix(in srgb,var(--ink) 10%,transparent)}
.st-seats .on{background:var(--tangerine)}
.st-seats .tk{background:color-mix(in srgb,var(--ink) 24%,transparent)}
.st-seats .ok{background:var(--teal)}
@container (max-width:380px){.st-row{flex-direction:column;align-items:flex-start;gap:8px}}
/* 08 · cover: the translation sheet before the tool: EN / TH columns, row 3 copied out, empty TH cells, the last row 3,000 */
.cover.cv-sheet .cover-ui{width:330px}
.sh{position:relative}
.sh-rows li{display:grid;grid-template-columns:44px minmax(0,1fr) minmax(0,1fr);align-items:center;gap:10px;height:28px;padding:0 12px;border-top:1px solid var(--il-line)}
.sh-rows li:first-child{border-top:0}
.sh-rows small{font-size:var(--il-fs-2xs);font-weight:700;color:var(--muted);font-variant-numeric:tabular-nums}
.sh-rows b{font-size:var(--il-fs-2xs);font-weight:700;letter-spacing:.04em;color:var(--muted)}
.sh-rows i{display:block;height:6px;border-radius:3px;background:var(--il-line-strong)}
.sh-rows .sh-th{width:80%;background:color-mix(in srgb,var(--teal) 30%,var(--white))}
.sh-rows .sh-empty{width:24px;background:transparent;box-shadow:inset 0 -1.5px 0 var(--il-line-strong)}
.sh-rows .sh-on{background:color-mix(in srgb,var(--sun-art) 22%,transparent);box-shadow:inset 0 0 0 1.5px var(--sun-art)}
.sh-rows .sh-gap{height:18px}
.sh-chips{position:absolute;right:12px;top:87px;display:flex;gap:6px}
.sh-chips .cv-chip{box-shadow:var(--il-sh-sm)}
.sh-chips .cv-chip+.cv-chip{background:var(--white)}
/* 09 · the Layers panel, default names turning into real ones */
.cover.cv-names .cover-ui{width:270px}
.cv-layers{padding:6px 0}
.cv-layers li{display:flex;align-items:center;gap:8px;height:32px;padding:0 14px 0 calc(14px + var(--d,0) * 18px);font-size:var(--il-fs-sm);font-weight:600;color:var(--ink);white-space:nowrap}
.cv-ly{flex:none;width:12px;height:12px;border-radius:3px;background:color-mix(in srgb,var(--ink) 24%,transparent)}
.cv-nm{display:grid}
.cv-nm>*{grid-area:1/1}
.cv-nm s{opacity:0;font-weight:500;color:var(--muted);text-decoration:none}
/* 11 · the Plugins panel: my three Momo plugins */
/* 12 · Figma first, then AI builds: a frame in a Figma window -> the same screen on a phone (PF_SCREEN parts, also the
   note's template figure .tp-*) */
.cover.cv-draft .cover-ui{width:360px}
.pf-flow{display:flex;align-items:center;gap:12px}
.pf-flow .ilw{flex:1}
.pf-canvas{display:grid;place-items:center;padding:16px;background-image:radial-gradient(circle,color-mix(in srgb,var(--ink) 9%,transparent) 1px,transparent 1.2px);background-size:14px 14px}
.pf-frame,.pf-phone,.tp-p{display:flex;flex-direction:column;gap:5px;width:84px;padding:8px;border-radius:8px;background:var(--white);box-shadow:var(--il-sh-sm)}
.pf-frame{box-shadow:var(--il-sh-sm),0 0 0 1.5px color-mix(in srgb,var(--teal) 55%,transparent)}
.pf-phone{flex:none;width:92px;padding:14px 8px 10px;border-radius:16px;box-shadow:var(--il-sh),0 0 0 4px var(--white),0 0 0 5px color-mix(in srgb,var(--ink) 12%,transparent)}
:is(.pf-frame,.pf-phone,.tp-p) i{display:block;height:5px;border-radius:3px;background:var(--il-line-strong)}
:is(.pf-frame,.pf-phone,.tp-p) .pf-hd{width:45%;height:7px;background:color-mix(in srgb,var(--ink) 30%,transparent)}
:is(.pf-frame,.pf-phone,.tp-p) .pf-img{height:34px;border-radius:5px;background:color-mix(in srgb,var(--teal) 22%,var(--white))}
:is(.pf-frame,.pf-phone,.tp-p) .pf-s{width:60%}
:is(.pf-frame,.pf-phone,.tp-p) .pf-btn{height:12px;margin-top:3px;border-radius:6px;background:var(--sun-art)}
.pf-arr{position:relative;flex:none;width:26px;height:2px;border-radius:1px;background:color-mix(in srgb,var(--ink) 35%,transparent)}
.pf-arr::after{content:"";position:absolute;right:-2px;top:-4px;width:7px;height:10px;background:color-mix(in srgb,var(--ink) 35%,transparent);clip-path:polygon(0 0,100% 50%,0 100%)}
/* 13 · mirror vs RTL */
.cover.cv-rtl .cover-ui{width:282px}
.cv-phones{display:flex;gap:14px}
.cv-ph{display:flex;flex-direction:column;gap:9px;width:134px;padding:11px;border-radius:14px;background:var(--white);box-shadow:var(--il-sh)}
.cv-top{display:flex;align-items:center;gap:8px;height:18px}
.cv-bk{width:9px;height:12px;background:var(--ink);clip-path:polygon(100% 0,0 50%,100% 100%)}
.cv-mag{position:relative;width:10px;height:10px;border-radius:50%;box-shadow:inset 0 0 0 1.8px var(--ink)}
.cv-mag::after{content:"";position:absolute;left:8px;top:8px;width:5px;height:1.8px;border-radius:1px;background:var(--ink);rotate:45deg;transform-origin:0 50%}
.cv-clk{margin-left:auto;font-size:var(--il-fs-sm);font-weight:700;font-variant-numeric:tabular-nums;color:var(--ink)}
.cv-pb{height:6px;border-radius:3px;background:var(--il-line)}
.cv-pb i{display:block;width:60%;height:100%;border-radius:3px;background:var(--teal)}
.cv-ln{display:block;width:85%;height:6px;border-radius:3px;background:var(--il-line-strong)}
.cv-ln-s{width:55%}
.cv-lab{display:flex;align-items:center;justify-content:space-between;margin-top:4px;font-size:var(--il-fs-xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
:is(.cv-mir,.cv-ok-rtl) .cv-top{flex-direction:row-reverse}
:is(.cv-mir,.cv-ok-rtl) .cv-clk{margin:0 auto 0 0}
:is(.cv-mir,.cv-ok-rtl) .cv-bk{clip-path:polygon(0 0,100% 50%,0 100%)}
:is(.cv-mir,.cv-ok-rtl) .cv-pb i{margin-left:auto}
:is(.cv-mir,.cv-ok-rtl) .cv-ln{align-self:flex-end}
.cv-mir :is(.cv-clk,.cv-mag){scale:-1 1}  /* the shortcut: everything mirrored, even the digits and the search handle */
/* 14 · the Variables panel */
.cover.cv-tokens .cover-ui{width:270px}
.cv-vars{padding:4px 0}
.cv-vars li{display:flex;align-items:center;gap:10px;padding:7px 14px;font-size:var(--il-fs-sm);font-weight:600;color:var(--ink);white-space:nowrap}
.cv-vars li+li{border-top:1px solid var(--il-line)}
.cv-vars small{margin-left:auto;font-size:var(--il-fs-xs);font-weight:600;color:var(--muted)}
.cv-sw2,.cv-sp,.cv-ty,.cv-rd{flex:none;width:28px;height:28px;border-radius:7px}
.cv-sw2{display:grid;overflow:hidden}
.cv-sw2 i{grid-area:1/1;display:block}
.cv-sw2 i:first-child{background:var(--tangerine)}
.cv-sw2 i:last-child{background:var(--teal)}
.cv-sp{display:grid;place-items:center;background:var(--cream)}
.cv-sp i{width:16px;height:16px;border-radius:2px;background:color-mix(in srgb,var(--teal) 30%,transparent)}
.cv-ty{display:grid;place-items:center;background:var(--cream);font-size:var(--il-fs-sm);font-weight:700}
.cv-rd{border-radius:11px;background:color-mix(in srgb,var(--ink) 22%,transparent)}
/* the one loop per cover (7 s, transform / opacity; .is-paused from data-pause; reduced motion = none) */
@media(prefers-reduced-motion:no-preference){
  .cover.cv[data-loop] .cv-a{animation:7s var(--ease) infinite backwards}
  .cover.cv.is-paused .cv-a{animation-play-state:paused}
  /* per element (same .cover.cv specificity as the shorthand above, later wins) */
  .cover.cv :is(.cv-chip,.cv-pill,.cv-tick,.cv-ok).cv-a{animation-name:cvPop}
  .cover.cv .cv-bad{animation-name:cvBad}
  .cover.cv .cv-back{animation-name:cvShow}
  .cover.cv .cv-plug{animation-name:cvPlug}
  .cover.cv .cv-nm s{animation-name:cvOld;animation-delay:calc(var(--d,0) * .45s)}
  .cover.cv .cv-nm b{animation-name:cvNew;animation-delay:calc(var(--d,0) * .45s)}
  .cover.cv .cv-sw2 i:first-child{animation-name:cvSwA}
  .cover.cv .cv-sw2 i:last-child{animation-name:cvSwB}
}
@keyframes cvPop{0%,40%{opacity:0;scale:.7;animation-timing-function:var(--il-pop)}47%,90%{opacity:1;scale:1}95%,100%{opacity:0;scale:1}}
@keyframes cvBad{0%,30%{opacity:1}40%,94%{opacity:.35}100%{opacity:1}}
@keyframes cvShow{0%,42%{opacity:0}50%,90%{opacity:1}95%,100%{opacity:0}}
@keyframes cvPlug{0%,18%{translate:-30px 0;animation-timing-function:var(--il-carry)}32%,100%{translate:none}}
@keyframes cvOld{0%,35%{opacity:1}42%,94%{opacity:0}100%{opacity:1}}
@keyframes cvNew{0%,35%{opacity:0}42%,94%{opacity:1}100%{opacity:0}}
@keyframes cvSwA{0%,45%{opacity:1}55%,94%{opacity:0}100%{opacity:1}}
@keyframes cvSwB{0%,45%{opacity:0}55%,94%{opacity:1}100%{opacity:0}}

/* Momo PinPoint figures follow the extension's CURRENT UI (owner 19 Oct 2026: "the illustrations are still the old UI"): blue (#0072E8) teardrop pins
   with a white number, the note editor = white card, blue number badge + "Comment" + grey selector chip, a white field with a blue ring,
   a blue Save; the toolbar = a dark pill, white teardrop mark, blue "Commenting" pill, count, white "Copy for AI". */
.ip{--ip-blue:var(--pinpoint-blue,#0072E8)}
.ip .pin{background:var(--ip-blue)}
.ip .pin::after{box-shadow:0 0 0 2px var(--ip-blue)}
.ip-pop{border-radius:14px}
.ip-pop-h{justify-content:flex-start;gap:8px;padding:9px 10px 6px;background:var(--white);font-size:var(--il-fs-xs);font-weight:700;letter-spacing:0;text-transform:none;color:var(--ink)}
.ip-pop-n{display:grid;place-items:center;width:18px;height:18px;border-radius:6px;background:var(--ip-blue);color:var(--white);font-size:10px;font-weight:700;line-height:1}
.ip-pop-h code{margin-left:auto;padding:2px 8px;border-radius:999px;background:color-mix(in srgb,var(--ink) 6%,transparent);font-family:inherit;font-size:var(--il-fs-xs);font-weight:500;color:var(--muted)}
.ip-pop-t{margin:2px 10px 8px;padding:7px 9px;border-radius:9px;box-shadow:inset 0 0 0 2px var(--ip-blue),0 0 0 3px color-mix(in srgb,var(--ip-blue) 18%,transparent)}
.ip-pop-f{border-top:0;padding:0 10px 10px}
.ip-pop-save{background:var(--ip-blue);color:var(--white)}
.ip.is-live .ip-pop-save.is-on{background:color-mix(in srgb,var(--ip-blue) 80%,var(--ink));scale:.95}
.ip-tb{border-radius:999px;padding:6px 8px 6px 12px}
.ip-tb-pin{width:11px;height:11px;border-radius:50% 50% 50% 0;background:var(--white);box-shadow:none;rotate:-45deg}
.ip-tb-on{background:var(--ip-blue);border-radius:999px}
.ip-tb-n,.ip-copy,.ip-tb-x{border-radius:999px}
.ip-area{background:color-mix(in srgb,var(--ip-blue) 10%,transparent);box-shadow:inset 0 0 0 1.5px var(--ip-blue)}
.ip-chip{background:var(--ip-blue)}

/* Momo Hop cover = the real app window (owner 19 Oct 2026: "the cover is the old UI"). Three screenshots stacked; base = the last (three picked); the
   cover loop picks them one at a time, then fades back to the list. */
.cover-hop .cover-ui{width:360px}
.hpr{position:relative;display:block;width:100%;aspect-ratio:1000/828;filter:drop-shadow(0 18px 28px color-mix(in srgb,var(--ink) 20%,transparent)) drop-shadow(0 2px 5px color-mix(in srgb,var(--ink) 14%,transparent))}
.hpr img{position:absolute;inset:0;display:block;width:100%;height:100%}
.hpr img:nth-child(2){opacity:0}
@media(prefers-reduced-motion:no-preference){
  .cover[data-loop] .hpr img:nth-child(2){opacity:1;animation:hprPick1 7s var(--ease) infinite backwards}
  .cover[data-loop] .hpr img:nth-child(3){animation:hprPick3 7s var(--ease) infinite backwards}
  .cover.is-paused .hpr img{animation-play-state:paused}
}
@keyframes hprPick1{0%,14%{opacity:0}20%,92%{opacity:1}98%,100%{opacity:0}}
@keyframes hprPick3{0%,40%{opacity:0}46%,92%{opacity:1}98%,100%{opacity:0}}

/* Note 12, the three Momo Figma plugins = the REAL plugin windows (owner 19 Oct 2026: real UI, not drawn mocks;
   assets/lineup/*.webp, 800x635 screenshots, the same files as the Vibe Code cards). Dark windows on the pale ground,
   radius + soft shadow, slight tilt (the Vibe Code -4deg family). Static, no loop. */
.mp-win{position:absolute;display:block;width:62%;height:auto;aspect-ratio:800/635;border-radius:var(--il-r-md);background:var(--ink);
  box-shadow:0 0 0 1px color-mix(in srgb,var(--ink) 10%,transparent),0 2px 5px color-mix(in srgb,var(--ink) 12%,transparent),0 22px 34px -16px color-mix(in srgb,var(--ink) 40%,transparent)}
/* Fig "two in, one out": the first two plugins (stacked, left) -> one arrow -> Momo UI Kit (right), its Colors and Fonts
   tabs ringed in sun (positions = % of the 800x635 screenshot). Phones: the two side by side on top, the arrow points down. */
.mp-merge{display:grid;grid-template-columns:minmax(0,.62fr) auto minmax(0,1fr);align-items:center;gap:var(--s-4)}
.mp-two{display:grid;gap:var(--s-3)}
.mp-merge .mp-win{position:relative;width:100%}
.mp-two .mp-win:nth-child(1){rotate:-3deg}
.mp-two .mp-win:nth-child(2){rotate:2deg}
.mp-arrow{width:28px;height:28px;color:var(--il-pen)}
.mp-kit{position:relative;rotate:-1.5deg}
.mp-tab{position:absolute;top:8.7%;height:7.2%;border-radius:8px;box-shadow:0 0 0 2px var(--sun-art);background:color-mix(in srgb,var(--sun-art) 18%,transparent)}
.mp-tab-c{left:3.6%;width:14%}
.mp-tab-f{left:23.2%;width:13.6%}
@container (max-width:520px){
  .mp-merge{grid-template-columns:minmax(0,1fr);justify-items:center}
  .mp-two{grid-template-columns:repeat(2,minmax(0,1fr));width:100%}
  .mp-arrow{rotate:90deg}
}
.il.mp-fig{container-type:inline-size}

/* note 12 cover (owner 19 Oct: the dark fan and the teal field were worse; "the original ground, with the app icons"): the three plugins as app icons on the
   pale cover ground, each with its name; a slight tilt, the middle one lifted. The icons are the same marks as the Vibe Code cards (.app-ic, css/site.css). */
.cover-mp .cover-ui{left:50%;right:auto;top:50%;translate:-50% -50%;width:74cqi;zoom:1}
.mp-icons{display:flex;justify-content:center;align-items:flex-start;gap:6cqi}
.mp-ic{display:flex;flex-direction:column;align-items:center;gap:2.6cqi;width:20cqi;text-align:center;font-weight:700;font-size:clamp(.62rem,2.3cqi,1rem);line-height:1.2;color:var(--ink)}
.mp-tile{display:block;width:16cqi;height:16cqi;border-radius:24%;overflow:hidden;box-shadow:0 1px 3px color-mix(in srgb,var(--ink) 14%,transparent),0 16px 26px -12px color-mix(in srgb,var(--ink) 38%,transparent)}
.mp-tile svg{display:block;width:100%;height:100%}
.mp-ic:nth-child(1){rotate:-4deg;translate:0 2cqi}
.mp-ic:nth-child(2){translate:0 -3cqi}
.mp-ic:nth-child(3){rotate:4deg;translate:0 2cqi}

/* note 10 figure (ill_export): one chat, the same question from three developers, answered once with a link card to a page in
   the Figma file. Static. */
.ex-fig{container-type:inline-size;display:grid;place-items:center;padding:clamp(var(--s-5),6%,var(--s-8)) var(--s-4)}
.ex-fig .ilw{width:min(100%,440px)}
.ex-chat{display:flex;flex-direction:column;gap:10px;padding:14px}
.ex-q,.ex-me{display:flex;align-items:flex-end;gap:8px}
.ex-me{justify-content:flex-end;margin-top:6px}
.ex-av{flex:none;display:grid;place-items:center;width:28px;height:28px;border-radius:50%;overflow:hidden;font-size:var(--il-fs-2xs);font-weight:700;color:var(--white)}
.ex-av img{display:block;width:100%;height:100%}
.ex-av-1{background:var(--teal)}
.ex-av-2{background:var(--tangerine)}
.ex-av-3{background:color-mix(in srgb,var(--ink) 55%,transparent)}
.ex-av-me{background:var(--sun-art)}
.ex-b{padding:8px 12px;border-radius:14px 14px 14px 4px;background:var(--cream);font-size:var(--il-fs-sm);font-weight:600;line-height:1.3;color:var(--ink)}
.ex-link{display:flex;align-items:center;gap:10px;padding:8px 12px 8px 8px;border-radius:14px 14px 4px 14px;background:color-mix(in srgb,var(--sun-art) 28%,var(--white));box-shadow:var(--il-sh-sm)}
.ex-link b{display:block;font-size:var(--il-fs-sm);color:var(--ink)}
.ex-link small{display:block;font-size:var(--il-fs-xs);font-weight:500;color:var(--body)}
.ex-pg{flex:none;display:flex;flex-direction:column;gap:4px;width:34px;height:42px;padding:7px 6px;border-radius:6px;background:var(--white);box-shadow:var(--il-ring)}
.ex-pg i{display:block;height:4px;border-radius:2px;background:var(--il-line-strong)}
.ex-pg i:last-child{width:60%}


/* note 13 figure (ill_templates): one template page + the data per page -> many pages. Static; stacks on narrow widths. */
.tp-fig{container-type:inline-size;padding:clamp(var(--s-5),6%,var(--s-8)) var(--s-4)}
.tp-flow{display:flex;align-items:center;justify-content:center;gap:14px}
.tp-col{display:flex;flex-direction:column;align-items:center;gap:8px}
.tp-col small{font-size:var(--il-fs-2xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);white-space:nowrap}
.tp-op{font-size:var(--il-fs-md);color:var(--muted)}
.tp-tpl{box-shadow:var(--il-sh-sm),0 0 0 1.5px color-mix(in srgb,var(--teal) 55%,transparent)}
.tp-ds{display:flex;flex-direction:column;gap:6px}
.tp-d{display:flex;align-items:center;gap:6px;padding:5px 10px;border-radius:var(--pill);background:var(--white);box-shadow:var(--il-sh-sm);font-size:var(--il-fs-xs);font-weight:600;color:var(--ink)}
.tp-dot{width:8px;height:8px;border-radius:50%}
.tp-ps{display:flex;gap:6px}
.tp-ps .tp-p{width:62px;padding:6px}
.tp-ps .tp-p .pf-img{height:24px}
.tp-c1.tp-dot,.tp-p.tp-c1 .pf-img{background:color-mix(in srgb,var(--teal) 30%,var(--white))}
.tp-c2.tp-dot,.tp-p.tp-c2 .pf-img{background:color-mix(in srgb,var(--tangerine) 30%,var(--white))}
.tp-c3.tp-dot,.tp-p.tp-c3 .pf-img{background:color-mix(in srgb,var(--sun-art) 45%,var(--white))}
.tp-dot.tp-c1{background:var(--teal)}
.tp-dot.tp-c2{background:var(--tangerine)}
.tp-dot.tp-c3{background:var(--sun-art)}
@container (max-width:520px){.tp-flow{flex-direction:column;gap:10px}.tp-op{line-height:1}.tp-flow .pf-arr{rotate:90deg;margin:8px 0}.tp-ds{flex-direction:row}}

/* note 08 figure (ill_review): the Momo Copy Review card as it ended up: one tapped word (sun), the comment box, the buttons,
   and the pager (5 per page). Static. */
.rv-fig{container-type:inline-size;display:grid;place-items:center;padding:clamp(var(--s-5),6%,var(--s-8)) var(--s-4)}
.rv-stack{display:flex;flex-direction:column;align-items:center;gap:12px;width:min(100%,440px)}
.rv-stack .ilw{width:100%}
.rv-card .rv-tap{background:var(--sun-art)}
.rv-com{display:flex;flex-direction:column;gap:2px;padding:8px 12px;border-radius:var(--r-inner);box-shadow:inset 0 0 0 1px var(--il-line-strong)}
.rv-com small{font-size:var(--il-fs-2xs);font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.rv-com span{font-size:var(--il-fs-xs);font-weight:500;color:var(--muted)}
.rv-foot{display:flex;flex-wrap:wrap;gap:6px}
.rv-b{padding:5px 12px;border-radius:var(--pill);background:var(--cream);font-size:var(--il-fs-xs);font-weight:700;color:var(--ink)}
.rv-send{margin-left:auto;background:var(--ink);color:var(--white)}
.rv-pager{display:flex;align-items:center;gap:6px;font-size:var(--il-fs-xs);font-weight:700;color:var(--muted)}
.rv-pager :is(b,i){display:grid;place-items:center;width:24px;height:24px;border-radius:7px;font-style:normal;background:var(--white);box-shadow:var(--il-sh-sm)}
.rv-pager b{background:var(--ink);color:var(--white)}
.rv-pager small{margin-left:6px;font-size:var(--il-fs-xs);font-weight:600}