/* Periferal marketing site, in the pitch video's style.
   The brand is the stack tile: four ink blocks, alternately pushed right, on an orange tile. Its pieces
   come back across the page: tiles as icons and section markers, offset blocks as timelines
   and illustrations, and the orange as the one accent on near-black. */

:root {
  color-scheme: dark;
  --bg: #050406;
  --surface: #0e0d11;
  --raised: #151419;
  --line: #222128;
  --line-strong: #2e2d35;
  --text: #f1f0f4;
  --text-2: #b4b3bc;
  --muted: #807f89;
  --faint: #55545d;
  --orange: #ff8a4c;
  --orange-2: #f47c3e;
  --ink: #16120f;
  --amber: #e5b257;
  --coral: #ef6a5a;
  --green: #74d39a;
  --sky: #7cc4f5;
  --violet: #9d8cff;
  --alex: #f7a072;
  --mia: #f28fb5;
  --josh: #5fc9b5;
  --radhi: #c9a0f0;
  --grad: linear-gradient(90deg, #ffc46b, var(--orange) 55%, var(--coral));
  --sans: Geist, -apple-system, system-ui, "Segoe UI", sans-serif;
  --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --wrap: 1180px;
  --gutter: max(20px, env(safe-area-inset-left, 0px));
  --radius: 18px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 80px; }
/* The orange band starts right under the 68px header, not below a strip of dark: 12px less than the page's 80. */
#solution { scroll-margin-top: -12px; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font: 17px/1.6 var(--sans); -webkit-font-smoothing: antialiased; overflow-x: hidden;
}
img, video, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button, input { font: inherit; color: inherit; }
::selection { background: var(--orange); color: var(--ink); }

.wrap { width: min(var(--wrap), 100% - 2 * var(--gutter)); margin-inline: auto; }
.grad { background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.mono { font-family: var(--mono); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- The mark ---------- */

/* The tile with its four blocks, at any size (set --s). Each block is a rect in the SVG; `.build`
   stacks them in one by one, like the video's logo. */
.tile { width: var(--s, 40px); height: var(--s, 40px); flex: none; }
.tile .bg { fill: var(--orange); }
.tile .b { fill: var(--ink); }
.tile.build .bg { transform-origin: 32px 32px; animation: tile-pop .7s cubic-bezier(.2, 1.4, .4, 1) both; }
.tile.build .b { transform-box: fill-box; animation: block-in .75s cubic-bezier(.2, 1.3, .35, 1) both; }
.tile.build .b:nth-of-type(1) { animation-delay: .35s; }
.tile.build .b:nth-of-type(2) { animation-delay: .5s; }
.tile.build .b:nth-of-type(3) { animation-delay: .65s; }
.tile.build .b:nth-of-type(4) { animation-delay: .8s; }
@keyframes tile-pop { from { transform: scale(.4) rotate(-10deg); opacity: 0; } }
@keyframes block-in { from { transform: translateX(-60%) scaleX(.2); opacity: 0; } }

.lockup { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; font-size: 21px; letter-spacing: -.03em; }
.lockup .tile { --s: 30px; }

/* A small tile with one glyph or number on it: section markers and list bullets. */
.chip-tile {
  display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 7px; flex: none;
  background: var(--orange); color: var(--ink); font: 600 13px var(--mono);
}

/* ---------- Nav ---------- */

.nav { position: sticky; top: 0; z-index: 50; backdrop-filter: blur(14px); background: rgba(5, 4, 6, .72); border-bottom: 1px solid transparent; transition: border-color .2s; }
.nav.scrolled { border-bottom-color: var(--line); }
.nav .wrap { display: flex; align-items: center; gap: 28px; height: 68px; }
/* The section links in the eyebrows' type: mono capitals, spaced out. */
.nav .links { --gap: 42px; display: flex; align-items: center; gap: var(--gap); margin-left: auto; font: 500 13px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--text-2); white-space: nowrap; }
/* On narrower screens the links sit closer, a size smaller, to stay on one line. */
@media (max-width: 1240px) { .nav .links { --gap: 28px; font-size: 12px; } }
.nav .links a:hover { color: var(--text); }
/* A thin rule between the items, like the panel bar's (.panelline i), in the middle of the gap as it looks (the letter
   spacing trails each item by .12em), most of the bar's height (40 of its 68px, clear of its edges), dimmed, fading out at its
   top and bottom. */
.nav .links a + a { position: relative; }
.nav .links a + a::before { content: ""; position: absolute; left: calc(var(--gap) / -2 - .06em - .5px); top: 50%; width: 1px; height: 40px; translate: 0 -50%; background: linear-gradient(transparent, var(--line-strong) 25% 75%, transparent); opacity: .6; pointer-events: none; }
/* The menu button (phones and tablets), at the right of the header: the logo's four blocks as lines, in
   its proportions (blocks 27.62 wide, every other one pushed 2.76, the stub 12.89, drawn 22px wide: 20px
   lines, a 2px push, a 9.3px stub). Open, the first and third cross into an ✕ and the others fade. */
.menu-btn { display: none; position: relative; flex: none; width: 40px; height: 40px; margin: 0 -8px 0 2px; padding: 0; border: 0; background: none; cursor: pointer; border-radius: 10px; }
.menu-btn:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.menu-btn i { position: absolute; left: 9px; width: 20px; height: 2px; border-radius: 1px; background: var(--text); transition: transform .3s, opacity .2s, top .3s, left .3s, width .3s; }
.menu-btn i:nth-child(1) { top: 11px; }
.menu-btn i:nth-child(2) { top: 17px; left: 11px; }
.menu-btn i:nth-child(3) { top: 23px; }
.menu-btn i:nth-child(4) { top: 29px; left: 11px; width: 9.3px; }
.menu-btn[aria-expanded="true"] i:nth-child(1) { top: 19px; left: 10px; transform: rotate(45deg); }
.menu-btn[aria-expanded="true"] i:nth-child(3) { top: 19px; left: 10px; transform: rotate(-45deg); }
.menu-btn[aria-expanded="true"] i:nth-child(2), .menu-btn[aria-expanded="true"] i:nth-child(4) { opacity: 0; }
.mobile-menu { position: absolute; left: 0; right: 0; top: 100%; display: grid; padding: 8px var(--gutter) 18px; background: var(--bg);
  border-bottom: 1px solid var(--line); box-shadow: 0 30px 60px -20px rgba(0, 0, 0, .8); animation: menu-in .25s ease-out; }
.mobile-menu[hidden] { display: none; }
/* The sections in the header links' type (mono capitals), a size up for tapping. */
.mobile-menu a { padding: 16px 4px; font: 500 15px var(--mono); letter-spacing: .12em; text-transform: uppercase; border-bottom: 1px solid var(--line); color: var(--text); }
.mobile-menu a:hover, .mobile-menu a:focus-visible { color: var(--orange); outline: none; }
.mobile-menu a:last-child { border-bottom: 0; }
@keyframes menu-in { from { opacity: 0; transform: translateY(-8px); } }
.alpha {
  font: 500 11px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--orange);
  border: 1px solid rgba(255, 138, 76, .45); background: rgba(255, 138, 76, .1); border-radius: 999px; padding: 5px 9px;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px; height: 46px; padding: 0 20px;
  border-radius: 12px; font-weight: 600; font-size: 15px; letter-spacing: -.01em; border: 0; cursor: pointer;
  transition: transform .15s, background .15s, box-shadow .15s; white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--orange); color: var(--ink); box-shadow: 0 0 0 0 rgba(255, 138, 76, .5); }
