/* ============================================================
   Case study pages (projects/*.html). Loads after site.css, tokens only.
   Story shape, same on every page: hero (facts + device composition),
   results strip, the problem, numbered moves with real artifacts,
   what I learned, next project, contact strip.
   Shape rule follows site.css: pills = buttons/chips, --r-card = cards + stages, --r-inner = images. Client case stages wear
   the project's case hue (.cs-stage.case-x, the same hue as its project card); side-project stages are white.
   ============================================================ */

/* Silka 600 (site.css loads 400/500/700 only, so a 600 rendered the 700 file): the Scale A titles and big numbers of the
   kit figures and the impact opening; same face as css/ill.css */
@font-face{font-family:"Silka";src:url("../fonts/silka-semibold-webfont.woff2") format("woff2");font-weight:600;font-style:normal;font-display:swap}

:root{
  --scrim:rgba(25,26,30,.86);
  --clip-w:900px;   /* widest a process clip (and the legend under it) gets */
  /* --mono lives in site.css. dark-mode values for the Momo semantic-token demo: */
  --dark-surface-2:rgba(255,255,255,.06);
  --dark-text-2:rgba(255,255,255,.7);
  --dark-border:rgba(255,255,255,.18);
  --dark-brand-soft:rgba(62,230,200,.16);
}

/* ---------- Hero ---------- */
.cs-hero{position:relative;padding-top:calc(var(--nav-h) + clamp(3.5rem,9vw,6rem));padding-bottom:clamp(2.5rem,6vw,4.5rem)}
.cs-hero-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-7)}
@media(min-width:900px){.cs-hero-grid{grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:var(--s-8);align-items:start}}
.cs-copy{display:flex;flex-direction:column;align-items:flex-start;min-width:0}
.cs-copy .kicker{margin-bottom:var(--s-4)}
.cs-copy .kicker .cs-mark{width:auto;height:75px;max-width:180px;margin:-29px 0 -20px -30px;border-radius:0;box-shadow:none;object-fit:contain}
.cs-title{font-size:var(--fs-page);font-weight:700;line-height:var(--lh-tight);letter-spacing:var(--ls-display);max-width:17ch}
.cs-copy .lead{margin-top:var(--s-5);max-width:54ch}
.cs-copy .tags{margin-top:var(--s-5)}
/* hero facts: small label over a value, in a ruled grid */
.facts{display:grid;gap:var(--s-4);padding-top:var(--s-5);border-top:1px solid var(--line-soft)}
.facts div{min-width:0}
.facts small{display:block;font-size:var(--fs-cap);font-weight:500;color:var(--muted);margin-bottom:2px}
.facts b{display:block;font-weight:500;font-size:var(--fs-body);line-height:var(--lh-snug)}
.cs-facts{width:100%;grid-template-columns:repeat(2,minmax(0,1fr));margin-top:var(--s-6)}
@media(min-width:600px) and (max-width:899px){.cs-facts{grid-template-columns:repeat(4,minmax(0,1fr))}}
@media(min-width:600px){.cs-facts-3{grid-template-columns:repeat(3,minmax(0,1fr))}}

/* ---------- Stage with a device composition: white card, or the project's case hue ---------- */
.cs-stage{position:relative;overflow:hidden;border-radius:var(--r-card);background:var(--wk-bg,var(--white));box-shadow:var(--shadow-rest);padding:clamp(1.25rem,4vw,2.5rem);min-width:0}
.cs-stage[class*="case-"]{box-shadow:none}
.cs-stage .tone-card{position:relative;z-index:1;box-shadow:var(--shadow-overlay)}
.cs-stage>*{position:relative;z-index:1}
.cs-stage .sticker{position:absolute;z-index:3;right:var(--s-4);top:var(--s-4);--rot:5deg;opacity:0;animation:popIn var(--dur-2) var(--ease-out) .3s forwards}
/* cover stage: one presentation image fills the case-hue card edge to edge */
.cs-cover{padding:0;margin:0;width:100%;aspect-ratio:1230/1401}
.cs-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:left top}
/* a light tint of the case hue (.cs-tint + .case-x + .mesh): media beds inside a case page, the hue's blobs softened to the bed */
.cs-stage.cs-tint{background:color-mix(in srgb,var(--wk-bg,var(--white)) 18%,var(--white));box-shadow:none;--m1:color-mix(in srgb,var(--wk-bg) 34%,var(--white));--m2:color-mix(in srgb,var(--wk-bg) 8%,var(--white));--m3:color-mix(in srgb,var(--wk-bg) 22%,var(--sun-tint))}
.cs-comp{position:relative;padding-right:24%;padding-bottom:5%}
.cs-shot{border-radius:var(--r-inner);overflow:hidden;background:var(--white);box-shadow:var(--shadow-overlay)}
.cs-shot img{width:100%;height:auto;display:block}
.cs-comp .cs-device{position:absolute;right:0;bottom:0;width:36%;z-index:2}
/* pointer parallax: JS writes --px/--py (-1..1) on the stage; each layer moves by its depth */
.cs-stage[data-tilt] [data-depth]{transform:translate(calc(var(--px,0) * var(--depth,0) * 1px),calc(var(--py,0) * var(--depth,0) * .7px));transition:transform var(--dur-2) var(--ease)}

/* CSS phone frame for raw screenshots (some case images already carry their own frame) */
.cs-device{overflow:hidden;border:7px solid var(--ink);border-radius:var(--r-card);background:var(--ink);box-shadow:var(--shadow-overlay)}
.cs-device img{width:100%;height:auto;display:block}
@media(max-width:480px){.cs-device{border-width:5px}}

/* ---------- App demo (.cs-demo, js/case.js "Tap-around demo"): a looping clip phone + a tap-around phone ----------
   Kit language (css/article.css "Kit figures"): neutral white -> cream panel, white boards with the soft glow, the dotted sheet
   (.dot-back) peeking out behind, one sticker label each. The screens carry the colour. Screens are stacked <img>s (the locked
   page decrypts them near the viewport); one is shown, the rest are inert. JS moves them with transform / opacity only (push,
   hero expand, sheet, modal, fade) and builds its overlay layers from the decrypted images (--img). Hotspots: --x/--y/--w/--h in
   % of their layer. On phones (< 600px) the bezel goes and the screen fits the viewport. */
.cs-demo-band{padding-bottom:clamp(var(--s-6),6vw,var(--s-8))}
.cs-demo{--demo-w:300px;position:relative;isolation:isolate;padding:clamp(var(--s-6),5vw,var(--s-8)) var(--s-4);border-radius:var(--r-card);background:linear-gradient(160deg,var(--white),var(--cream));box-shadow:var(--edge);overflow:hidden;
  --demo-glow:0 0 40px -6px color-mix(in srgb,color-mix(in srgb,var(--ink) 14%,var(--white)) 80%,transparent),var(--shadow-overlay)}
.cs-demo-grid{display:grid;grid-template-columns:minmax(0,1fr);justify-items:center;gap:clamp(var(--s-8),8vw,var(--s-10))}
/* the whole phone stays in view on short laptop screens (no % width inside the two auto tracks: it would collapse) */
/* --demo-min keeps the phone usable on a short landscape viewport (the height rule alone would shrink it to ~100 px) */
.cs-demo-stage{--demo-min:240px;position:relative;width:min(100%,var(--demo-w),max(var(--demo-min),calc((100svh - var(--nav-h) - var(--s-9)) * 375 / 812)))}
@media(min-width:720px){
  .cs-demo-grid{grid-template-columns:repeat(2,auto);justify-content:center;align-items:start;gap:clamp(var(--s-8),7vw,var(--s-10))}
  .cs-demo-stage{width:clamp(var(--demo-min),calc((100svh - var(--nav-h) - var(--s-9)) * 375 / 812),var(--demo-w))}
}
/* one accent in the block (the case hue): both dotted sheets and the "Try it" sticker; the clip phone's sticker is plain white */
.cs-demo .dot-back{left:var(--s-6);top:var(--s-7);right:calc(var(--s-5) * -1);bottom:calc(var(--s-5) * -1);border-radius:calc(var(--r-card) * 1.75);background-color:color-mix(in srgb,var(--case-h) 55%,var(--white))}
.cs-demo-phone{position:relative;padding:calc(var(--s-1) * 1.5);border-radius:calc(var(--r-card) * 1.75);background:var(--white);box-shadow:var(--demo-glow);touch-action:manipulation;user-select:none;-webkit-user-select:none}
/* pan-y: the page still scrolls over the phone, a sideways drag from the left edge reaches the swipe-back code (js) */
.cs-demo-view{position:relative;aspect-ratio:375 / 812;overflow:hidden;border-radius:calc(var(--r-card) * 1.5);background:var(--cream);box-shadow:inset 0 0 0 1px var(--line-soft);isolation:isolate;transform:translateZ(0);touch-action:pan-y pinch-zoom}
/* the clip phone: the locked video (js/site.js video[data-autoplay]) with its pause button in a bar under the phone */
.cs-demo-view-clip video{display:block;width:100%;height:100%;object-fit:cover;background:var(--cream)}
.cs-demo-view-clip .cs-video-msg{position:absolute;inset:auto 0 var(--s-7);margin:0;text-align:center;font-size:var(--fs-cap);color:var(--muted)}
.cs-demo-watch .cs-clip-bar,.cs-demo-bar{position:relative;z-index:1;display:flex;justify-content:center;margin-top:var(--s-5)}   /* above the dotted sheet */
.cs-demo-replay{gap:var(--s-2)}
.cs-demo-replay svg{width:16px;height:16px}
.cs-demo-screen{position:absolute;inset:0;visibility:hidden;background:var(--white)}
.cs-demo-probe{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none}   /* js: the eased clock behind the Home glide */
.cs-demo-dim{z-index:2}
.cs-demo-screen.is-on{visibility:visible}
.cs-demo-screen.is-lift{box-shadow:-10px 0 28px rgba(25,26,30,.14)}
.cs-demo-screen:focus-visible{outline:none}
.cs-demo-screen>img{display:block;width:100%;height:100%;object-fit:cover;-webkit-user-drag:none}
.cs-demo-screen img:not([src]){visibility:hidden}   /* locked page: no src until decrypted, so no alt-text flash */
/* Home = one scrolling page (375 x 1302): the top export, then the scrolled export from its white gap (seam at 490 + 210);
   its compact header and the tab bar are fixed overlays painted from the same two images once they are decrypted */
