/* The Studio (AI Creative Systems) — fixed template, V0.1 62:1925. Page coords below are
   the 1280 frame minus the 112px nav. Scroll path: assets/js/modules/studio-path.js. */
.studio {
  --studio-col-gap: 220px;          /* two 482 columns: text at x48 or x750, path between */
  --stat-orange: #ff6313;           /* V0.1 */
  --stat-purple: #8e4ef7;           /* V0.1 #8743f6, lifted 6% toward white: black label 4.16 → 4.58:1 (AA) */
  --stat-sky: #03b1ff;              /* V0.1 */
  --stat-teal: #01cca0;             /* V0.1 */
  --studio-raised: #1c1c1c;         /* V0.1 app card */
  position: relative;
  overflow: clip;
}

/* ---------- Ground: faint road map (V0.1 "Roads Alt 1", 18% #949494) ---------- */
.studio__roads {
  position: absolute; inset: 0; overflow: hidden;
  background: url("../../images/studio-roads.svg") 50% 0 / max(1280px, 100%) auto repeat-y;
  pointer-events: none;
}
/* Traffic: faint dots driving the roads, laid exactly over the road artwork's first tile
   (studio-traffic.js). Small and dim on purpose: the one bright light is the route's. */
.studio__traffic { position: absolute; top: 0; left: 50%; width: max(1280px, 100%); max-width: none; /* base.css caps svg at 100%, which shrank it below 1280 */ height: auto; translate: -50% 0; overflow: visible; }
.studio__traffic circle { fill: #d9d9d9; opacity: 0; transition: opacity 1200ms var(--ease-out); } /* each fades in on its own delay (studio-traffic.js) */
.studio__traffic.is-on circle { opacity: 0.27; } /* Nick #6: 0.6 × the old 0.45 */
@media (prefers-reduced-motion: reduce) { .studio__traffic { display: none; } }

/* ---------- The path: sized and drawn by studio-path.js ---------- */
.studio__path { position: absolute; inset: 0; pointer-events: none; }
.studio__path-clip { position: absolute; inset: 0; overflow: hidden; will-change: transform; }
/* The line dissolves over its last 120px instead of stopping square above the stats
   (review A1). --end is set by studio-path.js; the mask sits on the path's own frame. */
.studio__path { -webkit-mask-image: linear-gradient(to bottom, #000 calc(var(--end, 100%) - 120px), transparent var(--end, 100%)); mask-image: linear-gradient(to bottom, #000 calc(var(--end, 100%) - 120px), transparent var(--end, 100%)); }
.studio__path-svg { position: absolute; top: 0; left: 0; overflow: visible; will-change: transform; }
.studio__path-line { fill: none; stroke-width: 8; stroke-linejoin: round; }
.no-js .studio__path { display: none; }

/* The leading tip of the line: a small light riding the draw edge. studio-path.js sets
   its opacity: it fades in as the line starts and out as the line ends above the stats. */
.studio__tip {
  position: absolute; top: -7px; left: -7px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--color-white);
  box-shadow: 0 0 12px 4px rgb(255 255 255 / 0.45), 0 0 34px 10px rgb(67 111 255 / 0.45);
  opacity: 0;
  will-change: transform;
}

/* ---------- Intro ---------- */
.studio-intro { position: relative; padding-top: 113px; /* = page-hero: eyebrows line up across pages (review S2) */ padding-bottom: var(--space-120); }
.studio-intro__eyebrow { margin-bottom: 30px; }
.studio-intro__headline { max-width: 640px; font-weight: 300; /* V0.1: Ekstra Light 86 */ }

.studio .tag--eyebrow { background: var(--surface-page); border-width: 1.5px; }

/* ---------- Modules: one per viewport (Nick 07-16), zigzag around the path ---------- */
.studio-module { position: relative; min-height: 100svh; display: grid; align-content: center; padding-block: var(--space-80); }
.studio-module__inner { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--studio-col-gap); align-items: start; }
.studio-module__text, .studio-module__visual { grid-row: 1; }
.studio-module--left .studio-module__text, .studio-module--right .studio-module__visual { grid-column: 1; }
.studio-module--right .studio-module__text, .studio-module--left .studio-module__visual { grid-column: 2; }
.studio-module__text { position: relative; z-index: 1; }
.studio-module__heading sup { font-size: 0.5em; line-height: 0; vertical-align: 0.8em; }
.studio-module__body { margin-top: var(--space-24); max-width: 480px; }
.studio-module--right .studio-module__body { max-width: 424px; }

/* ---------- App objects: abstract on purpose (DESIGN.md rule 8) ---------- */
.studio-visual--card, .studio-visual--icons { position: relative; min-height: 520px; } /* the 09-28 card is taller */
.studio-visual--icons { min-height: 150px; }

/* Icon tiles: a row of three on the page ground. The grey glow band behind them is gone
   (Nick 09-29); the side tiles still fade out at their outer edges (Nick 09-28). */
.studio-dock {
  position: absolute; top: 55px; left: 262px;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  width: 250px; height: 95px;
}
.studio-dock__tile { position: relative; flex: none; width: 60px; height: 60px; border-radius: 15px; }
.studio-dock__tile--a, .studio-dock__tile--b { background: #f4f4f4; /* V0.1-style light app tile */ display: grid; place-content: center; }
/* Each side tile fades out to fully transparent at its outer edge (Nick 09-28, 11:56). */
.studio-dock__tile--a { -webkit-mask-image: linear-gradient(90deg, transparent, #000 60%); mask-image: linear-gradient(90deg, transparent, #000 60%); }
.studio-dock__tile--b { -webkit-mask-image: linear-gradient(270deg, transparent, #000 60%); mask-image: linear-gradient(270deg, transparent, #000 60%); }
.studio-dock__tile--a svg { width: 34px; height: 34px; }
.studio-dock__tile--b svg { width: 24px; height: 36px; }
.studio-dock__tile--main { overflow: hidden; background: linear-gradient(160deg, #262626, #0d0d0d); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.08); } /* V0.1 */

/* The eclipse tile (Nick 09-28): a ring of light around a black moon. Behind it, a soft
   corona in the ring's colours turns and breathes, subtly; now and then Baily's beads
   flicker on the upper-right limb. Colours are the reference icon's, not tokens. */
.studio-eclipse > i { position: absolute; left: 50%; top: 50%; border-radius: 50%; translate: -50% -50%; }
.studio-eclipse {
  --eclipse: conic-gradient(from 20deg, #ffd9a0, #ffb07a, #ff8fcf 30%, #c79bff 50%, #8fb0ff 62%, #b8e4ff 72%, #ffffff 82%, #ffd9a0); /* V0.1 */
}
.studio-eclipse__corona {
  width: 54px; height: 54px;
  background: var(--eclipse);
  -webkit-mask: radial-gradient(closest-side, transparent 58%, #000 66%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 58%, #000 66%, transparent 100%);
  filter: blur(3px);
  opacity: 0.75;
  animation: studio-corona 24s linear infinite, studio-corona-breathe 7s ease-in-out infinite alternate;
}
.studio-eclipse__ring {
  width: 38px; height: 38px;
  background: var(--eclipse);
  -webkit-mask: radial-gradient(closest-side, transparent 86%, #000 89%, #000 97%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 86%, #000 89%, #000 97%, transparent 100%);
}
.studio-eclipse__moon { width: 33px; height: 33px; background: #000; box-shadow: 0 0 0 0.5px rgb(255 255 255 / 0.6), 0 0 2px 0.5px rgb(255 255 255 / 0.35); }
/* Baily's beads: points of sunlight through the moon's valleys, just outside its limb. */
.studio-eclipse__bead {
  --a: 38deg;
  width: 2px; height: 2px; background: #fff;
  box-shadow: 0 0 2px 0.5px rgb(255 255 255 / 0.9), 0 0 6px 1.5px rgb(255 230 190 / 0.5);
  transform: rotate(var(--a)) translateY(-17.5px);
  opacity: 0;
  animation: studio-bead 9s ease-in-out infinite;
}
.studio-eclipse__bead:nth-child(5) { --a: 52deg; animation-delay: 0.25s; }
.studio-eclipse__bead:nth-child(6) { --a: 63deg; animation-delay: 0.5s; }
@keyframes studio-corona { to { rotate: 1turn; } }
@keyframes studio-corona-breathe { from { scale: 0.96; opacity: 0.55; } to { scale: 1.04; opacity: 0.8; } }
@keyframes studio-bead { 0%, 62%, 82%, 100% { opacity: 0; } 68%, 74% { opacity: 1; } }

.studio-card {
  position: absolute; top: 211px; left: 38px;
  width: 440px; padding: 20px 22px 24px; /* 396 → 440: the four chips sit on one row (Nick 09-28 mock) */
  border-radius: var(--radius-md);
  background: var(--studio-raised);
  font-family: var(--font-body); color: var(--ink-primary);
}
.studio-card__head { display: flex; align-items: center; gap: 12px; }
.studio-card__avatar { flex: none; display: grid; place-content: center; width: 42px; height: 42px; border-radius: 50%; background: var(--stat-purple); color: var(--color-black); font-size: 16px; font-weight: 500; font-style: normal; } /* a monogram, not a photo (Nick 11-05) */
.studio-card__who { display: grid; gap: 2px; flex: 1; }
.studio-card__who b { font-size: 16px; font-weight: 500; letter-spacing: -0.01em; }
.studio-card__who small { font-size: 11px; color: var(--ink-muted); }
.studio-card__gear { display: grid; place-content: center; width: 42px; height: 42px; border-radius: 50%; background: #2a2a2a; }
.studio-card__gear svg { width: 20px; height: 20px; fill: none; stroke: var(--ink-muted); stroke-width: 1.4; }
/* Body after Nick's 09-28 mock: a headline with an arrow, a rule, then source chips. */
.studio-card__news { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.studio-card__title { display: grid; gap: 4px; flex: 1; }
.studio-card__title b { font-size: 22px; font-weight: 500; line-height: 1.1; letter-spacing: -0.02em; }
.studio-card__title small { font-size: 11px; color: var(--ink-muted); }
.studio-card__go { display: grid; place-content: center; flex: none; width: 42px; height: 42px; border-radius: 50%; background: #2a2a2a; }
.studio-card__go svg { width: 18px; height: 18px; fill: none; stroke: var(--ink-primary); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.studio-card__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px; padding-top: 16px; border-top: 1px solid rgb(255 255 255 / 0.1); list-style: none; }
.studio-card__chips li { display: flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px 0 8px; border-radius: var(--radius-pill); background: #262626; font-size: 11px; color: var(--ink-muted); white-space: nowrap; }
.studio-card__chips svg { width: 13px; height: 13px; margin-right: 2px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* App pills (V0.1: 87 tall, 71px orb, 43% opacity, rows 69px apart). STATIC above 767px
   until the animation is art-directed (Tucker, 2026-09-21); a finished animation replaces the
   cloud via the module's "Image, video, GIF or Lottie" visual. The earlier drift/highlight
   keyframes are in git history (231b8f0) if a coded version is wanted instead. Phones get
   the ticker (below). */
.studio-pills { display: grid; gap: 16px; margin-top: 59px; margin-left: -114px; margin-right: calc(-1 * var(--gutter) - 120px); }
.studio-pills__row { display: flex; gap: 16px; margin-left: calc(var(--r) * 69px); }
.studio-pill {
  --orb: var(--color-blue);
  display: flex; align-items: center; gap: 10px; flex: none;
  height: 87px; padding: 8px 26px 8px 8px;
  border: 1px solid #141414; border-radius: var(--radius-pill); /* V0.1 */
  background: var(--color-black);
  box-shadow: inset 0 0 10px rgb(255 255 255 / 0.06);
  color: var(--color-gray-200);
  opacity: 0.43;
}
/* Orb colour per pill: studio.php picks it from the pill's place in its row. */
.studio-pill--teal { --orb: var(--stat-teal); }
.studio-pill--purple { --orb: var(--stat-purple); }
.studio-pill--chartreuse { --orb: var(--color-chartreuse); }
/* The ticker's copies (studio.php) only run on phones. */
@media (min-width: 768px) { .studio-pill--copy { display: none; } }
.studio-pill__orb {
  flex: none; width: 71px; height: 71px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, var(--orb) 0%, color-mix(in srgb, var(--orb) 45%, #1a1a1a) 45%, #1a1a1a 78%);
}
.studio-pill__label { white-space: nowrap; }
@keyframes studio-float { from { transform: translateY(-5px); } to { transform: translateY(5px); } }

/* Gentle life in the card stack. */
.studio-card { animation: studio-float 7s ease-in-out infinite alternate; }

/* ---------- Stat bars: full-bleed to the right, length follows the value ---------- */
.studio-stats { position: relative; z-index: 1; padding-top: var(--space-160); }
.studio-stat {
  --min: 22.66vw; --range: 61.56vw;  /* V0.1: 3% → 290px, 47% → 1078px at 1280 */
  width: calc(var(--min) + var(--range) * var(--r));
  min-height: 126px; margin-left: auto; /* min: a long label wraps and the bar grows */
  padding: 6px 24px 12px 56px;
  color: var(--color-black);
  will-change: transform;
}
.studio-stat__value { line-height: 1; }
.studio-stat__label { margin-top: 10px; }
.studio-stat--orange { background: var(--stat-orange); }
.studio-stat--purple { background: var(--stat-purple); }
.studio-stat--sky { background: var(--stat-sky); }
.studio-stat--teal { background: var(--stat-teal); }

/* ---------- Tablet and mobile: single column, the path runs down the right edge ---------- */
@media (max-width: 1023px) {
  .studio-module__inner { grid-template-columns: minmax(0, 1fr); row-gap: var(--space-48); padding-right: calc(var(--gutter) + 28px); }
  .studio-module__text, .studio-module__visual { grid-column: 1 !important; grid-row: auto; }
  .studio-intro { padding-right: calc(var(--gutter) + 28px); }
  .studio-dock { left: 0; top: 0; }
  .studio-card { left: 0; top: 125px; }
  .studio-visual--card { min-height: 380px; }
  .studio-pills { margin: 0 calc(-1 * var(--gutter) - 56px) 0 0; }
  .studio__path-line { stroke-width: 5; }
}

@media (max-width: 767px) {
  /* One module per screen left 230–280px of dead black around short modules on a phone.
     64 each side (a plain value: the phone mode's --space-64 is 32), twice what it was: more
     air between the sections (Nick 09-30). */
  .studio-module { min-height: 0; padding-block: 64px; }
  /* The cover, as every page opens on a phone: the pill at the top, air, the headline low in
     the first screen, at the size every page hero gets (mobile experience, 2026-09-30). */
  .studio-intro { display: grid; grid-template-rows: auto 1fr auto; padding-top: var(--space-48); padding-bottom: var(--space-64); }
  /* Measured by an empty item over the three rows, as page-hero.css does it: the headline's
     bottom edge lands at 58svh. One column, placed explicitly so the item can't push the
     eyebrow into an implicit second column. */
  .studio-intro::before { content: ""; grid-row: 1 / 4; grid-column: 1; min-height: calc(58svh - var(--nav-height) - var(--space-48)); }
  .studio-intro__eyebrow { grid-row: 1; grid-column: 1; }
  .studio-intro__headline { grid-row: 3; grid-column: 1; font-size: clamp(40px, 12.5vw, 56px); text-wrap: balance; } /* balance: the Panel's line break left "the" alone at 440 */
  /* The visuals fill the width: the dock centred, the card under it (mobile experience, 2026-09-30). */
  .studio-visual--card, .studio-visual--icons { min-height: 0; }
  .studio-dock { position: relative; top: auto; left: auto; margin: 0 auto; }
  .studio-card { position: relative; top: auto; left: auto; width: 100%; margin-top: var(--space-20); padding: 16px 18px 20px; }
  .studio-card__title b { font-size: 19px; }
  .studio-pill { height: 64px; padding: 6px 20px 6px 6px; margin-right: 10px; }
  .studio-pill__orb { width: 52px; height: 52px; }
  /* The apps drift sideways, alternate rows in opposite directions: "new apps ship weekly",
     shown, not said (mobile experience, 2026-09-30). A row is two identical halves
     (studio.php), so sliding it by one half lands the copies where the originals were and the
     loop has no seam; pills space with a margin, not a gap, so the halves measure the same.
     --tick is one pass of the row's own pills (a half holds --reps of them). The right fade is
     the longer one: the pills dim before the edge line instead of chopping it into dashes.
     Offscreen, the module's .is-paused stops the rows. */
  .studio-pills {
    display: grid; gap: 10px;
    margin-inline: calc(-1 * var(--gutter));
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 78%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 8%, #000 78%, transparent);
  }
  .studio-pills__row { width: max-content; margin-left: 0; gap: 0; animation: studio-ticker calc(var(--tick, 42s) * var(--reps, 1)) linear infinite; }
  .studio-pills__row:nth-child(3n+1) { --tick: 38s; }
  .studio-pills__row:nth-child(3n+2) { --tick: 46s; }
  .studio-pills__row:nth-child(even) { animation-direction: reverse; }
  .studio-stat { --min: 54vw; --range: 42vw; min-height: 104px; padding-left: 24px; }
  .studio-stat__label { margin-top: 6px; }
}
@keyframes studio-ticker { to { transform: translate3d(-50%, 0, 0); } }

/* Reduced motion on phones: still rows, no copies, each row wrapping inside the column. */
@media (max-width: 767px) and (prefers-reduced-motion: reduce) {
  .studio-pill--copy { display: none; }
  .studio-pills { margin-inline: 0; -webkit-mask-image: none; mask-image: none; }
  .studio-pills__row { width: auto; flex-wrap: wrap; gap: 10px; }
  .studio-pill { margin-right: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .studio-pill, .studio-pills__row, .studio-card, .studio-eclipse > i { animation: none; }
  .studio-eclipse__bead { opacity: 0; }
}

/* Uploaded visual (image / video / GIF / Lottie) in place of the coded objects. */
.studio-visual--media { margin-top: 59px; }
.studio-visual--media .studio-visual__media { aspect-ratio: 4 / 3; border-radius: var(--radius-md); background: var(--surface-raised); }

/* ---------- Micro-animations below Meet (11-02 copy; restyled after the 11-03 review) ----------
   Workspace drawn the way the exec roadshow deck drew it (~/Projects/CoSi Workspace Marketing/exec-deck-micro, kit.css):
   simplified UI fragments with the product's real strings, cursor pills doing the work, wires that draw on and sparks
   that ride them for cause and effect, nothing fast. In the site's tokens: the card is the app card's raised grey, the
   accents are the path's colours, type is Inter at 12/11. A fixed 480 × 420 stage, zoomed down on phones.

   One loop each, 14–17s, timed as percentages of --loop. The stage (.sa-stage) fades the whole piece out at the end
   and back in a beat into the next loop; everything else only enters and holds, so an element's resting style is
   the loop's finished frame and reduced motion (bottom) just drops the animations and shows the outcome. Siblings
   stagger with animation-delay: that shifts their loop, so a delay must stay under the stage's opening beat (1.1s)
   or the element shows early. Each loop holds at its start until the piece is 40% in view (studio-anim.js, Nick 11-03
   #3: the first one had played before anyone reached it); after that, offscreen, the section's .is-paused stops it. */
.studio-anim {
  --loop: 16s;
  position: relative; width: 480px; height: 420px; margin-top: 24px;
  font-family: var(--font-body); font-size: 12px; line-height: 1.2; color: var(--ink-primary);
  -webkit-font-smoothing: antialiased;
}
.studio-anim--cpe { --loop: 17s; }
.studio-anim--resize { --loop: 14s; height: 300px; } /* the frames end at 280; the strip under them is gone (7c) */
.studio-module--right .studio-anim { margin-left: auto; }
.studio-anim *, .studio-anim *::before, .studio-anim *::after { animation-duration: var(--loop); animation-iteration-count: infinite; animation-fill-mode: both; animation-timing-function: var(--ease-out); }
.studio-anim b { font-weight: 500; color: var(--ink-primary); }
.sa-stage { position: absolute; inset: 0; animation-name: sa-stage; }
@keyframes sa-stage { 0%, 7% { opacity: 0; } 9%, 94% { opacity: 1; } 98%, 100% { opacity: 0; } }
.js .studio-anim:not(.is-on) *, .js .studio-anim:not(.is-on) *::before, .js .studio-anim:not(.is-on) *::after { animation-play-state: paused; }

/* The vocabulary. */
.sa-card { position: absolute; border-radius: var(--radius-sm); background: var(--studio-raised); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.06); }
.sa-meta { font-size: 11px; color: var(--ink-muted); }
.sa-ulab { font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-muted); }
.sa-bar { display: block; height: 6px; border-radius: var(--radius-pill); background: rgb(255 255 255 / 0.16); transform-origin: 0 50%; }
/* A dot pill: a coloured dot, a label and, when it has read something, a check. ::after is its glow while it reads. */
.sa-pill { position: absolute; display: flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px 0 10px; border-radius: var(--radius-pill); background: rgb(255 255 255 / 0.06); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16); white-space: nowrap; }
.sa-pill::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--c); }
.sa-pill::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 1.5px var(--c), 0 0 16px 2px color-mix(in srgb, var(--c) 40%, transparent); opacity: 0; }
.sa-ok { display: grid; place-content: center; flex: none; width: 16px; height: 16px; margin-right: -4px; border-radius: 50%; background: var(--color-green); color: var(--color-black); }
.sa-ok svg { width: 10px; height: 10px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* Buttons: the product's ghost and primary. ::after is the primary fill that comes on when it's pressed and running. */
.sa-btn { position: absolute; isolation: isolate; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px; border-radius: var(--radius-sm); background: rgb(255 255 255 / 0.08); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16); white-space: nowrap; }
.sa-btn--primary { background: var(--color-blue); box-shadow: none; }
.sa-btn::after { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--color-blue); opacity: 0; }
/* Wires: each path is normalised to length 1 (pathLength in the template), so drawing it is dash offset 1 → 0.
   Sparks ride the same path with offset-path; teal ones are answers coming back. */
.sa-wires { position: absolute; left: 0; top: 0; width: 480px; height: 420px; max-width: none; overflow: visible; }
.sa-wires path { fill: none; stroke: rgb(255 255 255 / 0.25); stroke-width: 1.3; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 0; }
.sa-spark { position: absolute; left: 0; top: 0; width: 7px; height: 7px; border-radius: 50%; background: var(--color-white); box-shadow: 0 0 10px 3px rgb(255 255 255 / 0.7); opacity: 0; offset-rotate: 0deg; }
.sa-spark--teal { background: var(--stat-teal); box-shadow: 0 0 10px 3px color-mix(in srgb, var(--stat-teal) 70%, transparent); }
/* Cursors (the kit's): an arrow with a labelled pill. A person is a monogram disc and a role, an agent the robot on its
   own colour. They enter from off the stage, press (the arrow squashes), and leave; at rest they're gone. */
.sa-cur { position: absolute; left: 0; top: 0; z-index: 5; width: 0; height: 0; opacity: 0; animation-timing-function: var(--ease-in-out); }
.sa-cur__arrow { position: absolute; left: -2px; top: -2px; width: 22px; max-width: none; height: 24px; overflow: visible; transform-origin: 2px 2px; fill: var(--color-white); stroke: var(--color-black); stroke-width: 1.3; stroke-linejoin: round; } /* max-width: base.css caps an svg at its parent, 0 wide here: until 11-05 only the pills showed */
.sa-cur__lab { position: absolute; left: 15px; top: 21px; display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 3px; border-radius: var(--radius-pill); background: var(--color-white); color: var(--color-black); font-weight: 500; white-space: nowrap; }
.sa-cur__mono { display: grid; place-content: center; width: 20px; height: 20px; border-radius: 50%; background: var(--c); color: var(--color-white); font-size: 10px; font-weight: 600; font-style: normal; }
.sa-cur--agent .sa-cur__arrow { fill: var(--c); stroke: var(--color-white); }
.sa-cur--agent .sa-cur__lab { padding-left: 8px; background: var(--c); }
.sa-cur--agent .sa-cur__lab svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.sa-cur--agent .sa-cur__lab svg circle { fill: currentColor; stroke: none; }

/* ---- Art: the creative in these pieces is abstract (Nick 11-05: real-looking ads "can be picked apart"), stacked
   layers on a dark tile in the Home Workspace mock's look (feature.css, after Nick's touchstone). The template's $art(n)
   picks the shape, so the pieces read as one campaign: a three flat layers, b two panels (B, blue, the one that wins;
   its versions take teal, purple and lilac), c three panels, d a panel and a disc, loose round one's scattered layers.
   The tile is a size container, so a shape fits whatever box a piece gives it. ---- */
.sa-art { position: relative; display: block; container-type: size; border-radius: var(--radius-sm); background: linear-gradient(160deg, rgb(255 255 255 / 0.06), rgb(255 255 255 / 0.015)); }
.sa-shape { position: absolute; inset: 0; margin: auto; width: 74cqmin; height: 74cqmin; }
.sa-shape i { position: absolute; border-radius: 9%; background: linear-gradient(140deg, #6e6e6e, #2c2c2c 70%); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16), 0 4px 8px rgb(0 0 0 / 0.5); }
.sa-shape--a i { left: 20%; width: 60%; aspect-ratio: 1; transform: rotateX(60deg) rotate(45deg); }
.sa-shape--a i:nth-child(1) { top: 0; z-index: 3; }
.sa-shape--a i:nth-child(2) { top: 14%; z-index: 2; }
.sa-shape--a i:nth-child(3) { top: 28%; }
.sa-shape--b i { top: 16%; width: 46%; height: 60%; transform: skewY(-16deg); }
.sa-shape--b i:nth-child(1) { left: 14%; }
.sa-shape--b i:nth-child(2) { left: 38%; top: 26%; }
.sa-shape--c i { width: 38%; height: 54%; transform: skewY(-16deg); }
.sa-shape--c i:nth-child(1) { left: 12%; top: 12%; }
.sa-shape--c i:nth-child(2) { left: 31%; top: 23%; }
.sa-shape--c i:nth-child(3) { left: 50%; top: 34%; }
.sa-shape--d i:nth-child(1) { left: 16%; top: 14%; width: 42%; height: 66%; transform: skewY(-16deg); }
.sa-shape--d i:nth-child(2) { left: 44%; top: 30%; width: 42%; aspect-ratio: 1; border-radius: 50%; }
.sa-shape--loose i { background: linear-gradient(140deg, #505050, #262626 70%); }
.sa-shape--loose i:nth-child(1) { left: 2%; top: 30%; width: 40%; height: 46%; rotate: -14deg; }
.sa-shape--loose i:nth-child(2) { left: 34%; top: 4%; width: 34%; height: 40%; rotate: 10deg; }
.sa-shape--loose i:nth-child(3) { left: 54%; top: 48%; width: 40%; height: 40%; rotate: -5deg; }
.sa-shape--b i:nth-child(3), .sa-shape--d i:nth-child(3) { display: none; }
.sa-shape--blue { --tint: var(--color-blue); }
.sa-shape--teal { --tint: var(--stat-teal); }
.sa-shape--purple { --tint: var(--stat-purple); }
.sa-shape--lilac { --tint: var(--color-lilac); }
.sa-shape[class*="--blue"] i:nth-child(2), .sa-shape[class*="--teal"] i:nth-child(2), .sa-shape[class*="--purple"] i:nth-child(2), .sa-shape[class*="--lilac"] i:nth-child(2) { background: linear-gradient(140deg, var(--tint), color-mix(in srgb, var(--tint) 30%, #151515) 75%); }

/* ---- Brief in the morning (16s). A Strategist clicks into the composer and the ask types itself; the composer reads the client's knowledge and the Creative
   Performance Engine (wire out, a glow while it reads, a check, a spark back); the brief drafts itself, section by
   section, under a "Proposed" pill; three concepts come out under it. ---- */
.sb-comp { position: absolute; left: 0; top: 0; display: flex; align-items: center; width: 480px; height: 44px; padding: 0 7px 0 16px; border-radius: var(--radius-pill); background: rgb(255 255 255 / 0.04); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16); animation-name: sb-comp; }
.sb-comp__ph, .sb-comp__q { position: absolute; left: 16px; right: 46px; top: 50%; translate: 0 -50%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } /* right: clear of send; a large text size ends the ask in an ellipsis, not under the button */
.sb-comp__ph { color: var(--ink-muted); opacity: 0; animation-name: sb-ph; }
.sb-comp__q { animation-name: sb-type; animation-timing-function: steps(69, end); } /* types on: one step per character */
.sb-comp__send { position: relative; display: grid; place-content: center; width: 30px; height: 30px; margin-left: auto; border-radius: 50%; background: color-mix(in srgb, var(--color-white) 30%, var(--color-black)); color: var(--color-black); animation-name: sb-press; }
.sb-comp__send::after { content: ""; position: absolute; inset: 0; border-radius: 50%; background: var(--color-white); animation-name: sb-send; } /* lights once the ask is typed */
.sb-comp__send svg { position: relative; z-index: 1; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
@keyframes sb-comp { 0%, 9.4% { opacity: 0; transform: translateY(10px); } 12.5%, 100% { opacity: 1; transform: none; } }
@keyframes sb-ph { 0%, 16.9% { opacity: 1; } 18%, 100% { opacity: 0; } }
@keyframes sb-type { 0%, 18.1% { clip-path: inset(0 100% 0 0); } 33.1%, 100% { clip-path: inset(0 0 0 0); } }
@keyframes sb-send { 0%, 33.1% { opacity: 0; } 33.3%, 100% { opacity: 1; } }
@keyframes sb-press { 0%, 36.4% { scale: 1; } 36.7% { scale: 0.86; } 37.3%, 100% { scale: 1; } }
.sb-cur { animation-name: sb-cur, sb-cur-op; }
.sb-cur .sa-cur__arrow { animation-name: sb-arrow; }
/* It clicks into the composer, steps aside while the ask types, and drifts off as it fades; Enter sends (Nick 11-03,
   7a: it used to vanish, and the long ask puts the send at the stage's edge). */
@keyframes sb-cur { 0%, 10.6% { transform: translate(-60px, 460px); } 16.9%, 17.5% { transform: translate(130px, 42px); } 24%, 31% { transform: translate(146px, 76px); } 38%, 100% { transform: translate(170px, 112px); } }
@keyframes sb-cur-op { 0%, 10.6% { opacity: 0; } 10.8%, 31% { opacity: 1; } 38%, 100% { opacity: 0; } }
@keyframes sb-arrow { 0%, 16.7% { scale: 1; } 16.9% { scale: 0.86; } 17.5%, 100% { scale: 1; } }
/* The live status line (three dots, the real "Reading…" strings), only while it reads. */
.sb-stat { position: absolute; left: 16px; top: 56px; height: 16px; width: 260px; color: var(--ink-muted); opacity: 0; animation-name: sb-stat; }
.sb-stat__dots { position: absolute; left: 0; top: 6px; display: flex; gap: 3px; }
.sb-stat__dots i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: sb-dot 1.2s ease-in-out infinite; }
.sb-stat__dots i:nth-child(2) { animation-delay: -0.4s; }
.sb-stat__dots i:nth-child(3) { animation-delay: -0.8s; }
.sb-stat__a, .sb-stat__b { position: absolute; left: 25px; top: 0; max-width: 240px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 11px; } /* max: clear of the source pills at 290 at a large text size */
.sb-stat__a { opacity: 0; animation-name: sb-stat-a; }
.sb-stat__b { animation-name: sb-stat-b; }
@keyframes sb-stat { 0%, 38.1% { opacity: 0; } 38.8%, 59.9% { opacity: 1; } 60.6%, 100% { opacity: 0; } }
@keyframes sb-stat-a { 0%, 49.2% { opacity: 1; } 49.6%, 100% { opacity: 0; } }
@keyframes sb-stat-b { 0%, 49.2% { opacity: 0; } 49.6%, 100% { opacity: 1; } }
@keyframes sb-dot { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
/* The two sources: wire draws on, pill pops, glows while it reads, checks, and a spark runs back. */
.sb-wire { animation-name: sb-wire-a; }
.sb-wire:nth-child(2) { animation-name: sb-wire-b; }
.sb-src { animation-name: sb-pop-a; }
.sb-src::after { animation-name: sb-glow-a; }
.sb-src .sa-ok { animation-name: sb-ok-a; }
.sb-src--b { animation-name: sb-pop-b; }
.sb-src--b::after { animation-name: sb-glow-b; }
.sb-src--b .sa-ok { animation-name: sb-ok-b; }
.sb-spark { animation-name: sb-spark-a; }
.sb-spark:nth-of-type(2) { animation-name: sb-spark-b; }
@keyframes sb-wire-a { 0%, 37.5% { stroke-dashoffset: 1; } 40.6%, 100% { stroke-dashoffset: 0; } }
@keyframes sb-wire-b { 0%, 44.4% { stroke-dashoffset: 1; } 47.5%, 100% { stroke-dashoffset: 0; } }
@keyframes sb-pop-a { 0%, 40.6% { opacity: 0; scale: 0.6; } 43%, 100% { opacity: 1; scale: 1; } }
@keyframes sb-pop-b { 0%, 47.5% { opacity: 0; scale: 0.6; } 49.9%, 100% { opacity: 1; scale: 1; } }
@keyframes sb-glow-a { 0%, 41.2% { opacity: 0; } 42.5% { opacity: 1; } 45% { opacity: 0.45; } 47% { opacity: 1; } 49.4%, 100% { opacity: 0; } }
@keyframes sb-glow-b { 0%, 48.1% { opacity: 0; } 49.5% { opacity: 1; } 52% { opacity: 0.45; } 54.5% { opacity: 1; } 56.9%, 100% { opacity: 0; } }
@keyframes sb-ok-a { 0%, 49.4% { scale: 0; } 51%, 100% { scale: 1; } }
@keyframes sb-ok-b { 0%, 56.9% { scale: 0; } 58.5%, 100% { scale: 1; } }
@keyframes sb-spark-a { 0%, 49.4% { opacity: 0; offset-distance: 0%; } 49.6% { opacity: 1; } 53.1% { opacity: 1; offset-distance: 100%; } 53.3%, 100% { opacity: 0; offset-distance: 100%; } }
@keyframes sb-spark-b { 0%, 56.9% { opacity: 0; offset-distance: 0%; } 57.1% { opacity: 1; } 60.6% { opacity: 1; offset-distance: 100%; } 60.8%, 100% { opacity: 0; offset-distance: 100%; } }
/* The brief: the real document's sections, each drawing in; "Proposed" is the amber pill the Builder puts on a drafted section. */
.sb-brief { left: 0; top: 150px; width: 320px; padding: 14px 16px 12px; border-radius: var(--radius-md); animation-name: sb-brief; }
.sb-brief__head { display: flex; align-items: center; gap: 8px; }
.sb-brief__head svg { width: 14px; height: 14px; fill: none; stroke: var(--ink-muted); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.sb-brief__proposed { min-height: 20px; margin-left: auto; padding: 0 8px; border-radius: var(--radius-pill); background: color-mix(in srgb, var(--color-amber) 18%, transparent); color: var(--color-amber); font-size: 10px; line-height: 20px; animation-name: sb-proposed; }
.sb-brief__checked { margin: 8px 0 0; font-size: 11px; font-style: italic; color: var(--ink-muted); animation-name: sb-checked; }
.sb-brief__row { margin-top: 10px; animation-name: sb-row; animation-delay: calc(var(--k) * 0.5s); }
.sb-brief__row span { display: block; font-size: 11px; color: var(--ink-muted); }
.sb-brief__row .sa-bar { margin-top: 5px; animation-name: sb-row-bar; animation-delay: calc(var(--k) * 0.5s); }
@keyframes sb-brief { 0%, 61.9% { opacity: 0; transform: translateY(-10px) scale(0.97); } 64.4%, 100% { opacity: 1; transform: none; } }
@keyframes sb-proposed { 0%, 63.75% { opacity: 0; scale: 0.6; } 65.5%, 100% { opacity: 1; scale: 1; } }
@keyframes sb-checked { 0%, 64.4% { opacity: 0; } 66%, 100% { opacity: 1; } }
@keyframes sb-row { 0%, 66.25% { opacity: 0; } 68%, 100% { opacity: 1; } }
@keyframes sb-row-bar { 0%, 66.25% { scale: 0 1; } 68.75%, 100% { scale: 1 1; } }
/* The concepts: three starters, each carrying a dot for the sources it was built from. */
.sb-con { left: calc(var(--k) * 165px); top: 330px; width: 150px; padding: 6px; animation-name: sb-con; animation-delay: calc(var(--k) * 0.35s); }
.sb-con__art { height: 56px; }
.sb-con__row { display: flex; align-items: center; justify-content: space-between; margin: 6px 2px 0; font-size: 11px; }
.sb-con__dots { display: flex; gap: 4px; }
.sb-con__dots b { width: 6px; height: 6px; border-radius: 50%; background: var(--c); }
@keyframes sb-con { 0%, 76.25% { opacity: 0; transform: translateY(8px) scale(0.9); } 78.75%, 100% { opacity: 1; transform: none; } }

/* ---- Creative made better (18s). The four knowledge sources noodle into one idea, loose layers (round one); four
   synthetic personas score it, the idea changes (the sharpened version, B's aligned layers, wipes over it), and they
   score it again, higher (Tucker 11-04). The rest frame is the sharpened idea and the round-two meters. ---- */
.studio-anim--network { --loop: 18s; }
.sn-src { min-width: 156px; animation-name: sn-src; animation-delay: calc(var(--k) * 0.2s); }
.sn-in { animation-name: sn-in; animation-delay: calc(var(--k) * 0.35s); }
.sn-ride { animation-name: sn-ride; animation-delay: calc(var(--k) * 0.35s); }
@keyframes sn-src { 0%, 8.9% { opacity: 0; transform: translateX(-12px); } 11.1%, 100% { opacity: 1; transform: none; } }
@keyframes sn-in { 0%, 13.3% { stroke-dashoffset: 1; } 16.1%, 100% { stroke-dashoffset: 0; } }
@keyframes sn-ride { 0%, 15% { opacity: 0; offset-distance: 0%; } 15.2% { opacity: 1; } 17.8% { opacity: 1; offset-distance: 100%; } 18%, 100% { opacity: 0; offset-distance: 100%; } }
/* The idea: an empty frame, then round one wipes in top to bottom. The change: the sharpened idea
   wipes over it left to right, a light riding the seam (::after), and the card settles with a small overshoot. */
.sn-ad { left: 236px; top: 10px; width: 180px; height: 221px; border-radius: var(--radius-md); animation-name: sn-ad; }
.sn-ad::before { content: ""; position: absolute; left: 8px; top: 8px; width: 164px; height: 205px; border-radius: var(--radius-sm); background: rgb(255 255 255 / 0.04); }
.sn-ad::after { content: ""; position: absolute; left: 7px; top: 8px; width: 2px; height: 205px; border-radius: 1px; background: var(--color-white); box-shadow: 0 0 12px 3px rgb(255 255 255 / 0.6); opacity: 0; animation-name: sn-seam; }
.sn-ad__art { position: absolute; left: 8px; top: 8px; width: 164px; height: 205px; animation-name: sn-art; }
.sn-ad__next { animation-name: sn-next; }
@keyframes sn-ad { 0%, 12.2% { opacity: 0; scale: 0.96; } 14.4%, 53.3% { opacity: 1; scale: 1; } 54.4% { scale: 1.03; } 56.1%, 100% { scale: 1; } }
@keyframes sn-art { 0%, 20% { clip-path: inset(0 0 100% 0); } 24.4%, 100% { clip-path: inset(0); } }
@keyframes sn-next { 0%, 50% { clip-path: inset(0 100% 0 0); } 53.3%, 100% { clip-path: inset(0); } }
@keyframes sn-seam { 0%, 49.8% { opacity: 0; transform: none; } 50% { opacity: 1; transform: none; } 53.3% { opacity: 1; transform: translateX(164px); } 54.4%, 100% { opacity: 0; transform: translateX(164px); } }
.sn-round { position: absolute; left: 236px; top: 239px; margin: 0; font-size: 11px; color: var(--ink-muted); }
.sn-round span { position: absolute; left: 0; top: 0; white-space: nowrap; }
.sn-round__a { opacity: 0; animation-name: sn-round-a; }
.sn-round__b { animation-name: sn-round-b; }
@keyframes sn-round-a { 0%, 25.6% { opacity: 0; } 26.7%, 49.4% { opacity: 1; } 50.3%, 100% { opacity: 0; } }
@keyframes sn-round-b { 0%, 53.3% { opacity: 0; } 54.4%, 100% { opacity: 1; } }
/* The personas: a disc, a name and a meter, in a row under the idea (Nick 11-03, 7b: plain, not sci-fi). Wires draw
   down to them, they score round one in muted ink, and after the change each meter grows and turns teal. */
.sn-out { animation-name: sn-out; animation-delay: calc(var(--k) * 0.2s); }
.sn-per { position: absolute; top: 286px; width: 80px; display: flex; flex-direction: column; align-items: center; gap: 5px; animation-name: sn-per; animation-delay: calc(var(--k) * 0.2s); }
.sn-per__disc { display: grid; place-content: center; width: 26px; height: 26px; border-radius: 50%; background: var(--c); color: var(--color-black); }
.sn-per__disc svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
.sn-per > span { font-size: 11px; text-align: center; } /* wraps to "Persona / 1" at a large text size rather than running into the next */
/* Scores are meters, never figures (Nick 11-05): round one fills part-way in muted ink; after the change it grows
   further and turns teal, with an up arrow. --a and --b are the lengths. */
.sn-score { display: flex; align-items: center; justify-content: center; gap: 4px; width: 100%; height: 20px; color: var(--stat-teal); }
.sn-score i { position: relative; width: 44px; height: 6px; border-radius: var(--radius-pill); background: rgb(255 255 255 / 0.12); overflow: hidden; }
.sn-score i::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--stat-teal); transform-origin: 0 50%; scale: var(--b) 1; animation-name: sn-meter; animation-delay: calc(var(--k) * 0.3s); }
.sn-score svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; animation-name: sn-score-b; animation-delay: calc(var(--k) * 0.3s); }
.sn-ok { animation-name: sn-ok; }
@keyframes sn-out { 0%, 27.8% { stroke-dashoffset: 1; } 30.6%, 100% { stroke-dashoffset: 0; } }
@keyframes sn-per { 0%, 30.6% { opacity: 0; scale: 0.6; } 32.8%, 100% { opacity: 1; scale: 1; } }
@keyframes sn-meter { 0%, 35.6% { scale: 0 1; background: var(--ink-muted); } 37.8%, 58.9% { scale: var(--a) 1; background: var(--ink-muted); } 61.1%, 100% { scale: var(--b) 1; background: var(--stat-teal); } }
@keyframes sn-score-b { 0%, 58.9% { opacity: 0; transform: translateY(8px); } 61.1%, 100% { opacity: 1; transform: none; } }
@keyframes sn-ok { 0%, 68.9% { opacity: 0; scale: 0.6; } 71.1%, 100% { opacity: 1; scale: 1; } }
/* The hands: a Data Agent sends the idea to the personas (round one) and comes back to run them again (round two); in
   between, a Designer drags the change across it, riding the seam. They come and go under the stage, never past
   x 400, so a pill never runs off the page's right edge (this piece sits on the right). */
.sn-cur-data { animation-name: sn-data, sn-data-op; }
.sn-cur-data .sa-cur__arrow { animation-name: sn-data-arrow; }
@keyframes sn-data { 0%, 22% { transform: translate(380px, 460px); } 27%, 27.8% { transform: translate(326px, 222px); } 32%, 54% { transform: translate(390px, 470px); } 58%, 59% { transform: translate(326px, 222px); } 64%, 100% { transform: translate(400px, 470px); } }
@keyframes sn-data-op { 0%, 22% { opacity: 0; } 22.2%, 31.8% { opacity: 1; } 32%, 54% { opacity: 0; } 54.2%, 63.8% { opacity: 1; } 64%, 100% { opacity: 0; } }
@keyframes sn-data-arrow { 0%, 27.1% { scale: 1; } 27.3% { scale: 0.86; } 27.9%, 58.2% { scale: 1; } 58.4% { scale: 0.86; } 59%, 100% { scale: 1; } }
.sn-cur-des { animation-name: sn-des, sn-des-op; }
.sn-cur-des .sa-cur__arrow { animation-name: sn-des-arrow; }
/* The drag runs with the seam (50% → 53.3%, same easing), the arrow held down. */
@keyframes sn-des { 0%, 44% { transform: translate(170px, 460px); } 49.5% { transform: translate(244px, 205px); } 50% { transform: translate(244px, 205px); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); } /* --ease-out: a var() in a keyframe is ignored */ 53.3%, 54% { transform: translate(408px, 205px); } 59%, 100% { transform: translate(330px, 470px); } }
@keyframes sn-des-op { 0%, 44% { opacity: 0; } 44.2%, 58.8% { opacity: 1; } 59%, 100% { opacity: 0; } }
@keyframes sn-des-arrow { 0%, 49.6% { scale: 1; } 49.8%, 53.3% { scale: 0.86; } 53.6%, 100% { scale: 1; } }

/* ---- Find what will work next (17s). The Creative Performance Engine's read, as the product draws it: a Data Agent
   presses "Update this read", the creative loads into its tiles, the winner opens to its index against the platform
   average and the real analysis headings, and a Strategist takes "Work with this" → "Version this": three versions
   land under the read. Strings from workspace-ui.md §2; no numbers anywhere. ---- */
.sc-hd { position: absolute; left: 0; top: 4px; animation-name: sc-in; }
.sc-hd b { display: block; font-size: 13px; }
.sc-hd .sa-meta { display: block; margin-top: 2px; }
.sc-upd { right: 0; top: 0; animation-name: sc-in, sc-upd-press; }
.sc-upd::after { animation-name: sc-upd-on; }
@keyframes sc-in { 0%, 8.8% { opacity: 0; transform: translateY(8px); } 11.2%, 100% { opacity: 1; transform: none; } }
@keyframes sc-upd-press { 0%, 15.1% { scale: 1; } 15.3% { scale: 0.94; } 15.9%, 100% { scale: 1; } }
@keyframes sc-upd-on { 0%, 15.3% { opacity: 0; } 15.6%, 26.5% { opacity: 1; } 28%, 100% { opacity: 0; } }
.sc-cur-data { animation-name: sc-data, sc-data-op; }
.sc-cur-data .sa-cur__arrow { animation-name: sc-data-arrow; }
@keyframes sc-data { 0%, 9.4% { transform: translate(-80px, 300px); } 15.3%, 17.1% { transform: translate(372px, 16px); } 23.5%, 100% { transform: translate(400px, -60px); } }
@keyframes sc-data-op { 0%, 9.4% { opacity: 0; } 9.6%, 23.3% { opacity: 1; } 23.5%, 100% { opacity: 0; } }
@keyframes sc-data-arrow { 0%, 15.1% { scale: 1; } 15.3% { scale: 0.86; } 15.9%, 100% { scale: 1; } }
/* The tiles: the frame first (an empty plate), then the creative loads into it, then its line: standing pill, platform. */
.sc-tile { width: 150px; padding: 6px; animation-name: sc-tile; animation-delay: calc(var(--k) * 0.15s); }
.sc-tile::before { content: ""; position: absolute; left: 6px; top: 6px; width: 138px; height: 66px; border-radius: var(--radius-sm); background: rgb(255 255 255 / 0.05); }
.sc-tile__art { position: relative; height: 66px; animation-name: sc-art; animation-delay: calc(var(--k) * 0.35s); }
.sc-tile__meta { margin-top: 7px; animation-name: sc-meta; animation-delay: calc(var(--k) * 0.35s); }
.sc-tile__meta .sa-bar { width: 70%; height: 5px; margin: 2px 2px 7px; }
/* One line, always: at a large text size the platform name wraps under the pill and the row's height hides it, so the
   tile keeps its size and the second row stays clear of "Versions" (Nick's phone, 11-05: the pill used to wrap). */
.sc-tile__meta span { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; max-height: max(18px, 1.2em); overflow: hidden; margin: 0 2px; font-size: 10px; color: var(--ink-muted); }
.sc-status { display: inline-flex; align-items: center; gap: 3px; min-height: 18px; padding: 0 7px; white-space: nowrap; border-radius: var(--radius-pill); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16); color: var(--ink-primary); font-style: normal; }
.sc-status--up { color: var(--stat-teal); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--stat-teal) 50%, transparent); }
.sc-status svg { width: 9px; height: 9px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.sc-tile--win::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 1.5px var(--stat-teal), 0 0 16px 2px color-mix(in srgb, var(--stat-teal) 35%, transparent); animation-name: sc-win; }
@keyframes sc-tile { 0%, 15.9% { opacity: 0; transform: translateY(6px); } 18.2%, 100% { opacity: 1; transform: none; } }
@keyframes sc-art { 0%, 21.2% { opacity: 0; scale: 0.92; } 23.5%, 100% { opacity: 1; scale: 1; } }
@keyframes sc-meta { 0%, 22.9% { opacity: 0; } 24.7%, 100% { opacity: 1; } }
@keyframes sc-win { 0%, 31.8% { opacity: 0; } 33.5%, 100% { opacity: 1; } }
/* The winner's detail: its index bar past the platform-average line, the analysis headings, "Work with this" on a row of
   its own (Tucker 11-04: it sat on the last bar). The Strategist presses its bottom edge, so the label hangs below. */
/* The button sits in the bottom 42px; at a large text size the art gives up height so the analysis stays above it. */
.sc-det { left: 330px; top: 44px; display: flex; flex-direction: column; width: 150px; height: 264px; padding: 8px 8px 42px; animation-name: sc-det; }
.sc-det > * { flex-shrink: 0; }
.sc-det__art { flex: 0 1 60px; min-height: 0; }
.sc-det__ix { display: block; position: relative; height: 8px; margin-top: 10px; border-radius: var(--radius-pill); background: rgb(255 255 255 / 0.1); }
.sc-det__ix b { position: absolute; left: 0; top: 0; bottom: 0; width: 78%; border-radius: inherit; background: var(--stat-teal); transform-origin: 0 50%; animation-name: sc-ix; }
.sc-det__ix::after { content: ""; position: absolute; left: 52%; top: -3px; bottom: -3px; width: 1.5px; background: var(--color-white); }
.sc-det .sa-meta { display: block; margin-top: 6px; font-size: 10px; }
.sc-det .sa-ulab { display: block; margin-top: 10px; }
.sc-det__an { margin-top: 7px; animation-name: sc-an; animation-delay: calc(var(--k) * 0.4s); }
.sc-det__an span { display: block; font-size: 11px; }
.sc-det__an .sa-bar { width: 86%; height: 5px; margin-top: 4px; }
.sc-ww { left: 8px; bottom: 8px; height: 26px; font-size: 11px; animation-name: sc-ww, sc-ww-press; }
@keyframes sc-det { 0%, 35.3% { opacity: 0; transform: translateX(-12px); } 38%, 100% { opacity: 1; transform: none; } }
@keyframes sc-ix { 0%, 37.1% { scale: 0 1; } 41.8%, 100% { scale: 1 1; } }
@keyframes sc-an { 0%, 42.9% { opacity: 0; transform: translateY(4px); } 45%, 100% { opacity: 1; transform: none; } }
@keyframes sc-ww { 0%, 49.4% { opacity: 0; } 51.5%, 100% { opacity: 1; } }
@keyframes sc-ww-press { 0%, 54.5% { scale: 1; } 54.7% { scale: 0.94; } 55.3%, 100% { scale: 1; } }
/* "Work with this" menu (its real items), opening upward over the analysis so it never sits on the button (Tucker
   11-04), then the versions. */
.sc-menu { position: absolute; left: 330px; top: 188px; width: 150px; padding: 4px; border-radius: var(--radius-sm); background: var(--studio-raised); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.16), 0 12px 30px rgb(0 0 0 / 0.6); opacity: 0; animation-name: sc-menu; }
.sc-menu span { position: relative; isolation: isolate; display: block; height: 24px; padding: 0 8px; border-radius: var(--radius-sm); font-size: 11px; line-height: 24px; }
.sc-menu__pick::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; background: var(--color-blue); opacity: 0; animation-name: sc-pick; }
.sc-ver__lab { position: absolute; left: 0; top: 300px; margin: 0; animation-name: sc-verlab; }
.sc-ver { top: 318px; width: 150px; padding: 6px; animation-name: sc-ver; animation-delay: calc(var(--k) * 0.35s); }
.sc-ver__art { height: 58px; }
.sc-ver .sa-bar { width: 60%; height: 5px; margin: 6px 2px 1px; }
/* It wipes up out of the button and back down, never fading, so nothing under it shows through (FOUNDRY 11-04). */
@keyframes sc-menu { 0%, 54.9% { opacity: 0; clip-path: inset(100% 0 0 0); } 54.95% { opacity: 1; clip-path: inset(100% 0 0 0); } 56%, 61.8% { opacity: 1; clip-path: inset(-12px -30px -42px); } 62.75% { opacity: 1; clip-path: inset(100% 0 0 0); } 62.8%, 100% { opacity: 0; clip-path: inset(100% 0 0 0); } }
@keyframes sc-pick { 0%, 59% { opacity: 0; } 59.6%, 62% { opacity: 1; } 62.8%, 100% { opacity: 0; } }
@keyframes sc-verlab { 0%, 62.9% { opacity: 0; } 64.5%, 100% { opacity: 1; } }
@keyframes sc-ver { 0%, 63.5% { opacity: 0; transform: translateY(8px) scale(0.9); } 66%, 100% { opacity: 1; transform: none; } }
.sc-cur-strat { animation-name: sc-strat, sc-strat-op; }
.sc-cur-strat .sa-cur__arrow { animation-name: sc-strat-arrow; }
@keyframes sc-strat { 0%, 48.8% { transform: translate(400px, 460px); } 54.7%, 55.9% { transform: translate(372px, 297px); } 59.4%, 61.8% { transform: translate(412px, 230px); } 67.6%, 100% { transform: translate(400px, 470px); } }
@keyframes sc-strat-op { 0%, 48.8% { opacity: 0; } 49%, 67.4% { opacity: 1; } 67.6%, 100% { opacity: 0; } }
@keyframes sc-strat-arrow { 0%, 54.5% { scale: 1; } 54.7% { scale: 0.86; } 55.3%, 60.4% { scale: 1; } 60.6% { scale: 0.86; } 61.2%, 100% { scale: 1; } }

/* ---- More ideas, same budget (14s; Nick 11-05 note 6, Tucker 11-04). One insight, three concepts dealt out of it on
   arcs (each a different way in), then each is built out into Stories, Feed and CTV, row by row, sliding out of
   its concept: more ideas and every placement from one brief. Frame staggers stay under the 1.1s opening beat. */
.studio-anim--ideas { --loop: 14s; height: 310px; }
/* At a large text size (Nick's phone, 11-05) the card grows with its text: taller, and up to 150 wide for "Everyone"
   (min-content is its longest word), short of the concepts at 160. */
.si-insight { left: 0; top: 105px; z-index: 1; width: min-content; min-width: 130px; max-width: 150px; min-height: 100px; padding: 12px; animation-name: si-insight; }
.si-insight p { margin: 8px 0 0; font-size: 14px; line-height: 1.25; }
.si-insight::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 1.5px var(--color-chartreuse), 0 0 18px 2px color-mix(in srgb, var(--color-chartreuse) 35%, transparent); opacity: 0; animation-name: si-glow; }
@keyframes si-insight { 0%, 9.3% { opacity: 0; transform: translateY(8px); } 13.6%, 19.3% { opacity: 1; transform: none; } 21.4% { scale: 0.97; } 23.6%, 100% { opacity: 1; scale: 1; } }
@keyframes si-glow { 0%, 19.3% { opacity: 0; } 21.4% { opacity: 1; } 30%, 100% { opacity: 0; } }
/* The card keeps its 84px: at a large text size the art gives up the height and the card widens round its centre for
   "Concept A" on one line (Nick's phone, 11-05; 270px at most, short of the formats at 276). */
.si-con { left: 0; top: 0; display: flex; flex-direction: column; min-width: 100px; height: 84px; padding: 6px; white-space: nowrap; offset-anchor: 50% 50%; offset-rotate: 0deg; offset-distance: 100%; animation-name: si-con; animation-delay: calc(var(--k) * 0.15s); }
.si-con__row { display: flex; align-items: baseline; justify-content: space-between; margin: 4px 2px 0; font-size: 11px; animation-name: si-row; animation-delay: calc(var(--k) * 0.2s); }
@keyframes si-con { 0%, 21.4% { opacity: 0; offset-distance: 0%; scale: 0.6; } 22.9% { opacity: 1; } 25.7% { offset-distance: 100%; scale: 1.05; } 27.9%, 100% { opacity: 1; offset-distance: 100%; scale: 1; } }
@keyframes si-row { 0%, 31.4% { opacity: 0; } 34.3%, 100% { opacity: 1; } }
.si-con .sa-art { flex: 1 1 58px; min-height: 0; }
/* Centred over their column, so a large text size spreads them both ways: left-aligned, "Stories" ran into "Feed" (Nick 11-05). */
.so-col { position: absolute; top: 0; translate: -50% 0; white-space: nowrap; animation-name: so-col; animation-delay: calc(var(--c) * 0.12s); }
.so-fr { animation-name: so-fr; animation-delay: calc(var(--k) * 1s); }
.so-fr .sa-art { height: 100%; background: none; }
@keyframes so-col { 0%, 36.4% { opacity: 0; } 39.3%, 100% { opacity: 1; } }
@keyframes so-fr { 0%, 37.9% { opacity: 0; translate: var(--dx) 0; scale: 0.4; } 39.3% { opacity: 1; } 42.1% { translate: 0 0; scale: 1.06; } 43.6%, 100% { opacity: 1; translate: 0 0; scale: 1; } }
/* The hands: a Strategist clicks the insight (it presses and lights, then deals the concepts), and a Design Agent takes
   Concept A by its edge and drags right, and every row builds out after it, the arrow held down through the drag
   (same easing as the frames). */
.si-cur-strat { animation-name: si-strat, si-strat-op; }
.si-cur-strat .sa-cur__arrow { animation-name: si-strat-arrow; }
@keyframes si-strat { 0%, 13% { transform: translate(-60px, 380px); } 19%, 21.4% { transform: translate(70px, 170px); } 27%, 100% { transform: translate(-40px, 360px); } }
@keyframes si-strat-op { 0%, 13% { opacity: 0; } 13.2%, 26.8% { opacity: 1; } 27%, 100% { opacity: 0; } }
@keyframes si-strat-arrow { 0%, 19.1% { scale: 1; } 19.3% { scale: 0.86; } 19.9%, 100% { scale: 1; } }
.si-cur-des { animation-name: si-des, si-des-op; }
.si-cur-des .sa-cur__arrow { animation-name: si-des-arrow; }
@keyframes si-des { 0%, 31% { transform: translate(330px, 380px); } 37.4% { transform: translate(256px, 68px); } 37.9% { transform: translate(256px, 68px); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); } 42.1%, 43.6% { transform: translate(370px, 68px); } 49%, 100% { transform: translate(330px, 380px); } }
@keyframes si-des-op { 0%, 31% { opacity: 0; } 31.2%, 48.8% { opacity: 1; } 49%, 100% { opacity: 0; } }
@keyframes si-des-arrow { 0%, 37.5% { scale: 1; } 37.7%, 42.3% { scale: 0.86; } 42.6%, 100% { scale: 1; } }

/* ---- One idea, every format (14s; parked, the Panel's 'resize': Tucker 11-04, it shows resizing, not more ideas). A Designer runs Quick Resize on one concept: a wire to each format, and a frame
   lands on each. (Nick 11-03, 7c: the Formats/Budget strip under it was gratuitous; gone.) ---- */
.sv-src { left: 0; top: 40px; width: 130px; padding: 8px; animation-name: sv-src; }
.sv-src__art { height: 112px; }
.sv-src > span:not(.sa-btn) { display: block; margin: 6px 2px 0; font-size: 11px; }
.sv-btn { position: relative; margin-top: 8px; height: 24px; font-size: 11px; animation-name: sv-btn-press; }
.sv-btn::after { animation-name: sv-btn-on; }
@keyframes sv-src { 0%, 10.7% { opacity: 0; transform: translateY(8px); } 13.5%, 100% { opacity: 1; transform: none; } }
@keyframes sv-btn-press { 0%, 18.4% { scale: 1; } 18.6% { scale: 0.94; } 19.2%, 100% { scale: 1; } }
@keyframes sv-btn-on { 0%, 18.6% { opacity: 0; } 18.9%, 42% { opacity: 1; } 44%, 100% { opacity: 0; } }
.sv-cur { animation-name: sv-cur, sv-cur-op; }
.sv-cur .sa-cur__arrow { animation-name: sv-arrow; }
@keyframes sv-cur { 0%, 11.4% { transform: translate(-60px, 300px); } 18.6%, 20.7% { transform: translate(65px, 199px); } 28.6%, 100% { transform: translate(-60px, 440px); } }
@keyframes sv-cur-op { 0%, 11.4% { opacity: 0; } 11.6%, 28.4% { opacity: 1; } 28.6%, 100% { opacity: 0; } }
@keyframes sv-arrow { 0%, 18.4% { scale: 1; } 18.6% { scale: 0.86; } 19.2%, 100% { scale: 1; } }
.sv-wire { animation-name: sv-wire; animation-delay: calc(var(--k) * 0.2s); }
.sv-fr { position: absolute; animation-name: sv-fr; animation-delay: calc(var(--k) * 0.2s); }
.sv-fr .sa-art { position: absolute; inset: 0; box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.12); }
.sv-fr .sa-meta { position: absolute; left: 0; top: 100%; margin-top: 4px; font-size: 10px; animation-name: sv-lab; animation-delay: calc(var(--k) * 0.2s); }
@keyframes sv-wire { 0%, 20.7% { stroke-dashoffset: 1; } 23.9%, 100% { stroke-dashoffset: 0; } }
@keyframes sv-fr { 0%, 23.9% { opacity: 0; scale: 0.85; } 26.5%, 100% { opacity: 1; scale: 1; } }
@keyframes sv-lab { 0%, 25.5% { opacity: 0; } 27.5%, 100% { opacity: 1; } }

@media (max-width: 767px) {
  .studio-anim { zoom: 0.66; margin-top: 0; }
}
/* Larger on a phone held upright (Nick 11-05): the most the column holds before "creative work," breaks, so it stays
   four lines: 53px at 390, 61 at 440 (was 12.5vw, 49 and 55). 68px is the column's margins. Wider screens keep 56. */
@media (max-width: 479px) {
  .studio-intro__headline { font-size: clamp(40px, (100vw - 68px) / 6.1, 64px); }
}
/* Reduced motion: no loops; every element's resting style is the loop's finished frame (cursors, sparks and the
   status line rest hidden), so the outcome shows and nothing moves. */
@media (prefers-reduced-motion: reduce) {
  .studio-anim, .studio-anim *, .studio-anim *::before, .studio-anim *::after { animation: none !important; }
}