.btn-primary:hover { background: #ff9a62; box-shadow: 0 8px 30px -6px rgba(255, 138, 76, .55); }
.btn-ghost { background: transparent; color: var(--text); box-shadow: inset 0 0 0 1.5px var(--line-strong); }
.btn-ghost:hover { box-shadow: inset 0 0 0 1.5px var(--muted); }
.btn-ink { background: var(--ink); color: var(--orange); }
.btn-ink:hover { background: #241c17; }
.nav .btn { height: 38px; padding: 0 14px; font-size: 14px; }

/* ---------- Sections ---------- */

section { position: relative; padding-block: 120px; }
.eyebrow { display: inline-flex; align-items: center; gap: 12px; font: 500 13px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.eyebrow .chip-tile { width: 22px; height: 22px; border-radius: 5px; font-size: 11px; letter-spacing: 0; }
/* The stages' tiles carry an icon in place of their number, drawn like the logo: dark rounded shapes on the orange
   tile (Shape, Context, Align, Build, Ship). */
/* Drawn like the hero's emojis: blocks with soft corners, edge to edge on the tile, at their size and dimmed like them. */
.chip-tile.ico { width: 24px; height: 24px; border-radius: 5px; opacity: .5; }
@media (max-width: 600px) { .chip-tile.ico { width: 21px; height: 21px; border-radius: 4.5px; } }
.chip-tile.ico svg { width: 100%; height: 100%; fill: var(--ink); color: var(--ink); }
.chip-tile.ico .o { fill: var(--orange); }
.chip-tile.ico .cut { stroke: var(--orange); stroke-width: 3.5; paint-order: stroke; }
h1, h2, h3 { margin: 0; letter-spacing: -.035em; line-height: 1.04; font-weight: 700; text-wrap: balance; }
h1 { font-size: clamp(44px, 6.6vw, 86px); font-weight: 800; }
h2 { font-size: clamp(34px, 4.6vw, 58px); font-weight: 800; }
h3 { font-size: 24px; letter-spacing: -.02em; line-height: 1.2; }
.lead { font-size: clamp(18px, 1.6vw, 21px); color: var(--text-2); max-width: 60ch; text-wrap: pretty; }
.head { display: grid; gap: 20px; margin-bottom: 64px; max-width: 820px; }
.head.center { margin-inline: auto; text-align: center; justify-items: center; }

/* Reveal on scroll. */
.reveal { opacity: 0; transform: translateY(28px); transition: opacity .8s cubic-bezier(.16, 1, .3, 1), transform .8s cubic-bezier(.16, 1, .3, 1); }
.reveal.in { opacity: 1; transform: none; }
.reveal[data-d="1"] { transition-delay: .08s; } .reveal[data-d="2"] { transition-delay: .16s; } .reveal[data-d="3"] { transition-delay: .24s; }

/* ---------- Background: the warm glows and a faint grid ---------- */

.glow { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: -1; mask-image: linear-gradient(black 55%, transparent); }
.glow::before, .glow::after { content: ""; position: absolute; border-radius: 50%; filter: blur(120px); }
.glow::before { width: 720px; height: 720px; left: -200px; top: -160px; background: var(--orange); opacity: .14; }
.glow::after { width: 640px; height: 640px; right: -200px; top: 120px; background: #c9502a; opacity: .16; }

/* ---------- Hero ---------- */

.hero { padding-block: 72px 0; isolation: isolate; } /* the demo below sits as far under the button as the button under the text */
/* All in the middle of the page: the text, then the button on its line. */
.hero .wrap { display: grid; grid-template-columns: minmax(0, 1fr); grid-template-areas: "copy" "go"; gap: 40px; align-items: center; justify-items: center; text-align: center; }
.hero .wrap > :first-child { grid-area: copy; }
.hero .actions { grid-area: go; justify-self: stretch; }
.hero .lead .say { justify-content: center; }
/* "Product specs," and "played as a team sport." each stay on one line: the longer one is about 10.8 × the
   font size, sized to the hero's text column (side by side with the animation above 980px, full width
   below). On phones the second line may wrap. */
.hero h1 { font-size: clamp(40px, 3.75vw, 56px); }
.hero h1 .line { display: block; white-space: nowrap; }
.hero .lead { position: relative; margin: 26px 0 0; }
/* The greeting on its own line, then the pitch. */
.hero .lead .hello { display: flex; gap: .45em; align-items: baseline; width: fit-content; margin-bottom: 14px; padding-bottom: 14px; color: var(--text); }
/* Periferal's own emoji: the logo's tile with a glyph drawn in its rounded bars. The hand waves, the question mark's dot pulses, the arrow nudges. */
.emo { display: inline-block; flex: none; width: 1.15em; height: 1.15em; vertical-align: -.2em; opacity: .5; }
.emo .bg { fill: var(--orange); }
.emo .g { fill: var(--ink); }
.emo.wave .g { transform-origin: 32px 52px; animation: emo-wave 2.4s ease-in-out infinite; }
.emo.point .g { animation: emo-nudge 1.6s ease-in-out infinite; }
.emo.ask .dot { transform-origin: 32px 48px; animation: emo-pulse 1.8s ease-in-out infinite; }
@keyframes emo-wave { 0%, 60%, 100% { rotate: 0deg; } 10%, 30% { rotate: 14deg; } 20%, 40% { rotate: -8deg; } }
@keyframes emo-nudge { 50% { translate: 4px 0; } }
@keyframes emo-pulse { 0%, 50%, 100% { scale: .7; } 25%, 75% { scale: 1.25; } }
@media (prefers-reduced-motion: reduce) { .emo .g, .emo .dot { animation: none; } }
/* Each line hangs after its emoji. */
.hero .lead .say { display: flex; gap: .45em; align-items: baseline; }
.hero .lead .say .emo, .hero .lead .hello .emo { translate: 0 .2em; }
.hero .lead .say + .say { margin-top: .35em; }
/* The first line, the one that says what it is, bright; the one after it, grey. */
.hero .lead .say:first-child { color: var(--text); }
.hero .lead .say + .say { color: var(--muted); }
/* The name, set like the logo's wordmark (.lockup). */
.word { font-weight: 600; letter-spacing: -.03em; }
.hero .lead .word { color: var(--text); }
.band .lead .word { color: var(--ink); }
.hero .actions { display: flex; gap: 12px; flex-wrap: wrap; }
/* Builders (a 🧑‍💻) flying along the line into the button from both ends of its row (--from-r, --from-l, set by main.js),
   fading in, dimmed, and gone behind the button. main.js sends them one after another, each flying once. */
.hero .dock { position: relative; display: inline-flex; }
.hero .dock .btn { position: relative; z-index: 1; }
.flyer { position: absolute; top: 50%; width: 22px; height: 22px; margin-top: -11px; opacity: 0; pointer-events: none; animation: 3.2s linear both; }
.flyer .coder { display: block; width: 100%; height: 100%; fill: none; stroke: var(--orange); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
/* The person in full colour; their laptop beside them, on the right, in a thick outline. */
.flyer .coder .fill { fill: var(--orange); stroke: none; }
.flyer .coder .pc { fill: var(--bg); }
/* Now and then a bus, a whole team, drives in along the same line: wider, its windows and wheels in the page's black. */
.flyer.bus { width: 34px; }
.flyer .coder.bus .win { fill: var(--bg); stroke: none; }
.flyer .coder.bus .wheel { fill: var(--orange); stroke: var(--bg); stroke-width: 1.6; }
/* Now and then a builder carries a flag, its pole up from the middle of their laptop's screen, towards the revolution. */
.flyer .coder.flag { overflow: visible; }
.flyer .coder .pole { stroke-width: 1.4; }
.flyer .coder .cloth { fill: var(--orange); stroke: none; transform-origin: 18px -2.4px; animation: flag-wave .5s ease-in-out infinite alternate; }
@keyframes flag-wave { from { scale: 1 1; } to { scale: .82 1.08; } }
.flyer.r { left: 100%; animation-name: fly-r; }
@keyframes fly-r { from { translate: var(--from-r, 200px) 0; opacity: 0; } 30%, 80% { opacity: .4; } to { translate: 0 0; opacity: 0; } }
/* From the left: mirrored, so they face the button too. */
.flyer.l { right: 100%; animation-name: fly-l; }
.flyer.l .coder { scale: -1 1; }
@keyframes fly-l { from { translate: calc(-1 * var(--from-l, 200px)) 0; opacity: 0; } 30%, 80% { opacity: .4; } to { translate: 0 0; opacity: 0; } }
/* The button stands in the middle of its row, on a line across the row that fades out at both ends, builders coming
   in along it from both sides. */
.hero .actions { position: relative; justify-content: center; }
.hero .actions::before {
  content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: 50%; height: 1px; pointer-events: none;
  background: color-mix(in srgb, var(--line-strong), var(--faint)); opacity: .3;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 25%, #000 75%, transparent); mask-image: linear-gradient(90deg, transparent, #000 25%, #000 75%, transparent);
}
@media (prefers-reduced-motion: reduce) { .flyers { display: none; } }

/* The hero art: the tile in the middle; the four builders and their agents around it, their streams
   flowing into it (the pitch's "together, with all their agents, in sync"). */
.orbit { --s: clamp(124px, 19vw, 210px); --ease: cubic-bezier(.65, 0, .35, 1); position: relative; aspect-ratio: 1; width: 100%; max-width: 540px; margin-inline: auto; }
.orbit svg.streams { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; transition: opacity .5s; }
.orbit .stream { fill: none; vector-effect: non-scaling-stroke; stroke-width: 3; stroke-linecap: round; stroke-dasharray: 3 12; animation: flow 1.4s linear infinite; opacity: .9; }
@keyframes flow { to { stroke-dashoffset: -30; } }
.orbit .core { position: absolute; left: 50%; top: 50%; translate: -50% -50%; transition: top .8s var(--ease); }
.orbit .core::before {
  content: ""; position: absolute; inset: -22%; border-radius: 28%; border: 1.5px solid rgba(255, 138, 76, .35);
  animation: ripple 3.2s cubic-bezier(.2, .6, .3, 1) infinite; transition: opacity .4s;
}
@keyframes ripple { from { transform: scale(.75); opacity: .9; } to { transform: scale(1.35); opacity: 0; } }

/* The hero's mark, morphing. Its box (--s square) is the tile. Logo: the orange tile with its four ink
   blocks at the mark's positions (the SVG's units as shares of 64). Editor (.editor): the tile opens into
   a dark window, and the blocks become its rows, every other one still pushed right; the stub becomes
   "+ New requirement". Positions, sizes and colours transition, block after block. */
.morph { width: var(--s); height: var(--s); }
.morph .frame, .morph .blk { position: absolute; transition: left .9s var(--ease), top .9s var(--ease), width .9s var(--ease), height .9s var(--ease), border-radius .9s var(--ease), background-color .6s, border-color .6s, box-shadow .6s; }
.morph .frame { left: 0; top: 0; width: 100%; height: 100%; border-radius: 21.9%; background-color: var(--orange); border: 1px solid transparent;
  box-shadow: 0 30px 80px -10px rgba(255, 138, 76, .45); animation: tile-pop .7s cubic-bezier(.2, 1.4, .4, 1) both; }
.morph .blk { left: 26.27%; width: 43.16%; height: 14.39%; border-radius: calc(var(--s) * .023); background-color: var(--ink); border: 1px solid transparent;
  overflow: hidden; transition-delay: calc(var(--i) * 70ms); animation: block-in .75s cubic-bezier(.2, 1.3, .35, 1) both; animation-delay: calc(.35s + var(--i) * .15s); }
.morph .blk:nth-of-type(2) { top: 15.63%; }
.morph .blk:nth-of-type(3) { top: 33.75%; left: 30.58%; }
.morph .blk:nth-of-type(4) { top: 51.88%; }
.morph .blk:nth-of-type(5) { top: 69.98%; left: 30.58%; width: 20.14%; }
.morph .ed-head, .morph .c { opacity: 0; transition: opacity .25s; }
.morph .ed-head { position: absolute; left: 0; right: 0; top: 0; height: calc(var(--s) * .15); display: flex; align-items: center; gap: 5px; padding: 0 12px;
  border-bottom: 1px solid var(--line); font: 500 calc(var(--s) * .052) var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; }
.morph .ed-head i { width: 7px; height: 7px; border-radius: 4px; background: #3a3940; flex: none; }
.morph .ed-head span { margin-left: 8px; overflow: hidden; text-overflow: ellipsis; }
.morph .c { position: absolute; inset: 0; display: flex; align-items: center; gap: 8px; padding: 0 10px; white-space: nowrap;
  font: 500 calc(var(--s) * .056) var(--sans); color: var(--text); }
.morph .c b { font: 600 calc(var(--s) * .048) var(--mono); color: var(--orange); }
.morph .c em { margin-left: auto; font: normal 600 calc(var(--s) * .042) var(--mono); color: var(--ink); background: var(--st); border-radius: 4px; padding: 1px 5px; }
.morph .stub .c { color: var(--muted); }
/* A row's title gives way (with an ellipsis) to its status or what it gained. */
.morph .c .t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.morph .c em, .morph .c .gain { flex: none; }

/* The editor: a window 1.6 × the tile's width and 1.28 × its height; rows of 20% height, 5% apart. */
.morph.editor .frame { left: -30%; top: -14%; width: 160%; height: 128%; border-radius: 14px; background-color: var(--surface); border-color: var(--line-strong);
  box-shadow: 0 40px 90px -20px rgba(0, 0, 0, .8), 0 0 0 1px rgba(255, 138, 76, .12); }
.morph.editor .blk { left: -23%; width: 146%; height: 20%; border-radius: 9px; background-color: var(--raised); border-color: var(--line); }
.morph.editor .blk.push { left: -17%; width: 140%; }
.morph.editor .blk:nth-of-type(2) { top: 5%; }
.morph.editor .blk:nth-of-type(3) { top: 30%; border-color: rgba(255, 138, 76, .55); }
.morph.editor .blk:nth-of-type(4) { top: 55%; }
.morph.editor .blk:nth-of-type(5) { top: 80%; width: 62%; background-color: transparent; border-style: dashed; }
.morph.editor .ed-head, .morph.editor .c { opacity: 1; transition: opacity .4s .7s; }
.orbit:has(.morph.editor) .core::before { opacity: 0; }
.who { position: absolute; z-index: 2; translate: -50% -50%; transition: opacity .5s; display: flex; align-items: center; gap: 8px; animation: bob 5s ease-in-out infinite; }
.who:nth-child(2n) { animation-delay: -2.5s; }
@keyframes bob { 50% { transform: translateY(-8px); } }
.avatar { width: 52px; height: 52px; border-radius: 50%; display: grid; place-items: center; color: #111; font-weight: 700; font-size: 20px; box-shadow: inset 0 -5px 12px rgba(0, 0, 0, .18); flex: none; }
.agent { display: inline-flex; align-items: center; gap: 6px; font: 500 12px var(--mono); padding: 5px 9px; border-radius: 999px; white-space: nowrap; }
.agent svg { width: 14px; height: 14px; }
.agent b { font-weight: inherit; }

/* ---------- Problem: the numbers ---------- */

.numbers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 56px; --gap: 56px; }
/* The cards are slightly see-through, so the fast-forward arrows behind them show as whole silhouettes. */
.stat { padding: 34px 30px; border-radius: var(--radius); background: rgba(14, 13, 17, .74); border: 1px solid var(--line); position: relative; }
/* The arrows are oversized; they never widen the page. */
#why { overflow-x: clip; }
#why .head { margin-bottom: 20px; } /* with the lead's own space below it, as far from the funnel as the lead is from the title */
.stat .big { font-size: clamp(44px, 4.6vw, 68px); white-space: nowrap; font-weight: 800; letter-spacing: -.05em; line-height: 1; }
.stat .label { color: var(--text-2); margin-top: 14px; font-size: 18px; }
.stat .bar { height: 10px; border-radius: 3px; margin-top: 30px; background: currentColor; opacity: .9; transform-origin: left; transform: scaleX(0); transition: transform 1.2s cubic-bezier(.16, 1, .3, 1) .2s; }
.stat.in .bar { transform: scaleX(var(--w)); }
.stat:nth-child(1) { color: var(--sky); } .stat:nth-child(2) { color: var(--orange); } .stat:nth-child(3) { color: var(--coral); }
.stat .big, .stat .label { color: inherit; } .stat .label { color: var(--text-2); }
/* "turns into": the cards read as one sentence. */
.stat .via { height: 20px; font: 500 12px var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: -14px 0 12px; display: flex; align-items: center; gap: 8px; }
.stat .via::before { content: "↳"; color: currentColor; font-size: 15px; letter-spacing: 0; }
.stat .via.start::before { content: none; }
/* The arrow between two cards, fast forward: two identical chevrons one after the other (›› , or two
   stacked "v" when the cards stack), with a gap of the same angle between them. It fades from nothing through this card's colour into the next card's, and a soft light runs
   along it. It sits behind both cards (z-index -1; a card makes no stacking context once revealed), from
   82% of this card to 17% into the next (when stacked: 136 × 130 px, 30px from the left, from 76% down the card) (the card is 100% wide and the next starts a gap after it: 35% +
   the gap), so the chevrons show in the gap between the cards. In the arrow's box each chevron is 26%
   thick and slants 40% to its point; the second starts 34% after the first (a gap of 8%). */
.stat .flow {
  --grad: linear-gradient(90deg, transparent, color-mix(in srgb, currentColor 55%, transparent) 38%, var(--next));
  --sheen: linear-gradient(90deg, transparent 0 35%, rgba(255, 255, 255, .28) 50%, transparent 65% 100%);
  position: absolute; z-index: -1; left: 82%; top: 50%; width: calc(35% + var(--gap)); height: 80%; translate: 0 -50%;
  opacity: 0; transform: scaleX(.3); transform-origin: left; transition: opacity .6s .9s, transform .9s cubic-bezier(.16, 1, .3, 1) .9s;
}
.stat .flow::before, .stat .flow::after {
  content: ""; position: absolute; inset: 0;
  background: var(--sheen), var(--grad); background-size: 200% 100%, 100% 100%; animation: sheen-x 2.4s linear infinite;
}
.stat .flow::before { clip-path: polygon(0 0, 26% 0, 66% 50%, 26% 100%, 0 100%, 40% 50%); }
.stat .flow::after { clip-path: polygon(34% 0, 60% 0, 100% 50%, 60% 100%, 34% 100%, 74% 50%); }
@keyframes sheen-x { from { background-position: 100% 0, 0 0; } to { background-position: -100% 0, 0 0; } }
@keyframes sheen-y { from { background-position: 0 100%, 0 0; } to { background-position: 0 -100%, 0 0; } }
.stat.in .flow { opacity: .35; transform: none; }
/* A funnel: each step splits in two. The 10× spans both rows; what goes on (2–3×, then even less) takes the top row,
   joined by the arrows, and what's left behind at each step (the rest) sits in the card under it. */
.numbers { grid-template-rows: auto auto; row-gap: 20px; }
.numbers .stat:nth-child(1) { grid-row: 1 / span 2; display: flex; flex-direction: column; justify-content: center; }
.numbers .stat:nth-child(1) .big { font-size: clamp(64px, 7.4vw, 112px); }
/* The arrow from the 10× into the 2–3× hangs from the 2–3× card, so it lines up with the arrow after it (the 10×
   is taller). It starts where it would on the 10×: 18% of a card and a gap before the 2–3×. */
.stat .flow.from-prev { left: calc(-18% - var(--gap)); }
.stat .flow.stacked-only { display: none; }
/* What each step leaves behind: a faint red wash. */
.stat.waste { background: linear-gradient(160deg, rgba(239, 106, 90, .07), rgba(239, 106, 90, .015) 60%), rgba(14, 13, 17, .74); border-color: rgba(239, 106, 90, .14); }
.stat.waste { color: var(--coral); padding-block: 26px; }
.stat.waste .via { margin-bottom: 16px; }
.stat.waste .via::before { content: "↳"; }
.rest { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; color: var(--text-2); font-size: 18px; }
.pill { font: 500 14px var(--mono); padding: 6px 12px; border-radius: 9px; border: 1.5px solid; }
.pill.red { color: var(--coral); border-color: rgba(239, 106, 90, .5); background: rgba(239, 106, 90, .08); }
/* An icon before the words: alarm, redo, bin. */
.rest .pill { display: inline-flex; align-items: center; gap: 8px; }
.rest .pill svg { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- The numbers as the app's graph view ---------- */
/* A dotted canvas, framed like the app's window; the cards are graph cards, each with its label over it (like
   "REQUIREMENT" in the app), joined by curved links with arrowheads (main.js) instead of the chevrons. */
.numbers.graph { position: relative; padding: 52px 40px 40px; row-gap: 52px; border: 1px solid var(--line); border-radius: 22px;
  background: radial-gradient(circle, #34333d 1.1px, transparent 1.3px) 0 0 / 24px 24px, var(--bg); } /* the graph view's dot grid, at full size, a touch brighter */
.numbers.graph .stat .flow { display: none !important; }
/* Smaller cards, of their own widths, with room between the columns for the links to split. */
@media (min-width: 981px) {
  .numbers.graph { grid-template-columns: auto auto auto; justify-content: space-between; column-gap: 0; }
  .numbers.graph .stat { justify-self: start; }
  .numbers.graph .stat:nth-child(1) { align-self: center; } /* as tall as its content, in the middle of the two rows */
  .numbers.graph .stat:nth-child(1) { width: 230px; }
  .numbers.graph .stat:nth-child(2), .numbers.graph .stat:nth-child(4) { width: 270px; }
  .numbers.graph .stat:nth-child(3), .numbers.graph .stat:nth-child(5) { width: 250px; }
}
.numbers.graph .stat .big { font-size: clamp(36px, 3.4vw, 48px); }
.numbers.graph .stat:nth-child(1) .big { font-size: clamp(54px, 5.6vw, 80px); }
.numbers.graph .stat .label { font-size: 16px; margin-top: 10px; }
.numbers.graph .stat .bar { margin-top: 20px; height: 8px; }
/* Each bar shows its whole length: a dark track, filled to its share (--w) in the card's colour. */
.numbers.graph .stat .bar { opacity: 1; transform: none; background: linear-gradient(currentColor, currentColor) 0 0 / 0 100% no-repeat, rgba(255, 255, 255, .08);
  transition: background-size 1.2s cubic-bezier(.16, 1, .3, 1) .2s; }
.numbers.graph .stat.in .bar { background-size: calc(var(--w) * 100%) 100%, auto; }
.numbers.graph .stat { padding: 22px 22px; }
.numbers.graph .stat.waste { padding-block: 20px; align-self: start; } /* what's left behind: as tall as its pills */
.numbers.graph .rest { gap: 8px; }
.numbers.graph .pill { font-size: 13px; padding: 5px 10px; }
.numbers.graph .stat { padding: 26px 24px; border-radius: 14px; background: var(--surface); border-color: var(--line-strong); box-shadow: 0 20px 50px -30px rgba(0, 0, 0, .9); }
.numbers.graph .stat.waste { background: linear-gradient(160deg, rgba(239, 106, 90, .08), rgba(239, 106, 90, .02) 60%), var(--surface); border-color: rgba(239, 106, 90, .22); }
.numbers.graph .stat .via { position: absolute; left: 4px; bottom: calc(100% + 8px); height: auto; margin: 0; font-size: 11px; color: var(--muted); }
.numbers.graph .stat .via::before { content: ""; width: 9px; height: 9px; border: 1.5px solid currentColor; border-radius: 3px; opacity: .8; }
/* The start of the funnel ("With AI"): a rocket, a line icon like the app's. */
.numbers.graph .stat .via.start::before { width: 14px; height: 14px; border: 0; border-radius: 0; background: currentColor; opacity: .9;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z'/%3E%3Cpath d='m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z'/%3E%3Cpath d='M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0'/%3E%3Cpath d='M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z'/%3E%3Cpath d='m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z'/%3E%3Cpath d='M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0'/%3E%3Cpath d='M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5'/%3E%3C/svg%3E") center / contain no-repeat; }
/* The outcomes ("real outcomes"): a dartboard with a dart that missed the bull's eye, the same kind of icon. */
.numbers.graph .stat .via.goal::before { width: 16px; height: 16px; border: 0; border-radius: 0; background: currentColor; opacity: .9;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 26 26' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8.5' cy='15.5' r='8'/%3E%3Ccircle cx='8.5' cy='15.5' r='4'/%3E%3Ccircle cx='8.5' cy='15.5' r='1'/%3E%3Cpath d='M14 10 22.5 1.5M22.5 1.5h2.5M22.5 1.5V-1M20.5 3.5h3M20.5 3.5V0.5'/%3E%3Cpath d='M14 10 17.5 6.5' stroke-width='3.6'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-1 -1 26 26' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8.5' cy='15.5' r='8'/%3E%3Ccircle cx='8.5' cy='15.5' r='4'/%3E%3Ccircle cx='8.5' cy='15.5' r='1'/%3E%3Cpath d='M14 10 22.5 1.5M22.5 1.5h2.5M22.5 1.5V-1M20.5 3.5h3M20.5 3.5V0.5'/%3E%3Cpath d='M14 10 17.5 6.5' stroke-width='3.6'/%3E%3C/svg%3E") center / contain no-repeat; }
/* What's left behind ("The rest?"): a sad face, the same kind of icon. */
.numbers.graph .stat.waste .via::before { width: 14px; height: 14px; border: 0; border-radius: 0; background: currentColor; opacity: .9;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M16 16s-1.5-2-4-2-4 2-4 2'/%3E%3Cline x1='9' y1='9' x2='9.01' y2='9'/%3E%3Cline x1='15' y1='9' x2='15.01' y2='9'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M16 16s-1.5-2-4-2-4 2-4 2'/%3E%3Cline x1='9' y1='9' x2='9.01' y2='9'/%3E%3Cline x1='15' y1='9' x2='15.01' y2='9'/%3E%3C/svg%3E") center / contain no-repeat; }
/* The team's output ("accepted team output"): a team, the same kind of icon. */
.numbers.graph .stat .via.team::before { width: 14px; height: 14px; border: 0; border-radius: 0; background: currentColor; opacity: .9;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87'/%3E%3Cpath d='M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87'/%3E%3Cpath d='M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E") center / contain no-repeat; }
.g-links { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.numbers.graph .stat { z-index: 1; }
.numbers.graph .g-links { z-index: 2; } /* over the cards' edges, so each arrowhead shows where it lands; links only run between cards */
.g-links > path { fill: none; stroke: color-mix(in srgb, var(--text-2) 55%, transparent); stroke-width: 2; }
.g-links > path.on { stroke: var(--orange); stroke-width: 2.2; stroke-dasharray: 6 5; animation: g-flow 1s linear infinite; }
.g-links > path.lost { stroke: rgba(239, 106, 90, .75); stroke-dasharray: 2 5; stroke-width: 2.2; }
.g-links circle { fill: var(--bg); stroke: var(--orange); stroke-width: 2; } /* where a step splits */
/* The graph builds up from the first card (main.js): each link draws itself out of its card (a mask over it, drawn out
   along it), and the card it leads to fades in, in place, where it lands. */
.numbers.graph .stat.reveal { transform: none; transition: opacity .45s ease; transition-delay: 0s; }
.g-links mask path { fill: none; stroke: #fff; stroke-width: 18; stroke-dasharray: 1 1; stroke-dashoffset: 1; }
.g-links mask path.drawn { stroke-dashoffset: 0; transition: stroke-dashoffset .6s cubic-bezier(.45, 0, .2, 1); }
.numbers.graph .g-links > circle { opacity: 0; transition: opacity .3s ease; }
.numbers.graph .g-links > circle.lit { opacity: 1; }
@keyframes g-flow { to { stroke-dashoffset: -11; } }
@media (prefers-reduced-motion: reduce) { .g-links > path.on { animation: none; } }
@media (max-width: 980px) { .numbers.graph { padding: 44px 18px 22px; row-gap: 104px; } } /* room for the links to split above the labels */

/* ---------- Human ↔ agent, crowding out human ↔ human ---------- */

/* The heading centred; under it the two kinds of work set against each other (vs.); under them the lanes, centred. */
.displaced .wrap { display: grid; justify-items: center; }
.displaced .head { margin-bottom: 44px; }
.versus { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: start; gap: 36px; width: min(100%, 920px); margin-bottom: 56px; }
.vs-side { display: grid; gap: 12px; justify-items: end; text-align: right; }
.vs-side:last-child { justify-items: start; text-align: left; }
.vs-side p { margin: 0; max-width: 34ch; font-size: 18px; line-height: 1.55; color: var(--text-2); }
/* VS as on a fight poster: heavy, slanted, split in the two sides' colours (coral for single-player, green for
   collaborative), with a slash cutting through behind it. */
.vs { align-self: center; position: relative; isolation: isolate; display: grid; place-items: center; padding: 6px 10px; font: 900 clamp(72px, 8vw, 104px)/1 var(--sans); letter-spacing: -.03em; /* upright; twice its old 52px at full size */
  background: linear-gradient(100deg, var(--coral) 0 47%, var(--green) 53%); -webkit-background-clip: text; background-clip: text; color: transparent; filter: drop-shadow(0 6px 22px rgba(255, 138, 76, .28)); }
/* Fading out a little at the sides: the fade covers a wider box than the letters (so their glow fades with it, and no
   edge shows), reaching the letters' ends at well under half strength. */
.vs { padding: .65em .85em; margin: -.54em -.65em; -webkit-mask: linear-gradient(90deg, transparent 6%, #000 50%, transparent 94%), linear-gradient(transparent, #000 35%, #000 65%, transparent); -webkit-mask-composite: source-in; mask: linear-gradient(90deg, transparent 6%, #000 50%, transparent 94%), linear-gradient(transparent, #000 35%, #000 65%, transparent); mask-composite: intersect; }
.vs::before { content: ""; position: absolute; z-index: -1; left: 50%; top: -18%; width: 3px; height: 136%; translate: -50% 0; rotate: 22deg; background: linear-gradient(transparent, var(--line-strong) 25%, var(--line-strong) 75%, transparent); }
.displaced .lanes { width: min(100%, 560px); }
/* Desktops: the verdict beside the lanes, in the same panel; the people's places (--px, a share of the lanes' width)
   count across the lanes' column only (--u). */
@media (min-width: 981px) {
  .displaced .lanes { width: min(100%, 900px); grid-template-columns: minmax(0, 1fr) 260px; column-gap: 24px; --u: calc((100cqi - 284px) / 100); }
  .displaced .lanes > :not(.verdict) { grid-column: 1; }
  .displaced .lanes .verdict { grid-column: 2; grid-row: 1 / span 4; align-self: center; margin: 0; }
}
@media (max-width: 760px) {
  .versus { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 18px; }
  .vs-side, .vs-side:last-child { justify-items: center; text-align: center; }
}
.versus .pt-tag { white-space: nowrap; font: 500 13px var(--mono); border-radius: 7px; padding: 1px 9px; } /* as in the lanes' head */
.versus .pt-tag.single { color: var(--coral); border: 1px solid rgba(239, 106, 90, .45); background: rgba(239, 106, 90, .08); }
.versus .pt-tag.together { color: var(--green); border: 1px solid rgba(116, 211, 154, .45); background: rgba(116, 211, 154, .08); }
/* Three lanes, each one person and their agent, walled off from the others by dashed lines; work goes
   back and forth along each. */
.lanes { display: grid; gap: 14px; padding: 22px; border-radius: 22px; background: var(--surface); border: 1px solid var(--line); }
.lanes-head { display: flex; justify-content: space-between; align-items: center; font: 500 13px var(--mono); color: var(--muted); padding: 0 4px 4px; }
.lanes-head .single { color: var(--coral); border: 1px solid rgba(239, 106, 90, .45); background: rgba(239, 106, 90, .08); border-radius: 7px; padding: 2px 9px; }
.lane { display: grid; grid-template-columns: 44px 1fr 44px; align-items: center; gap: 12px; padding: 14px; border-radius: 14px; border: 1.5px dashed var(--line-strong); }
.lane .person, .lane .bot { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; color: var(--c); background: color-mix(in srgb, var(--c) 14%, transparent); border: 1.5px solid color-mix(in srgb, var(--c) 55%, transparent); }
.lane .bot { border-radius: 12px; }
.lane svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* The labels slide along the track by transform (100cqi is the track's width), not by left: no layout each frame. */
.lane .track { position: relative; height: 30px; container-type: inline-size; }
.lane .track::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 2px; translate: 0 -50%; background: color-mix(in srgb, var(--c) 35%, transparent); }
.lane .go, .lane .back { position: absolute; top: 50%; translate: 0 -50%; white-space: nowrap; font: 600 12px var(--mono); color: var(--c); background: var(--bg);
  border: 1.5px solid var(--c); border-radius: 8px; padding: 3px 8px; opacity: 0; animation: lane-go 4.8s cubic-bezier(.45, 0, .55, 1) infinite; animation-delay: var(--d); }
.lane .back { animation-name: lane-back; animation-delay: calc(var(--d) + 2.4s); }
@keyframes lane-go { 0% { transform: translateX(0); opacity: 0; } 8% { opacity: 1; } 42% { opacity: 1; } 50%, 100% { transform: translateX(calc(100cqi - 100%)); opacity: 0; } }
@keyframes lane-back { 0% { transform: translateX(calc(100cqi - 100%)); opacity: 0; } 8% { opacity: 1; } 42% { opacity: 1; } 50%, 100% { transform: translateX(0); opacity: 0; } }
.lanes .verdict { display: flex; align-items: center; gap: 16px; margin-top: 6px; padding: 18px 20px; border-radius: 14px; border: 2px dashed rgba(255, 138, 76, .5); color: var(--text-2); font-size: 16px; }
.lanes .verdict b { color: var(--text); }

/* Before: human ↔ human (.together). The people gather in the middle as a small network (--px: where
   each one's centre goes, in % of the panel; it starts 60px in), linked by dotted lines with what passes
   between them; lanes, agents and their traffic are gone. Then they move back out into their lanes. */
.lanes { position: relative; container-type: inline-size; }
.lanes .links { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; opacity: 0; transition: opacity .25s; }
.lanes .links.show { opacity: 1; transition-duration: .5s; }
.lanes .links line { stroke: var(--text-2); stroke-width: 2; stroke-dasharray: 2 7; stroke-linecap: round; opacity: .55; animation: flow 1s linear infinite; }
.lanes .link-label { position: absolute; z-index: 3; translate: -50% -50%; font: 600 11px var(--mono); color: var(--text); background: var(--raised); border: 1px solid var(--line-strong);
  border-radius: 7px; padding: 2px 7px; white-space: nowrap; opacity: 0; transform: scale(.7); transition: opacity .35s, transform .35s; }
.lanes .link-label.show { opacity: 1; transform: none; }
/* In order. Into the lanes: the people move first (.9s), then the walls, agents and traffic fade in.
   Back together: the walls, agents and traffic fade out first, then the people gather. */
.lane { transition: border-color .5s .9s; }
.lane .person { position: relative; z-index: 2; transition: transform .9s cubic-bezier(.65, 0, .35, 1); }
.lane .bot, .lane .track { transition: opacity .45s .9s, transform .45s .9s; }
.lanes.together .lane { transition-delay: 0s; }
.lanes.together .lane .bot, .lanes.together .lane .track { transition-delay: 0s; }
.lanes.together .lane .person { transition-delay: .45s; }
.lanes.together .lane { border-color: transparent; }
.lanes.together .lane .person { transform: translateX(calc(var(--px) * var(--u, 1cqi) - 60px)); }
.lanes.together .lane .bot { opacity: 0; transform: scale(.5); }
/* Two of them keep their agent, beside them (--bx, --by), linked (main.js): it moves with its person. */
.lanes.together .lane .bot.paired { opacity: 1; z-index: 2; transform: translate(calc(var(--px) * var(--u, 1cqi) - 60px - var(--span, 0px) + var(--bx)), var(--by)) scale(.82); transition-delay: .45s; transition-duration: .9s; transition-timing-function: cubic-bezier(.65, 0, .35, 1); }
.lanes .links line.ag { stroke: var(--c, var(--text-2)); stroke-dasharray: 1 5; opacity: .45; }
.lanes .links line.aa { stroke: var(--text-2); stroke-dasharray: 1 6; opacity: .3; } /* agent ↔ agent: in sync too */
/* Into the lanes, each person's agent moves with them, at the same time and pace (it stays in view throughout). */
.lane .bot.paired { transition: opacity .45s .9s, transform .9s cubic-bezier(.65, 0, .35, 1); }
.lanes.together .lane .track { opacity: 0; }
/* Each label and tag pair shares one spot, and they cross-fade. */
.lanes-head .mode, .lanes-head .tags { display: grid; } .lanes-head .mode > *, .lanes-head .tags > * { grid-area: 1 / 1; transition: opacity .4s; }
.lanes-head .tags > * { justify-self: end; }
.lanes-head .m-before, .lanes-head .together-tag { opacity: 0; }
.lanes.together .m-before, .lanes.together .together-tag { opacity: 1; }
.lanes.together .m-now, .lanes.together .single { opacity: 0; }
.lanes-head .together-tag { color: var(--green); border: 1px solid rgba(116, 211, 154, .45); background: rgba(116, 211, 154, .08); border-radius: 7px; padding: 2px 9px; }

/* ---------- Mission band: the orange tile, full width ---------- */

.band { background: var(--orange); color: var(--ink); overflow: hidden; isolation: isolate; padding-block: 110px; }
.band h2 { font-size: clamp(38px, 5.4vw, 72px); max-width: 15ch; }
.band h2 .soft { color: rgba(22, 18, 15, .55); }
/* "People shape…" on its own line, half a line (.8em of the 1.6 line height) below the first. */
.band .lead .para { display: block; margin-top: .8em; }
.band .lead { color: rgba(22, 18, 15, .78); margin-top: 26px; max-width: 46ch; }
.band .eyebrow { color: rgba(22, 18, 15, .7); }
.band .eyebrow .chip-tile { background: var(--ink); color: var(--orange); }
/* The chain along the bottom of the band, at every width: people side by side, hands joined and raised, their agents
   among them, a flag of the logo's blocks over one pair. Ink on the orange, faint, behind the words, edge to edge:
   lined up on the right (preserveAspectRatio), it runs on past the left edge, and past the right edge after the flag.
   The drawing is 254 units high: the people in its lower 194, at --chain-h, and the top 60 for the flag. --run is the
   part after the flag, 1072 units (1796 wide before it), at whichever scale the slice takes; the chain is that much
   wider than the width that puts the flag where it is. */
.band { --chain-h: 196px; padding-bottom: calc(var(--chain-h) * 254 / 194 - 10px); }
.band .chain { --w: calc(108vw - min(38vw, 540px) - 32px); --run: max(var(--w) * 1072 / 1796, var(--chain-h) * 1072 / 194); position: absolute; z-index: -2; left: 0; bottom: -6px; width: calc(var(--w) + var(--run)); max-width: none; height: calc(var(--chain-h) * 254 / 194); color: var(--ink); opacity: .11; pointer-events: none; overflow: visible; }
/* On smaller screens the people are scaled to span the band, and the chain is lined up a fifth of the width in from
   the right, so the flag stands well inside the screen. The text ends above it. */
@media (max-width: 980px) {
  .band { --chain-h: max(170px, (100vw - 12px) * 194 / 858); padding-bottom: calc(var(--chain-h) * 254 / 194 + 24px); }
  .band .chain { --run: max(1500px * 1072 / 1796, var(--chain-h) * 1072 / 194); left: auto; right: calc(22vw - var(--run)); width: calc(1500px + var(--run)); opacity: .09; }
}
@media (max-width: 600px) {
  .band { --chain-h: max(130px, (100vw - 12px) * 194 / 858); }
  .band .chain { --run: max(1100px * 1072 / 1796, var(--chain-h) * 1072 / 194); width: calc(1100px + var(--run)); }
}
/* Where the flag stands beside the text (main.js), at any width, the text only ends a little above the raised hands. */
.band.flag-side { padding-bottom: calc(var(--chain-h) * 100 / 194 + 64px); }
/* As the chain comes into view it appears from left to right, the way the logo's blocks used to slide in: an orange
   cover over its strip, with a soft leading edge, glides off to the right, in the band's own frame. */
.band::after { content: ""; position: absolute; z-index: -1; left: -160px; right: 0; bottom: 0; height: calc(var(--chain-h) * 254 / 194 + 6px); background: linear-gradient(90deg, transparent, var(--orange) 160px); pointer-events: none; transition: transform 1.6s cubic-bezier(.16, 1, .3, 1) .1s; }
.band:has(.chain.in)::after { transform: translateX(calc(100% + 160px)); }
.band .chain .p, .band .chain .cloth, .band .chain .sway > circle { fill: currentColor; }
.band .chain .arms, .band .chain .pole { fill: none; stroke: currentColor; stroke-width: 11; stroke-linecap: round; stroke-linejoin: round; }
.band .chain .pole { stroke-width: 3.5; }
.band .chain .b { fill: none; stroke: currentColor; stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; }
.band .chain .b .e { fill: currentColor; stroke: none; }
.band .chain .sway { transform-origin: 50% 100%; transform-box: fill-box; animation: band-sway 6s ease-in-out infinite alternate; }
.band .chain .cloth { transform-box: fill-box; transform-origin: left center; animation: band-wave 2.4s ease-in-out infinite alternate; }
@keyframes band-sway { from { transform: rotate(-.6deg) translateX(-6px); } to { transform: rotate(.6deg) translateX(6px); } }
@keyframes band-wave { from { transform: skewY(-4deg) scaleX(.96); } to { transform: skewY(3deg) scaleX(1); } }
@media (prefers-reduced-motion: reduce) { .band .chain .sway, .band .chain .cloth { animation: none; } }
/* The flag grows from the foot of its pole. Where there is room right of the text, main.js moves it to the joined hands
   where it can stand biggest without reaching over the text or past the page's edge, and scales it to fit. */
.band .chain .flag { transform-box: fill-box; transform-origin: 0% 100%; }

/* ---------- Pillars ---------- */

.pillars { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.pillar, .pillar .art { min-width: 0; }
.pillar { border-radius: 22px; background: linear-gradient(180deg, var(--raised), var(--surface)); border: 1px solid var(--line); padding: 30px; display: flex; flex-direction: column; gap: 16px; min-height: 560px; }
/* Labelled like the stages in How it all works. */
.pillar .num { font: 500 13px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--orange); display: flex; align-items: center; gap: 12px; }
/* The tile at the size of the hero's emojis, dimmed like them. */
.pillar .num .tile { --s: 24px; opacity: .5; }
@media (max-width: 600px) { .pillar .num .tile { --s: 21px; } }
.pillar p { margin: 0; color: var(--text-2); font-size: 16px; }
.pillar .art { margin-top: auto; border-radius: 14px; background: var(--bg); border: 1px solid var(--line); padding: 18px; min-height: 230px; position: relative; overflow: hidden; font-size: 13px; }

/* Pillar 1: a requirement block, with its panels sliding through, one by one. */
.req .id { font: 500 12px var(--mono); color: var(--alex); }
.req .text { color: var(--text-2); line-height: 1.45; } .req .text b { color: var(--text); font-weight: 600; }
.tools { display: flex; gap: 4px; margin: 12px 0 10px; }
.tools span { display: inline-flex; align-items: center; gap: 4px; padding: 4px 7px; border-radius: 6px; color: var(--faint); font: 12px var(--mono); transition: color .3s, background .3s; }
.tools span.on { color: var(--orange); background: rgba(255, 138, 76, .14); }
.tools svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.tools .sep { width: 1px; background: var(--line); margin: 3px 4px; padding: 0; }
.tools svg { flex: none; }
.tools .n { font-weight: inherit; }
/* In a narrow card the counts go, and the icons keep their size. */
.pillar .art.req { container-type: inline-size; }
@container (max-width: 240px) { .tools .n { display: none; } .tools span { padding: 5px 7px; } }
.panels { position: relative; height: 120px; border-radius: 10px; border: 1px solid var(--line); background: var(--surface); overflow: hidden; }
.panels .track { display: flex; height: 100%; transition: transform .9s cubic-bezier(.65, 0, .35, 1); }
.panels .p { flex: 0 0 100%; padding: 10px 12px; display: grid; gap: 7px; align-content: start; }
.panels .p .t { font-weight: 600; font-size: 13px; display: flex; gap: 8px; align-items: center; }
.panels .rid { font: 11px var(--mono); color: var(--orange); background: rgba(255, 138, 76, .14); border-radius: 5px; padding: 0 6px; }
.panels .p { min-width: 0; }
/* Every line stays on one line: anything too long ends with an ellipsis, so the panel fits any width. */
.panels .row { display: flex; align-items: center; gap: 8px; min-width: 0; white-space: nowrap; color: var(--text-2); }
.panels .row .x { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.panels .row.meta { color: var(--muted); font-size: 12px; }
.mini { width: 18px; height: 18px; border-radius: 9px; display: inline-grid; place-items: center; font-size: 9px; font-weight: 700; color: #111; flex: none; }
.did { font: 11px var(--mono); color: var(--green); border: 1px solid rgba(116, 211, 154, .5); background: rgba(116, 211, 154, .1); border-radius: 5px; padding: 0 5px; }
.meta { color: var(--faint); font-size: 12px; }

/* Pillar 2: the ledger: the tile in the middle, the sources syncing into it. */
/* The block, and under it on a rail the entries synced into it, newest on top: each one slides in from above, the rest
   move down a row and age, the fifth fades out (main.js sets --at, the row's place). Only transform and opacity move. */
.ledger { display: flex; flex-direction: column; gap: 12px; }
.lg-block { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--raised); font-size: 12.5px; color: var(--text); white-space: nowrap; min-width: 0; }
.lg-block .tile { --s: 18px; flex: none; }
.lg-block > b { font: 600 11px var(--mono); color: var(--orange); }
.lg-block > span { overflow: hidden; text-overflow: ellipsis; }
.lg-block em { margin-left: auto; font: 500 10.5px var(--mono); font-style: normal; color: var(--muted); }
.lg-block .lg-count { display: inline-block; color: var(--text); }
.lg-block .lg-count.bump { animation: lg-bump .45s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes lg-bump { 40% { transform: scale(1.35); } }
.lg-feed { position: relative; height: 136px; margin-left: 18px; border-left: 1px dashed var(--line-strong); }
.lg-row {
  position: absolute; left: 0; right: 0; top: 2px; height: 30px; display: flex; align-items: center; gap: 8px; padding: 0 8px 0 14px;
  border-radius: 8px; font-size: 12px; white-space: nowrap; transform: translateY(calc(var(--at, 0) * 34px));
  transition: transform .55s cubic-bezier(.2, .8, .2, 1), opacity .45s, background-color .6s;
}
.lg-row.gone { opacity: 0; }
.lg-row.enter { transition: none; transform: translateY(-34px); opacity: 0; }
.lg-row.new { background-color: color-mix(in srgb, var(--c) 9%, transparent); }
.lg-row i { position: absolute; left: -4.5px; width: 8px; height: 8px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 3px var(--bg); }
.lg-row b { font: 600 11.5px var(--mono); color: var(--c); }
.lg-row span { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.lg-row time { margin-left: auto; font: 500 10.5px var(--mono); color: var(--faint); }

/* Pillar 3: the live surface: cursors of the team editing the same sentence. */
.live { font-size: 15px; line-height: 2.1; color: var(--text-2); }
/* The requirement's text stays narrow enough to wrap in three lines, however wide the card is, centred in
   the full-width block. */
.pillar .art.live { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; }
.live-text { width: 100%; max-width: 344px; }
.live b { color: var(--text); font-weight: 600; }
.cursor { position: relative; display: inline-block; width: 2px; height: 1.15em; vertical-align: -.2em; margin: 0 1px; animation: blink 1.1s steps(1) infinite; }
.cursor::after { content: attr(data-who); position: absolute; left: 0; bottom: 100%; font: 600 10px/1 var(--sans); color: #111; background: inherit; padding: 2px 5px; border-radius: 4px 4px 4px 0; white-space: nowrap; animation: none; }
@keyframes blink { 50% { opacity: .35; } }
.hl { border-radius: 3px; padding: 1px 0; }
.typing::after { content: ""; display: inline-block; width: 0; overflow: hidden; vertical-align: bottom; white-space: nowrap; }

/* A list with pulsing orange dots as bullets; the pulses ripple down the list. */
/* Indented to line up with the text inside the stage cards below (their 1px border and 36px padding; 26px on narrow screens). */
.pulse-list { list-style: none; margin: 0; padding: 0 0 0 37px; display: grid; gap: 10px; font-size: clamp(17px, 1.5vw, 19px); color: var(--text); }
.pulse-list li { position: relative; display: flex; align-items: center; gap: 14px; }
.pulse-list li::before {
  content: ""; flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--orange);
  animation: dot-beat 2.4s ease-out infinite; animation-delay: calc(var(--i) * .25s);
}
/* The ripple: a disc behind the dot that grows to three times its size (9px all round) and fades, by transform and
   opacity, so it never repaints. */
.pulse-list li::after {
  content: ""; position: absolute; left: 0; top: 50%; width: 9px; height: 9px; margin-top: -4.5px; border-radius: 50%;
  background: rgba(255, 138, 76, .55); opacity: 0; pointer-events: none;
  animation: dot-ripple 2.4s ease-out infinite; animation-delay: calc(var(--i) * .25s);
}
@keyframes dot-beat { 30% { transform: scale(1.15); } }
@keyframes dot-ripple { 0% { transform: scale(1); opacity: 1; } 70%, 100% { transform: scale(3); opacity: 0; } }

/* The list and, to its right, a plan going through the five stages: rows appear (shape), then gain
   attachments (context), comments (align) and agents (build); each row moves through Draft, Review,
   In dev and Built on its own schedule, all Built at ship. .s1 to .s4
   are set cumulatively by main.js; the current bullet is lit (.on). */
#how .head { max-width: none; }
.howto { display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr); gap: 10px; align-items: center; } /* with the list's own 37px for its dots, 47px from the plan to them */
@media (min-width: 981px) { .howto .plan-anim { order: -1; } } /* the plan on the left, the stages on the right; text first when stacked */
@media (min-width: 981px) { .howto { grid-template-columns: minmax(0, 560px) auto; justify-content: center; } } /* the plan and the list sized to their content and centred as one group, no empty space after the list */
.howto-text { display: grid; gap: 18px; }
.pulse-list li { transition: color .4s; color: var(--text-2); }
.pulse-list li.on { color: var(--text); }
.pulse-list li.on::before { background: #ffb07f; }
/* Stacked, with the plan under it: one stage at a time, in a band (.shown, main.js). The next one slides up into place
   from below as the one before slides up and out; the others wait out of sight below. */
@media (max-width: 980px) {
  /* Its lines, top and bottom, and its fill fade out to the left and right. */
  .pulse-list { --edge: linear-gradient(90deg, transparent 22%, var(--line-strong) 48%, var(--line-strong) 52%, transparent 78%); overflow: hidden; padding: 14px 20px;
    background: var(--edge) top / 100% 1px no-repeat, var(--edge) bottom / 100% 1px no-repeat, linear-gradient(90deg, transparent 22%, var(--surface) 48%, var(--surface) 52%, transparent 78%); }
  .pulse-list li { grid-area: 1 / 1; opacity: 0; transform: translateY(130%); transition: transform .55s cubic-bezier(.16, 1, .3, 1), opacity .35s, color .4s; }
  .pulse-list li.shown { opacity: 1; transform: none; color: var(--text); }
  .pulse-list li.out { transform: translateY(-130%); }
  .pulse-list li { justify-self: center; } /* each stage, dot and words, centred in the band */
}
.plan-anim { position: relative; padding: 0 0 14px; border-radius: 14px; border: 1px solid var(--line-strong); background: var(--surface); overflow: hidden;
  font: 500 12px var(--mono); box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .8); }
.pa-head { display: flex; align-items: center; gap: 5px; padding: 10px 12px; border-bottom: 1px solid var(--line); color: var(--muted); margin-bottom: 8px; }
.pa-head i { width: 7px; height: 7px; border-radius: 4px; background: #3a3940; }
.pa-head span:first-of-type { margin-left: 8px; }
.pa-stage { margin-left: auto; color: var(--orange); }
.pa-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 10px; margin: 0 12px 6px 12px; padding: 8px 10px; border-radius: 8px;
  background: var(--raised); border: 1px solid var(--line); opacity: 0; transform: translateX(-14px); transition: opacity .5s, transform .5s; transition-delay: calc(var(--i) * .12s); }
.pa-row.push { margin-left: 26px; }
.plan-anim.s0 .pa-row { opacity: 1; transform: none; }
.pa-row b { color: var(--orange); font-weight: 600; }
.pa-row .line { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, .14); max-width: 100%; }
/* As wide as the widest row's pills (three agents), so the statuses line up down the rows. */
.pa-row .pills { display: flex; gap: 4px; min-width: 150px; }
@media (max-width: 600px) {
  .pa-row .pills { min-width: 0; gap: 3px; }
  .plan-anim .pill { padding: 1px 4px; }
  .plan-anim .pill.bot svg { width: 10px; height: 10px; }
  .plan-anim .pill.bot.many { gap: 2px; }
  .pa-row { gap: 6px; margin: 0 8px 6px; padding: 8px; }
  .pa-row.push { margin-left: 18px; }
}
.plan-anim .pill { display: inline-flex; align-items: center; gap: 3px; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--line-strong); color: var(--text-2); font-size: 11px;
  opacity: 0; transform: scale(.5); transition: opacity .35s, transform .35s cubic-bezier(.2, 1.5, .4, 1); transition-delay: calc(var(--i) * .1s); }
.plan-anim .pill.talk i { width: 8px; height: 8px; border-radius: 50%; margin-right: -2px; }
.plan-anim .pill.talk i + i { margin-right: 2px; }
.plan-anim .pill.bot { color: #d97757; border-color: #d9775766; } .plan-anim .pill.bot svg { width: 12px; height: 12px; }
/* Several agents on a block: each in its own colour (Claude Code, Codex, Cursor), on a neutral pill. */
.plan-anim .pill.bot.many { gap: 4px; border-color: var(--line-strong); }
/* On the narrowest phones a pill with several agents shows the first and how many (main colour, count). */
.plan-anim .pill.bot .n { display: none; font-weight: 500; color: var(--text-2); }
@media (max-width: 400px) {
  .plan-anim .pill.bot.many svg + svg { display: none; }
  .plan-anim .pill.bot.many .n { display: inline; }
}
.plan-anim .pill.ctx svg { width: 11px; height: 11px; flex: none; color: var(--muted); }
.plan-anim.s1 .ctx, .plan-anim.s2 .talk, .plan-anim.s3 .bot { opacity: 1; transform: none; }
/* Each row shows one status at a time (data-st, set by main.js on its own schedule). */
.pa-row .st { display: grid; } .pa-row .st > span { grid-area: 1 / 1; padding: 1px 7px; border-radius: 5px; font-size: 11px; font-weight: 600; text-align: center; color: var(--ink); opacity: 0; transition: opacity .35s; }
.st .draft { background: #3a3940; color: var(--text-2); } .st .review { background: var(--amber); } .st .dev { background: var(--sky); } .st .built { background: var(--green); }
.pa-row[data-st="draft"] .draft, .pa-row[data-st="review"] .review, .pa-row[data-st="dev"] .dev, .pa-row[data-st="built"] .built { opacity: 1; }
/* Progress through the five stages. */
.pa-track { margin: 8px 12px 0; height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
.pa-track span { display: block; height: 100%; width: calc(var(--p, 0) * 20%); background: var(--orange); transition: width .6s cubic-bezier(.65, 0, .35, 1); }
/* "Shaped together": the team on the blocks (main.js picks them), coming in one block after another, gone at the next
   stage. */
.pa-row { position: relative; }
.pa-who { position: absolute; top: 50%; display: flex; translate: 0 -50%; pointer-events: none; }
.pa-who i { display: grid; place-items: center; width: 20px; height: 20px; margin-left: -6px; border-radius: 50%; border: 2px solid var(--raised);
  font: 700 9px/1 var(--sans); font-style: normal; color: var(--ink); opacity: 0; scale: .6; transition: opacity .25s, scale .25s; }
.pa-who i:first-child { margin-left: 0; }
.plan-anim.s0:not(.s1) .pa-who i { opacity: 1; scale: 1; transition: opacity .35s, scale .35s cubic-bezier(.3, 1.6, .5, 1); transition-delay: calc(.15s + var(--i) * .2s + var(--k) * .08s); }
/* The plan as it starts (.md, main.js): a Markdown spec where the blocks will be, its lines going one after another as
   the blocks come in. */
.pa-md { position: absolute; left: 12px; right: 12px; display: grid; gap: 6px; padding: 6px 10px; font: 500 13px/1.6 var(--mono); color: var(--text-2); pointer-events: none; }
.pa-md span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: 0; translate: 14px 0; transition: opacity .18s, translate .18s; transition-delay: calc(var(--i) * .1s); }
.pa-md em { margin-right: 9px; font-style: normal; color: var(--orange); }
.plan-anim.md .pa-md span { opacity: 1; translate: none; transition-duration: .35s; transition-delay: calc(.3s + var(--i) * .1s); }
/* One by one, each block comes in where its bullet was. */
.plan-anim.md .pa-row.on { opacity: 1; transform: none; transition: opacity .28s, transform .28s; }
/* Starting over: the blocks go quickly, before the Markdown comes back. */
.plan-anim.md .pa-row { transition: opacity .2s, transform .2s; transition-delay: 0s; }
/* Where the bullets became them, the blocks stand at once. */
.plan-anim.morphed .pa-row { transition: none; }

/* ---------- How it works: the five stages, as a stack of offset blocks ---------- */

/* Between the plan and the stages: a plain line, fading out to both sides, like the other separators' lines. */
#how .head { margin-bottom: 32px; } /* a separator within the section: half the space either side */
.fade-rule { height: 1px; margin: 0 0 32px; background: linear-gradient(90deg, transparent 12%, var(--line-strong) 44%, var(--line-strong) 56%, transparent 88%); }
.stages { display: grid; gap: 22px; }
.stage { display: grid; grid-template-columns: 1fr 1.25fr; gap: 56px; align-items: center; padding: 36px; border-radius: 26px; background: var(--surface); border: 1px solid var(--line); }
/* Every other stage is pushed right, like the mark's blocks. */
.stage:nth-child(even) { margin-left: 4%; } .stage:nth-child(odd) { margin-right: 4%; }
.stage .k { font: 500 13px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--orange); display: flex; align-items: center; gap: 12px; }
.stage h3 { font-size: clamp(26px, 2.6vw, 34px); margin: 16px 0 14px; letter-spacing: -.03em; }
.stage p { color: var(--text-2); margin: 0; }
.stage ul { margin: 18px 0 0; padding: 0; list-style: none; display: grid; gap: 10px; color: var(--text-2); font-size: 16px; }
.stage li { display: flex; gap: 12px; align-items: baseline; }
.stage li::before { content: ""; width: 10px; height: 4px; border-radius: 1px; background: var(--orange); flex: none; translate: 0 -3px; }
.shot { border-radius: 14px; overflow: hidden; border: 1px solid var(--line-strong); background: #0b0a0e; box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .8); }
.shot .bar { height: 30px; display: flex; align-items: center; gap: 6px; padding: 0 12px; border-bottom: 1px solid var(--line); background: var(--raised); }
.shot .bar i { width: 9px; height: 9px; border-radius: 5px; background: #3a3940; }
.shot .bar span { margin-left: auto; margin-right: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; font: 11px var(--mono); color: var(--muted); }
.shot img { width: 100%; height: auto; }
/* Structure: a Markdown spec beside the same spec as blocks; each bullet lights in turn with the block it became. */
.md2blocks .mb { display: grid; grid-template-columns: minmax(0, 1.25fr) 24px minmax(0, 1fr); align-items: center; gap: 14px; padding: 26px 22px; }
.mb-md { display: grid; gap: 9px; padding: 14px 16px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg); font: 500 11.5px/1.4 var(--mono); color: var(--text-2); }
.mb-md span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-radius: 4px; padding: 1px 4px; margin: 0 -4px; }
.mb-md em { font-style: normal; margin-right: 8px; color: var(--orange); }
.mb-md .h { color: var(--text); }
.mb-arrow { height: 2px; background: var(--line-strong); position: relative; }
.mb-arrow::after { content: ""; position: absolute; right: -1px; top: -4px; border: 5px solid transparent; border-left: 7px solid var(--line-strong); border-right: 0; }
.mb-blocks { display: grid; gap: 8px; }
.mb-blocks .g { font: 600 13px var(--sans); color: var(--text); margin-bottom: 2px; }
.mb-blocks .blk { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--raised); }
.mb-blocks .blk:nth-child(odd) { margin-left: 12px; }
.mb-blocks b { flex: none; white-space: nowrap; font: 600 11px var(--mono); color: var(--orange); }
.mb-blocks s { flex: 0 1 auto; min-width: 12px; height: 5px; border-radius: 3px; background: rgba(255, 255, 255, .14); }
.mb-blocks .blk em { flex: none; white-space: nowrap; margin-left: auto; font: normal 600 10.5px var(--mono); color: var(--ink); background: var(--st); border-radius: 4px; padding: 1px 6px; }
.stage.in .mb-md span[style], .stage.in .mb-blocks .blk { animation: mb-on 6s ease-in-out infinite; animation-delay: calc(var(--i) * 1.5s); }
@keyframes mb-on {
  0%, 22%, 100% { background-color: transparent; border-color: var(--line); }
  4%, 18% { background-color: rgba(255, 138, 76, .1); border-color: rgba(255, 138, 76, .55); }
}
.stage.in .mb-blocks .blk { animation-name: mb-blk; }
@keyframes mb-blk {
  0%, 22%, 100% { border-color: var(--line); box-shadow: none; }
  4%, 18% { border-color: rgba(255, 138, 76, .7); box-shadow: 0 0 0 3px rgba(255, 138, 76, .12); }
}
@media (prefers-reduced-motion: reduce) { .stage.in .mb-md span[style], .stage.in .mb-blocks .blk { animation: none; } }
@media (max-width: 600px) { .md2blocks .mb { grid-template-columns: minmax(0, 1fr); padding: 18px 14px; } .mb-arrow { justify-self: center; width: 2px; height: 22px; } .mb-arrow::after { right: -4px; top: auto; bottom: -2px; border: 5px solid transparent; border-top: 7px solid var(--line-strong); border-bottom: 0; } }
/* A highlight blinking over one card of a screenshot, placed in percentages of the image. */
.shot .pic { position: relative; }
/* Mia's caret in the plan shot (it has none of its own: scripts/capture-screens.mjs), blinking as she types. */
.shot .caret { position: absolute; width: .28%; background: var(--c); pointer-events: none; animation: caret-blink 1.1s steps(1) infinite; }
@keyframes caret-blink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .shot .caret { animation: none; } }
.shot .blink { position: absolute; border: 1.5px solid var(--orange); border-radius: 8px; box-shadow: 0 0 0 3px rgba(255, 138, 76, .18), 0 0 24px rgba(255, 138, 76, .35); animation: card-blink 1.6s ease-in-out infinite; pointer-events: none; }
@keyframes card-blink { 50% { opacity: .15; } }
@media (prefers-reduced-motion: reduce) { .shot .blink { animation: none; } }

/* A terminal: Claude Code, Codex or any agent, working through the Periferal MCP. */
.term { border-radius: 14px; background: #0b0a0e; border: 1px solid var(--line-strong); font: 13.5px/1.75 var(--mono); overflow: hidden; box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .8); }
.term .bar { height: 30px; display: flex; align-items: center; gap: 6px; padding: 0 12px; border-bottom: 1px solid var(--line); background: var(--raised); color: var(--muted); font-size: 11px; }
.term .bar i { width: 9px; height: 9px; border-radius: 5px; background: #3a3940; }
.term .bar span { margin-left: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.term pre { margin: 0; padding: 18px 20px; white-space: pre-wrap; color: var(--text-2); }
.term .you { color: var(--text); } .term .tool { color: var(--orange); } .term .mcp { color: var(--sky); } .term .ok { color: var(--green); } .term .dim { color: var(--faint); } .term .sky { color: var(--sky); }
/* A line with what it saved, the saving on the right. */
.term .saved { display: flex; justify-content: space-between; gap: 16px; }
.term .saved > :first-child { padding-left: 2ch; }
.term .save { flex: none; color: var(--green); }
.term .notice { display: block; margin-top: 10px; padding: 8px 12px; border-radius: 8px; background: rgba(255, 138, 76, .1); border: 1px solid rgba(255, 138, 76, .35); color: var(--orange); }
/* The context stage's terminal plays out (main.js): the prompt is typed in, a character at a time behind a block
   cursor, then each call and its result appear in turn. Everything keeps its place while hidden, so the card never
   changes size. */
.term pre[data-play] .typed > span { position: relative; visibility: hidden; }
.term pre[data-play] .typed > span.on { visibility: visible; }
.term pre[data-play] .typed > span.at::after { content: ""; position: absolute; left: 100%; top: .15em; bottom: .15em; width: .55em; background: var(--text); }
.term pre[data-play] .typed > span.at.idle::after { animation: term-caret 1s steps(1) infinite; }
.term pre[data-play] .typed > span.at.before::after { left: 0; }
@keyframes term-caret { 50% { opacity: 0; } }
.term pre[data-play] .ln { opacity: 0; transition: opacity .25s; }
.term pre[data-play] .ln.on { opacity: 1; }
/* A dashed rule between what the MCPs fetched and what goes into Periferal. */
.term pre .ln.sep { display: block; height: 0; margin: .55em 0 .5em; border-top: 1px dashed var(--line-strong); }
.term pre[data-play] .ln.res .ok { display: inline-block; }
.term pre[data-play] .ln.res.on .ok { animation: term-ok .4s cubic-bezier(.2, 1.6, .4, 1); }
@keyframes term-ok { from { transform: scale(0); } }

/* ---------- Agents ---------- */

.agents { display: grid; grid-template-columns: .9fr 1.1fr; gap: 56px; align-items: center; }
.points { display: grid; gap: 12px; margin-top: 34px; }
.point { display: grid; grid-template-columns: auto 1fr; gap: 16px; }
.point { align-items: start; } .point > .ico { translate: 0 calc(clamp(18px, 1.6vw, 21px) * .8 - 50%); } /* level with the first line, however many it wraps to */ .point b { display: block; font-size: clamp(18px, 1.6vw, 21px); font-weight: 400; color: color-mix(in srgb, var(--text-2) 50%, transparent); } /* set as the lead above it, at half its colour */
.point p { margin: 0; color: var(--text-2); font-size: 16px; }
.terms { display: grid; gap: 16px; }
/* The plugin hub: the Periferal plugin on the left, served through marketplaces to each agent on the right. */
.hub-body { display: grid; grid-template-columns: auto minmax(40px, 90px) 1fr; align-items: stretch; padding: 18px 20px; font-family: var(--sans); }
/* The source: a marketplace listing the Periferal plugin between other plugins. */
.market { align-self: center; display: grid; gap: 8px; width: 168px; padding: 10px; border-radius: 12px; background: var(--raised); border: 1px solid var(--line-strong); }
.mk-head { display: flex; align-items: center; gap: 6px; padding: 5px 8px; border-radius: 7px; background: var(--bg); border: 1px solid var(--line); font: 10.5px var(--mono); color: var(--muted); }
.mk-head svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.mk-skel { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; border: 1px solid var(--line); opacity: .6; }
.mk-skel i { width: 18px; height: 18px; border-radius: 5px; background: var(--line-strong); }
.mk-skel b { height: 6px; width: 60%; border-radius: 3px; background: var(--line-strong); }
.mk-item { display: grid; justify-items: center; gap: 4px; padding: 12px 8px 10px; border-radius: 10px; text-align: center; background: rgba(255, 138, 76, .08); border: 1px solid rgba(255, 138, 76, .45); }
.mk-item .tile { --s: 40px; margin-bottom: 2px; }
.mk-item b { font-size: 14px; color: var(--text); }
.mk-item small { font: 10.5px var(--mono); color: var(--muted); white-space: nowrap; }
.mk-btn { margin-top: 6px; padding: 3px 14px; border-radius: 99px; background: var(--orange); color: var(--ink); font: 600 11.5px var(--sans); }
.hub-lines { width: 100%; height: 0; min-height: 100%; overflow: visible; }
.hub-lines path { fill: none; stroke: rgba(255, 138, 76, .75); stroke-width: 1.75; vector-effect: non-scaling-stroke; stroke-dasharray: 3 7; animation: hub-flow 1.4s linear infinite; animation-delay: calc(var(--i) * -.23s); }
@keyframes hub-flow { to { stroke-dashoffset: -20; } }
.hub-agents { list-style: none; margin: 0; padding: 0; display: grid; }
.hub-agents li { padding: 4px 0; }
.hub-agents .card { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; background: var(--raised); border: 1px solid var(--line); }
.hub-agents .ag { width: 26px; height: 26px; flex: none; display: grid; place-items: center; border-radius: 7px; background: color-mix(in srgb, var(--c) 18%, transparent); color: var(--c); font: 600 11px var(--mono); }
.hub-agents .nm { display: grid; min-width: 0; line-height: 1.25; }
.hub-agents .nm b { font-size: 13.5px; color: var(--text); font-weight: 600; }
.hub-agents .nm small { font: 10.5px var(--mono); color: var(--faint); }
.hub-agents em { margin-left: auto; font: normal 11px var(--mono); color: var(--green); white-space: nowrap; animation: hub-in 6s ease-in-out infinite; animation-delay: calc(var(--i) * .25s); }
@keyframes hub-in { 0%, 8% { opacity: 0; } 16%, 100% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .hub-lines path, .hub-agents em { animation: none; } }
@media (max-width: 600px) { .hub-body { padding: 14px; } .market { width: 124px; padding: 8px; } .mk-item small { white-space: normal; } .mk-item .tile { --s: 32px; } .hub-agents em { display: none; } .hub-agents .nm b { font-size: 12.5px; white-space: nowrap; } }
/* The fast-forward arrow from the plugins down to the tokens it saves: the first section's two stacked
   chevrons, behind the window above and the number below, in orange. */
.hub, .tokens { position: relative; z-index: 1; }
.ff-down {
  --grad: linear-gradient(180deg, transparent, color-mix(in srgb, var(--orange) 55%, transparent) 38%, var(--orange));
  --sheen: linear-gradient(180deg, transparent 0 35%, rgba(255, 255, 255, .28) 50%, transparent 65% 100%);
  position: relative; display: block; width: 104px; height: 100px; margin: -30px 0 -20px 53px; opacity: .35; /* centred under the marketplace: the window border, its 20px padding, half the 168px marketplace, less half the arrow */
}
.ff-down::before, .ff-down::after { content: ""; position: absolute; inset: 0; background: var(--sheen), var(--grad); background-size: 100% 200%, 100% 100%; animation: sheen-y 2.4s linear infinite; }
.ff-down::before { clip-path: polygon(0 0, 50% 40%, 100% 0, 100% 26%, 50% 66%, 0 26%); }
.ff-down::after { clip-path: polygon(0 34%, 50% 74%, 100% 34%, 100% 60%, 50% 100%, 0 60%); }
@media (prefers-reduced-motion: reduce) { .ff-down::before, .ff-down::after { animation: none; } }
@media (max-width: 600px) { .ff-down { margin-left: 25px; } }
.tokens { display: flex; align-items: baseline; gap: 14px; margin-top: 4px; }
.tokens .n { font: 700 44px/1 var(--sans); letter-spacing: -.04em; color: var(--orange); }
.tokens s { color: var(--faint); font: 500 20px var(--mono); }

/* ---------- Waitlist ---------- */

.waitlist { background: var(--orange); color: var(--ink); overflow: hidden; isolation: isolate; text-align: center; }
.waitlist h2 { font-size: clamp(44px, 7vw, 96px); max-width: none; }
.waitlist .lead { color: rgba(22, 18, 15, .78); margin: 22px auto 0; }
.waitlist .eyebrow { color: rgba(22, 18, 15, .7); }
.waitlist .eyebrow .chip-tile { background: var(--ink); color: var(--orange); }
.waitlist .tile { --s: 92px; margin: 0 auto 30px; }
.waitlist .tile .bg { fill: var(--ink); } .waitlist .tile .b { fill: var(--orange); }
.form { margin: 44px auto 0; max-width: 600px; display: grid; gap: 12px; text-align: left; }

/* The form as the logo, block for block. In the mark (64 units) each long block is 27.62 × 9.21, every
   other one is pushed 2.76 to the right, the stub is 12.89 × 9.21, the blocks are 2.39 apart, and their
   corners round at 1.47. Everything here is a share of the stack's width (27.62 + 2.76 = 30.38 units),
   measured in container units (cqi), so the stack keeps the mark's proportions at every size:
   long blocks 90.9% wide, the push 9.1%, the stub 42.4%, corners 4.84%. The blocks are a third less tall
   than the mark's (4.5 : 1, the stub 2.1 : 1), so at the stack's 280px they are about 57px tall, and the
   gaps are 3.94% (about 11px). */
.logo-form { container-type: inline-size; display: grid; max-width: 280px; margin-inline: auto; width: 100%; }
/* The gaps go on the blocks: cqi on the form's own gap would measure its parent, not the form. */
.logo-form .block ~ .block { margin-top: 3.94cqi; }
.logo-form .block {
  display: block; width: 90.9cqi; aspect-ratio: 27.62 / 6.14; height: auto; margin: 0; border: 0; border-radius: 4.84cqi;
  background-color: var(--ink); color: var(--text); padding: 0 7cqi;
  font: 500 clamp(14px, 5.6cqi, 17px) var(--sans); outline: none; transition: transform .2s, box-shadow .2s, background-color .2s;
}
.logo-form .push { margin-left: 9.1cqi; }
/* The fields are see-through ink, so the solid button block stands out. Their hints are cream, which
   reads on the warm brown that ink over orange makes. */
.logo-form .block:not(.stub) { background-color: rgba(22, 18, 15, .55); }
.logo-form .block:not(.stub):hover { background-color: rgba(22, 18, 15, .65); }
.logo-form .block:not(.stub):focus { background-color: rgba(22, 18, 15, .8); }
.logo-form .block::placeholder { color: rgba(255, 236, 224, .72); }
.logo-form .block:focus-visible { box-shadow: 0 0 0 3px var(--orange), 0 0 0 6px var(--ink); }
.logo-form .stub { box-shadow: 0 10px 24px -10px rgba(22, 18, 15, .7); }
.logo-form .stub:hover { background-color: #221b17; }
.logo-form select { appearance: none; cursor: pointer; color: var(--text);
  background-image: linear-gradient(45deg, transparent 50%, rgba(255, 236, 224, .8) 50%), linear-gradient(135deg, rgba(255, 236, 224, .8) 50%, transparent 50%);
  background-position: calc(100% - 7cqi - 6px) 50%, calc(100% - 7cqi) 50%; background-size: 6px 6px; background-repeat: no-repeat; }
.logo-form select:has(option[value=""]:checked) { color: rgba(255, 236, 224, .72); }
.logo-form option { color: var(--text); background: var(--ink); }
.logo-form .stub {
  width: 42.4cqi; aspect-ratio: 12.89 / 6.14; display: flex; align-items: center; justify-content: space-between; gap: 8px; cursor: pointer;
  color: var(--orange); font-weight: 700; white-space: nowrap;
}
.logo-form .stub:hover { transform: translateX(4px); }
.logo-form .stub:disabled { opacity: .6; cursor: progress; }
.logo-form .stub .long { display: none; }

.form .fine { font-size: 13.5px; color: rgba(22, 18, 15, .7); text-align: center; margin: 6px 0 0; }
.form .msg { min-height: 24px; text-align: center; font-weight: 600; }
.form.done .fields { display: none; }
.form .thanks { display: none; text-align: center; padding: 26px; border-radius: 16px; background: var(--ink); color: var(--text); }
.form.done .thanks { display: block; }
.form .thanks .tile { --s: 48px; margin-bottom: 14px; } .form .thanks .tile .bg { fill: var(--orange); } .form .thanks .tile .b { fill: var(--ink); }
@media (min-width: 1100px) {
  .waitlist .wrap { display: grid; grid-template-columns: 340px minmax(0, 1fr); gap: 80px; align-items: center; text-align: left; }
  .waitlist .wl-text { grid-column: 2; grid-row: 1; }
  .waitlist .form { grid-column: 1; grid-row: 1; }
  .waitlist h2 { font-size: clamp(56px, 5.4vw, 80px); }
  .waitlist .lead { margin: 22px 0 0; }
  .waitlist .form { margin: 0; max-width: none; }
}

/* ---------- Footer ---------- */

footer { padding-block: 56px 48px; border-top: 1px solid var(--line); color: var(--muted); font-size: 14px; }
footer .wrap { display: flex; gap: 24px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
/* The mark on the footer's left: the tile opening into the block editor and folding back (main.js), small. */
.foot-mark { display: block; flex: none; }
.foot-mark .orbit { --s: 64px; width: 150px; max-width: none; margin: -24px 0; }
/* The line, Privacy and the button: in the footer's row on desktops; stacked beside the mark, aligned left, on tablets;
   under a bigger mark, centred, on phones. */
.foot-info { display: contents; }
@media (max-width: 980px) {
  footer .wrap { flex-wrap: nowrap; justify-content: flex-start; gap: 36px; }
  .foot-info { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
}
@media (max-width: 600px) {
  footer .wrap { flex-direction: column; gap: 28px; }
  .foot-info { align-items: center; text-align: center; }
  .foot-mark .orbit { --s: 96px; width: 220px; margin: -20px 0; }
}
/* The way to the arcade version, as an arcade button: its pixel font, tangerine, hard edges, pressed in one step. */
@font-face { font-family: "Periferal Pixel"; src: url("../assets/fonts/periferal-pixel.woff?v=2") format("woff"); font-display: swap; }
footer .to-arcade {
  display: inline-flex; align-items: center; padding: 11px 14px 10px;
  font: 400 11px/1.2 "Periferal Pixel", "Press Start 2P", ui-monospace, monospace; text-transform: uppercase; letter-spacing: .02em;
  color: #05060d; background: #ff8a4c; border: 2px solid #05060d;
  box-shadow: inset 3px 3px 0 0 #ffc19c, inset -3px -3px 0 0 rgba(5, 6, 13, .45), 4px 4px 0 0 #05060d;
  transition: transform 60ms steps(1), box-shadow 60ms steps(1);
}
footer .to-arcade:hover { color: #05060d; background: #ffa06b; box-shadow: inset 3px 3px 0 0 #ffe0cc, inset -3px -3px 0 0 rgba(5, 6, 13, .45), 4px 4px 0 0 #05060d; }
footer .to-arcade:active { transform: translate(4px, 4px); box-shadow: inset 3px 3px 0 0 #ffe0cc, inset -3px -3px 0 0 rgba(5, 6, 13, .45), 0 0 0 0 #05060d; }
footer .to-arcade:focus-visible { outline: 2px solid #ffd166; outline-offset: 3px; }

/* ---------- Small screens ---------- */

@media (max-width: 980px) {
  section { padding-block: 84px; }
  .hero .wrap, .agents { grid-template-columns: 1fr; }
  .hero { padding-top: 40px; }
  .hero h1 { font-size: clamp(40px, calc((100vw - 40px) / 11), 64px); }
  .orbit { max-width: 440px; }
  .numbers, .pillars { grid-template-columns: 1fr; }
  .numbers { gap: 48px; --gap: 48px; }
  .numbers .stat:nth-child(1) { grid-row: auto; }
  .stat .flow.stacked-only { display: block; }
  .stat .flow.from-prev { display: none; }
  /* Stacked: the 10× across the top, then each step on the left with what it leaves behind on its right. */
  .numbers { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); column-gap: 14px; }
  .numbers .stat:nth-child(1) { grid-column: 1 / -1; }
  .numbers .stat:nth-child(2) { grid-column: 1; grid-row: 2; }
  .numbers .stat:nth-child(3) { grid-column: 1; grid-row: 3; }
  .numbers .stat:nth-child(4) { grid-column: 2; grid-row: 2; }
  .numbers .stat:nth-child(5) { grid-column: 2; grid-row: 3; }
  .stat.waste .rest { flex-direction: column; align-items: flex-start; gap: 8px; }
  .stat .flow {
    --grad: linear-gradient(180deg, transparent, color-mix(in srgb, currentColor 55%, transparent) 38%, var(--next));
    --sheen: linear-gradient(180deg, transparent 0 35%, rgba(255, 255, 255, .28) 50%, transparent 65% 100%);
    left: 30px; top: 76%; width: 136px; height: 130px; translate: none; /* lined up with the card's content, clear of its rounded corners */ /* a fixed size, the desktop arrow's proportions turned down: it never widens with the screen */ transform: scaleY(.3); transform-origin: top;
  }
  .stat.in .flow { transform: none; }
  .stat .flow::before, .stat .flow::after { background-size: 100% 200%, 100% 100%; animation-name: sheen-y; }
  .stat .flow::before { clip-path: polygon(0 0, 50% 40%, 100% 0, 100% 26%, 50% 66%, 0 26%); }
  .stat .flow::after { clip-path: polygon(0 34%, 50% 74%, 100% 34%, 100% 60%, 50% 100%, 0 60%); }
  .pillar { min-height: 0; }
  .stage { grid-template-columns: 1fr; gap: 30px; padding: 26px; align-content: start; } /* stacked: the animation right under the text, whatever the tallest slide */
  .howto { grid-template-columns: 1fr; gap: 28px; }
  .stage:nth-child(n) { margin: 0; }
  .nav .links { display: none; }
  .menu-btn { display: block; }
  .nav .btn { margin-left: auto; }
}
@media (max-width: 600px) {
  body { font-size: 16px; }
  .hero h1 .line { white-space: normal; }
  .form .row { flex-direction: column; }
  .who:not(.bubble) .agent { display: none; }
  /* On phones the conversation, issue and pull request bubbles show their icons only. */
  .bubble .agent { padding: 7px; } .bubble .agent b { display: none; } .bubble .agent svg { width: 16px; height: 16px; }
  .avatar { width: 44px; height: 44px; font-size: 17px; }
  .nav .alpha { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal, .stat .bar { opacity: 1; transform: none; }
  .band::after { display: none; }
}

/* The blocks drawn through <use href="#blocks"> inherit their fill. */
.tile use { fill: var(--ink); }

/* ---------- Connected: an app from "Works with", wired into the editor ---------- */

/* The orbit dims; the editor drops to the lower part, and the app's window opens above it. --c is the
   app's colour (set by main.js). */
.orbit.connected .who, .orbit.connected svg.streams { opacity: .08; }
.orbit.connected .core { top: 70%; }
.app-card {
  position: absolute; z-index: 3; left: 50%; top: 0; width: min(86%, 380px); height: 27%; translate: -50% 0;
  border-radius: 12px; background: var(--surface); border: 1px solid color-mix(in srgb, var(--c, var(--orange)) 55%, transparent);
  box-shadow: 0 24px 60px -20px rgba(0, 0, 0, .8), 0 0 40px -12px var(--c, var(--orange));
  opacity: 0; transform: translateY(-14px) scale(.96); pointer-events: none; overflow: hidden;
  transition: opacity .45s, transform .6s var(--ease); font-size: clamp(10px, calc(var(--s) * .058), 12.5px);
}
.orbit.connected .app-card { opacity: 1; transform: none; transition-delay: .35s; }
.app-card .top { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-bottom: 1px solid var(--line); font: 600 1em var(--sans); white-space: nowrap; }
.app-card .top .ic { width: 1.6em; height: 1.6em; border-radius: 5px; display: grid; place-items: center; background: var(--c); color: var(--ink); font: 700 .85em var(--mono); flex: none; }
.app-card .top small { color: var(--muted); font: 500 .9em var(--mono); overflow: hidden; text-overflow: ellipsis; }
.app-card .body { padding: 7px 10px; display: grid; gap: 5px; color: var(--text-2); line-height: 1.35; }
.app-card .body .ln { display: flex; gap: 7px; align-items: baseline; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-card .body .ln b { color: var(--text); font-weight: 600; }
.app-card .body .mono { font-family: var(--mono); font-size: .95em; }
.app-card .body .k { color: var(--c); }
.app-card .body .ok { color: var(--green); }
.app-card .body .dim { color: var(--faint); }

/* The wire: from the window's bottom to the editor's top, flowing in the app's colour. */
.wire {
  position: absolute; z-index: 1; left: 50%; top: 27%; width: 2px; translate: -1px 0;
  height: calc(70% - 27% - var(--s) * .64); opacity: 0; transition: opacity .4s;
  background: repeating-linear-gradient(to bottom, var(--c, var(--orange)) 0 6px, transparent 6px 12px); background-size: 2px 12px;
  animation: wire 0.6s linear infinite;
}
@keyframes wire { to { background-position: 0 12px; } }
.orbit.connected .wire { opacity: 1; transition-delay: .6s; }
/* A piece of data flying down the wire into the editor. */
.packet {
  position: absolute; left: 50%; top: 0; translate: -50% -50%; white-space: nowrap;
  font: 600 11px var(--mono); color: var(--ink); background: var(--c); border-radius: 999px; padding: 3px 9px;
  box-shadow: 0 0 18px var(--c); animation: fly 1.1s cubic-bezier(.45, 0, .7, 1) forwards;
}
@keyframes fly { 0% { top: 0; opacity: 0; transform: scale(.7); } 15% { opacity: 1; transform: none; } 85% { opacity: 1; } 100% { top: 100%; opacity: 0; transform: scale(.6); } }

/* Where the data lands: the row flashes, and what it gained replaces its status. */
.morph .blk.hit { box-shadow: 0 0 0 2px var(--c), 0 0 26px -2px var(--c); }
.morph .gain { display: none; margin-left: auto; font: normal 600 calc(var(--s) * .042) var(--mono); color: var(--c); border: 1px solid var(--c); border-radius: 4px; padding: 0 5px; white-space: nowrap; }
.morph .blk.gained .gain { display: inline; animation: gain .4s cubic-bezier(.2, 1.5, .4, 1); }
.morph .blk.gained em { display: none; }
@keyframes gain { from { transform: scale(.4); } }

/* ---------- Phones: "Works with" as a dropdown under the animation ---------- */

.art { position: relative; min-width: 0; }
.connect-select { display: none; }
@media (max-width: 600px) {
  /* Right under the animation, overlapping its bottom edge a little. */
  .connect-select { display: block; position: relative; z-index: 4; width: min(100%, 320px); margin: -10px auto 0; }
  .connect-select select {
    appearance: none; width: 100%; height: 48px; padding: 0 44px 0 16px; border-radius: 12px; cursor: pointer;
    background-color: var(--raised); color: var(--text); border: 1px solid var(--line-strong); font: 500 15px var(--sans);
    box-shadow: 0 16px 40px -12px rgba(0, 0, 0, .8);
    background-image: linear-gradient(45deg, transparent 50%, var(--orange) 50%), linear-gradient(135deg, var(--orange) 50%, transparent 50%);
    background-position: calc(100% - 22px) 50%, calc(100% - 16px) 50%; background-size: 6px 6px; background-repeat: no-repeat;
  }
  .connect-select select:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
  .connect-select select.on { border-color: var(--c, var(--orange)); color: var(--orange); }
}

/* ---------- Screenshots: responsive sizes ---------- */
.shot picture { display: block; }

/* ---------- Where the numbers come from ---------- */
.tokens .source { font: 500 12px var(--mono); color: var(--muted); }

/* ---------- FAQ ---------- */
.faq-list { display: grid; gap: 10px; max-width: 860px; }
.qa { border: 1px solid var(--line); border-radius: 14px; background: var(--surface); }
/* Stepped like the logo's blocks, loosely: each tile starts a little further in or not, unevenly, and all of them end on
   the same right edge. Narrower on phones. */
.qa { margin-left: min(var(--in, 0px), 6vw); }
.qa:nth-child(2) { --in: 40px; } .qa:nth-child(3) { --in: 12px; } .qa:nth-child(4) { --in: 56px; }
.qa:nth-child(6) { --in: 28px; } .qa:nth-child(7) { --in: 16px; }
.qa summary { cursor: pointer; display: flex; align-items: center; gap: 14px; padding: 18px 22px; list-style: none; }
.qa summary::-webkit-details-marker { display: none; }
.qa summary h3 { margin: 0; font-size: 19px; letter-spacing: -.02em; }
.qa summary::after { content: "+"; margin-left: auto; font: 500 22px/1 var(--mono); color: var(--orange); transition: transform .2s; }
.qa[open] summary::after { transform: rotate(45deg); }
.qa p { margin: 0; padding: 0 22px 20px; color: var(--text-2); max-width: 720px; }
.form .fine a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* ---------- Try it: the live app (../app/) ---------- */
.try .head { margin-bottom: 40px; }
.app-window { position: relative; border: 1px solid var(--line-strong); border-radius: 16px; overflow: hidden; background: #0b0a0e; box-shadow: 0 60px 140px -40px rgba(255, 138, 76, .3), 0 30px 80px -30px rgba(0, 0, 0, .9); }
.app-chrome { display: flex; align-items: center; gap: 7px; height: 36px; padding: 0 14px; border-bottom: 1px solid var(--line); background: var(--surface); font: 500 12px var(--mono); color: var(--faint); }
.app-chrome i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-strong); }
.app-chrome span { flex: 1; text-align: center; margin-right: 44px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.try { padding-top: 120px; }
/* Three live views, stacked: the desktop window behind sits lower right, smaller, its right edge peeking out; the
   phone stands at the left, its left edge peeking out. Views behind are dimmed. A click on one, or the switch,
   brings it to the front (../showcase.js). */
.try-stack { --peek: 170px; --ppeek: 120px; --drop: 28px; width: min(1360px, 100vw - 48px); margin-left: 50%; translate: -50% 0; }
/* The phone stands on the same line as the graph window behind: that one is dropped by --drop and scaled to .95 about
   its middle, so its bottom is --drop, less 2.5% of its height (the screen, 65vh, and its 48px frame), below the stack's.
   Behind, the phone is never taller than the document window: its scale follows that window's height (--ps-back,
   showcase.js), up to .7. */
.try-stack { --win-h: calc(clamp(454px, 65vh, 632px) + 48px); --ps: var(--ps-back, .7); }
.try-windows { position: relative; display: grid; }
.try-windows .try-window { grid-area: 1 / 1; z-index: 2; width: calc(100% - var(--peek) - var(--ppeek)); transform: translateX(var(--ppeek)); transform-origin: right center; transition: transform .7s cubic-bezier(.16, 1, .3, 1); }
.try-stack[data-desk="page"] [data-view="graph"], .try-stack[data-desk="graph"] [data-view="page"] { z-index: 1; transform: translate(calc(var(--ppeek) + var(--peek)), var(--drop)) scale(.95); }
.try-phone { position: absolute; left: 0; bottom: calc(.025 * var(--win-h) - var(--drop)); z-index: 1; width: calc(426px * var(--ps)); height: calc(898px * var(--ps)); transition: transform .7s cubic-bezier(.16, 1, .3, 1), width .7s cubic-bezier(.16, 1, .3, 1), height .7s cubic-bezier(.16, 1, .3, 1); }
/* In front, the phone grows to full size, so its text is as big as the desktop window's; it grows upward from
   its bottom edge. */
.try-stack[data-front="phone"] { --ps: 1; }
.try-stack[data-front="phone"] .try-phone { z-index: 3; transform: translate(32px, calc(var(--drop) * -.5)); }
.phone { width: 426px; height: 898px; padding: 12px; border-radius: 68px; transform: scale(var(--ps)); transform-origin: 0 0; transition: transform .7s cubic-bezier(.16, 1, .3, 1); }
.phone { background: #1c1b21; box-shadow: inset 0 0 0 2px #3a3941, inset 0 0 0 6px #0c0b0e, 0 50px 110px -30px rgba(0, 0, 0, .95), 0 0 80px -30px rgba(255, 138, 76, .25); }
.phone-screen { position: relative; width: 402px; height: 874px; border-radius: 56px; overflow: hidden; background: #121116; }
/* The app runs edge to edge, under the status bar, which sits on a dark blur that fades out downward, so the time
   and battery stay readable over anything. */
.phone-status { position: absolute; z-index: 1; inset: 0 0 auto; display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 34px 0 46px; pointer-events: none; font: 600 16px/1 -apple-system, var(--sans, system-ui), sans-serif; color: #f1f0f4; text-shadow: 0 1px 3px rgba(0, 0, 0, .5); }
.phone-status::before { content: ""; position: absolute; z-index: -1; inset: 0 0 -18px; background: linear-gradient(rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); -webkit-mask-image: linear-gradient(#000 50%, transparent); mask-image: linear-gradient(#000 50%, transparent); }
.phone-status .island { position: absolute; left: 50%; top: 11px; width: 126px; height: 37px; margin-left: -63px; border-radius: 20px; background: #000; }
.phone-status .battery { width: 26px; height: 12px; padding: 1.5px; border: 1.5px solid rgba(241, 240, 244, .6); border-radius: 4px; background: #f1f0f4 content-box; }
.phone-screen .try-live { position: absolute; left: 0; top: 0; width: 402px; height: 874px; }
/* A view behind the front window is a screenshot until a visitor reaches for it; then its live app loads under
   the screenshot and takes its place once it has drawn (.live, ../showcase.js). */
.try-live { position: absolute; inset: 0; overflow: hidden; }
.try-live img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: left top; }
.try-live iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; visibility: hidden; }
.try-live.live iframe { visibility: inherit; } /* hidden with its view, when the phone shows the other one */
.try-live.live img { display: none; }
/* Reached for before its app is ready: a light sweeps over the screenshot until it is. */
.try-live.loading::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 30%, rgba(255, 138, 76, .28) 50%, transparent 70%) 0 0 / 250% 100%;
  animation: try-load 1.1s linear infinite;
}
/* A view that is loading shows at full brightness, so the light reads. */
.try-windows [data-view]:has(.try-live.loading) > :not(.try-back) { filter: none; }
@keyframes try-load { from { background-position: 125% 0; } to { background-position: -125% 0; } }
@media (prefers-reduced-motion: reduce) { .try-live.loading::after { animation-duration: 3s; } }
/* The phone shows the view of the desktop window in front. */
.try-stack:not([data-desk="page"]) [data-phone="page"], .try-stack:not([data-desk="graph"]) [data-phone="graph"] { visibility: hidden; }
/* Dimmed: every view but the one in front. */
.try-windows [data-view] > :not(.try-back) { transition: filter .5s; }
.try-stack:not([data-front="page"]) [data-view="page"] > :not(.try-back),
.try-stack:not([data-front="graph"]) [data-view="graph"] > :not(.try-back),
.try-stack:not([data-front="phone"]) [data-view="phone"] > :not(.try-back) { filter: brightness(.4) saturate(.6); }
.try-stack:not([data-front="page"]) [data-view="page"]:hover > :not(.try-back),
.try-stack:not([data-front="graph"]) [data-view="graph"]:hover > :not(.try-back),
.try-stack:not([data-front="phone"]) [data-view="phone"]:hover > :not(.try-back) { filter: brightness(.6) saturate(.8); }
.try-back { display: none; position: absolute; inset: 0; z-index: 2; padding: 0; border: 0; background: transparent; cursor: pointer; }
.try-stack:not([data-front="page"]) [data-view="page"] .try-back,
.try-stack:not([data-front="graph"]) [data-view="graph"] .try-back,
.try-stack:not([data-front="phone"]) [data-view="phone"] .try-back { display: block; }
/* A view's name, upright in the strip that peeks out: on the right for a window, on the left for the phone. While
   the phone is in front, the desktop window under it shows no name. */
.try-back span { position: absolute; right: calc(var(--peek) / 2 - 14px); top: 50%; writing-mode: vertical-rl; transform: translateY(-50%); white-space: nowrap; }
/* On the right edge the label reads top to bottom; on the phone, at the left edge, bottom to top. */
.try-phone .try-back span { right: auto; left: calc(var(--ppeek) / 2 - 14px); transform: translateY(-50%) rotate(180deg); }
.try-stack[data-front="phone"][data-desk="page"] [data-view="page"] .try-back span,
.try-stack[data-front="phone"][data-desk="graph"] [data-view="graph"] .try-back span { display: none; }
.try-back span { padding: 12px 6px; border-radius: 8px; font: 500 12px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text); background: rgba(14, 13, 17, .8); border: 1px solid var(--line-strong); transition: color .2s, border-color .2s; }
.try-back:hover span { color: var(--orange); border-color: var(--orange); }
.try-switches { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-bottom: 20px; }
/* Above phones the views are picked from their edges (the side tabs); the switches show on phones only, where the
   views behind don't peek out. */
@media (min-width: 601px) { .try-switches { display: none; } }
/* With the phone in front, which rises over the left of the section, the switches move to the right, in line
   with the right edge of the desktop window. */
.try-stack[data-front="phone"] .try-switches { justify-content: flex-end; padding-right: var(--peek); }
.try-switch { display: flex; padding: 4px; gap: 2px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.try-device button { display: inline-flex; align-items: center; gap: 7px; }
.try-device svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.try-switch button { padding: 7px 15px; border: 0; border-radius: 9px; background: none; cursor: pointer; font: 500 14px var(--sans); color: var(--muted); transition: color .2s, background .2s; }
.try-switch button:hover { color: var(--text-2); }
.try-switch button[aria-pressed="true"] { color: var(--text); background: var(--raised); box-shadow: inset 0 0 0 1px var(--line-strong); }
.try-switch button:focus-visible { outline: 2px solid var(--orange); outline-offset: -2px; }
.try-screen { position: relative; height: clamp(454px, 65vh, 632px); background: #111013; }
.try-screen iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* The picture of the document view, over the app until it has drawn (showcase.js). */
.try-shot { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; object-position: left top; pointer-events: none; transition: opacity .4s; }
.try-screen.live .try-shot { opacity: 0; visibility: hidden; transition: opacity .4s, visibility 0s .4s; }
/* The demos under the windows: each plays in the document view, and fills as it plays (../showcase.js). */
.try-demos { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; max-width: 1120px; margin: 24px auto 0; }
.try-demos button {
  position: relative; display: flex; gap: 11px; align-items: center; padding: 15px 14px 13px; overflow: hidden; text-align: left; cursor: pointer;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface); transition: border-color .2s, background .2s, opacity .3s;
}
.try-demos button:hover { border-color: var(--line-strong); }
.try-demos button:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.try-demos b { display: inline-grid; place-items: center; flex: none; width: 22px; height: 22px; border-radius: 5px; background: var(--raised); color: var(--muted); font: 600 11px var(--mono); transition: background .2s, color .2s; }
.try-demos span { display: grid; gap: 3px; }
.try-demos strong { font: 600 14.5px/1.3 var(--sans); color: var(--text); }
.try-demos .playing { border-color: rgba(255, 138, 76, .5); background: #17120f; }
.try-demos .playing b { background: var(--orange); color: var(--ink); }
/* The demo playing fills its card from left to right, in the brand's yellow-to-orange, dimmed under white text. It
   grows at one speed over the demo's whole length (--p, set every frame by ../showcase.js). */
.try-demos button::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: linear-gradient(90deg, rgba(255, 196, 107, .2), rgba(255, 138, 76, .26) 60%, rgba(239, 106, 90, .3));
  clip-path: inset(0 calc(100% - var(--p, 0) * 100%) 0 0); transition: opacity .3s;
}
.try-demos button > * { position: relative; z-index: 1; }
.try-demos .playing strong { color: var(--text); }
.try-demos button:not(.playing)::after { opacity: 0; transition: none; }
/* With the graph or the phone in front, the demos wait. */
/* Stacked in two columns or one: each card as tall as its own content, so the closed ones stay one line high. */
@media (max-width: 980px) { .try-deck, .try-demos { align-items: start; } }
/* Side by side (desktops), a closed card is always two title lines tall, whichever is open, and so is the arrow
   beside them: a switch only changes the open card. Stacked, each card is as tall as its own content. */
/* Stacked, only the first three cards of the wheel show: the one playing and the next two (../showcase.js); before
   the wheel first turns, the first three. */
@media (max-width: 980px) {
  .try-demos button[data-far] { display: none; }
  .try-demos:not(:has(button[data-far])) button:nth-of-type(n + 4) { display: none; }
}
.try-more:disabled { opacity: .35; cursor: default; pointer-events: none; } /* waits with the demos */
/* With another view in front the demos wait, dimmed; pointed at, they light up again (a click brings the document view back). */
.try-demos button.waiting { opacity: .35; transition: opacity .25s; }
.try-deck:hover .try-demos button.waiting { opacity: 1; }
.try-demos button:disabled { opacity: .35; cursor: default; pointer-events: none; }
@media (max-width: 980px) { .try-demos { grid-template-columns: 1fr; align-content: start; } } /* the cards one under the other, as close as side by side */
/* The spec-creation demo's Claude Code terminals, drawn over the document window (showcase.js): one, large, then four
   in a grid. Like the terminals further down: dark, a bar of three dots, mono text. */
.demo-terms { position: absolute; inset: 0; z-index: 3; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 6% 7%; align-content: center; pointer-events: none; opacity: 0; transition: opacity .45s; background: rgba(5, 4, 6, .45); }
.demo-terms.on { opacity: 1; }
.demo-term { min-width: 0; border: 1px solid var(--line-strong); border-radius: 12px; background: #0b0a0e; box-shadow: 0 30px 80px -30px rgba(0, 0, 0, .8); overflow: hidden; font: 500 12.5px/1.65 var(--mono); color: var(--text-2); }
.demo-term.solo { grid-column: 1 / -1; font-size: 14px; }
.dt-bar { display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border-bottom: 1px solid var(--line); background: var(--surface); color: var(--faint); font-size: 11.5px; }
.dt-bar i { width: 9px; height: 9px; border-radius: 50%; background: var(--line-strong); }
.dt-bar span { margin-left: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dt-body { min-height: 120px; padding: 14px 16px 16px; }
.demo-term.solo .dt-body { min-height: 200px; }
.dt-you { color: var(--text); }
.dt-line { white-space: pre-wrap; animation: dt-in .3s both; }
.dt-dim { color: var(--muted); }
.dt-tool { color: var(--orange); }
.dt-ok { color: var(--green); }
@keyframes dt-in { from { opacity: 0; transform: translateY(4px); } }
/* Closing the terminals. A lone one closes from its first dot, as a Mac window does: the dot goes red while the pointer
   is on the window, and shows its × under the pointer. Four, while the pointer is on the window, move apart toward
   the corners, and "Close all" comes in in their middle. */
.demo-term.closable { pointer-events: auto; }
.dt-close { flex: none; width: 9px; height: 9px; display: grid; place-items: center; padding: 0; border: 0; border-radius: 50%; background: var(--line-strong); color: transparent; font: 700 9px/1 var(--sans); cursor: pointer; transition: background .15s; }
.dt-close::before { content: "×"; translate: 0 -.5px; }
.demo-term:hover .dt-close { background: #ff5f57; }
.dt-close:hover { color: rgba(60, 0, 0, .75); }
.demo-terms { transition: opacity .45s, gap .5s cubic-bezier(.16, 1, .3, 1); }
.try-screen:hover .demo-terms.four { gap: 64px 140px; }
.dt-close-all { position: absolute; left: 50%; top: 50%; translate: -50% -50%; padding: 8px 14px; border: 1px solid var(--line-strong); border-radius: 9px; background: var(--surface); color: var(--text-2); font: 500 12.5px var(--mono); white-space: nowrap; cursor: pointer; pointer-events: none; box-shadow: 0 12px 30px -10px rgba(0, 0, 0, .8); opacity: 0; scale: .8; transition: color .2s, border-color .2s, opacity .3s, scale .3s; }
.try-screen:hover .dt-close-all { opacity: 1; scale: 1; pointer-events: auto; transition-delay: 0s, 0s, .15s, .15s; }
.dt-close-all:hover { color: var(--text); border-color: var(--orange); }
/* A narrow window (the document view is under 600px wide from tablets down): the terminals stack, the four with
   their "Close all" above them, as wide as they are, shown while the pointer is on the window; a browser opens under
   its terminal. */
.try-screen { container-type: inline-size; }
@container (max-width: 599px) {
  .demo-terms, .demo-terms.pair { grid-template-columns: minmax(0, 1fr); gap: 8px; padding: 12px; align-content: safe center; }
  .demo-term, .demo-term.solo { font-size: 11px; }
  .dt-bar { height: 26px; }
  .dt-body, .demo-term.solo .dt-body { min-height: 0; padding: 8px 12px 10px; }
  .try-screen:hover .demo-terms.four { gap: 8px; }
  .dt-close-all { position: static; translate: none; order: -1; width: 100%; max-height: 0; padding-block: 0; border-width: 0; overflow: hidden; scale: 1;
    transition: color .2s, border-color .2s, opacity .3s, max-height .3s, padding .3s; }
  .try-screen:hover .dt-close-all { max-height: 40px; padding: 8px 14px; border-width: 1px; }
  .db-view { height: 170px; }
}
/* The cards and, beside them, the button that turns to the other set (showcase.js): as tall as a card, 50px wide,
   dashed and dim until hovered. It sits on the right with the first set, on the left with the second, its arrow
   pointing back. Below the desktop layout it's a bar under the cards. */
.try-deck { display: grid; grid-template-columns: minmax(0, 1fr) 50px; gap: 10px; max-width: 1120px; margin: 24px auto 0; }
.try-deck .try-demos { max-width: none; margin: 0; }
.try-deck.p2 { grid-template-columns: 50px minmax(0, 1fr); }
.try-deck.p2 .try-more { order: -1; }
.try-demos button[hidden] { display: none; }
/* A demo's title, in its card for search engines and screen readers; showcase.js shows it over the window. */
.try-demos .vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.try-more { display: grid; place-items: center; padding: 0; border: 1px dashed var(--line-strong); border-radius: 12px; background: var(--surface); color: var(--faint); cursor: pointer; transition: border-color .2s, color .2s; }
.try-more:hover { border-color: var(--orange); color: var(--orange); }
.try-more:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.try-more svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: scale .4s; }
.try-deck.p2 .try-more svg { scale: -1 1; }
/* Below desktops, one column: the cards in their own list, which turns like a wheel (their order changes), and a slim
   row for the button under them. */
@media (max-width: 980px) {
  .try-deck, .try-deck.p2 { grid-template-columns: minmax(0, 1fr); }
  .try-deck.p2 .try-more { order: 0; }
  .try-deck .try-demos { display: grid; }
  .try-more { height: 44px; }
}

/* The keys a demo presses, as keycaps over the document window: each pops in, then fades. */
.demo-keys { position: absolute; left: 0; right: 0; bottom: 72px; display: flex; justify-content: center; gap: 8px; pointer-events: none; }
.demo-keys kbd {
  display: grid; place-items: center; min-width: 46px; height: 46px; padding: 0 12px; border-radius: 10px;
  font: 600 20px/1 var(--sans); color: var(--text); background: rgba(21, 20, 25, .92); border: 1px solid var(--line-strong); border-bottom-width: 3px;
  box-shadow: 0 12px 30px -8px rgba(0, 0, 0, .8), 0 0 0 1px rgba(255, 138, 76, .25);
  animation: key-in .2s cubic-bezier(.2, 1.4, .4, 1), key-out .35s 1.15s forwards;
}
@keyframes key-in { from { transform: translateY(8px) scale(.85); opacity: 0; } }
@keyframes key-out { to { opacity: 0; transform: translateY(-4px); } }
@media (max-width: 600px) {
  .app-window { border-radius: 12px; }
  .app-chrome span { margin-right: 0; }
  .try-screen { height: 518px; }
  .numbers .stat:not(:nth-child(1)) { padding: 24px 16px; }
  .numbers .stat:nth-child(2) .big, .numbers .stat:nth-child(3) .big { font-size: 34px; }
  .numbers .stat .label { font-size: 15px; }
  .stat.waste .pill { font-size: 11.5px; padding: 4px 8px; gap: 6px; white-space: normal; text-align: left; }
  .stat.waste .pill svg { width: 13px; height: 13px; }
  .try-switches { flex-wrap: nowrap; gap: 6px; }
  .try-switch button { padding: 7px 10px; font-size: 13px; }
  .try-device span { display: none; }
  .try-stack[data-front="phone"] .try-switches { justify-content: center; padding-right: 0; }
  .try-demos { grid-template-columns: 1fr; }
  /* No room to peek on a phone: the switch alone picks the view. */
  .try-stack, .try-stack[data-front="phone"] { --peek: 0px; --ppeek: 0px; --drop: 0px; --ps: .8; width: auto; margin-left: 0; translate: none; }
  .try-stack:not([data-front="page"]) [data-view="page"], .try-stack:not([data-front="graph"]) [data-view="graph"], .try-stack:not([data-front="phone"]) [data-view="phone"] { display: none; }
  .try-windows .try-window { transform: none; width: 100%; }
  .try-phone { position: relative; justify-self: center; transform: none !important; }
}

/* ---------- Separator under "Try it": a branch of the graph view, links drawn and cards lit in turn ---------- */
.graphline { display: flex; align-items: center; gap: 18px; padding: 24px 0 50px; }
.graphline::before, .graphline::after { content: ""; flex: 1; height: 1px; }
.graphline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.graphline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.graphline svg { flex: none; overflow: visible; }
/* Kept in the background: the whole separator is dimmed. */
.graphline svg, .graphline .graph-keys { opacity: .6; }
.graphline .edges path { fill: none; stroke: var(--line-strong); stroke-width: 1.2; }
.graphline .flows path { fill: none; stroke: rgba(255, 138, 76, .45); stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.graphline .cards rect { fill: var(--surface); stroke: var(--line-strong); stroke-width: 1; }
.graphline .cards .plan { stroke: rgba(255, 138, 76, .45); }
.graphline .lines path { fill: none; stroke: var(--faint); stroke-width: 2; stroke-linecap: round; }
.graphline.in .flows path { animation: graph-link 5s ease-in-out infinite; }
.graphline.in .cards rect:not(.plan) { animation: graph-card 5s ease-in-out infinite; animation-delay: .35s; }
/* Each link draws in turn, and the card at its end lights up just after. */
.graphline.in .flows path:nth-child(2) { animation-delay: .5s; }
.graphline.in .flows path:nth-child(3) { animation-delay: 1s; }
.graphline.in .flows path:nth-child(4) { animation-delay: 1.5s; }
.graphline.in .cards rect:nth-child(3) { animation-delay: .85s; }
.graphline.in .cards rect:nth-child(4) { animation-delay: 1.35s; }
.graphline.in .cards rect:nth-child(5) { animation-delay: 1.85s; }
@keyframes graph-link { 0% { stroke-dashoffset: 1; opacity: 1; } 8%, 22% { stroke-dashoffset: 0; opacity: 1; } 30%, 100% { stroke-dashoffset: 0; opacity: 0; } }
@keyframes graph-card { 0%, 6%, 34%, 100% { stroke: var(--line-strong); } 10%, 24% { stroke: rgba(255, 138, 76, .4); fill: #16130f; } }
@media (prefers-reduced-motion: reduce) { .graphline.in .flows path, .graphline.in .cards rect { animation: none; } }

/* ---------- Separator under "Local and cloud": a block's panel buttons, opened in turn ---------- */
.panelline { display: flex; align-items: center; gap: 18px; padding-block: 8px; }
.panelline::before, .panelline::after { content: ""; flex: 1; height: 1px; }
.panelline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.panelline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.panelline .tools { display: flex; align-items: center; gap: 4px; padding: 5px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
/* Kept in the background: dimmed like the other separators. */
.panelline .tools { opacity: .4; }
.panelline span { display: inline-flex; align-items: center; gap: 6px; padding: 6px 9px; border-radius: 8px; font: 500 12.5px/1 var(--mono); color: var(--muted); }
.panelline svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.panelline i { width: 1px; height: 18px; margin-inline: 4px; background: var(--line-strong); }
.panelline.in .tools span { animation: panel-on 6s ease-in-out infinite; }
.panelline.in .tools span:nth-of-type(2) { animation-delay: 0.7s; }
.panelline.in .tools span:nth-of-type(3) { animation-delay: 1.4s; }
.panelline.in .tools span:nth-of-type(4) { animation-delay: 2.1s; }
.panelline.in .tools span:nth-of-type(5) { animation-delay: 2.8s; }
.panelline.in .tools span:nth-of-type(6) { animation-delay: 3.5s; }
@keyframes panel-on { 0%, 12%, 100% { color: var(--muted); background: transparent; } 2%, 10% { color: var(--orange); background: rgba(255, 138, 76, .14); } }
@media (prefers-reduced-motion: reduce) { .panelline.in .tools span { animation: none; } }

/* ---------- Local and cloud: the app's sidebar in both modes ---------- */
.sides { padding-block: 56px 80px; }
.sides .head { margin-bottom: 36px; }
.sides-row { display: flex; justify-content: center; align-items: flex-start; gap: 36px; }
.side { margin: 0; width: 316px; }
.side-shot { height: 400px; overflow: hidden; }
.side-shot img { display: block; width: 316px; height: auto; -webkit-mask-image: linear-gradient(#000 78%, transparent); mask-image: linear-gradient(#000 78%, transparent); }
/* The Local side: a replay of the app's sidebar (main.js plays it). Rows come in as the replay opens them; the state
   is a class on .sbd-in: folder (opened), open (expanded), rtc (a plan expanded), hover, menu, pick, moved, toast. */
.sbd-in { position: relative; height: 100%; font: 400 13px var(--sans); color: var(--text-2); user-select: none;
  -webkit-mask-image: linear-gradient(#000 86%, transparent); mask-image: linear-gradient(#000 86%, transparent); }
.sbd .ic { flex: none; width: 15px; height: 15px; } .sbd .ic.sm { width: 13px; height: 13px; }
.sbd-head { display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 14px; border-bottom: 1px solid var(--line); color: var(--text); font-weight: 600; }
.sbd-head .tile { --s: 16px; } .sbd-head > .ic { color: var(--muted); }
.sbd-r { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; color: var(--muted); }
.sbd-seg { display: grid; grid-template-columns: 1fr 1fr; margin: 10px 10px 8px; padding: 3px; border: 1px solid var(--line-strong); border-radius: 9px; background: #0b0a0e; }
.sbd-seg span { display: flex; align-items: center; justify-content: center; gap: 6px; height: 26px; border-radius: 6px; color: var(--muted); }
.sbd-seg .on { background: var(--raised); color: var(--text); }
.sbd-row { position: relative; display: flex; align-items: center; gap: 8px; height: 26px; margin: 0 8px; padding: 0 8px; border-radius: 7px; white-space: nowrap; transition: background-color .15s; }
.sbd-row > .ic { color: var(--muted); }
.sbd kbd { padding: 1px 5px; border: 1px solid var(--line-strong); border-radius: 5px; font: 500 10px var(--mono); color: var(--muted); }
.sbd-count i { width: 5px; height: 5px; border-radius: 50%; background: var(--orange); margin-right: 6px; }
.sbd-label { margin: 18px 16px 6px; font: 500 10.5px var(--mono); letter-spacing: .1em; color: var(--faint); }
.sbd-mono { font: 400 11.5px var(--mono); color: var(--muted); }
.sbd-chev { display: inline-flex; color: var(--faint); }
.sbd-chev .ic { rotate: -90deg; transition: rotate .2s; }
.sbd-in.open .sbd-folder .sbd-chev .ic, .sbd-in.rtc [data-at="rtc"] .ic { rotate: 0deg; }
.sbd-file { padding-left: 22px; } .sbd-ver { padding-left: 36px; gap: 7px; }
.sbd-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--d); }
.sbd-badge { height: 20px; padding: 0 6px; border: 1px solid var(--line-strong); border-radius: 6px; font-size: 11.5px; color: var(--text-2); }
.sbd-plain { color: var(--faint); } .sbd-add { color: var(--muted); }
/* Rows the replay hasn't opened yet; they come in with a short fade and slide when it does. */
.sbd-folder, .sbd-in [data-in], .sbd-new, .sbd-more { display: none; }
.sbd-in.folder .sbd-folder, .sbd-in.open [data-in="1"], .sbd-in.rtc [data-in="2"] { display: flex; animation: sbd-in .3s ease-out backwards; }
.sbd-in.open [data-in="1"] { animation-delay: calc(var(--n, 0) * 45ms); }
@keyframes sbd-in { from { opacity: 0; transform: translateY(-4px); } }
.sbd-in.hover .sbd-cr { background: var(--raised); color: var(--text); }
.sbd-in.hover:not(.moved) .sbd-cr .sbd-more { display: inline-flex; }
.sbd-in.moved .sbd-new { display: inline-flex; animation: sbd-pop .35s cubic-bezier(.2, 1.5, .4, 1); }
@keyframes sbd-pop { from { opacity: 0; transform: scale(.6); } }
.sbd-row.press, .sbd-mi.press, .sbd-pr.press { background: rgba(255, 255, 255, .1); }
/* The file's menu, by the pointer, and the project picker, over the sidebar. */
.sbd-menu { position: absolute; z-index: 3; display: none; padding: 4px; min-width: 176px; border: 1px solid var(--line-strong); border-radius: 10px; background: #151419; box-shadow: 0 16px 40px -10px rgba(0, 0, 0, .8); }
.sbd-in.menu .sbd-menu { display: grid; animation: sbd-in .18s ease-out; }
.sbd-mi { display: flex; align-items: center; gap: 8px; height: 28px; padding: 0 10px; border-radius: 6px; font-size: 12.5px; white-space: nowrap; }
.sbd-mi > .ic { color: var(--muted); }
.sbd-mi.hi { background: rgba(255, 255, 255, .06); color: var(--text); }
.sbd-pick { position: absolute; z-index: 3; left: 18px; right: 18px; top: 112px; display: none; gap: 6px; padding: 12px; border: 1px solid var(--line-strong); border-radius: 12px; background: #151419; box-shadow: 0 0 0 999px rgba(5, 4, 6, .5), 0 20px 50px -10px rgba(0, 0, 0, .8); }
.sbd-in.pick .sbd-pick { display: grid; animation: sbd-in .2s ease-out; }
.sbd-pick b { display: flex; align-items: center; gap: 7px; color: var(--text); font-weight: 600; }
.sbd-pick small { margin-bottom: 4px; font-size: 11.5px; color: var(--muted); }
.sbd-pr { display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border: 1px solid var(--line); border-radius: 8px; font-size: 12.5px; }
.sbd-pr > .ic { color: var(--muted); }
.sbd-pr em { margin-left: auto; font: 400 10.5px var(--mono); font-style: normal; color: var(--faint); }
.sbd-pr.hi { border-color: rgba(255, 138, 76, .5); background: rgba(255, 138, 76, .08); color: var(--text); }
/* The toast, as the app's but in Periferal's colours: the move's icon on an orange tile, what happened, and a button
   to dismiss it; a line along its foot counts down until it would go by itself. It rises from the sidebar's foot. */
.sbd { position: relative; }
.sbd-toast { position: absolute; z-index: 5; left: 10px; right: 10px; bottom: 10px; display: flex; align-items: center; gap: 10px; padding: 9px 8px 9px 10px;
  border: 1px solid var(--line-strong); border-radius: 12px; background: #151419; box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .9); overflow: hidden;
  font: 400 12px var(--sans); color: var(--text-2); opacity: 0; translate: 0 14px; transition: opacity .25s, translate .3s cubic-bezier(.2, .9, .3, 1); pointer-events: none; }
.sbd-in.toast ~ .sbd-toast { opacity: 1; translate: 0 0; }
.sbd-t-ic { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 8px; background: rgba(255, 138, 76, .14); color: var(--orange); }
.sbd-t-tx { display: grid; gap: 1px; min-width: 0; }
.sbd-t-tx b { font-weight: 600; font-size: 12.5px; color: var(--text); }
.sbd-t-tx small { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sbd-t-x { display: grid; place-items: center; flex: none; width: 24px; height: 24px; margin-left: auto; border-radius: 6px; color: var(--muted); transition: background-color .15s, color .15s; }
.sbd-t-x.press { background: rgba(255, 255, 255, .1); color: var(--text); }
.sbd-toast::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--orange); opacity: .7; transform-origin: left; transform: scaleX(0); }
.sbd-in.toast ~ .sbd-toast::after { animation: sbd-countdown 3s linear both; }
@keyframes sbd-countdown { from { transform: scaleX(1); } to { transform: scaleX(0); } }
/* The Cloud side's replay: the open plan is highlighted, with its author's avatar, its sections listing their counts.
   Comment reactions comes in when it moves to the cloud (.cr) and takes the highlight; .crx opens it. */
.sbd-on, .sbd-cplan { background: var(--raised); color: var(--text); }
.sbd-in.cr .sbd-on { background: transparent; color: var(--text-2); }
.sbd-cplan { display: none; }
.sbd-in.cr .sbd-cplan, .sbd-in.crx [data-in="3"] { display: flex; animation: sbd-in .3s ease-out backwards; }
.sbd-in.crx [data-at="crx"] .ic { rotate: 0deg; }
.sbd-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.sbd-av { flex: none; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: #f7a072; color: #16120f; font: 700 8px var(--sans); }
.sbd-n { font: 400 11px var(--mono); color: var(--faint); }
/* Comment reactions flying over from the Local sidebar to its place in the Cloud one (main.js): a chip that lifts off,
   arcs across and lands, then the row lights up and settles. In the app's colours, outside both sidebars. */
.sides-row { position: relative; }
.sbd-fly { position: absolute; left: 0; top: 0; z-index: 10; display: flex; align-items: center; gap: 7px; padding: 5px 11px 5px 8px; pointer-events: none;
  border: 1px solid rgba(255, 138, 76, .6); border-radius: 9px; background: #1b1714; color: #f1f0f4; font: 500 12.5px Geist, -apple-system, system-ui, sans-serif; white-space: nowrap;
  box-shadow: 0 0 0 4px rgba(255, 138, 76, .12), 0 14px 34px -8px rgba(255, 138, 76, .45); }
.sbd-fly svg { width: 14px; height: 14px; color: #ff8a4c; }
.sbd-in.landing .sbd-cplan { visibility: hidden; animation: none; }
.sbd-in.cr .sbd-cplan.flash { animation: sbd-land 1.1s ease-out; }
@keyframes sbd-land { 0% { background-color: rgba(255, 138, 76, .3); box-shadow: inset 0 0 0 1px rgba(255, 138, 76, .8); } 100% { background-color: var(--raised); box-shadow: inset 0 0 0 1px transparent; } }
/* Teammates join the new plan: their avatars pop up next to Mia's, one by one (.av1–.av3), overlapping a little.
   Then the plan fades (.leaving) as the first plan opens again. */
.sbd-avs { gap: 0; }
.sbd-avs .sbd-av + .sbd-av { margin-left: -5px; }
.sbd-avs .sbd-av { box-shadow: 0 0 0 2px var(--raised); }
.sbd-avs .a1, .sbd-avs .a2, .sbd-avs .a3 { display: none; }
.sbd-in.av1 .sbd-avs .a1, .sbd-in.av2 .sbd-avs .a2, .sbd-in.av3 .sbd-avs .a3 { display: grid; animation: sbd-pop .35s cubic-bezier(.2, 1.6, .4, 1); }
.sbd-in.leaving .sbd-cplan, .sbd-in.leaving [data-in="3"] { opacity: 0; transition: opacity .5s; }
/* The pointer: an arrow that glides between the rows it acts on, and dips as it clicks. */
.sbd-ptr { position: absolute; z-index: 6; left: 0; top: 0; width: 18px; height: 18px; fill: #fff; stroke: #0b0a0e; stroke-width: 1.4; stroke-linejoin: round;
  transition: translate .7s cubic-bezier(.5, 0, .2, 1), scale .12s; filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .6)); }
.sbd-ptr.down { scale: .85; }
.side figcaption { display: grid; gap: 6px; margin-top: 18px; }
.side figcaption b { display: inline-flex; align-items: center; gap: 8px; }
.side figcaption svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* Over each side, who it's for and what they do: two lines, centred. */
.side-h { margin: 0 -60px 20px; text-align: center; font-size: 24px; line-height: 1.2; letter-spacing: -.02em; white-space: nowrap; } /* wider than its side, so each line stays whole */
@media (max-width: 999px) { .side-h { margin-inline: 0; font-size: 21px; } .side-move { margin-top: calc(170px + 2 * 1.2 * 21px + 20px); } } /* narrower: inside its side, a size smaller */
@media (max-width: 760px) { .side-h { font-size: 24px; white-space: normal; } }
.side-move { display: grid; justify-items: center; gap: 8px; margin-top: calc(170px + 2 * 1.2 * 24px + 20px); } /* level with the shots' middles, under the headings */
.side-move svg { width: 28px; height: 28px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* The arrow passes towards the Cloud side like a race car: in from the left, stretched by its speed, through the
   middle and gone on the right in half a second; then the road is empty for a while. Down where the two stack. */
.side-move svg { animation: pass-by 2.2s cubic-bezier(.3, 0, .7, 1) infinite; }
@keyframes pass-by {
  0% { translate: -90px 0; scale: 1.9 1; opacity: 0; }
  6% { opacity: 1; }
  18% { opacity: 1; }
  24%, 100% { translate: 90px 0; scale: 1.9 1; opacity: 0; }
}
@keyframes pass-down {
  0% { translate: 0 -60px; scale: 1.9 1; opacity: 0; }
  6% { opacity: 1; }
  18% { opacity: 1; }
  24%, 100% { translate: 0 60px; scale: 1.9 1; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .side-move svg { animation: none; } }
@media (max-width: 760px) {
  .sides-row { flex-direction: column; align-items: center; gap: 22px; }
  .side-move { margin-top: 0; }
  .side-move svg { transform: rotate(90deg); animation-name: pass-down; }
}
.side-shot { border: 1px solid var(--line-strong); border-radius: 16px; background: #0e0d11; box-shadow: 0 40px 100px -40px rgba(0, 0, 0, .9); }
.side figcaption b { font: 600 16px var(--sans); color: var(--text); }
.side figcaption { font-size: 15px; line-height: 1.5; color: var(--text-2); }
.side-move { color: var(--muted); font: 500 12px var(--mono); letter-spacing: .08em; text-transform: uppercase; }
.side-move span { text-align: center; line-height: 1.6; }
.side-move svg { color: rgba(255, 138, 76, .7); }

/* The title of the demo about to play, centered over the document window on a dark blur. */
.demo-name {
  position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; padding: 24px 12%; pointer-events: none; opacity: 0; text-wrap: balance;
  background: rgba(5, 4, 6, .55); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  font: 700 clamp(26px, 3vw, 40px)/1.15 var(--sans); letter-spacing: -.03em; color: var(--text); text-align: center; transition: opacity .35s;
}
.demo-name.on { opacity: 1; }


/* ---------- Separator above "How it works": a plan's lifecycle, its statuses lit in turn ---------- */
.lifeline { display: flex; align-items: center; gap: 18px; padding-block: 8px; }
.lifeline::before, .lifeline::after { content: ""; flex: 1; height: 1px; min-width: 24px; }
.lifeline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.lifeline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.lifeline .life-steps { display: flex; align-items: center; }
.lifeline span { display: inline-flex; align-items: center; gap: 7px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font: 500 12px var(--mono); color: var(--muted); white-space: nowrap; }
.lifeline span::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--c); opacity: .45; }
.lifeline i { width: 14px; height: 1px; background: var(--line-strong); }
/* Kept in the background like the other separators: dimmed, each status only just brightening in turn, slowly. */
.lifeline .life-steps { opacity: .6; }
.lifeline.in .life-steps span { animation: life-on 8.4s ease-in-out infinite; }
.lifeline.in .life-steps span:nth-of-type(2) { animation-delay: 1.4s; }
.lifeline.in .life-steps span:nth-of-type(3) { animation-delay: 2.8s; }
.lifeline.in .life-steps span:nth-of-type(4) { animation-delay: 4.2s; }
.lifeline.in .life-steps span:nth-of-type(5) { animation-delay: 5.6s; }
.lifeline.in .life-steps span:nth-of-type(6) { animation-delay: 7s; }
@keyframes life-on {
  0%, 16%, 100% { color: var(--muted); border-color: var(--line); }
  6%, 12% { color: color-mix(in srgb, var(--text-2) 45%, var(--muted)); border-color: color-mix(in srgb, var(--c) 16%, var(--line)); }
}
@media (max-width: 900px) { .lifeline::before, .lifeline::after { min-width: 12px; } .lifeline { justify-content: center; } .lifeline span:not(:first-child):not(:last-child) { display: none; } .lifeline i:not(:first-of-type) { display: none; } .lifeline i { width: 40px; } }
@media (prefers-reduced-motion: reduce) { .lifeline.in .life-steps span { animation: none; } }

/* ---------- Separator above the FAQ: integrations sending context into the plan ---------- */
.syncline { display: flex; align-items: center; gap: 18px; padding-block: 8px; }
.syncline::before, .syncline::after { content: ""; flex: 1; height: 1px; min-width: 24px; }
.syncline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.syncline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.sync-row { display: flex; align-items: center; gap: 8px; opacity: .49; }
.syncline i { position: relative; width: 64px; height: 1px; overflow: visible; }
.syncline i::after { content: ""; position: absolute; top: 50%; width: 6px; height: 6px; margin-top: -3px; border-radius: 50%; opacity: 0; }
.syncline.in i::after { animation: sync-dot 2.4s ease-in infinite; }
.syncline.in i.in-left::after { animation-name: sync-dot-left; animation-delay: 1.2s; }
@keyframes sync-dot { 0% { left: 0; opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { left: calc(100% - 6px); opacity: 0; } }
@keyframes sync-dot-left { 0% { left: calc(100% - 6px); opacity: 0; } 15% { opacity: 1; } 85% { opacity: 1; } 100% { left: 0; opacity: 0; } }
.sync-hub { --s: 30px; width: 30px; height: 30px; flex: none; opacity: .7; }
@media (max-width: 760px) { .syncline::before, .syncline::after { min-width: 12px; } .syncline { justify-content: center; } .syncline i { width: 32px; } }
@media (prefers-reduced-motion: reduce) { .syncline.in i::after { animation: none; } }
.sync-row span { padding: 5px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface); font: 500 12px var(--mono); color: var(--muted); }
.syncline i { background: var(--line-strong); }
.syncline i::after { background: rgba(255, 138, 76, .6); box-shadow: 0 0 8px rgba(255, 138, 76, .3); }
.sync-row .sync-app { display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border: 1px solid var(--line); border-radius: 9px; background: var(--surface); color: var(--text-2); }
.sync-app svg { width: 16px; height: 16px; }
/* Loom and Granola, half gone at each end: more apps beyond them. */
.sync-app.far { opacity: .3; }
/* A step down toward each end: the logo between the nearest one and the faded end is a little dimmer. */
.sync-app:nth-child(2), .sync-app:nth-last-child(2) { opacity: .65; }
.sync-app.far:first-child { -webkit-mask-image: linear-gradient(90deg, transparent, #000 80%); mask-image: linear-gradient(90deg, transparent, #000 80%); }
.sync-app.far:last-child { -webkit-mask-image: linear-gradient(90deg, #000 20%, transparent); mask-image: linear-gradient(90deg, #000 20%, transparent); }

/* The graph separator's keys: each press draws the link that lights next (the graph's 5s loop). */
.graph-keys { display: flex; gap: 5px; margin-right: 4px; }
.graph-keys kbd { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 6px; font: 500 12px/1 var(--sans); color: var(--muted); background: var(--surface); border: 1px solid var(--line-strong); border-bottom-width: 2px; }
.graphline.in .graph-keys kbd { animation: gkey 5s ease-in-out infinite; }
.graphline.in .graph-keys kbd:nth-child(2) { animation-delay: 0.5s; }
.graphline.in .graph-keys kbd:nth-child(3) { animation-delay: 1.0s; }
.graphline.in .graph-keys kbd:nth-child(4) { animation-delay: 1.5s; }
@keyframes gkey { 0%, 8%, 100% { color: var(--muted); border-color: var(--line-strong); transform: none; } 2% { color: rgba(255, 138, 76, .5); border-color: rgba(255, 138, 76, .2); border-bottom-width: 1px; transform: translateY(1px); } }
@media (max-width: 760px) { .graph-keys { display: none; } }
@media (prefers-reduced-motion: reduce) { .graphline.in .graph-keys kbd { animation: none; } }


/* ---------- Separator after the numbers: what teams lose, drifting past from left to right ---------- */
.driftline { display: flex; align-items: center; gap: 18px; padding-block: 8px; }
.driftline::before, .driftline::after { content: ""; flex: 1; height: 1px; min-width: 24px; }
.driftline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.driftline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.drift { position: relative; flex: none; width: min(460px, 70vw); height: 48px; opacity: .4;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent); mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent); }
.drift i { position: absolute; left: 0; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; color: var(--coral);
  border: 1px solid rgba(239, 106, 90, .3); background: rgba(239, 106, 90, .06); opacity: 0; }
.drift svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.driftline.in .drift i { opacity: 1; animation: drift 10s linear infinite; }
.driftline.in .drift i:nth-child(1) { animation-delay: 0s; top: 6px; }
.driftline.in .drift i:nth-child(2) { animation-delay: -2s; top: 20px; }
.driftline.in .drift i:nth-child(3) { animation-delay: -4s; top: 2px; }
.driftline.in .drift i:nth-child(4) { animation-delay: -6s; top: 16px; }
.driftline.in .drift i:nth-child(5) { animation-delay: -8s; top: 9px; }
@keyframes drift {
  from { transform: translateX(-28px) rotate(-8deg); }
  50% { transform: translateX(calc(min(460px, 70vw) / 2 - 14px)) translateY(-4px) rotate(4deg); }
  to { transform: translateX(min(460px, 70vw)) rotate(-6deg); }
}
@media (prefers-reduced-motion: reduce) { .drift { display: flex; align-items: center; justify-content: space-evenly; } .driftline.in .drift i { position: static; animation: none; } }


/* Phones: the separators keep their fading side lines; their middles get a little narrower to leave them room. */
@media (max-width: 600px) {
  .sync-app.far { display: none; }
  /* Two logos a side: the outer one is the dimmer. */
  .sync-app:nth-child(2), .sync-app:nth-last-child(2) { opacity: .45; }
  .syncline, .lifeline { gap: 10px; }
}

/* The live plan's statuses, drawn over the shot (it has none of its own) and walked up to Built one requirement at a
   time (../showcase.js). Sized like the app's pills, in units of the shot's width (720 CSS pixels in the app). */
.status-run { container-type: inline-size; }
.status-run .st {
  position: absolute; translate: 0 -50%; height: calc(18 / 720 * 100cqw); padding: 0 calc(6 / 720 * 100cqw) 0 calc(8 / 720 * 100cqw);
  border-radius: calc(9 / 720 * 100cqw); background: var(--c, #807f89); color: #0b0b0e; pointer-events: none;
  font: 500 calc(11 / 720 * 100cqw) / calc(18 / 720 * 100cqw) "Geist Mono", ui-monospace, monospace; letter-spacing: .04em; white-space: nowrap;
  transition: background .35s;
}
.status-run .st.bump { animation: st-bump .45s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes st-bump { 40% { scale: 1.18; } }
@media (prefers-reduced-motion: reduce) { .status-run .st.bump { animation: none; } }

/* Out of view (main.js), a block's animations pause, and carry on when it scrolls back in. */
.offscreen, .offscreen *, .offscreen *::before, .offscreen *::after { animation-play-state: paused !important; }
/* A browser window beside a terminal in the demos: the same frame, the page drawn behind a cover that clears. */
.demo-terms.pair { grid-template-columns: 1fr 1.15fr; padding-inline: 4%; align-items: start; }
@container (max-width: 599px) { .demo-terms.pair { grid-template-columns: minmax(0, 1fr); padding-inline: 12px; } } /* narrow: the browser under its terminal */
.demo-browser { animation: db-in .55s cubic-bezier(.16, 1, .3, 1) both; }
.db-url { flex: 1; margin-left: 12px !important; padding: 2px 10px; border-radius: 6px; background: var(--bg); color: var(--muted); text-align: center; }
.db-view { position: relative; height: 290px; background: #f6f5f2; }
.db-view iframe, .db-view canvas { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.db-view iframe { pointer-events: none; }
@keyframes db-in { from { opacity: 0; transform: translateX(24px); } }

/* The header's button, while the hero's own is in view (main.js): out of the way, the menu's links moved right into its
   place. Once that one has gone, the links move back and it fades in from the right, a beat after them; going, it fades
   out at once. */
header .btn-primary { transition: opacity .35s .2s, translate .5s cubic-bezier(.16, 1, .3, 1) .1s, visibility 0s .1s; }
header { overflow-x: clip; } /* the away button, moved off to the right, never widens the page */
header .btn-primary.away { opacity: 0; visibility: hidden; translate: 24px 0; transition: opacity .15s, translate .15s, visibility 0s .15s; }
.nav .links { transition: translate .5s cubic-bezier(.16, 1, .3, 1); }
.nav .wrap:has(.btn.away) .links { translate: var(--cta-shift, 0px) 0; }

/* ---------- The manifesto: a dialog like the app's search modal ---------- */
/* Under the band's text, its two buttons side by side: join, and a quieter one to read the manifesto. */
.band-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
.btn-line { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1.5px rgba(22, 18, 15, .5); }
.btn-line:hover { background: rgba(22, 18, 15, .08); box-shadow: inset 0 0 0 1.5px var(--ink); }
/* As in the app: dimmed and blurred behind, a raised box with a strong border and a deep shadow, a 56px header row
   with its icon, title and Esc, and the text scrolling below it. In the middle of the screen. */
.manifesto { width: min(680px, calc(100vw - 32px)); max-height: min(80vh, 760px); padding: 0; overflow: hidden; color: var(--text);
  background: var(--raised); border: 1px solid var(--line-strong); border-radius: 12px; box-shadow: 0 24px 64px rgba(0, 0, 0, .6); }
.manifesto[open] { display: flex; flex-direction: column; animation: mf-in .25s cubic-bezier(.16, 1, .3, 1); }
.manifesto::backdrop { background: rgba(0, 0, 0, .5); backdrop-filter: blur(2px); }
@keyframes mf-in { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.mf-head { flex: none; display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 10px 0 16px; border-bottom: 1px solid var(--line); }
.mf-ic { width: 18px; height: 18px; fill: none; stroke: var(--muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.mf-head b { flex: 1; font-size: 15px; font-weight: 500; }
.mf-head kbd { font: 500 10.5px/1 var(--mono); color: var(--faint); padding: 3px 5px; border: 1px solid var(--line-strong); border-radius: 4px; }
.mf-close { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 8px; background: none; color: var(--muted); cursor: pointer; }
.mf-close:hover { background: var(--line); color: var(--text); }
.mf-close svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.mf-body { overflow: auto; padding: 22px 28px 30px; font-size: 16px; line-height: 1.7; color: var(--text-2); overscroll-behavior: contain; }
.mf-body h3 { margin: 26px 0 8px; font-size: 19px; color: var(--text); letter-spacing: -.01em; }
.mf-body h3:first-child { margin-top: 0; }
.mf-body p { margin: 0 0 14px; }
html:has(.manifesto[open]) { overflow: hidden; } /* the page stays put behind it */
@media (prefers-reduced-motion: reduce) { .manifesto[open] { animation: none; } }

/* ---------- "How it works" as a carousel (../showcase.js) ---------- */
/* One card at a time, the track sliding left to the next; dots under it. The cards' alternating offsets don't apply. */
.carousel { overflow: hidden; margin: 0 -4px; padding: 4px; } /* room for the cards' edges */
.carousel .stages { display: flex; gap: 24px; align-items: stretch; transition: transform .8s cubic-bezier(.65, 0, .35, 1); }
.carousel .stage { flex: 0 0 100%; min-width: 0; }
.carousel .stage:nth-child(n) { margin: 0; }
.carousel { position: relative; }
.car-nav { position: absolute; z-index: 2; top: 14px; left: 0; right: 0; display: flex; justify-content: center; align-items: center; gap: 18px; } /* over the top of the card showing */
.car-dots { position: relative; display: flex; justify-content: center; gap: 14px; }
/* "previous" and "next", in the cards' window-bar font, shown while the slides are hovered or focused (always on touch). */
.car-prev, .car-next { padding: 4px 6px; border: 0; background: none; cursor: pointer; font: 11px var(--mono); color: var(--muted); opacity: 0; transition: opacity .25s, color .2s; }
.car-prev::before { content: "← "; } .car-next::after { content: " →"; }
.carousel:hover .car-prev, .carousel:hover .car-next, .carousel:focus-within .car-prev, .carousel:focus-within .car-next { opacity: 1; }
@media (hover: none) { .car-prev, .car-next { opacity: 1; } }
.car-prev:hover, .car-next:hover { color: var(--orange); }
.car-prev:focus-visible, .car-next:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; border-radius: 4px; }
.car-dots button { width: 8px; height: 8px; padding: 0; border: 0; border-radius: 99px; background: var(--line-strong); cursor: pointer; transition: width .4s cubic-bezier(.16, 1, .3, 1), background .3s; }
.car-dots button:hover { background: var(--muted); }
.car-pill { position: absolute; top: 0; left: 0; width: 28px; height: 8px; border-radius: 99px; background: var(--orange); pointer-events: none; } /* the current one, over its dot (../showcase.js) */
.car-dots button:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

/* ---------- "Try it", rearranged (desktops and tablets) ---------- */
/* The front view fills the stack. The two behind it shrink to half and wait above it, side by side, their tops peeking
   out over it (--top) with their names: the phone on the left, the other desktop view on the right. A click on one
   brings it forward (../showcase.js). With the phone in front, it stands at the left, as tall as the stack, and both
   desktop views stand on its right, one over the other. From 1180px, the demos are a column on the right. */
@media (min-width: 601px) {
  /* --bs: the views behind (.6 of a desktop window; the phone at --ps .5), side by side as one pair, centred, --pair apart.
     --ss: the two desktop views beside the phone in front. */
  .try-stack { --top: 72px; --bs: .6; --ss: .5; --gap: 16px; --pair: 24px; --pw: calc(426px * .5); --lead: calc((100% - var(--bs) * 100% - var(--pair) - var(--pw)) / 2); width: auto; margin-left: 0; translate: none; }
  .try-windows { padding-top: var(--top); }
  .try-windows .try-window { width: 100%; transform: none; transform-origin: top right; }
  .try-stack[data-front="page"] [data-view="graph"], .try-stack[data-front="graph"] [data-view="page"] { z-index: 1; transform: translate(calc(-1 * var(--lead)), calc(-1 * var(--top))) scale(var(--bs)); }
  /* With the phone in front: the phone and the two views beside it as one group, centred, --gap apart throughout. */
  .try-stack[data-front="phone"] { --ss: .42; --off: calc((898px * var(--ps-front, .8) - 2 * var(--ss) * var(--win-real, var(--win-h)) - var(--gap)) / 2); --side: calc(var(--gap) + 4px); --lead2: calc((100% - var(--ss) * 100% - var(--side) - 426px * var(--ps-front, .8)) / 2); } /* --side: as wide as the gap between the two views, which comes out a little over --gap */
  .try-stack[data-front="phone"] [data-view="page"] { z-index: 1; transform: translate(calc(-1 * var(--lead2)), calc(var(--off) - var(--top))) scale(var(--ss)); }
  .try-stack[data-front="phone"] [data-view="graph"] { z-index: 1; transform: translate(calc(-1 * var(--lead2)), calc(var(--off) + var(--ss) * var(--win-real, var(--win-h)) + var(--gap) - var(--top))) scale(var(--ss)); } /* smaller than the phone, the pair centred on it */
  .try-phone { --ps: .5; --raise: calc(16px * var(--bs) - 68px * var(--ps)); left: var(--lead); top: var(--raise); bottom: auto; /* raised so the curve of its top corners ends level with the window's beside it */ transform: none; transition: left .7s cubic-bezier(.16, 1, .3, 1), top .7s cubic-bezier(.16, 1, .3, 1), width .7s cubic-bezier(.16, 1, .3, 1), height .7s cubic-bezier(.16, 1, .3, 1); }
  .try-stack[data-front="phone"] .try-phone { --ps: var(--ps-front, .8); left: var(--lead2); top: 0; transform: none; }
  /* The names, level along the top of each view behind, at the same size whatever the view's scale. */
  .try-back span { left: 50%; right: auto; top: 14px; writing-mode: horizontal-tb; transform: translateX(-50%); padding: 6px 12px; } /* lying flat: the padding turned with it */
  .try-window .try-back span { top: calc(22px + 10px / var(--bs)); transform: translateX(-50%) scale(calc(1 / var(--bs))); transform-origin: top center; }
  .try-stack[data-front="phone"] .try-window .try-back span { top: 50%; transform: translate(-50%, -50%) scale(calc(1 / var(--ss))); transform-origin: center; } /* the whole window shows: its name in the middle */
  .try-phone .try-back span { left: 50%; top: calc(22px * var(--bs) + 10px - var(--raise)); transform: translateX(-50%); } /* level with the window's name, however far the phone is raised */
  .try-stack[data-front="phone"][data-desk="page"] [data-view="page"] .try-back span,
  .try-stack[data-front="phone"][data-desk="graph"] [data-view="graph"] .try-back span { display: block; }
}
@media (min-width: 981px) {
  .try-layout { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: 28px; align-items: center; }
}
@media (min-width: 1180px) {
  .try-layout { width: min(1400px, 100vw - 48px); margin-left: 50%; translate: -50% 0; }
}
/* Narrower desktops: the demos still on the right, reaching in over the window's right edge and running off the page's
   right side, as if they came in from it. */
@media (min-width: 981px) and (max-width: 1179px) {
  .try { overflow-x: clip; }
  .try-layout { grid-template-columns: minmax(0, 1fr) 132px; gap: 0; margin-right: calc((100% - 100vw) / 2); } /* narrow: the titles take two lines */
  .try .try-layout .try-deck, .try .try-layout .try-deck.p2 { position: relative; z-index: 3; margin-left: -64px; transition: filter .5s; } /* both sets */
  /* While the pointer is on the window, the demos step behind it, dimmed like the views waiting at the top. */
  .try-layout .try-stack { position: relative; z-index: 2; }
  .try .try-layout:has(.try-windows:hover) .try-deck { z-index: 1; filter: brightness(.4) saturate(.6); }
  .try-layout .try-demos button, .try-layout .try-more { border-right: 0; border-radius: 12px 0 0 12px; box-shadow: -18px 20px 40px -24px rgba(0, 0, 0, .9); }
}
@media (min-width: 981px) {
  .try-layout .try-deck, .try-layout .try-deck.p2 { grid-template-columns: minmax(0, 1fr); align-content: start; align-self: start; margin: 140px 0 0; } /* from the top, a little under the window's own top (the views wait 72px above it): both sets start on the same line */ /* the second set keeps the first's height (../showcase.js): its cards and the button from the top, the room left under them */
  .try-layout .try-deck.p2 .try-more { order: -1; } /* back to the first set: above the second set's cards */
  .try-layout .try-demos { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; }
  .try-layout .try-more { height: 44px; }
}

/* The note over the demos, beside the window (desktops only): the arrow points at it; a short rule; how to take it over. */
.try-hint { display: none; }
@media (min-width: 981px) {
  .try-layout .try-hint { order: -2; display: grid; gap: 12px; margin: 0 0 18px; font-size: 14px; line-height: 1.5; color: var(--text-2); }
  .try-hint .th-arrow { color: var(--orange); font-weight: 600; }
  .try-hint .th-sub { padding-top: 12px; border-top: 1px solid var(--line-strong); color: var(--muted); font-size: 13px; }
}

@media (min-width: 981px) and (max-width: 1179px) { .try-layout .try-hint { position: relative; isolation: isolate; padding: 14px 14px 16px; margin-bottom: 0; font-size: 13px; } .try-layout .try-hint::before { content: ""; position: absolute; inset: 0; z-index: -1; border: 1px solid var(--line); border-right: 0; border-radius: 12px 0 0 12px; background: var(--surface); box-shadow: -18px 20px 40px -24px rgba(0, 0, 0, .9); -webkit-mask: linear-gradient(90deg, #000 45%, transparent); mask: linear-gradient(90deg, #000 45%, transparent); } .try-layout .try-hint .th-sub { border-top: 0; background: linear-gradient(90deg, var(--line-strong) 40%, transparent) top / 100% 1px no-repeat; } .try-hint .th-sub { font-size: 12px; } } /* a card like the demos, over the window's edge with them, its frame, fill and rule fading out to the right */

/* Under the phone in front, a switch between its two views (601px and up; phones have the switches on top). */
.phone-views { display: none; }
@media (min-width: 601px) {
  .try-stack .try-windows { transition: padding-bottom .7s cubic-bezier(.16, 1, .3, 1); }
  .try-stack[data-front="phone"] .try-windows { padding-bottom: 18px; }
  .try-stack[data-front="phone"] .phone-views { display: flex; position: absolute; left: 50%; top: calc(100% + 14px); translate: -50% 0; white-space: nowrap; animation: pv-in .4s .3s both; }
  @keyframes pv-in { from { opacity: 0; } }
}
.try-hint .th-lead { color: var(--text); } /* white, like the views' names */
.try-hint .th-lead { font: 500 12.5px/1.6 var(--mono); letter-spacing: .02em; } /* the views' names' type */
/* Overlapping the window (981–1179px), the demo cards and the button fade out to the right like the note: their frame
   and fill are drawn on a ::before, masked, so the text stays whole. */
@media (min-width: 981px) and (max-width: 1179px) {
  .try-layout .try-demos button, .try-layout .try-more { --bg: var(--surface); --bd: var(--line); --bs: solid; isolation: isolate; border: 0; background: none; box-shadow: none; }
  .try-layout .try-demos button { padding: 16px 14px 14px 15px; }
  .try-layout .try-demos button:hover { --bd: var(--line-strong); }
  .try-layout .try-demos .playing { --bg: #17120f; --bd: rgba(255, 138, 76, .5); }
  .try-layout .try-more { --bd: var(--line-strong); --bs: dashed; }
  .try-layout .try-more:hover { --bd: var(--orange); }
  .try-layout .try-more { position: relative; } .try-layout .try-more svg { position: relative; }
  .try-layout .try-demos button::before, .try-layout .try-more::before { content: ""; position: absolute; inset: 0; z-index: -1; border: 1px var(--bs) var(--bd); border-right: 0; border-radius: inherit; background: var(--bg); transition: border-color .2s, background .2s;
    -webkit-mask: linear-gradient(90deg, #000 45%, transparent); mask: linear-gradient(90deg, #000 45%, transparent); }
  .try-layout .try-demos button::after { -webkit-mask: linear-gradient(90deg, #000 45%, transparent); mask: linear-gradient(90deg, #000 45%, transparent); }
}

/* "How it all works": its eyebrow and heading centred over the plan and the stages. */
#how .head > .eyebrow { display: flex; width: fit-content; margin-inline: auto; }
#how .head > h2 { text-align: center; }
#faq .faq-list { margin-inline: auto; } /* centred under its heading */
/* "How it works": every card's animation is one window shape at every width. Under its title bar (../showcase.js wraps
   the rest in .win-body) it has the app screenshots' proportions. A screenshot covers it from the top, cropped below
   (or at the sides, when it's wider); the terminal and the Markdown-to-blocks are laid out at a set width and scaled
   to fit, like pictures of themselves. */
.carousel .win-body { position: relative; aspect-ratio: 2304 / 1964; overflow: hidden; }
.carousel .win-body > .pic { width: max(100%, calc(100% * var(--r, 1) * 1964 / 2304)); left: 50%; translate: -50% 0; }
.carousel .win-body img { display: block; }
.carousel .win-body > :is(pre, .mb) { position: absolute; top: 0; left: 0; box-sizing: border-box; transform-origin: 0 0; }
.carousel .md2blocks .mb { align-content: center; }
/* The Markdown on top and the blocks below where that fits the window, else side by side (../showcase.js). */
.carousel .md2blocks .mb.wide { grid-template-columns: minmax(0, 1.25fr) 24px minmax(0, 1fr); padding: 26px 22px; }
.carousel .mb.wide .mb-arrow { justify-self: stretch; width: auto; height: 2px; }
.carousel .mb.wide .mb-arrow::after { right: -1px; top: -4px; bottom: auto; border: 5px solid transparent; border-left: 7px solid var(--line-strong); border-right: 0; }
.carousel .md2blocks .mb.tall { grid-template-columns: minmax(0, 1fr); gap: 18px; padding: 26px 22px; }
.carousel .mb.tall .mb-arrow { justify-self: center; width: 2px; height: 22px; }
.carousel .mb.tall .mb-arrow::after { right: -4px; top: auto; bottom: -2px; border: 5px solid transparent; border-top: 7px solid var(--line-strong); border-bottom: 0; }
.versus .vs { opacity: .125; } /* the VS, well in the background */
.term pre:not(.roomy) :is(.more, .gap) { display: none; } /* extras, where its window has room (../showcase.js) */

/* ---------- For every role (../showcase.js) ---------- */
.roles .head { margin-bottom: 40px; }
.role-pick { position: relative; display: flex; justify-content: center; align-items: center; gap: 12px; margin-bottom: 28px; }
.rp-step { flex: none; width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted); font: 15px var(--mono); cursor: pointer; transition: color .2s, border-color .2s; }
.rp-step:hover { color: var(--orange); border-color: var(--orange); }
/* "I am" and the role, the role sliding up as it changes, the pill's width following it. The bar filling till the
   next one runs along its bottom border, between the rounded ends. */
.rp-pill { position: relative; display: inline-flex; align-items: center; gap: .3em; padding: 12px 20px 14px 24px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--surface); color: var(--text);
  font: 600 clamp(19px, 2.4vw, 28px)/1.25 var(--sans); letter-spacing: -.02em; cursor: pointer; transition: border-color .2s; }
.rp-pill:hover, .rp-pill[aria-expanded="true"] { border-color: var(--orange); }
.rp-i { color: var(--text-2); font-weight: 500; }
.rp-roles { display: grid; height: 1.25em; overflow: hidden; transition: width .55s cubic-bezier(.16, 1, .3, 1); }
.rp-roles > span { grid-area: 1 / 1; justify-self: start; width: max-content; white-space: nowrap; opacity: 0; transform: translateY(110%);
  transition: transform .55s cubic-bezier(.16, 1, .3, 1), opacity .35s; }
.rp-roles > .on { opacity: 1; transform: none; }
.rp-roles > .out { transform: translateY(-110%); }
.rp-chev { width: 9px; height: 9px; margin: -4px 0 0 6px; border: solid var(--muted); border-width: 0 2px 2px 0; rotate: 45deg; }
.rp-bar { position: absolute; left: 26px; right: 26px; bottom: -1.5px; height: 2px; border-radius: 2px; background: var(--grad); opacity: .8; transform: scaleX(0); transform-origin: left; transition: transform .1s linear; }
/* The whole list, under the pill. */
.rp-menu { position: absolute; z-index: 5; top: calc(100% + 10px); left: 50%; translate: -50% 0; width: min(560px, calc(100vw - 32px)); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px;
  padding: 8px; border-radius: 16px; border: 1px solid var(--line-strong); background: var(--raised); box-shadow: 0 30px 70px -20px rgba(0, 0, 0, .85); }
.rp-menu[hidden] { display: none; }
.rp-menu button { padding: 9px 12px; border: 0; border-radius: 10px; background: none; color: var(--text-2); font: 15px var(--sans); text-align: left; cursor: pointer; }
.rp-menu button:hover, .rp-menu button:focus-visible { background: var(--surface); color: var(--text); outline: none; }
.rp-menu button[aria-current="true"] { color: var(--orange); }
.rp-step:focus-visible, .rp-pill:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
/* What each role gets, one card at a time, sliding along with the picker. */
.role-view { overflow: hidden; border-radius: 26px; border: 1px solid var(--line); background: var(--surface); }
.role-track { display: flex; transition: transform .8s cubic-bezier(.65, 0, .35, 1); }
.role-slide { flex: 0 0 100%; min-width: 0; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: 44px; align-items: center; padding: 40px 44px; }
.role-slide .k { font: 500 13px var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--orange); }
.role-slide h3 { margin: 14px 0 0; font-size: clamp(24px, 2.5vw, 32px); line-height: 1.15; letter-spacing: -.03em; }
.role-gets { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.role-gets li { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 14px; align-items: baseline; padding: 14px 18px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg); color: var(--text-2); font-size: 16px; }
.role-gets li span { font: 500 12px var(--mono); color: var(--orange); }
@media (max-width: 980px) { .role-slide { grid-template-columns: minmax(0, 1fr); gap: 24px; padding: 30px 26px; } }
@media (max-width: 600px) {
  .rp-step { display: none; } /* the pill opens the list; it moves on by itself */
  .rp-pill { padding: 10px 16px 12px 18px; }
  .rp-bar { left: 22px; right: 22px; }
  .rp-menu { grid-template-columns: minmax(0, 1fr); }
  .role-slide { padding: 24px 20px; }
}
@media (prefers-reduced-motion: reduce) { .role-track, .rp-roles, .rp-roles > span { transition: none; } }

/* ---------- Separator: the team on one line (four people, three agents), a bubble over each head in turn ---------- */
.teamline { --tm-mia: var(--mia); --tm-josh: var(--josh); --tm-alex: var(--alex); --tm-radhi: var(--radhi); --tm-cc: #d97757; --tm-cx: #7cc4f5; --tm-cu: #9d8cff;
  display: flex; align-items: center; gap: 18px; padding: 52px 0 8px; } /* room above for the bubbles */
.teamline::before, .teamline::after { content: ""; flex: 1; height: 1px; min-width: 24px; }
.teamline::before { background: linear-gradient(90deg, transparent, var(--line-strong)); }
.teamline::after { background: linear-gradient(90deg, var(--line-strong), transparent); }
.team-row { position: relative; display: flex; align-items: center; gap: 22px; opacity: .42; }
.team-row::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--line-strong); } /* the line they stand on */
.tm { position: relative; display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid var(--line-strong); border-radius: 50%; background: var(--surface); font: 600 12px/1 var(--sans); color: var(--muted); }
.tm.bot { border-radius: 9px; font: 500 11px/1 var(--mono); }
.tm b { font-weight: inherit; }
.tm q { --x: -50%; position: absolute; bottom: calc(100% + 10px); left: 50%; translate: var(--x) 0; padding: 6px 10px; border: 1px solid color-mix(in srgb, var(--c) 40%, var(--line-strong)); border-radius: 10px; background: var(--raised);
  font: 500 12px/1.2 var(--sans); color: var(--text-2); white-space: nowrap; quotes: none; opacity: 0; transform: translateY(6px) scale(.92); transform-origin: 50% 100%; }
.tm.bot q { font: 500 11.5px/1.2 var(--mono); }
.tm q::after { content: ""; position: absolute; top: 100%; left: calc(50% - 5px); border: 5px solid transparent; border-top-color: color-mix(in srgb, var(--c) 40%, var(--line-strong)); }
/* The ones at the ends keep their bubbles over the row, not past it. */
.tm:first-child q { --x: -30px; transform-origin: 14px 100%; } .tm:first-child q::after { left: 25px; }
.tm:last-child q { --x: calc(-100% + 30px); transform-origin: calc(100% - 14px) 100%; } .tm:last-child q::after { left: auto; right: 25px; }
.teamline.in .tm, .teamline.in .tm q { animation: tm-on 8.4s ease-in-out infinite; animation-delay: calc(var(--i) * 1.2s); }
.teamline.in .tm q { animation-name: tm-say; }
@keyframes tm-on { 0%, 16%, 100% { color: var(--muted); border-color: var(--line-strong); } 3%, 13% { color: var(--c); border-color: color-mix(in srgb, var(--c) 55%, var(--line-strong)); } }
@keyframes tm-say { 0%, 16%, 100% { opacity: 0; transform: translateY(6px) scale(.92); } 3%, 13% { opacity: .7; transform: none; } } /* the bubbles a step dimmer than the row */
@media (max-width: 600px) { .teamline { gap: 10px; } .teamline::before, .teamline::after { min-width: 10px; } .team-row { gap: 12px; } }
@media (prefers-reduced-motion: reduce) { .teamline.in .tm, .teamline.in .tm q { animation: none; } .tm:nth-child(4) q { opacity: .7; transform: none; } }
.tm svg { width: 17px; height: 17px; } /* an agent: the bot, in its colour as it speaks */
/* The graph view, behind the window: its frame, under its label, round an empty canvas: the graph's dark ground and
   its dot grid, drawn at the screenshot's own spacing (19.25px in its 2140 × 1264, covering the screen as it does). */
.try-window[data-view="graph"] .try-screen { container-type: size; background: #050407; }
.try-window[data-view="graph"] .try-screen::before { --s: max(100cqw * 19.25 / 2140, 100cqh * 19.25 / 1264); content: ""; position: absolute; inset: 0;
  background: radial-gradient(circle, rgba(255, 255, 255, .15) 0 .9px, transparent 1.3px) calc(var(--s) * .14) calc(var(--s) * .33) / var(--s) var(--s); }
/* What the views behind show. Above the document window, as they are at first, the phone and the graph view are just
   their frames, round an empty dark screen, under their labels. With the phone or the graph view in front, the others
   show what's on them, at half strength. Each fades as the front changes. (A filter, so it stacks on the screens' own
   fades, such as the screenshot giving way to the live app.) */
.phone-screen > *, .try-window .try-screen > * { transition: filter .5s; }
.try-stack:not([data-front="phone"], [data-front="graph"]) :is(.phone-screen, .try-window[data-view="graph"] .try-screen) > * { filter: opacity(0); }
.try-stack[data-front="graph"] .phone-screen > * { filter: opacity(.5); }
.try-stack[data-front="phone"] .try-window .try-screen > * { filter: opacity(.25); } /* beside the phone, a step further back */
.try-stack[data-front="phone"] .try-window[data-view="page"] .try-screen > * { filter: opacity(.125); } /* the document, busier, further still */
/* With the graph view in front, the document window above it is just its frame and label round faint tiles where the
   document's text is. */
.try-stack[data-front="graph"] .try-window[data-view="page"] .try-screen > :not(.doc-ghost) { filter: opacity(0); }
.doc-ghost { position: absolute; inset: 0; display: grid; align-content: start; gap: 14px; padding: 9% 14% 0 17%; opacity: 0; transition: opacity .5s; pointer-events: none; }
.try-stack[data-front="graph"] .doc-ghost { opacity: 1; }
.doc-ghost i { width: var(--w); height: 10px; border-radius: 4px; background: rgba(255, 255, 255, .045); }
.doc-ghost .h { height: 26px; margin-bottom: 8px; border-radius: 6px; background: rgba(255, 255, 255, .065); }
.doc-ghost .k { height: 7px; }
.doc-ghost .g { height: 16px; background: rgba(255, 255, 255, .055); }
.doc-ghost .gap { margin-top: 26px; }
.terms .ff-down { filter: opacity(.25); } /* the arrow down to the tokens, at a quarter strength (a filter, so it stacks on its own blink) */
.point > .ico { filter: opacity(.5); } /* the plugin points' icons, at half strength */
/* Side by side, the VS takes little room of its own: the two sides come in close and run over it, the VS behind. */
@media (min-width: 761px) {
  .versus { grid-template-columns: minmax(0, 1fr) 0 minmax(0, 1fr); column-gap: 28px; }
  .versus .vs { justify-self: center; width: max-content; z-index: 0; }
  .vs-side { position: relative; z-index: 1; }
}
.try-hint .th-brand { font: 600 1.18em/1 var(--sans); letter-spacing: -.03em; } /* the name in the logo's type */
/* "How it works": room above the dots and below them, before the card's content. */
/* The first dot as far down from the card's top as in from its side: on the diagonal through its rounded corner. */
.car-nav { top: 34px; }
.carousel .stage { padding-top: 86px; }
@media (max-width: 980px) { .car-nav { top: 24px; } .carousel .stage { padding-top: 70px; } }
/* The dots at the left, in line with the card's content; "previous" and "next" after them. */
.car-nav { left: 41px; right: auto; justify-content: flex-start; } .car-dots { order: -1; gap: 22px; } /* room for the band on the first or last dot, which starts or ends with it (../showcase.js) */
@media (max-width: 980px) { .car-nav { left: 31px; } }
/* The card stays put and only what's in it slides: the frame is the carousel's, the slides are bare. The dots keep
   their place, the first one on the diagonal through the frame's rounded corner, in line with the content. */
.carousel { margin: 0; padding: 0; border-radius: 26px; background: var(--surface); border: 1px solid var(--line); }
.carousel .stage { border: 0; border-radius: 0; background: none; }
.car-nav { left: 36px; top: 29px; height: 22px; } /* one height, however tall the touch-sized buttons get: the dots keep their place */
@media (max-width: 980px) { .car-nav { left: 26px; top: 19px; } }
/* The current dot opens to the pill's width under it, the others keeping their spacing either side (../showcase.js). */
.car-dots { gap: 12px; }
.car-dots button { transition: width .7s var(--dots-ease, cubic-bezier(.65, 0, .35, 1)); }
.car-dots button.on { width: 28px; }
/* Side by side, the stages but the current one at half strength. */
@media (min-width: 981px) {
  .pulse-list li { transition: color .4s, opacity .4s; }
  .pulse-list li:not(.on) { opacity: .5; }
}
/* A hairline between the roles in the list, in the gap above each one past the first row. */
.rp-menu button { position: relative; }
.rp-menu button:nth-child(n + 3)::before { content: ""; position: absolute; left: 12px; right: 12px; top: -1.5px; height: 1px; background: linear-gradient(90deg, var(--line) 40%, transparent); }
@media (max-width: 600px) { .rp-menu button:nth-child(2)::before { content: ""; position: absolute; left: 12px; right: 12px; top: -1.5px; height: 1px; background: linear-gradient(90deg, var(--line) 40%, transparent); } }
.brand { font-weight: 600; letter-spacing: -.03em; color: var(--text); } /* the name in running text, as the logo writes it */
.foot-info .brand { color: inherit; } /* in the footer, as quiet as the line around it */
/* The window peeking out above the one in front shows no title in its bar either: just its frame and its label. */
.try-window .app-chrome span { transition: opacity .5s; }
.try-stack:not([data-front="phone"], [data-front="graph"]) .try-window[data-view="graph"] .app-chrome span,
.try-stack[data-front="graph"] .try-window[data-view="page"] .app-chrome span { opacity: 0; }
/* The phone behind the document view still shows its clock and battery, at half strength, as it does behind the graph view. */
.try-stack:not([data-front="phone"], [data-front="graph"]) .try-windows .try-phone .phone-screen > .phone-status { filter: opacity(.5); }
/* The desktop view behind, peeking out above the one in front, 30% narrower (--bw), beside the phone: the pair
   from 20px in from the front window's left edge. */
@media (min-width: 601px) {
  .try-stack { --bw: .7; --lead: 20px; } /* the pair starts 20px in from the front window's left edge */
  .try-windows .try-window { justify-self: end; transition: transform .7s cubic-bezier(.16, 1, .3, 1), width .7s cubic-bezier(.16, 1, .3, 1); }
  .try-stack[data-front="page"] [data-view="graph"], .try-stack[data-front="graph"] [data-view="page"] { width: calc(100% * var(--bw));
    transform: translate(calc(var(--lead) + var(--pw) + var(--pair) + var(--bs) * 100% - 100% / var(--bw)), calc(-1 * var(--top))) scale(var(--bs)); }
}
/* The views' names, at 56% until pointed at or reached by keyboard. */
.try-back span { transition: opacity .2s; }
.try-back:not(:hover, :focus-visible) span { opacity: .56; }
.mk-btn { border-radius: 6px; background: #000; color: var(--text); padding: 4px 14px; } /* black, its corners the waitlist buttons' (12px on 46px), in proportion */
/* The views waiting at the top, 10px lower (--low): a narrower strip showing, their names still centred in it, the
   phone's level with the window's. */
@media (min-width: 601px) {
  .try-stack { --low: 10px; }
  .try-stack[data-front="page"] [data-view="graph"], .try-stack[data-front="graph"] [data-view="page"] {
    transform: translate(calc(var(--lead) + var(--pw) + var(--pair) + var(--bs) * 100% - 100% / var(--bw)), calc(var(--low) - var(--top))) scale(var(--bs)); }
  .try-stack:not([data-front="phone"]) .try-phone { top: calc(var(--raise) + var(--low)); }
  .try-stack:not([data-front="phone"]) .try-window .try-back span { top: calc(22px + (7px - var(--low) / 2) / var(--bs)); }
  .try-stack:not([data-front="phone"]) .try-phone .try-back span { top: calc(22px * var(--bs) + 7px - var(--low) / 2 - var(--raise)); }
}
.mk-btn { padding: 6px 18px; border-radius: 8px; font-size: 13px; } /* a bit bigger, the corners kept in proportion */
.mk-btn { padding: 9px 26px; border-radius: 11px; font-size: 16px; } /* bigger still, in the room of the row that was under it; the corners in proportion */
/* The roles run down the first column, then down the second: a line above each but the top one of each column. */
.rp-menu { grid-auto-flow: column; grid-template-rows: repeat(6, auto); }
.rp-menu button:nth-child(2)::before { content: ""; position: absolute; left: 12px; right: 12px; top: -1.5px; height: 1px; background: linear-gradient(90deg, var(--line) 40%, transparent); }
.rp-menu button:nth-child(7)::before { display: none; }
@media (max-width: 600px) { .rp-menu { grid-auto-flow: row; grid-template-rows: none; } .rp-menu button:nth-child(7)::before { display: block; } }
/* The caption band over the top of the window, narrating the demo playing (../showcase.js). */
.demo-cap { position: absolute; left: 0; right: 0; top: 0; z-index: 3; padding: 12px 24px; pointer-events: none; opacity: 0; transition: opacity .3s;
  background: rgba(14, 13, 17, .82); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid var(--line-strong);
  font: 500 14px/1.45 var(--sans); color: var(--text); text-align: center; text-wrap: balance; }
.demo-cap.on { opacity: 1; }
@media (max-width: 600px) { .demo-cap { padding: 10px 16px; font-size: 13px; } }
.demo-cap { font: 500 13px/1.6 var(--mono); letter-spacing: .02em; } /* the note's type, beside the window */
.joined { width: min(520px, calc(100vw - 32px)); } .joined .joined-actions { margin: 22px 0 0; } /* the waitlist's thank-you, like the manifesto, smaller */