.cs-demo-scroll{position:absolute;inset:0;overflow:hidden auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.cs-demo-scroll::-webkit-scrollbar{display:none}
.cs-demo-page{position:relative;width:100%;aspect-ratio:375 / 1302}
.cs-demo-page .cs-demo-img{position:absolute;left:0;top:0;width:100%;height:auto;-webkit-user-drag:none}
.cs-demo-page .cs-demo-img-2{top:calc(490 / 1302 * 100%);clip-path:inset(calc(210 / 812 * 100%) 0 0 0)}
.cs-demo-head{position:absolute;left:0;top:0;width:100%;height:calc(116 / 812 * 100%);background:var(--img) 0 0 / 100% auto no-repeat;opacity:0;pointer-events:none;z-index:2}
.cs-demo-tab{position:absolute;left:0;bottom:0;width:100%;height:calc(96 / 812 * 100%);background:var(--img) 0 100% / 100% auto no-repeat;pointer-events:none;z-index:3}
.cs-demo-tab .cs-demo-hot{pointer-events:auto}
/* transition layers (js): a full-screen copy of a screen's image, clipped and moved; the hero box grows from the tapped tile */
.cs-demo-dim{position:absolute;inset:0;background:var(--ink);opacity:0;pointer-events:none}
.cs-demo-layer{position:absolute;inset:0;background:var(--img) 0 0 / 100% 100% no-repeat;pointer-events:none;will-change:transform}
.cs-demo-hero{position:absolute;left:0;top:0;width:100%;height:calc(342 / 812 * 100%);overflow:hidden;transform-origin:0 0;pointer-events:none;will-change:transform,clip-path}
.cs-demo-hero i{position:absolute;display:block;background:var(--img) 0 0 / 100% 100% no-repeat}
/* a small note for tiles that are not part of the demo (js: data-toast): rises from the bottom, opacity + translate only */
.cs-demo-toast{position:absolute;left:50%;bottom:calc(96 / 812 * 100% + var(--s-4));z-index:70;max-width:calc(100% - var(--s-6));padding:var(--s-2) var(--s-4);border-radius:var(--pill);background:var(--ink);color:var(--white);font-size:var(--fs-cap);font-weight:500;white-space:nowrap;opacity:0;transform:translate(-50%,6px);pointer-events:none;transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out)}
.cs-demo-toast.is-on{opacity:1;transform:translate(-50%,0)}
.cs-demo-hot{position:absolute;left:calc(var(--x) * 1%);top:calc(var(--y) * 1%);width:calc(var(--w) * 1%);height:calc(var(--h) * 1%);padding:0;border:0;border-radius:var(--r-inner);background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
.cs-demo-hot:focus-visible{outline:var(--stroke) solid var(--ink);outline-offset:calc(var(--stroke) * -1);box-shadow:inset 0 0 0 calc(var(--stroke) * 2) var(--white)}
/* the hint: the next tap targets glow twice when a screen arrives (opacity only, the block's one accent; never on the tab bar, a back button or a not-in-demo tile) */
.cs-demo-hot::after{content:"";position:absolute;inset:0;border-radius:inherit;background:color-mix(in srgb,var(--case-h) 30%,transparent);box-shadow:inset 0 0 0 1.5px var(--case-h);opacity:0;pointer-events:none}
.is-hint .cs-demo-hot:not([data-tab]):not([data-scroll]):not([data-back]):not([data-toast])::after{animation:csHint .8s var(--ease-inout) 2}
.is-hint-scroll .cs-demo-hot[data-scroll]::after{animation:csHint 1.2s var(--ease-inout) 1}   /* first sight: the scroll band pulses once */
@keyframes csHint{50%{opacity:1}}
.cs-demo-ripple{--tap:var(--demo-tap,var(--s-7));position:absolute;z-index:70;width:var(--tap);height:var(--tap);margin:calc(var(--tap) / -2) 0 0 calc(var(--tap) / -2);border-radius:var(--pill);background:color-mix(in srgb,var(--ink) 16%,transparent);pointer-events:none;animation:csDemoTap var(--dur-3) var(--ease-out) forwards}
@keyframes csDemoTap{from{opacity:1;transform:scale(.25)}to{opacity:0;transform:scale(1)}}
/* the label sits on the phone's top-left corner, outside the screen; on a phone it sits above the frame */
.cs-demo-label{position:absolute;z-index:3;right:calc(100% - var(--s-5));top:calc(var(--s-4) * -1);--rot:-5deg;pointer-events:none}
.cs-demo-try .cs-demo-label{background:var(--case-h)}
.cs-demo-label-watch{background:var(--white);box-shadow:var(--shadow-rest),var(--edge-out);--rot:-4deg}
@media(min-width:1000px){.cs-demo-try .cs-demo-label{right:auto;left:calc(100% - var(--s-5));--rot:5deg}}   /* the two labels sit on the outer corners */
/* two columns but little room beside them (tablet, landscape phone): both labels sit on their phone's top-left corner, inside the panel */
@media(min-width:720px) and (max-width:999px){.cs-demo-label{right:auto;left:var(--s-3);top:calc(var(--s-5) * -1)}}
@media(max-width:599px){
  .cs-demo{padding:calc(var(--s-8) + var(--s-4)) var(--s-4) var(--s-6)}
  .cs-demo-grid{gap:calc(var(--s-8) + var(--s-6))}
  .cs-demo-stage{width:min(100%,calc((100svh - var(--nav-h) - var(--s-9)) * 375 / 812))}
  .cs-demo-phone{padding:0;background:none;box-shadow:none}
  .cs-demo-view{box-shadow:var(--demo-glow),inset 0 0 0 1px var(--line-soft)}
  .cs-demo-label{right:auto;left:0;top:calc(var(--s-8) * -1)}
}

/* ---------- Results strip ---------- */
.cs-results{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-6);align-items:center;padding:clamp(1.25rem,4vw,2.5rem);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest);min-width:0}
@media(min-width:900px){.cs-results{grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:var(--s-8)}}
.cs-results .h3{margin-bottom:var(--s-5);max-width:26ch}
.cs-nums{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:var(--s-5) var(--s-4)}
.cs-num{min-width:0;padding-top:var(--s-3);border-top:1px solid var(--line-soft)}
.cs-num b{display:block;font-size:var(--fs-section);font-weight:700;letter-spacing:var(--ls-display);line-height:1;font-variant-numeric:tabular-nums;white-space:nowrap}
.cs-num b em{font-style:normal}
.cs-num>span{display:block;margin-top:var(--s-2);font-size:var(--fs-cap);color:var(--body);font-weight:500;line-height:var(--lh-snug)}
@media(min-width:600px){.cs-nums-4{grid-template-columns:repeat(2,minmax(0,1fr))}}
.cs-src{margin-top:var(--s-5);font-size:var(--fs-cap);color:var(--muted);max-width:52ch}
.cs-src a{text-decoration:underline;text-underline-offset:2px}
/* Impact opening (client case, case-h hue; was case-b until 7 Nov 2026): kit neutral panel, launch forecast vs year one as two calm bars (the result bar is the
   one case-hue pop) with "5x" and the orders beside them, one note line, then the year-one milestone strip (white tiles on the
   page ground, one tile in the case hue) and one source line. Scale A weights (400/500/600), every label >= --fs-cap. */
.cs-impact{padding:clamp(var(--s-5),4vw,var(--s-7));border-radius:var(--r-card);background:linear-gradient(160deg,var(--white),var(--cream));box-shadow:var(--edge);min-width:0}
.cs-impact .h3{max-width:26ch}
.cs-fc{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-6);margin-top:var(--s-6)}
@media(min-width:600px){.cs-fc{grid-template-columns:minmax(0,1fr) auto;gap:var(--s-8);align-items:end}}
.cs-fc-bars{display:grid;gap:var(--s-5);min-width:0}
.cs-fc-l{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:baseline;gap:var(--s-1) var(--s-3);margin-bottom:var(--s-2);font-size:var(--fs-cap);font-weight:500;color:var(--body)}
.cs-fc-l b{font-size:var(--fs-body);font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.cs-fc-bar{display:block;height:var(--s-4);border-radius:var(--pill);background:var(--fill-soft);overflow:hidden}
/* the bars draw in from the left once the panel scrolls in (transform only; still sheet = drawn) */
.cs-fc-bar i{display:block;width:var(--w);height:100%;border-radius:inherit;background:var(--line-mid);transform:scaleX(0);transform-origin:left;transition:transform var(--dur-3) var(--ease-out) .15s}
.cs-fc-row.is-res .cs-fc-bar i{background:var(--case-h);transition-delay:.3s}
.is-in .cs-fc-bar i{transform:none}
/* beside the bars: the derived 5x and the orders, two small stats at the sub-head size (no second hero) */
.cs-fc-side{display:flex;gap:var(--s-6);margin:0;padding:0;list-style:none;min-width:0}
@media(min-width:600px){.cs-fc-side{flex-direction:column;gap:var(--s-4);padding-left:var(--s-6);border-left:1px solid var(--line-soft)}}
.cs-fc-side li{display:flex;flex-direction:column;gap:var(--s-1);min-width:0}
.cs-fc-side b{font-size:var(--fs-sub);font-weight:600;letter-spacing:var(--ls-display);line-height:1;font-variant-numeric:tabular-nums;white-space:nowrap}
.cs-fc-side li>span{font-size:var(--fs-cap);font-weight:500;color:var(--body)}
.cs-fc-note{margin-top:var(--s-5);font-size:var(--fs-cap);color:var(--muted);max-width:70ch}
.cs-ms-fig figcaption a,.cs-src-inline a{text-decoration:underline;text-underline-offset:2px}
.cs-src-inline{font-size:var(--fs-cap);color:var(--muted)}
.cs-fig.cs-ms-fig{margin-top:var(--s-5);gap:var(--s-4)}
.cs-ms{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-2);margin:0;padding:0;list-style:none}
.cs-ms li{position:relative;isolation:isolate;display:grid;grid-template-columns:calc(var(--s-9) + var(--s-2)) minmax(0,1fr);grid-template-areas:"big when" "big txt";align-items:center;column-gap:var(--s-4);padding:var(--s-3) var(--s-4);border-radius:var(--r-inner);background:var(--white);box-shadow:var(--edge-out);min-width:0}
.cs-ms-when{grid-area:when;font-size:var(--fs-cap);font-weight:500;color:var(--muted)}
.cs-ms b{grid-area:big;font-size:var(--fs-sub);font-weight:600;letter-spacing:var(--ls-display);line-height:1;font-variant-numeric:tabular-nums}
.cs-ms li>span:last-child{grid-area:txt;font-size:var(--fs-cap);color:var(--body)}
/* the one highlighted tile: its case-hue fill is a layer that fades in after the tiles have risen (opacity only) */
.cs-ms li.is-on{box-shadow:none}
.cs-ms li.is-on::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--case-h);opacity:0;transition:opacity var(--dur-3) var(--ease-out) .5s}
.is-in li.is-on::before{opacity:1}
.cs-ms li.is-on :is(.cs-ms-when,span){color:var(--ink)}
@media(min-width:900px){
  .cs-ms{grid-template-columns:repeat(5,minmax(0,1fr));gap:var(--s-3)}
  .cs-ms li{grid-template-columns:minmax(0,1fr);grid-template-areas:"when" "big" "txt";align-content:start;row-gap:var(--s-2);padding:var(--s-4)}
}
.cs-video{margin-top:var(--s-7)}
.cs-video .cs-src{max-width:none}
.cs-video video{display:block;width:100%;height:auto;aspect-ratio:1280/795;border-radius:var(--r-card);background:var(--ink);box-shadow:var(--shadow-overlay)}
.cs-video.is-error video{display:none}
.cs-video-msg{margin-top:var(--s-3);font-size:var(--fs-body);color:var(--muted)}

/* ---------- The problem ---------- */
.cs-problem{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-6)}
@media(min-width:900px){.cs-problem{grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:var(--s-9);align-items:start}}
.cs-quote{font-size:var(--fs-sub);font-weight:700;letter-spacing:var(--ls-display);line-height:var(--lh-tight);max-width:22ch}
.cs-problem p{color:var(--body);max-width:52ch}
.cs-problem p+p{margin-top:var(--s-3)}
.cs-list{display:flex;flex-direction:column;gap:var(--s-3);color:var(--body)}
.cs-list li{position:relative;padding-left:var(--s-6);max-width:52ch}
.cs-list li::before{content:"";position:absolute;left:0;top:.6em;width:8px;height:8px;border-radius:var(--pill);background:var(--sun)}  /* = .sqb */
.cs-problem .cs-fig{margin-top:var(--s-4)}

/* ---------- What I did: numbered moves ---------- */
.cs-moves{display:flex;flex-direction:column;gap:clamp(3.5rem,8vw,6rem)}
.cs-move{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-5);min-width:0}
@media(min-width:900px){
  .cs-move{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:var(--s-8);align-items:center}
  .cs-move-flip .cs-move-copy{order:2}
  .cs-move-wide{grid-template-columns:minmax(0,1fr)}
  .cs-move-wide .cs-move-copy{max-width:64ch}
}
.cs-move-copy{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-3);min-width:0}
.cs-n{--nsq-bg:var(--sun);margin-bottom:var(--s-2);transition:transform var(--dur-2) var(--ease)}  /* + .nsq */
.cs-move:hover .cs-n{transform:scale(1.08)}   /* no hover rotate (motion-spec rule 2; the sticker is the only one) */
.cs-move h3{font-size:var(--fs-sub);font-weight:700;letter-spacing:var(--ls-display);line-height:var(--lh-tight);max-width:20ch}
.cs-move p{color:var(--body);max-width:46ch}
.cs-move .out{font-size:var(--fs-body);font-weight:500;color:var(--ink);max-width:46ch}
.cs-move .out b{color:var(--ink)}
.cs-stack{display:flex;flex-direction:column;gap:var(--s-4);min-width:0}
.cs-2up{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-4);min-width:0}
@media(min-width:600px){.cs-2up{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ---------- Figures: framed artifacts, zoomable ---------- */
.cs-fig{display:flex;flex-direction:column;gap:var(--s-3);min-width:0;margin:0}
.cs-fig figcaption{font-size:var(--fs-cap);color:var(--muted)}
.cs-fig figcaption b{color:var(--ink);font-weight:700}
.cs-frame{position:relative;border-radius:var(--r-inner);overflow:hidden;background:var(--white);box-shadow:var(--shadow-overlay)}
.cs-frame img{width:100%;height:auto;display:block}
.cs-frame-pad{padding:var(--s-3);background:var(--cream)}
.cs-frame-pad img{border-radius:var(--r-inner)}
.cs-frame-dark{background:var(--ink)}
.cs-zoom{position:relative;display:block;width:100%;padding:0;cursor:zoom-in;text-align:left;overflow:hidden;border-radius:inherit}
.cs-zoom img{transition:transform var(--dur-2) var(--ease)}
.cs-zoom:hover img{transform:scale(1.025)}
.cs-zoom .zm{position:absolute;right:var(--s-3);bottom:var(--s-3);z-index:2;display:grid;place-items:center;width:40px;height:40px;border-radius:var(--pill);background:var(--white);box-shadow:var(--shadow-rest);color:var(--ink);opacity:0;transform:translateY(4px);transition:opacity var(--dur-1) var(--ease),transform var(--dur-1) var(--ease)}
.cs-zoom .zm svg{width:16px;height:16px}
.cs-zoom:hover .zm,.cs-zoom:focus-visible .zm{opacity:1;transform:none}
@media(hover:none){.cs-zoom .zm{opacity:1;transform:none}}
.browser .cs-zoom{border-radius:0}

/* Save deterrents ([data-nosave], js/site.js): no drag ghost, no iOS long-press menu, no selection on media and figures */
[data-nosave] :is(img,video){-webkit-user-drag:none;-webkit-touch-callout:none}
[data-nosave] :is(figure,.kf,.cs-stage,.cs-demo){-webkit-user-select:none;user-select:none}

/* Lightbox */
.cs-lb{border:0;padding:0;margin:auto;background:transparent;max-width:min(96vw,1400px);max-height:96vh;overflow:visible;color:var(--white)}
.cs-lb::backdrop{background:var(--scrim)}
.cs-lb figure{margin:0;display:flex;flex-direction:column;align-items:center;gap:var(--s-3)}
.cs-lb img{display:block;max-width:min(96vw,1400px);max-height:86vh;width:auto;height:auto;border-radius:var(--r-inner);box-shadow:var(--shadow-overlay);background:var(--white)}
.cs-lb figcaption{font-size:var(--fs-cap);text-align:center;max-width:60ch;padding-inline:var(--s-4)}
.cs-lb-close{position:fixed;top:var(--s-4);right:var(--s-4);z-index:2;display:grid;place-items:center;width:44px;height:44px;border-radius:var(--pill);background:var(--sun);color:var(--ink);transition:transform var(--dur-1) var(--ease)}
.cs-lb-close:hover{transform:rotate(90deg)}
.cs-lb-close svg{width:18px;height:18px}
.cs-lb[open]{animation:lbIn var(--dur-2) var(--ease-out)}
@keyframes lbIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}

/* ---------- Inline SVG diagrams: ink line-art, sun for the one highlight, cream / grey for the rest (no teal, no tangerine) ---------- */
.dg{width:100%;height:auto;display:block;overflow:visible}
.dg text{font-family:var(--font);font-weight:700;fill:var(--ink)}
.dg .ln{fill:none;stroke:var(--ink);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.dg .ln-tan{stroke:var(--muted);stroke-dasharray:4 5}
.dg .box{fill:var(--white);stroke:var(--ink);stroke-width:2}
.dg .sun{fill:var(--sun)}
.dg .teal{fill:var(--ink)}
.dg .mint{fill:var(--sun)}
.dg .tint{fill:var(--cream)}
.dg .cream{fill:var(--cream)}
.dg .pop{opacity:0;transform-box:fill-box;transform-origin:center;transform:scale(var(--sc,.5))}
.is-in .dg .pop{animation:dgPop var(--dur-2) var(--ease-out) forwards;animation-delay:calc(var(--i,0) * var(--ps,28ms) + var(--pd,.15s))}
@keyframes dgPop{to{opacity:1;transform:none}}
.dg .draw{stroke-dasharray:var(--len,700);stroke-dashoffset:var(--len,700)}
.is-in .dg .draw{animation:draw var(--dt,var(--dur-3)) var(--ease-out) forwards var(--dd,.3s)}
.cs-legend{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-3);margin-top:var(--s-4);font-size:var(--fs-cap);color:var(--body)}
@media(min-width:600px){.cs-legend{grid-template-columns:repeat(3,minmax(0,1fr))}}
.cs-legend b{display:block;color:var(--ink);font-weight:700}
.cs-diagram{padding:clamp(1rem,3vw,2rem);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest)}
/* A process clip (js/site.js video[data-autoplay]) and stills on a cream bed framed like a kit panel (--r-card + --edge). 16:10 is
   reserved, so nothing shifts while a locked file decrypts. The clip caps at --clip-w, centred; its pause button sits in a bar under
   it (never over the picture), and the legend follows. */
.cs-clip{position:relative;max-width:var(--clip-w);margin-inline:auto;aspect-ratio:16 / 10;overflow:hidden;border-radius:var(--r-card);background:var(--cream);box-shadow:var(--edge)}
.cs-clip video{display:block;width:100%;height:100%;object-fit:cover}
.cs-clip .cs-video-msg{position:absolute;inset:auto 0 var(--s-3);margin:0;text-align:center;font-size:var(--fs-cap)}
.cs-clip-bar{display:flex;justify-content:flex-end;max-width:var(--clip-w);margin:var(--s-2) auto 0}
.cs-clip-bar .clip-toggle{position:static;opacity:1;box-shadow:var(--edge-out)}
.cs-clip-bar+.cs-legend{max-width:var(--clip-w);margin:var(--s-2) auto 0}
.cs-still{aspect-ratio:16 / 10;border-radius:var(--r-card);background:var(--cream);box-shadow:var(--edge)}
.cs-still img{display:block;width:100%;height:100%;object-fit:cover}
.cs-still img:not([src]){visibility:hidden}   /* locked page: no src until decrypted, so no alt-text flash */
/* a small still (its true size is 465px wide) sits centred on the bed at its own size, never enlarged, no zoom */
.cs-still-fit{display:grid;place-items:center;padding:var(--s-4)}
.cs-still-fit img{width:auto;max-width:min(100%,465px);height:auto;object-fit:contain;border-radius:var(--r-inner)}
/* .cs-move-art: the artifact takes the wide column; on phones the still shows its left part (source x 0-1180, y 150-880 of
   1600 x 1000) so the row names stay readable; the zoom still opens the whole picture */
@media(min-width:900px){.cs-move-flip.cs-move-art{grid-template-columns:minmax(0,7fr) minmax(0,5fr)}}
@media(max-width:600px){.cs-still-lanes img{width:calc(100% * 1600 / 1180);max-width:none;height:auto;margin:calc(-100% * 150 / 1180) 0 0 0}}
/* step 04 (.cs-move-top): copy starts at the top of the tall figure column and stays in view while it scrolls */
@media(min-width:900px){
  .cs-move-top{align-items:start}
  .cs-move-top .cs-move-copy{position:sticky;top:calc(var(--nav-h) + var(--s-6))}
}
/* kit figure tweaks for this case: the sprint arrow is a pale sun dot, not an ink one; on phones the mood figure keeps
   only the colour card, as large as the panel allows (generator: tools/case_figures.py, inline --u boxes) */
.kf-sprints .kf-dot{background:var(--sun-tint);color:var(--ink);box-shadow:var(--kf-sh-s)}
@media(max-width:600px){
  .kf-mood .kf-in{aspect-ratio:640 / 322}
  .kf-mood .kf-wrap:not(:first-child){display:none}
  .kf-mood .kf-wrap:first-child{left:calc(var(--u) * 16)!important;top:calc(var(--u) * 16)!important;width:calc(var(--u) * 608)!important;height:calc(var(--u) * 290)!important}
}
/* a kit figure that is itself the zoom button (tools/case_figures.py f_wireframes): spans inside a button, so the stage is a block */
.cs-zoom.kf>.kf-in{display:block}
.kf-imgb img:not([src]){visibility:hidden}
.cs-aside{color:var(--body);max-width:48ch}
.cs-note{display:inline-flex;align-items:center;gap:var(--s-2);font-size:var(--fs-cap);font-weight:500;color:var(--muted)}
.cs-code{font-family:var(--mono);font-size:var(--fs-body);padding:.08em .4em;border-radius:var(--r-inner);background:var(--fill-soft);color:var(--ink);overflow-wrap:anywhere}

/* ---------- Principles (visual direction) ---------- */
.cs-princ{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-4)}
@media(min-width:720px){.cs-princ{grid-template-columns:repeat(4,minmax(0,1fr))}}
.cs-princ div{display:flex;flex-direction:column;gap:var(--s-2);padding-top:var(--s-3);border-top:1px solid var(--line-soft);min-width:0}
.cs-princ img{width:40px;height:40px;border-radius:var(--r-inner)}
.cs-princ b{font-weight:700;font-size:var(--fs-body)}
.cs-princ span{font-size:var(--fs-cap);color:var(--body)}

/* ---------- Decisions / lessons: outlined rows, not cards ---------- */
.cs-cols{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-5) var(--s-7)}
@media(min-width:720px){.cs-cols{grid-template-columns:repeat(3,minmax(0,1fr))}}
.cs-cols>div{padding-top:var(--s-4);border-top:1px solid var(--line-soft);min-width:0}
.cs-cols h3{font-size:var(--fs-title);font-weight:700;letter-spacing:var(--ls-title);line-height:var(--lh-snug);display:flex;align-items:flex-start;gap:var(--s-3)}
.cs-cols h3 i{--nsq:32px;--nsq-bg:var(--sun);transition:transform var(--dur-2) var(--ease)}  /* + .nsq */
.cs-cols>div:hover h3 i{transform:scale(1.1)}
.cs-cols p{margin-top:var(--s-3);color:var(--body);font-size:var(--fs-body);max-width:38ch}

/* ---------- Design-system spotlight (copy + one wide figure) ---------- */
.cs-spot{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-6);align-items:center}
@media(min-width:900px){.cs-spot{grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:var(--s-8)}}

/* ---------- Token sheet (case move 01, Momo semantic map) ---------- */
.tok{display:flex;flex-direction:column;border-radius:var(--r-card);overflow:hidden;background:var(--white);box-shadow:var(--shadow-rest);min-width:0}
.tok-row{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr) minmax(0,1fr);gap:var(--s-3);align-items:center;padding:var(--s-3) var(--s-4);border-bottom:1px solid var(--line-soft)}
.tok-row:last-child{border-bottom:0}
.tok-head{font-size:var(--fs-cap);font-weight:700;color:var(--muted);background:var(--cream)}
.tok code{font-family:var(--mono);font-size:var(--fs-body);color:var(--ink);overflow-wrap:anywhere}
.tok .sw{display:inline-flex;align-items:center;gap:var(--s-2);font-size:var(--fs-cap);color:var(--body);font-weight:500;min-width:0}
.tok .sw i{flex:0 0 auto;width:18px;height:18px;border-radius:var(--pill);background:var(--c);box-shadow:inset 0 0 0 1px var(--ink-20)}
.tok .sw span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:420px){.tok-row{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1fr);gap:var(--s-2);padding-inline:var(--s-3)}.tok code{font-size:var(--fs-cap)}}

/* Semantic modes demo: the panel is its own surface, the toggle swaps every value */
.modes{--surface:var(--white);--surface-2:var(--cream);--text:var(--ink);--text-2:var(--body);--brand:var(--teal-text);--brand-soft:var(--teal-tint);--border:var(--line-mid);--ok:var(--teal);
  display:flex;flex-direction:column;gap:var(--s-4);padding:var(--s-5);border-radius:var(--r-card);background:var(--surface);color:var(--text);box-shadow:var(--edge-out);transition:background var(--dur-2) var(--ease),color var(--dur-2) var(--ease)}
.modes[data-mode="dark"]{--surface:var(--ink);--surface-2:var(--dark-surface-2);--text:var(--white);--text-2:var(--dark-text-2);--brand:var(--mint);--brand-soft:var(--dark-brand-soft);--border:var(--dark-border);--ok:var(--mint)}
.modes-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-3)}
.modes-head b{font-weight:700}
.modes-head small{display:block;font-size:var(--fs-cap);color:var(--text-2);margin-top:2px}
.modes .seg{background:var(--surface);box-shadow:inset 0 0 0 var(--stroke) var(--text)}
.modes .seg button{color:var(--text-2)}
.modes .seg button[aria-pressed="true"]{background:var(--text);color:var(--surface)}
.modes-rows{display:flex;flex-direction:column;gap:2px;border-radius:var(--r-inner);overflow:hidden;box-shadow:0 0 0 1px var(--border)}
.modes-row{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) auto;gap:var(--s-3);align-items:center;padding:var(--s-3) var(--s-4);background:var(--surface-2);transition:background var(--dur-2) var(--ease)}
.modes-row code{font-family:var(--mono);font-size:var(--fs-body);color:var(--text);overflow-wrap:anywhere}
.modes-row span{font-size:var(--fs-cap);color:var(--text-2);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.modes-row span::after{content:attr(data-light)}
.modes[data-mode="dark"] .modes-row span::after{content:attr(data-dark)}
.modes-row i{width:22px;height:22px;border-radius:6px;background:var(--v);box-shadow:inset 0 0 0 1px var(--border);transition:background var(--dur-2) var(--ease)}
.modes-sample{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3);padding:var(--s-4);border-radius:var(--r-inner);background:var(--surface-2);box-shadow:inset 0 0 0 1px var(--border);transition:background var(--dur-2) var(--ease)}
.modes-sample b{color:var(--text)}
.modes-sample small{color:var(--text-2);font-size:var(--fs-body)}
.modes-sample .pill{margin-left:auto;display:inline-flex;align-items:center;min-height:36px;padding:0 var(--s-4);border-radius:var(--pill);background:var(--brand);color:var(--surface);font-size:var(--fs-cap);font-weight:700;transition:background var(--dur-2) var(--ease),color var(--dur-2) var(--ease)}
.modes-sample .chip{display:inline-flex;align-items:center;min-height:28px;padding:0 var(--s-3);border-radius:var(--pill);background:var(--brand-soft);color:var(--brand);font-size:var(--fs-cap);font-weight:700;transition:background var(--dur-2) var(--ease),color var(--dur-2) var(--ease)}
@media(max-width:480px){.modes-row{grid-template-columns:minmax(0,1fr) auto}.modes-row span{display:none}}

/* ---------- Component list with variant bars (Momo) ---------- */
.comps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-3) var(--s-5)}
@media(min-width:600px){.comps{grid-template-columns:repeat(4,minmax(0,1fr))}}
.comp{padding:var(--s-3) 0;border-top:1px solid var(--line-soft);min-width:0}
.comp b{display:block;font-weight:700}
.comp span{font-size:var(--fs-cap);color:var(--muted);font-weight:500}
.comp i{display:block;height:6px;border-radius:var(--pill);background:var(--ink);width:calc(var(--v) / var(--max,60) * 100%);min-width:8px;margin-top:var(--s-2);transform:scaleX(0);transform-origin:left;transition:transform var(--dur-3) var(--ease-out) calc(var(--i,0) * 60ms)}
.is-in .comp i{transform:none}
.comps-total{margin-top:var(--s-4);display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s-2) var(--s-3)}
.comps-total b{font-size:var(--fs-section);font-weight:700;letter-spacing:var(--ls-display);line-height:1}
.comps-total span{font-size:var(--fs-body);color:var(--body)}

/* ---------- Four-function pattern (Momo) ---------- */
.flow{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-3);counter-reset:flow}
@media(min-width:720px){.flow{grid-template-columns:repeat(4,minmax(0,1fr))}}
.flow-step{position:relative;display:flex;flex-direction:column;gap:var(--s-2);padding:var(--s-4);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest);min-width:0}
.flow-step::before{counter-increment:flow;content:counter(flow,decimal-leading-zero);font-size:var(--fs-cap);font-weight:700;color:var(--muted)}
.flow-step code{font-family:var(--mono);font-size:var(--fs-body);font-weight:500;color:var(--ink);overflow-wrap:anywhere}
.flow-step code em{font-style:normal;font-weight:700}
.flow-step small{font-size:var(--fs-cap);color:var(--body);line-height:var(--lh-snug)}
.flow-step:last-child{background:var(--sun)}
@media(min-width:720px){
  .flow-step:not(:last-child)::after{content:"";position:absolute;right:calc(var(--s-3) * -1 - 1px);top:50%;width:var(--s-3);height:2px;background:var(--ink);transform:translateY(-50%)}
}

/* ---------- Base to variants (Momo) ---------- */
.bv{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-4);align-items:center;padding:var(--s-5);border-radius:var(--r-card);background:var(--white);box-shadow:var(--edge-out)}
@media(min-width:600px){.bv{grid-template-columns:auto 1fr}}
.bv-base{position:relative;display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 var(--s-6);border-radius:var(--pill);border:1.5px dashed var(--line-mid);font-weight:700;background:var(--sun-tint);justify-self:start}
.bv-base small{position:absolute;top:-12px;left:50%;transform:translateX(-50%);padding:2px var(--s-3);border-radius:var(--pill);background:var(--ink);color:var(--white);font-size:var(--fs-cap);font-weight:700;letter-spacing:.04em;white-space:nowrap}
.bv-vars{display:flex;flex-wrap:wrap;gap:var(--s-2)}
.bv-vars span{display:inline-flex;align-items:center;min-height:44px;padding:0 var(--s-5);border-radius:var(--pill);font-size:var(--fs-body);font-weight:500;opacity:0;transform:translateX(-8px);transition:opacity var(--dur-2) var(--ease-out),transform var(--dur-2) var(--ease-out);transition-delay:calc(var(--i,0) * 60ms + .1s)}
.is-in .bv-vars span{opacity:1;transform:none}
.bv-vars .v1{background:var(--teal-text);color:var(--white)}
.bv-vars .v2{box-shadow:var(--edge);color:var(--ink)}
.bv-vars .v3{background:var(--tangerine);color:var(--white)}
.bv-vars .v4{color:var(--teal-text);background:var(--teal-tint)}
.bv-vars .v5{color:var(--teal-text);text-decoration:underline;text-underline-offset:3px;padding-inline:var(--s-2)}

/* ---------- Next project (a .wk project card, wide) + contact strip ---------- */
.cs-strip{margin-top:var(--s-6)}

/* ---------- Reduced motion / Motion: off: bars drawn, the tile filled, no hint pulse ---------- */
html[data-motion="off"] .cs-fc-bar i,html[data-motion="off"] .cs-ms li.is-on::before{transition:none}
html[data-motion="off"] .cs-fc-bar i{transform:none}
html[data-motion="off"] .cs-ms li.is-on::before{opacity:1}
html[data-motion="off"] .is-hint .cs-demo-hot::after{animation:none}
@media(prefers-reduced-motion:reduce){
  html:not([data-motion="on"]) .cs-fc-bar i{transform:none;transition:none}
  html:not([data-motion="on"]) .cs-ms li.is-on::before{opacity:1;transition:none}
  html:not([data-motion="on"]) .is-hint .cs-demo-hot::after{animation:none}
  .cs-stage .sticker{opacity:1;animation:none}
  .cs-stage[data-tilt] [data-depth]{transform:none;transition:none}
  .dg .pop{opacity:1;transform:none;animation:none}
  .dg .draw{stroke-dashoffset:0;animation:none}
  .cs-zoom img{transition:none}
  .comp i,.scale-space i,.pills-set i{transform:none;opacity:1;transition:none}
  .bv-vars span{opacity:1;transform:none;transition:none}
  .cs-lb[open]{animation:none}
}

/* ---------- "If I ran it again today, with AI" note (client work was done by hand) ---------- */
.ai-note{margin-top:var(--s-7);padding:var(--s-5) var(--s-6);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest);max-width:78ch}
.ai-note-label{margin-bottom:var(--s-3)}  /* + .label */
.ai-note p{color:var(--body);line-height:1.6}
.ai-note ul{margin-top:var(--s-3);padding-left:var(--s-5);display:grid;gap:var(--s-2);color:var(--body);list-style:disc}
.ai-note-human{margin-top:var(--s-4);color:var(--ink)!important}

/* ---------- App Store screenshots: a scrolling strip ---------- */
.app-shot{position:relative;display:block;padding:0;border:0;background:none;border-radius:var(--r-inner);overflow:hidden;box-shadow:var(--shadow-overlay);cursor:zoom-in;transition:transform var(--dur-2) var(--ease)}
.app-shot img{display:block;width:100%;height:auto}
.app-shot:hover{transform:translateY(-4px)}
.app-strip{display:flex;gap:var(--s-4);overflow-x:auto;scroll-snap-type:x mandatory;padding:var(--s-2) var(--s-1) var(--s-4);-webkit-overflow-scrolling:touch}
.app-strip .app-shot{flex:0 0 clamp(150px,18vw,210px);scroll-snap-align:start}
@media(prefers-reduced-motion:reduce){.app-shot{transition:none}}

/* ---------- Vibe Code case studies (projects/momo-*.html): live demo in the hero stage ---------- */
.tool-links{display:flex;flex-wrap:wrap;gap:var(--s-2)}
.tool-stage{display:flex;flex-direction:column;justify-content:center;gap:var(--s-4);min-height:360px}
.tool-stage .sticker{position:absolute}
.tool-stage .pinboard{min-height:280px}
.tool-stage .specimen{background:var(--white);border-radius:var(--r-card);box-shadow:var(--shadow-rest);padding:var(--s-5)}
/* Color Generator demo: the plugin's real 10/20/40 ramps, ten per row like the plugin grid */
.cs-palette .swatches{grid-template-columns:repeat(10,minmax(0,1fr));min-height:0}
.cs-palette .swatches i{aspect-ratio:1}
/* two-list heads (By hand / With the tool, AI / Me) */
.cs-list-head{display:flex;flex-direction:column;gap:2px;margin-bottom:var(--s-4);font-size:var(--fs-title);font-weight:700;letter-spacing:var(--ls-title);line-height:var(--lh-snug)}
.cs-list-head small{font-size:var(--fs-cap);font-weight:500;color:var(--muted)}
/* real tool output (PinPoint "Copy for AI") */
.cs-pre{margin:0;font-family:var(--mono);font-size:var(--fs-cap);line-height:1.7;color:var(--ink);white-space:pre-wrap;overflow-wrap:anywhere}
/* browser frame in a figure: ring drawn outside so the bar and screenshot can't cover it */
.cs-fig .browser{box-shadow:var(--shadow-overlay)}
.cs-copy .tool-links{margin-top:var(--s-3)}
@media(max-width:899px){.tool-stage{min-height:0;padding-top:var(--s-9)}}


/* ---------- "Try it with your own AI" band (case studies) ---------- */
.try-band{background:var(--cream)}
.try-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-6);align-items:start}
@media(min-width:900px){.try-grid{grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:var(--s-8)}}
.try-copy{display:grid;gap:var(--s-4);justify-items:start}
.try-steps{display:grid;gap:var(--s-2);counter-reset:try}
.try-steps li{display:flex;align-items:center;gap:var(--s-3);counter-increment:try;font-weight:500}
.try-steps li::before{content:counter(try);display:grid;place-items:center;width:32px;height:32px;flex:0 0 auto;border-radius:var(--r-inner);background:var(--fill-soft);font-size:var(--fs-cap);font-weight:700}
.try-still{font-size:var(--fs-cap);color:var(--body);max-width:40ch}
.try-box{display:grid;gap:var(--s-3);justify-items:start;min-width:0;padding:var(--s-5);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest)}
.try-box .cs-pre{justify-self:stretch;max-height:360px;overflow:auto;padding:var(--s-4);border-radius:var(--r-inner);background:var(--cream);font-size:var(--fs-cap)}

/* ---------- Story case (sign-up flow case): short text blocks, the old path as a line, Old/New phone pairs ---------- */
.cs-story p{color:var(--body);max-width:52ch}
.cs-story p+p{margin-top:var(--s-3)}
.cs-story .h2+p{margin-top:var(--s-5)}
.cs-story p.stress{margin-top:var(--s-5);font-size:var(--fs-title);font-weight:500;line-height:var(--lh-body);color:var(--ink)}
.cs-story .list-emoji{display:flex;flex-direction:column;gap:var(--s-4);color:var(--body)}
.cs-story .list-emoji b{display:block;color:var(--ink);font-weight:700}
.cs-story-head{font-size:var(--fs-title);font-weight:700;letter-spacing:var(--ls-title);margin-bottom:var(--s-4)}

/* Hero: ten people walk the old path (illustration, not data). The markup is the end frame: five in the door, five faded
   under the path, two chips. js/case.js walks them there in a loop (transform + opacity only); no JS / reduced motion = end frame */
.cs-walk{display:flex;flex-direction:column;justify-content:center;align-self:stretch}
.cs-walk .cs-src{margin-top:var(--s-3)}
.dg .t-chip{font-size:17px;letter-spacing:-.01em}
.dg .tan{fill:var(--line-mid)}
.dg .pp{transform-box:fill-box;transform-origin:center}
.dg .pp circle,.dg .pp path{fill:var(--white);stroke:var(--ink);stroke-width:2;stroke-linejoin:round}
.dg .pp-done circle,.dg .pp-done path{fill:var(--sun)}  /* the end frame; js/case.js colours them as they reach the door */
.dg .pp-gone{opacity:.38}
.dg .door{transform-box:fill-box;transform-origin:50% 100%}

/* Flow map: old lane over new lane (>= 900px), two columns below. Nodes are focusable; a one-line note shows on hover,
   focus or tap (js/case.js writes it into .fd-tip). Draw order on .is-in: old lane, new lane, then the two moves */
.cs-flow{margin-top:clamp(3rem,6vw,4.5rem);padding-top:var(--s-5);border-top:1px solid var(--line-soft)}
.cs-flow-head{display:flex;flex-direction:column;gap:var(--s-2);margin-bottom:var(--s-5)}
.cs-flow-head p{color:var(--body);max-width:52ch}
.fd{position:relative;padding:clamp(1rem,3vw,2rem);border-radius:var(--r-card);background:var(--white);box-shadow:var(--shadow-rest)}
.fd-narrow{max-width:480px;margin-inline:auto}
@media(min-width:900px){.fd-narrow{display:none}}
@media(max-width:899px){.fd-wide{display:none}}
.dg .t-lab{font-size:13px;font-weight:500;letter-spacing:-.01em}
.dg .t-num{font-size:13px}
.dg .t-tag{font-size:11.5px;letter-spacing:0}
.dg .t-tag-teal{fill:var(--ink);font-weight:700}
.fd-narrow .t-lab{font-size:12px}
.fd-narrow .t-tag{font-size:10.5px}
.dg .tan-tint{fill:var(--cream)}
.dg .tan-hl{fill:var(--line-mid)}
.dg .ln-teal{stroke:var(--ink);stroke-width:2.5}
.fd-node{cursor:default;outline-offset:6px}
.fd-node:focus:not(:focus-visible){outline:none}  /* tapped or clicked: the note is the feedback, no browser ring */
.fd-node .fd-sq{transition:fill var(--dur-1) var(--ease)}
.fd-node:is(:hover,:focus-visible) .fd-sq{fill:var(--sun)}
.fd-tip{position:absolute;z-index:3;max-width:min(280px,calc(100% - var(--s-4)));padding:var(--s-2) var(--s-3);border-radius:var(--r-inner);background:var(--ink);color:var(--white);font-size:var(--fs-cap);font-weight:500;line-height:var(--lh-snug);box-shadow:var(--shadow-overlay);pointer-events:none}
.fd-tip::after{content:"";position:absolute;left:var(--cx,50%);bottom:-5px;width:10px;height:10px;margin-left:-5px;background:var(--ink);transform:rotate(45deg)}
.cs-flow-take{margin-top:var(--s-4);font-size:var(--fs-body);font-weight:500;color:var(--ink);max-width:60ch}

/* The journey: one stop per old step; the ink line draws down as each stop scrolls in, the node fills sun */
.cs-journey{--node:44px;--gap:clamp(3.5rem,7vw,5.5rem);display:flex;flex-direction:column;gap:var(--gap)}
.cs-stop{position:relative;display:grid;grid-template-columns:var(--node) minmax(0,1fr);column-gap:var(--s-5);min-width:0}
.cs-stop::before,.cs-stop::after{content:"";position:absolute;left:calc(var(--node) / 2 - 1px);top:calc(var(--node) + var(--s-3));bottom:calc(var(--gap) * -1 + var(--s-3));width:var(--stroke)}
.cs-stop::after{background:repeating-linear-gradient(var(--line-mid) 0 6px,transparent 6px 12px)}
.cs-stop::before{z-index:1;background:var(--line-mid);transform:scaleY(0);transform-origin:top;transition:transform var(--dur-3) var(--ease-out) .1s}
.cs-stop.is-in::before{transform:none}
.cs-stop:last-child::before,.cs-stop:last-child::after{display:none}
.cs-stop>.nsq{--nsq:var(--node);transition:background var(--dur-2) var(--ease) .2s}
.cs-stop.is-in>.nsq{--nsq-bg:var(--sun)}
.cs-stop-body{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-5);align-items:start;min-width:0}
@media(min-width:900px){.cs-stop-body{grid-template-columns:minmax(0,4fr) minmax(0,7fr);gap:var(--s-7)}}
.cs-stop-copy{display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-3);min-width:0;padding-top:var(--s-2)}
.cs-stop h3{font-size:var(--fs-sub);font-weight:700;letter-spacing:var(--ls-display);line-height:var(--lh-tight)}
.cs-drop{font-size:var(--fs-cap);padding:var(--s-1) var(--s-3);--rot:-3deg;margin-bottom:var(--s-1)}  /* + .sticker */
.cs-fix{display:grid;gap:var(--s-3);margin-top:var(--s-2);max-width:40ch}
.cs-fix span{display:grid;grid-template-columns:3.2em minmax(0,1fr);gap:var(--s-2);align-items:baseline;color:var(--body)}
.cs-fix span+span{color:var(--ink);font-weight:500}
.cs-fix small{font-size:var(--fs-cap);font-weight:700;color:var(--muted)}
.cs-fix span+span small{color:var(--ink)}

/* Old | New pair on a tinted stage. Under 700px: one phone + an Old/New toggle (case.js sets data-show) */
.cs-pair{display:flex;flex-direction:column;align-items:center;gap:var(--s-4);padding-block:clamp(1.5rem,4vw,2.5rem)}
.cs-pair-phones{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:var(--s-4);width:100%;max-width:560px}
.cs-ph{display:flex;flex-direction:column;align-items:center;gap:var(--s-3);min-width:0}
.cs-ph .cs-device{width:100%;max-width:236px;transform:rotate(-1.5deg)}
.cs-ph-new .cs-device{transform:rotate(1.5deg)}
.cs-ph .cs-device img{aspect-ratio:480/1039;background:var(--white)}
.cs-ph-new .label{background:var(--sun)}
.cs-pair-arrow{width:40px;height:40px;padding:10px;border-radius:var(--pill);background:var(--white);box-shadow:var(--shadow-rest);fill:none;stroke:var(--ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.cs-pair-seg{display:none}
@media(max-width:699px){
  .cs-journey{--node:32px}
  .cs-stop{column-gap:var(--s-4)}
  .cs-pair-seg{display:inline-flex}
  .cs-pair-phones{grid-template-columns:minmax(0,1fr);max-width:236px}
  .cs-pair-arrow{display:none}
  .cs-ph{grid-area:1 / 1;transition:opacity var(--dur-1) var(--ease),transform var(--dur-1) var(--ease),visibility 0s}
  .cs-ph .label{display:none}
  .cs-pair[data-show="old"] .cs-ph-new,.cs-pair[data-show="new"] .cs-ph-old{opacity:0;visibility:hidden;transform:scale(.97);transition:opacity var(--dur-1) var(--ease),transform var(--dur-1) var(--ease),visibility 0s linear var(--dur-1)}
}

/* Approval rounds: .flow with three steps */
@media(min-width:720px){.flow-3{grid-template-columns:repeat(3,minmax(0,1fr))}}
.flow-3 b{font-size:var(--fs-title);letter-spacing:var(--ls-title)}

@media(prefers-reduced-motion:reduce){
  .cs-stop::before{transform:none;transition:none}
  .cs-stop>.nsq,.cs-ph,.fd-node .fd-sq{transition:none}
}

/* How the project ran: five number squares in a row (a column on phones), joined by a line; the last one sun */
.cs-run{margin-top:clamp(3rem,6vw,4.5rem);padding-top:var(--s-5);border-top:1px solid var(--line-soft)}
.cs-steps{--nsq:36px;--step-gap:var(--s-3);display:grid;grid-template-columns:minmax(0,1fr);gap:var(--step-gap)}
.cs-steps li{position:relative;display:flex;align-items:center;gap:var(--s-3);min-width:0;font-weight:700;letter-spacing:-.01em;line-height:1.3}
.cs-steps li:last-child .nsq{--nsq-bg:var(--sun)}
.cs-steps li:not(:last-child)::after{content:"";position:absolute;left:calc(var(--nsq) / 2 - 1px);top:calc(var(--nsq) + 2px);width:var(--stroke);height:calc(var(--step-gap) - 4px);background:var(--line-mid)}
@media(min-width:760px){
  .cs-steps{--step-gap:var(--s-5);grid-template-columns:repeat(5,minmax(0,1fr))}
  .cs-steps li{flex-direction:column;align-items:flex-start}
  .cs-steps li:not(:last-child)::after{left:calc(var(--nsq) + var(--s-2));right:calc(var(--s-2) - var(--step-gap));top:calc(var(--nsq) / 2 - 1px);width:auto;height:var(--stroke)}
}

/* ---------- Wide illustration (who the product is for) ---------- */
.cs-people img{display:block;width:100%;height:auto;border-radius:var(--r-card)}
@media(max-width:599px){.cs-people img{aspect-ratio:4/3;object-fit:cover}}

/* ---------- Feature cards: the skills card anatomy (.sk + .sk-art tile in the case hue), one word + one line ---------- */
.cs-feats{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--s-4)}
@media(min-width:720px){.cs-feats{grid-template-columns:repeat(3,minmax(0,1fr))}}
.cs-feat{gap:var(--s-1)}  /* + .case-x on the card: its .sk-art.mesh tile takes the case hue (--wk-bg) */
.cs-feat .sk-art{position:relative;height:clamp(180px,22vw,240px);overflow:hidden;align-items:end}
.cs-feat .sk-art img{width:84%;height:auto;border-radius:var(--r-inner);box-shadow:var(--shadow-overlay);transform:translateY(12%) rotate(-4deg)}
.cs-feat .sk-art .cs-feat-card{width:78%;align-self:center;transform:rotate(-4deg)}

/* Wireframe | Final pair: the screens are 9:16 (the sign-up case's are taller) */
.cs-pair-tall .cs-ph .cs-device img{aspect-ratio:9/16}
.cs-move .cs-pair{min-width:0}

/* A flat artifact (spec sheet, icon set) on a tinted bed */
.cs-bed{padding:clamp(1rem,3vw,2rem)}
.cs-bed img{display:block;width:100%;height:auto;border-radius:var(--r-inner)}
.cs-bed .cs-zoom{border-radius:var(--r-inner);box-shadow:var(--shadow-rest)}

/* Flow at a glance: a few wireframes in a row on a tinted bed (scrolls sideways under 900px) */
.cs-flowrow{padding:clamp(1rem,3vw,2rem)}
.cs-flowrow ol{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(140px,42%);gap:var(--s-4);overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:var(--s-2);-webkit-overflow-scrolling:touch}
@media(min-width:900px){.cs-flowrow ol{grid-auto-flow:row;grid-template-columns:repeat(5,minmax(0,1fr));overflow:visible;padding-bottom:0}}
.cs-flowrow li{display:flex;flex-direction:column;gap:var(--s-3);min-width:0;scroll-snap-align:start}
.cs-flowrow img{display:block;width:100%;height:auto;border-radius:var(--r-inner);box-shadow:var(--shadow-rest);background:var(--white)}
.cs-flowrow span{display:flex;align-items:center;gap:var(--s-2);font-size:var(--fs-cap);font-weight:500;color:var(--ink)}
.cs-flowrow .nsq{--nsq:28px;--nsq-bg:var(--white)}
.cs-flowrow li:last-child .nsq{--nsq-bg:var(--sun)}

/* ===== Case lessons: 4 beats as 2x2 (cs-cols modifier) ===== */
@media(min-width:720px){.cs-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
.cs-cols-2 p{max-width:48ch}

/* ===== Teaching case page: hero composition + seven flat vignettes on tinted beds =====
   Prefix tc-. Tokens only; one CSS loop at most per beat (.tc-loop, var(--loop)); one-shots (.tc-once) run on .cs-stop.is-in.
   Base markup = the composed end state, so reduced motion / motion off / no JS show the finished frame. */
.tc-cover{display:flex;flex-direction:column;gap:var(--s-4)}
.tc-cover-art{position:relative;display:grid;padding-bottom:clamp(2rem,6vw,3rem)}
.tc-code{display:block;width:86%;border-radius:var(--r-inner);overflow:hidden;background:var(--white);box-shadow:var(--shadow-overlay);rotate:-4deg;margin-top:var(--s-3)}
.tc-code img{display:block;width:100%;height:auto}
.tc-cover .tc-cover-phone{position:absolute;right:0;bottom:0;width:28%;max-width:160px;rotate:4deg;z-index:2}
.tc-cover-cap{margin-top:0;color:var(--ink);max-width:none}

/* journey copy */
.tc-journey .cs-stop p{color:var(--body);max-width:40ch}
.tc-journey .cs-stop p b{color:var(--ink);font-weight:700}
.tc-journey .cs-stop h3{max-width:16ch}

/* vignette bed */
.tc-vig{display:grid;grid-template-columns:minmax(0,1fr);place-items:center;align-content:center;justify-items:center;min-height:clamp(220px,26vw,300px);padding:clamp(1rem,3vw,2rem)}
.tc-vig>*{max-width:100%}
@media(min-width:900px){.tc-vig{--tc-w:180px;--tc-m:112px}}
.tc-chip{display:inline-flex;align-items:center;min-height:28px;padding:0 var(--s-3);border-radius:var(--pill);background:var(--white);color:var(--ink);font-size:var(--fs-cap);font-weight:500;white-space:nowrap;box-shadow:var(--shadow-rest)}
.tc-chip-ink{background:var(--ink);color:var(--white)}
/* one generic mini screen: title bar, two lines, a block, a button in the case hue */
.tc-screen{position:relative;display:flex;flex-direction:column;gap:var(--s-2);width:var(--tc-w,150px);max-width:100%;padding:var(--s-3);border-radius:var(--r-inner);background:var(--white);box-shadow:var(--shadow-rest)}
.tc-bar,.tc-ln,.tc-box,.tc-btn{display:block;border-radius:var(--pill)}
.tc-bar{width:42%;height:8px;background:var(--ink)}
.tc-ln{width:100%;height:6px;background:var(--line-mid)}
.tc-ln-short{width:64%}
.tc-box{height:44px;border-radius:var(--r-inner);background:var(--cream)}
.tc-btn{position:relative;width:58%;height:20px;background:var(--wk-bg,var(--sun))}
.tc-mini{position:relative;display:flex;flex-direction:column;gap:var(--s-1);width:var(--tc-m,96px);max-width:100%;padding:var(--s-2);border-radius:var(--r-inner);background:var(--white);box-shadow:var(--shadow-rest)}
.tc-mini .tc-bar{height:5px}.tc-mini .tc-ln{height:4px}.tc-mini .tc-box{height:22px;border-radius:6px}.tc-mini .tc-btn{height:10px}
.tc-tick{display:grid;place-items:center;width:18px;height:18px;border-radius:var(--pill);background:var(--sun);flex:none}
.tc-tick::after{content:"";width:5px;height:8px;margin-top:-2px;border:solid var(--ink);border-width:0 2px 2px 0;rotate:45deg}

/* 01 terminal + the starter guide */
.tc-term{display:flex;flex-direction:column;gap:var(--s-2);width:min(100%,360px);padding:var(--s-4);border-radius:var(--r-inner);background:var(--ink);color:var(--white);font-family:var(--mono);font-size:var(--fs-cap);box-shadow:var(--shadow-overlay)}
.tc-term-bar{display:flex;gap:6px;margin-bottom:var(--s-2)}
.tc-term-bar i{width:8px;height:8px;border-radius:var(--pill);background:var(--muted)}
.tc-term-line{display:flex;align-items:center;gap:var(--s-2);min-height:1.4em}
.tc-term-dim{color:var(--muted)}
.tc-term b{color:var(--sun)}
.tc-caret{display:inline-block;width:8px;height:1em;background:var(--sun);animation:tc-blink 1s steps(2) infinite}
/* each .tc-loop beat is a loop-budget owner (data-pause, js/site.js): paused off screen, under the cap and with Motion: off */
.tc-loop.is-paused :is(*,*::before,*::after){animation-play-state:paused}
@keyframes tc-blink{to{opacity:0}}
.tc-guide{display:flex;flex-direction:column;gap:var(--s-2);width:min(100%,200px);padding:var(--s-3) var(--s-4);border-radius:var(--r-inner);background:var(--white);box-shadow:var(--shadow-overlay);margin-top:calc(var(--s-5) * -1);translate:min(80px,18%) 0;rotate:2deg}
.tc-guide-head{font-size:var(--fs-cap);font-weight:700;color:var(--ink)}
.tc-row{display:flex;align-items:center;gap:var(--s-2);font-size:var(--fs-cap);font-weight:500;color:var(--ink)}

/* 02 a pin on this screen + the link chip */
.tc-pin-wrap{display:flex;flex-direction:column;align-items:center;gap:var(--s-3)}
.tc-pin{position:absolute;right:-6px;top:50%;width:12px;height:12px;margin-top:-6px;border-radius:var(--pill);background:var(--ink);box-shadow:0 0 0 3px var(--white),0 0 0 6px var(--sun)}
.tc-pin::after{content:"";position:absolute;inset:-10px;border-radius:var(--pill);border:2px solid var(--ink);opacity:0;animation:tc-ring 2s var(--ease-out) infinite}
@keyframes tc-ring{0%{scale:.4;opacity:.9}70%{scale:1;opacity:0}100%{scale:1;opacity:0}}
.tc-chip-say{font-weight:500}

/* 03 messy → clean */
.tc-mess{display:flex;align-items:center;gap:var(--s-4);width:100%;justify-content:center}
.tc-mess .tc-screen{flex:1 1 0;min-width:0}
.tc-arrow{flex:none;width:40px;height:40px;padding:10px;border-radius:var(--pill);background:var(--white);box-shadow:var(--shadow-rest);fill:none;stroke:var(--ink);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.tc-screen-messy{rotate:-3deg;animation:tc-wobble var(--loop) var(--ease-inout) infinite}
.tc-screen-messy .tc-bar{width:70%;rotate:-6deg;transform-origin:left}
.tc-screen-messy .tc-ln{translate:14px 0}
.tc-screen-messy .tc-ln-short{translate:-6px 0;rotate:3deg}
.tc-screen-messy .tc-box{rotate:2deg;background:var(--sun)}
.tc-screen-messy .tc-btn{width:80%;background:var(--muted)}
.tc-btn-stray{position:absolute;right:-16px;bottom:-8px;width:44%!important;rotate:10deg;background:var(--wk-bg,var(--sun))!important}
@keyframes tc-wobble{50%{rotate:-1deg}}

/* 04 push → server → a real phone */
.tc-ship{display:flex;align-items:center;gap:var(--s-2);width:100%;justify-content:center}
.tc-wire{position:relative;flex:1 1 24px;min-width:16px;max-width:96px;height:2px;border-radius:var(--pill);background:var(--line-mid)}
.tc-dot{position:absolute;left:100%;top:50%;width:10px;height:10px;translate:-50% -50%;border-radius:var(--pill);background:var(--ink);animation:tc-travel var(--loop) var(--ease-inout) infinite}
.tc-dot-2{animation-delay:calc(var(--loop) / 2)}
@keyframes tc-travel{0%{left:0;opacity:0}6%{opacity:1}44%{left:100%;opacity:1}50%,100%{left:100%;opacity:0}}
.tc-phone{flex:none;width:clamp(84px,26%,110px);padding:0;border:5px solid var(--ink);border-radius:var(--r-inner);background:var(--ink);box-shadow:var(--shadow-overlay);overflow:hidden}
.tc-phone .tc-screen{width:100%;border-radius:8px;box-shadow:none;padding:var(--s-2)}
.tc-phone .tc-box{height:30px}

/* 05 the system sheet, applied to three screens */
.tc-sys{display:flex;align-items:center;gap:var(--s-5);width:100%;justify-content:center}
.tc-sheet{display:flex;flex-direction:column;gap:var(--s-3);width:min(var(--tc-w,170px),56%);padding:var(--s-4);border-radius:var(--r-inner);background:var(--white);box-shadow:var(--shadow-overlay)}
.tc-sheet-head{font-size:var(--fs-cap);font-weight:700;color:var(--ink)}
.tc-swatches{display:flex;gap:6px}
.tc-swatches i{width:18px;height:18px;border-radius:var(--pill);background:var(--ink)}
.tc-swatches i:nth-child(2){background:var(--sun)}.tc-swatches i:nth-child(3){background:var(--wk-bg,var(--sun))}.tc-swatches i:nth-child(4){background:var(--cream);box-shadow:var(--edge)}.tc-swatches i:nth-child(5){background:var(--muted)}
.tc-type{display:flex;flex-direction:column;gap:5px}
.tc-type i{display:block;height:10px;width:78%;border-radius:var(--pill);background:var(--ink)}
.tc-type i:nth-child(2){height:7px;width:58%;background:var(--body)}.tc-type i:nth-child(3){height:5px;width:44%;background:var(--muted)}
.tc-parts{display:flex;align-items:center;gap:var(--s-3)}
.tc-part-btn{display:block;width:56px;height:20px;border-radius:var(--pill);background:var(--wk-bg,var(--sun))}
.tc-part-toggle{position:relative;display:block;width:34px;height:20px;border-radius:var(--pill);background:var(--ink)}
.tc-part-toggle::after{content:"";position:absolute;top:3px;right:3px;width:14px;height:14px;border-radius:var(--pill);background:var(--white)}
.tc-minis{display:flex;flex-direction:column;gap:var(--s-2);width:min(var(--tc-m,96px),34%)}
.tc-minis .tc-tick{position:absolute;top:-6px;right:-6px}
.tc-tick-pop{animation:tc-tickpop var(--loop) var(--ease-out) infinite;animation-delay:calc(var(--i,0) * .5s)}
@keyframes tc-tickpop{0%{scale:0}12%{scale:1.15}18%{scale:1}78%{scale:1}88%,100%{scale:0}}

/* 06 a component-library window: list on the left, the component on the right, the tag */
.tc-sb{position:relative;display:grid;grid-template-columns:110px minmax(0,1fr);width:min(100%,440px);min-height:200px;border-radius:var(--r-inner);background:var(--white);box-shadow:var(--shadow-overlay);overflow:hidden}
.tc-sb-side{display:flex;flex-direction:column;gap:2px;padding:var(--s-3);background:var(--cream)}
.tc-sb-item{display:block;padding:var(--s-1) var(--s-3);border-radius:var(--pill);font-size:var(--fs-cap);font-weight:500;color:var(--body)}
.tc-sb-item.is-on{background:var(--sun);color:var(--ink);font-weight:700}
.tc-sb-canvas{position:relative;display:grid;place-items:center;padding:var(--s-4)}
.tc-sb-comp{display:block;width:120px;height:40px;border-radius:var(--pill);background:var(--wk-bg,var(--sun));box-shadow:var(--shadow-rest)}
.tc-sb .tc-sb-tag{top:auto;right:var(--s-3);bottom:var(--s-3);--rot:-3deg;animation:none;opacity:0;scale:.6;transition:opacity var(--dur-2) var(--ease-out) .4s,scale var(--dur-2) var(--ease-spring) .4s}
.cs-stop.is-in .tc-sb-tag{opacity:1;scale:1}
@media(max-width:480px){.tc-sb{grid-template-columns:84px minmax(0,1fr);min-height:224px}.tc-sb-side{padding:var(--s-2)}.tc-sb-item{padding-inline:var(--s-2)}.tc-sb-comp{width:88px;height:34px}}

/* 07 one template, three pages linked to it */
.tc-tpl{display:grid;grid-template-columns:minmax(0,1.5fr) 40px minmax(0,1fr);align-items:center;width:100%;max-width:480px}
.tc-tpl-main{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-2)}
.tc-tpl-lab{align-self:flex-start}
.tc-screen-wide{width:100%}
.tc-links{display:block;width:100%;height:188px;fill:none;stroke:var(--ink);stroke-width:2.5;stroke-linecap:round;overflow:visible}
.tc-links path{stroke-dasharray:1;stroke-dashoffset:1;transition:stroke-dashoffset var(--dur-3) var(--ease-out) calc(.3s + var(--i,0) * .15s)}
.cs-stop.is-in .tc-links path{stroke-dashoffset:0}
.tc-tpl-pages{display:flex;flex-direction:column;gap:var(--s-2)}
.tc-tpl-pages .tc-mini{width:100%}

/* result card */
.tc-results .cs-list{align-self:center}
.tc-results .cs-story .stress{margin-top:var(--s-5)}

/* motion off / reduced: loops stop on the composed frame, one-shots are already in */
html[data-motion="off"] .tc-loop,html[data-motion="off"] .tc-loop *,html[data-motion="off"] .tc-loop ::after{animation:none}
html[data-motion="off"] .tc-links path{stroke-dashoffset:0;transition:none}
html[data-motion="off"] .tc-sb-tag{opacity:1;scale:1;transition:none}
@media(prefers-reduced-motion:reduce){
  html:not([data-motion="on"]) .tc-loop,html:not([data-motion="on"]) .tc-loop *,html:not([data-motion="on"]) .tc-loop ::after{animation:none}
  html:not([data-motion="on"]) .tc-links path{stroke-dashoffset:0;transition:none}
  html:not([data-motion="on"]) .tc-sb-tag{opacity:1;scale:1;transition:none}
}
