/* Aouo Web — hero stage: chat deck → Cloudflare Tunnel → this Mac, where
   Aouo runs the tools inside the screen. */

.hero {
  /* Every vertical gap in the hero is `base + a share of --vgrow`, so the
     block grows with the window instead of being centred between two empty
     bands. --vgrow is 0 up to a 900-tall window — that size was tuned by hand
     and stays exactly as it was — and opens up from there. */
  --vgrow: clamp(0px, 100svh - 900px, 760px);
  /* --card-h sizes the chat cards and, through them, the machine facing them.
     It takes a small share of --vgrow: on a tall window the alternative is a
     band of empty page above the stage, which reads as the demo having sunk
     to the bottom. The share is small on purpose — most of the spare height
     still belongs to the gaps, and the stage must never outgrow the copy. */
  --card-h: calc(clamp(280px, 30svh, 360px) + var(--vgrow) * 0.13);
  /* Room the deck keeps free up-left for the sunk cards. The two are not the
     same on purpose: sideways a card only has to clear the one in front of it,
     but upward it has to show enough of its own head for you to read which
     tool it is, so the rise is the larger of the two. The rise also answers to
     the window: on a short screen it gives its room back rather than pushing
     the caption under the fold. */
  --deck-x: 66px;
  --deck-y: clamp(78px, 8.4svh, 104px);
  position: relative; overflow: hidden;
  display: flex; align-items: center;
  min-height: 100vh;
  min-height: 100svh;
  /* The app bar floats over this section, so the top padding clears its 64px
     as well as the section's own breathing room. */
  /* Spare height is weighted to the bottom, so the whole composition rides
     high in the window rather than settling into the middle of it. */
  padding-block:
    calc(64px + clamp(18px, 2.2vw, 32px))
    calc(clamp(22px, 2.6vw, 38px) + var(--vgrow) * 0.24);
}

/* ── Aurora backdrop ───────────────────────────────────────── */

.hero__aurora { position: absolute; inset: -20% -10% auto; height: 120%; pointer-events: none; z-index: 0; }
.hero__aurora span {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(110px); opacity: light-dark(0.24, 0.3);
  animation: drift 26s var(--ease) infinite alternate;
}
.hero__aurora span:nth-child(1) {
  width: 34vw; height: 34vw; left: -4vw; top: 2vw;
  background: radial-gradient(circle, var(--primary) 0%, transparent 68%);
}
.hero__aurora span:nth-child(2) {
  width: 28vw; height: 28vw; left: 40vw; top: -4vw; animation-delay: -9s;
  background: radial-gradient(circle, var(--icon-blue) 0%, transparent 68%);
}
.hero__aurora span:nth-child(3) {
  width: 26vw; height: 26vw; right: -3vw; top: 16vw; animation-delay: -17s;
  background: radial-gradient(circle, var(--icon-pink) 0%, transparent 68%);
}
@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(3vw, 4vw, 0) scale(1.12); }
  100% { transform: translate3d(-3vw, 2vw, 0) scale(0.95); }
}

.hero .wrap { position: relative; z-index: 1; width: 100%; }

/* ── Copy ──────────────────────────────────────────────────── */

.hero__copy { max-width: 760px; }
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 14px 7px 8px; border-radius: 999px;
  background: var(--surface-container-high); color: var(--on-surface-variant);
  font-size: 12.5px; font-weight: 500;
}
.eyebrow b {
  padding: 3px 8px; border-radius: 999px;
  background: var(--primary-container); color: var(--on-primary-container);
  font-size: 11px; font-weight: 600;
}
/* Two short sentences, one per line, so the break is the argument: the first
   line is where the AI thinks, the second is where the work happens. The
   ceiling is held at 52 because the hero still has to fit one 100svh screen
   together with the stage below it. */
.hero h1 {
  margin-top: calc(var(--sp-12) + var(--vgrow) * 0.05);
  font-size: clamp(32px, 4.3vw, 52px); font-weight: 650;
  line-height: 1.08; letter-spacing: -0.03em;
}
.hero h1 em {
  font-style: normal;
  background: linear-gradient(100deg, var(--primary), var(--icon-blue));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero__lede {
  margin-top: calc(var(--sp-12) + var(--vgrow) * 0.05);
  max-width: 58ch;
  font-size: 16px; line-height: 1.6; color: var(--on-surface-variant);
}
/* The specification, kept off the headline. What the product means to someone
   comes first; MCP, the tool count and the tunnel wait one line down, where
   the reader who cares about them will still find them immediately. */
.hero__meta {
  margin-top: var(--sp-16);
  font-family: var(--font-mono); font-size: 12.5px; letter-spacing: 0.01em;
  color: var(--on-surface-variant); opacity: 0.85;
}
.hero__actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-16);
  margin-top: calc(20px + var(--vgrow) * 0.035);
}
/* The Button Run is 44 tall; the text button beside it has to match, or its
   hover state reads as a smaller target sitting next to a bigger one. */
.hero__actions .btn { min-height: 44px; }
.hero__actions .btn--text { padding-inline: 18px; }

/* ── Stage ─────────────────────────────────────────────────── */

.stage {
  position: relative; margin-top: calc(clamp(14px, 1.8vw, 26px) + var(--vgrow) * 0.045);
  /* The lane holds a short straight run of pipe, nothing more — the width it
     used to spend on a long sagging one belongs to the machine. */
  display: grid; grid-template-columns: minmax(0, 0.88fr) 188px minmax(0, 1.2fr);
  align-items: center;
}

.stage__wire { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; pointer-events: none; overflow: visible; }
.stage__wire path { fill: none; }
/* Four strokes on the same path make a tube: outer casing, hollow bore,
   joint ribs, then the marching centre line that shows flow direction. */
.wire__casing { stroke: var(--outline-variant); stroke-width: 23; stroke-linecap: round; stroke-linejoin: round; }
/* The bore has to read as hollow against the page, which means lighter than
   the casing in light mode and lighter than the backdrop in dark. */
.wire__bore { stroke: light-dark(var(--surface), var(--surface-container)); stroke-width: 16; stroke-linecap: round; }
.wire__ribs { stroke: var(--outline); stroke-width: 23; stroke-dasharray: 2 48; stroke-linecap: butt; opacity: 0.45; }
.wire__base { stroke: light-dark(var(--outline-variant), var(--outline)); stroke-width: 1.5; stroke-dasharray: 3 7; stroke-linecap: round; animation: march 1.4s linear infinite; }
.wire__trail { stroke: url(#wireGrad); stroke-width: 10; stroke-linecap: round; opacity: 0; }
@keyframes march { to { stroke-dashoffset: -20; } }

/* ── Chat deck ─────────────────────────────────────────────── */

/* The deck is as tall as the front card plus the room the sunk ones rise into. */
.deck { position: relative; height: calc(var(--card-h) + var(--deck-y)); z-index: 3; }
.client {
  position: absolute; inset: var(--deck-y) 0 0 var(--deck-x);
  display: flex; flex-direction: column;
  border-radius: 18px; overflow: hidden;
  /* Fully opaque: a sunk card must never let the one behind it read through. */
  background: var(--surface-container-low);
  border: 1px solid var(--outline-variant);
  box-shadow: var(--shadow-3);
  transform-origin: center;
  transition: transform 560ms var(--ease-expressive), border-color 460ms var(--ease),
    box-shadow 460ms var(--ease);
}
/* Depth comes from a veil painted on top of the card instead of from opacity,
   so the card stays solid and only its own content is dimmed. */
.client::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--surface); opacity: 0; pointer-events: none;
  transition: opacity 460ms var(--ease);
}
.client[data-pos="0"] { transform: none; z-index: 3; }
/* The offsets are the room the deck reserves. Each step back is a shorter
   step and a paler card than the one before it, so the stack converges
   instead of ending — but the steps never collapse onto each other, or the
   back of the deck reads as one smudge instead of a queue going away.
   Four named clients in front, and behind them the rest of them. */
.client[data-pos="1"] { transform: translate(calc(var(--deck-x) * -0.34), calc(var(--deck-y) * -0.34)) scale(0.972); z-index: 2; }
.client[data-pos="2"] { transform: translate(calc(var(--deck-x) * -0.62), calc(var(--deck-y) * -0.62)) scale(0.948); z-index: 1; }
.client[data-pos="3"] { transform: translate(calc(var(--deck-x) * -0.85), calc(var(--deck-y) * -0.85)) scale(0.928); z-index: 0; }
.client[data-pos="4"] { transform: translate(calc(var(--deck-x) * -1.04), calc(var(--deck-y) * -1.04)) scale(0.911); z-index: 0; }
.client[data-pos="5"] { transform: translate(calc(var(--deck-x) * -1.20), calc(var(--deck-y) * -1.20)) scale(0.897); z-index: 0; }
.client[data-pos="1"]::after { opacity: 0.16; }
.client[data-pos="2"]::after { opacity: 0.30; }
.client[data-pos="3"]::after { opacity: 0.44; }
.client[data-pos="4"]::after { opacity: 0.66; }
.client[data-pos="5"]::after { opacity: 0.80; }
.client[data-pos="1"] { border-color: color-mix(in srgb, var(--outline-variant) 76%, var(--surface)); }
.client[data-pos="2"] { border-color: color-mix(in srgb, var(--outline-variant) 58%, var(--surface)); }
.client[data-pos="3"] { border-color: color-mix(in srgb, var(--outline-variant) 44%, var(--surface)); }
.client[data-pos="4"] { border-color: color-mix(in srgb, var(--outline-variant) 26%, var(--surface)); }
.client[data-pos="5"] { border-color: color-mix(in srgb, var(--outline-variant) 15%, var(--surface)); }
.client[data-pos="1"], .client[data-pos="2"], .client[data-pos="3"] { box-shadow: var(--shadow-1); }
.client[data-pos="4"], .client[data-pos="5"] { box-shadow: none; }
/* Past the named hosts the cards stop being cards and start being a
   direction: they lose the page as well as their colour, so the stack
   fades out rather than stopping at a last, countable one. */
.client--ghost[data-pos="4"] { opacity: 0.6; }
.client--ghost[data-pos="5"] { opacity: 0.3; }

/* A ghost is not a client: no name, no conversation, nothing to read. Just
   the shape of one more host, at the depth where a card stops being legible. */
.client--ghost { pointer-events: none; }
.ghost__bar { display: flex; align-items: center; gap: 9px; height: 38px; padding: 0 12px; }
.ghost__bar i { width: 22px; height: 22px; border-radius: 7px; background: var(--outline-variant); opacity: 0.5; }
.ghost__bar b { width: 52px; height: 8px; border-radius: 999px; background: var(--outline-variant); opacity: 0.4; }

.client__bar {
  display: flex; align-items: center; gap: 9px; flex: none;
  height: 38px; padding: 0 12px;
  background: color-mix(in srgb, var(--brand) 12%, var(--surface-container));
  border-bottom: 1px solid var(--outline-variant);
}
.client__mark {
  display: grid; place-items: center; width: 20px; height: 20px; border-radius: 6px;
  background: var(--brand); color: var(--brand-ink); flex: none;
}
.client__mark svg { width: 13px; height: 13px; }
.client__name { font-size: 12.5px; font-weight: 600; }
.client__link {
  margin-left: auto; display: flex; align-items: center; gap: 5px;
  font-size: 10.5px; font-family: var(--font-mono); color: var(--on-surface-variant);
}
/* Where the host is, not whether it is up: a screen for the ones on this
   Mac, a cloud for the ones that have to come in over the wire. */
.client__link svg { width: 12px; height: 12px; flex: none; opacity: 0.75; }

.client__log {
  flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  gap: 8px; padding: 14px; overflow: hidden;
  /* Older turns fade out at the top instead of being cut mid-bubble. */
  mask-image: linear-gradient(to bottom, transparent 0, #000 26px);
}
.bubble {
  max-width: 86%; padding: 9px 13px; font-size: 12.5px; line-height: 1.5;
  animation: bubbleIn 420ms var(--ease-expressive) both;
}
.bubble--user {
  align-self: flex-end; background: var(--primary-container); color: var(--on-primary-container);
  border-radius: 16px 16px 5px 16px;
}
.bubble--ai {
  align-self: flex-start; background: var(--surface-container-high); color: var(--on-surface);
  border-radius: 16px 16px 16px 5px;
}
.bubble--ghost { opacity: 0.45; }
/* The handle you type to reach Aouo from inside a chat. */
.mention {
  padding: 1px 5px; border-radius: 6px; margin-inline-end: 1px;
  background: color-mix(in srgb, var(--primary) 15%, transparent);
  color: var(--primary); font-weight: 600;
}
@keyframes bubbleIn {
  from { opacity: 0; transform: translateY(14px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}
.bubble__file {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 7px;
  padding: 5px 9px; border-radius: 8px;
  background: color-mix(in srgb, var(--on-surface) 7%, transparent);
  font-family: var(--font-mono); font-size: 10.5px;
}
.bubble__shot {
  margin-top: 8px; width: 148px; height: 86px; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--outline-variant);
  animation: shotIn 520ms var(--ease-expressive) both;
}
@keyframes shotIn { from { opacity: 0; transform: scale(0.82) rotate(-3deg); } to { opacity: 1; transform: none; } }

.client__composer {
  flex: none; display: flex; align-items: center; gap: 8px;
  margin: 0 12px 12px; padding: 7px 7px 7px 14px;
  border-radius: 999px; border: 1px solid var(--outline);
  background: var(--surface);
  transition: border-color var(--dur-state) var(--ease), box-shadow var(--dur-state) var(--ease);
}
.client.is-typing .client__composer { border-color: var(--primary); box-shadow: 0 0 0 3px var(--state-hover); }
.client__field { flex: 1; min-width: 0; font-size: 12.5px; color: var(--on-surface); white-space: nowrap; overflow: hidden; }
.client__field:empty::before { content: attr(data-placeholder); color: var(--on-surface-variant); }
.client.is-typing .client__field::after {
  content: ""; display: inline-block; width: 1.5px; height: 13px; margin-left: 1px;
  vertical-align: -2px; background: var(--primary); animation: caret 1s steps(1) infinite;
}
@keyframes caret { 50% { opacity: 0; } }
.client__send {
  display: grid; place-items: center; width: 28px; height: 28px; flex: none;
  border: 0; border-radius: 50%; background: var(--primary); color: var(--on-primary);
  transition: transform var(--dur-state) var(--ease), background var(--dur-state) var(--ease);
}
.client__send svg { width: 14px; height: 14px; }
.client.is-sending .client__send { transform: scale(0.82); background: var(--on-surface-variant); }

/* ── Lane: the pipe carries its own name ───────────────────── */

.stage__lane {
  /* Everything in the lane hangs off the pipe's centre line, which runs level
     with the front card — half the deck offset below the stage's centre. */
  --line: calc(50% + var(--deck-y) / 2);
  position: relative; align-self: stretch; z-index: 4;
}

/* The pipe is the tunnel — its name just labels it from above, no card.
   The pipe now crosses the whole lane, so the name sits over its middle. */
.tunnel {
  position: absolute; left: 50%; top: var(--line);
  transform: translate(-50%, -100%); margin-top: -24px;
  width: max-content; text-align: center; pointer-events: none;
}
.tunnel__row { display: flex; align-items: center; gap: 7px; }
.tunnel__icon {
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 8px;
  background: var(--icon-blue-container); color: var(--icon-blue);
  transition: background var(--dur-state) var(--ease), color var(--dur-state) var(--ease);
}
.tunnel__icon svg { width: 14px; height: 14px; }
.tunnel__name { font-size: 11.5px; font-weight: 600; letter-spacing: -0.01em; }
/* MCP is the protocol and never changes; the line under it is whatever is
   carrying it right now, which is exactly the part that is replaceable. */
.tunnel__sub {
  margin-top: 2px; font-family: var(--font-mono); font-size: 10px;
  color: var(--on-surface-variant); transition: color var(--dur-state) var(--ease);
}
.tunnel.is-hit .tunnel__icon { background: var(--primary); color: var(--on-primary); }
.tunnel.is-hit .tunnel__name { color: var(--primary); }

/* ── The machine ───────────────────────────────────────────────
   The tunnel does not end at a card floating in the gap — it ends at this
   Mac. Everything local happens inside the screen: Aouo is its top bar, the
   project's windows are on its desktop. It is as tall as the whole deck —
   sunk cards included — so it never looks dwarfed by the stack facing it. */

.mac {
  position: relative; z-index: 3;
  display: flex; flex-direction: column; align-items: center;
  --metal-hi: light-dark(#f7f6fb, #47434f);
  --metal-lo: light-dark(#dcdae6, #27242c);
}
.mac__body {
  position: relative; width: 100%; padding: 8px 8px 0;
  border-radius: 16px; border: 1px solid var(--outline-variant);
  background: linear-gradient(174deg, var(--metal-hi), var(--metal-lo));
  box-shadow: var(--shadow-3);
}
.mac__cam {
  position: absolute; top: 2.5px; left: 50%; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%;
  background: color-mix(in srgb, var(--on-surface) 34%, transparent);
}
.mac__screen {
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  height: calc(var(--card-h) + var(--deck-y) - 51px); border-radius: 5px;
  /* A desktop, not a card: wallpaper first, windows on top of it. */
  background:
    radial-gradient(118% 84% at 16% -6%, color-mix(in srgb, var(--primary) 26%, transparent), transparent 64%),
    linear-gradient(162deg, light-dark(#ddd8f0, #17151d), light-dark(#cbc4e4, #0c0b10));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--on-surface) 12%, transparent);
}
/* The chin an iMac has under its screen; the stand grows out of it.
   Screen + 8px bezel + chin + stand = the deck's full height, so the machine
   spans the stage top to bottom, level with the chat deck at both ends. */
.mac__chin { height: 20px; }
.mac__neck {
  width: 82px; height: 15px; border-inline: 1px solid var(--outline-variant);
  background: linear-gradient(90deg, var(--metal-lo), var(--metal-hi) 46%, var(--metal-lo));
}
.mac__foot {
  width: 160px; height: 6px; border-radius: 0 0 9px 9px;
  border: 1px solid var(--outline-variant); border-top: 0;
  background: linear-gradient(180deg, var(--metal-hi), var(--metal-lo));
  box-shadow: 0 8px 20px color-mix(in srgb, var(--on-surface) 16%, transparent);
}

/* ── Aouo: this machine's top bar ─────────────────────────────
   Aouo is never a step the demo passes through and leaves — it is on screen
   for every frame, it names the tool it is running, and the progress line
   under it says the work is his. */

.mac__bar {
  position: relative; z-index: 3; flex: none;
  display: flex; align-items: center; gap: 7px; height: 25px; padding: 0 9px;
  background: color-mix(in srgb, var(--surface) 76%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid color-mix(in srgb, var(--on-surface) 10%, transparent);
  font-family: var(--font-mono); font-size: 10px;
  transition: background var(--dur-state) var(--ease);
}
.mac__bar.is-hit { background: color-mix(in srgb, var(--primary) 16%, var(--surface)); }
.mac__logo { position: relative; width: 15px; height: 15px; flex: none; }
.mac__logo img { width: 100%; height: 100%; border-radius: 4px; }
.mac__ring {
  position: absolute; inset: -2px; border-radius: 6px; pointer-events: none;
  border: 2px solid var(--primary); opacity: 0;
}
.mac__bar.is-hit .mac__ring { animation: ring 760ms var(--ease) both; }
@keyframes ring {
  from { opacity: 0.8; transform: scale(1); }
  to   { opacity: 0; transform: scale(1.7); }
}
.mac__name { font-weight: 600; font-family: var(--font); font-size: 11px; letter-spacing: -0.01em; flex: none; }
.mac__tool {
  flex: none; padding: 2px 7px; border-radius: 6px;
  background: var(--primary-container); color: var(--on-primary-container); font-weight: 600;
}
.mac__arrow { flex: none; color: var(--outline); }
.mac__res {
  min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  color: var(--on-surface-variant); transition: color var(--dur-state) var(--ease);
}
.mac__res.is-ok { color: var(--success); }
.mac__res.is-pending { opacity: 0.55; }
.mac__meta { margin-left: auto; padding-left: 8px; flex: none; color: var(--on-surface-variant); opacity: 0.7; }
/* Work in flight: a line sweeps the bar Aouo owns, not the window. */
.mac__bar::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 2px; width: 34%;
  background: linear-gradient(90deg, transparent, var(--primary), transparent);
  opacity: 0;
}
.mac__bar.is-busy::after { opacity: 1; animation: scan 1.25s var(--ease) infinite; }
@keyframes scan { from { transform: translateX(-40%); } to { transform: translateX(340%); } }

/* ── Desktop: a stack that changes, beside a ledger that stays ─
   The windows Aouo works in are an LRU stack, the same idea as the chat deck
   one screen up. The project's memory is not one of them: it is what the
   windows are working against, so it keeps its own column and never goes
   behind anything. */

.desk {
  position: relative; flex: 1; min-height: 0;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(132px, 30%);
  /* Wallpaper the windows sit on, not a frame they fill: --desk-pad is the
     room kept clear all round, and the sunk window takes --win-x / --win-y
     up-left out of it — the same offsets the chat deck uses. */
  gap: var(--desk-pad); padding: var(--desk-pad);
  --desk-pad: 13px; --win-x: 20px; --win-y: 17px;
}
.desk__stack { position: relative; min-width: 0; }
.win {
  position: absolute;
  /* One window sits behind the front one, so the room kept up-left is one
     offset — the deck, which stacks three, doubles it. */
  inset: var(--win-y) 0 0 var(--win-x);
  display: flex; flex-direction: column; overflow: hidden;
  border-radius: 9px; border: 1px solid color-mix(in srgb, var(--on-surface) 14%, transparent);
  background: var(--surface-container-low); box-shadow: var(--shadow-3);
  transform-origin: center;
  transition: transform 520ms var(--ease-expressive), box-shadow 420ms var(--ease);
}
/* Same veil as the chat deck: the window behind stays solid, only dimmed. */
.win::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: var(--surface); opacity: 0; pointer-events: none;
  transition: opacity 420ms var(--ease);
}
.win[data-pos="0"] { transform: none; z-index: 2; }
.win[data-pos="1"] {
  transform: translate(calc(var(--win-x) * -1), calc(var(--win-y) * -1)) scale(0.96);
  z-index: 1; box-shadow: var(--shadow-1);
  border-color: color-mix(in srgb, var(--on-surface) 9%, transparent);
}
.win[data-pos="1"]::after { opacity: 0.3; }
/* The moment Aouo takes the window over. */
.win.is-driven { box-shadow: 0 0 0 2px var(--primary), var(--shadow-3); }

.win__bar {
  flex: none; display: flex; align-items: center; gap: 9px; height: 25px; padding: 0 9px;
  background: var(--surface-container); border-bottom: 1px solid var(--outline-variant);
}
.lights { display: flex; gap: 5px; flex: none; }
.lights i { width: 7px; height: 7px; border-radius: 50%; background: var(--outline-variant); }
.lights i:nth-child(1) { background: #ff5f57; }
.lights i:nth-child(2) { background: #febc2e; }
.lights i:nth-child(3) { background: #28c840; }
.win__title {
  min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-family: var(--font-mono); font-size: 10px; color: var(--on-surface-variant);
}
/* Every window says who is driving it. */
.win__by {
  margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 7px; border-radius: 6px;
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary);
  font-family: var(--font-mono); font-size: 9px; font-weight: 600;
}
.win__by b { font-weight: 600; color: var(--on-surface-variant); }
.win__body { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }

/* Editor. The highlight bleeds to both edges of the pane with square ends,
   the way an editor marks a changed line — a rounded pill would read as a
   chip sitting on the code instead of as the line itself. */
.editor { padding: 4px 0 0; font-family: var(--font-mono); font-size: 10.5px; line-height: 1.4; }
.line {
  display: flex; gap: 10px; padding-inline: 9px;
  max-height: 24px; overflow: hidden;
  transition: max-height 260ms var(--ease), opacity 260ms var(--ease);
}
.line__no { width: 15px; flex: none; text-align: right; color: var(--outline); }
.line__code { white-space: pre; color: var(--on-surface-variant); }
.line.is-added { background: color-mix(in srgb, var(--success) 16%, transparent); }
.line.is-added .line__no { color: var(--success); }
.line.is-pending { opacity: 0; max-height: 0; }
.tk-key { color: var(--primary); }
.tk-str { color: var(--icon-green); }
.tk-fn { color: var(--icon-blue); }
.tk-com { color: var(--outline); }

/* Browser */
.chrome { flex: none; display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-bottom: 1px solid var(--outline-variant); }
.chrome__nav { display: flex; gap: 4px; color: var(--outline); }
.chrome__nav svg { width: 12px; height: 12px; }
.chrome__url {
  flex: 1; display: flex; align-items: center; gap: 6px;
  height: 22px; padding: 0 9px; border-radius: 999px;
  background: var(--surface-container-high);
  font-family: var(--font-mono); font-size: 10px; color: var(--on-surface-variant);
}
.chrome__url svg { width: 10px; height: 10px; color: var(--success); flex: none; }
.chrome__spin {
  width: 12px; height: 12px; flex: none; border-radius: 50%;
  border: 1.6px solid var(--outline-variant); border-top-color: var(--primary);
  animation: spin 720ms linear infinite; opacity: 0;
  transition: opacity var(--dur-state) var(--ease);
}
.win--browser.is-loading .chrome__spin { opacity: 1; }
@keyframes spin { to { transform: rotate(360deg); } }

.viewport {
  position: relative; flex: 1; min-height: 0; padding: 10px;
  background: light-dark(#fbfaff, #0f0d13);
  opacity: 0; transition: opacity 460ms var(--ease);
}
.win--browser.is-loaded .viewport { opacity: 1; }
.mini {
  height: 100%; overflow: hidden; border-radius: 11px; padding: 10px;
  background: linear-gradient(150deg,
    color-mix(in srgb, var(--primary) 26%, var(--surface)),
    color-mix(in srgb, var(--icon-blue) 18%, var(--surface)));
  display: flex; flex-direction: column; gap: 8px;
}
.mini__card {
  flex: none; display: flex; align-items: center; gap: 9px;
  padding: 8px 11px; border-radius: var(--radius-outer);
  background: var(--surface); box-shadow: var(--shadow-1);
}
.mini__dot {
  width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--success);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--success) 22%, transparent);
  animation: breathe 2.4s var(--ease) infinite;
}
@keyframes breathe { 50% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--success) 10%, transparent); } }
.mini__t { font-size: 12px; font-weight: 600; }
.mini__s { font-size: 10.5px; color: var(--on-surface-variant); }
.mini__bars { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--gap-connected); }
.mini__bar {
  flex: 1; min-height: 10px; border-radius: var(--radius-inner);
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  box-shadow: var(--shadow-1);
}
.mini__bar:first-child { border-start-start-radius: var(--radius-outer); border-start-end-radius: var(--radius-outer); }
.mini__bar:last-child { border-end-start-radius: var(--radius-outer); border-end-end-radius: var(--radius-outer); }

/* ── Project memory ledger ─────────────────────────────────────
   The column the product is actually about, modelled on the real Project
   Context screen rather than invented: a kind chip, the fact itself, and
   where that fact came from. It is always on screen, so the reader can watch
   one AI write a fact into it and another read that same fact back out. */

.ledger {
  display: flex; flex-direction: column; min-width: 0; overflow: hidden;
  border-radius: 9px; border: 1px solid color-mix(in srgb, var(--on-surface) 12%, transparent);
  background: var(--surface-container-low); box-shadow: var(--shadow-1);
  transition: box-shadow 420ms var(--ease), border-color 420ms var(--ease);
}
/* The moment Aouo writes to it or reads from it. */
.ledger.is-driven { box-shadow: 0 0 0 2px var(--primary), var(--shadow-3); }
.ledger__bar {
  flex: none; display: flex; align-items: center; gap: 6px; height: 25px; padding: 0 8px;
  background: var(--surface-container); border-bottom: 1px solid var(--outline-variant);
}
.ledger__title {
  flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 10px; font-weight: 600; letter-spacing: -0.01em;
}
/* The whole machine is already labelled Aouo in the bar above; down here the
   column is 150px wide and only the action it is running has to fit. */
.ledger__by { margin-left: 0; padding: 2px 6px; }
.ledger__body { flex: 1; min-height: 0; display: flex; }
.ledger__body > .ctx { flex: 1; min-width: 0; }

.ctx { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.ctx__head {
  flex: none; display: flex; align-items: center; gap: 3px; padding: 6px 7px;
  border-bottom: 1px solid var(--outline-variant);
}
.ctx__tab {
  flex: none; padding: 2px 5px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 8px; color: var(--on-surface-variant);
}
.ctx__tab.is-on { background: var(--primary-container); color: var(--on-primary-container); font-weight: 600; }
/* The ledger's own total, on its own line: at 150px the tab strip has no
   room left, and spelled out it says more than "24 · 7" ever did. */
.ctx__foot {
  flex: none; padding: 5px 7px 6px;
  border-top: 1px solid var(--outline-variant);
  font-family: var(--font-mono); font-size: 8px;
  color: var(--on-surface-variant); opacity: 0.85;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
/* The list is a window onto a longer ledger, so it fades out at the bottom
   instead of ending on a half-cut card. */
.ctx__list {
  flex: 1; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
}
.mem {
  flex: none; padding: 5px 7px; border-radius: 8px;
  background: var(--surface-container); border: 1px solid transparent;
  transition: background var(--dur-state) var(--ease), border-color var(--dur-state) var(--ease);
}
.mem__top { display: flex; align-items: center; gap: 5px; }
.mem__kind {
  flex: none; padding: 1px 4px; border-radius: 4px;
  font-family: var(--font-mono); font-size: 7.5px; font-weight: 600; letter-spacing: 0.02em;
  background: var(--primary-container); color: var(--on-primary-container);
}
.mem__kind[data-kind="convention"] { background: var(--icon-green-container); color: var(--icon-green); }
.mem__kind[data-kind="pitfall"]    { background: var(--icon-orange-container); color: var(--icon-orange); }
.mem__kind[data-kind="constraint"] { background: var(--icon-blue-container); color: var(--icon-blue); }
.mem__src {
  margin-left: auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-family: var(--font-mono); font-size: 7.5px;
  color: var(--on-surface-variant); opacity: 0.75;
}
.mem__body { margin-top: 3px; font-size: 9px; line-height: 1.4; }
/* A fact being written arrives from the top of the ledger, the way it really
   does: newest first. */
.mem.is-new { animation: memIn 520ms var(--ease-expressive) both; }
@keyframes memIn {
  from { opacity: 0; transform: translateY(-10px) scale(0.96); }
  to { opacity: 1; transform: none; }
}
/* And a recalled one lights up where it already sits. */
.mem.is-match {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, var(--surface-container));
}

/* A memory quoted back into a conversation wears the same clothes it wears
   in the ledger — that is the whole point of the last scene. */
.bubble__mem {
  display: block; margin-top: 6px; padding: 6px 8px; border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 26%, transparent);
}
.bubble__mem b {
  display: block; margin-bottom: 3px;
  font-family: var(--font-mono); font-size: 9px; color: var(--primary);
}
.bubble__mem span { font-size: 11px; line-height: 1.45; }

/* Screenshot overlay — the whole window, chrome included. */
.shot { position: absolute; inset: 0; pointer-events: none; opacity: 0; z-index: 2; }
.shot.is-on { opacity: 1; }
.shot__frame {
  position: absolute; inset: 42px 11px 11px; border-radius: 10px;
  border: 2px dashed var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  animation: frameIn 420ms var(--ease-expressive) both;
}
@keyframes frameIn { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }
.shot__flash { position: absolute; inset: 0; background: #fff; opacity: 0; }
.shot.is-flash .shot__flash { animation: flash 420ms var(--ease) both; }
@keyframes flash { 0% { opacity: 0; } 22% { opacity: 0.86; } 100% { opacity: 0; } }

/* ── Packets ───────────────────────────────────────────────── */

.packets { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.packet {
  position: absolute; top: 0; left: 0; display: flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 999px; white-space: nowrap;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  background: var(--primary); color: var(--on-primary);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--primary) 16%, transparent),
    0 8px 24px color-mix(in srgb, var(--primary) 45%, transparent);
  will-change: transform, opacity;
}
.packet svg { width: 11px; height: 11px; }
.packet--return {
  background: var(--icon-green-container); color: var(--icon-green);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--icon-green) 14%, transparent),
    0 8px 24px color-mix(in srgb, var(--icon-green) 30%, transparent);
}
.packet--thumb { padding: 4px; border-radius: 10px; }
.packet--thumb .packet__img { width: 54px; height: 32px; border-radius: 7px; overflow: hidden; }

/* ── Stage caption + controls ──────────────────────────────── */

.stage__caption {
  position: relative; z-index: 5; display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px; margin-top: calc(18px + var(--vgrow) * 0.07);
  font-size: 12.5px; color: var(--on-surface-variant);
}
.hop {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 999px;
  background: var(--surface-container-high);
  transition: background var(--dur-state) var(--ease), color var(--dur-state) var(--ease);
}
.hop.is-on { background: var(--primary-container); color: var(--on-primary-container); font-weight: 600; }
.hop__sep { color: var(--outline); }
.stage__toggle {
  margin-left: auto; display: inline-flex; align-items: center; gap: 7px;
  padding: 6px 13px; border-radius: 999px; border: 1px solid var(--outline-variant);
  background: transparent; font-size: 12px; color: var(--on-surface-variant); cursor: pointer;
  transition: background var(--dur-state) var(--ease);
}
.stage__toggle:hover { background: var(--state-hover); }
.stage__toggle svg { width: 12px; height: 12px; }

/* ── Responsive ────────────────────────────────────────────── */

@media (max-width: 1080px) {
  .hero { --deck-x: 52px; --deck-y: clamp(64px, 7.2svh, 86px); }
  .desk { --desk-pad: 11px; --win-x: 18px; --win-y: 15px; grid-template-columns: minmax(0, 1fr) minmax(124px, 31%); }
  .stage { grid-template-columns: minmax(0, 0.86fr) 156px minmax(0, 1.16fr); }
  .tunnel { margin-top: -20px; }
  .tunnel__name { font-size: 11px; }
  .tunnel__sub { font-size: 9.5px; }
  .tunnel__icon { width: 21px; height: 21px; border-radius: 7px; }
  .tunnel__icon svg { width: 12px; height: 12px; }
  /* The top bar gets narrow before the result text does: drop the port first. */
  .mac__meta { display: none; }
}
@media (max-width: 860px) {
  /* Lane flips from a column between deck and machine to a row beneath them:
     the pipe drops straight down into the top of the machine. */
  /* Stacked, the hero scrolls instead of filling a screen, so there is no
     empty band to take up and --vgrow goes back to zero. */
  .hero {
    --vgrow: 0px;
    --card-h: clamp(304px, 42vw, 348px); --deck-y: 62px;
    /* One lane means a very wide card, and a centred scale() pulls a wide card's
       left edge back in almost as far as the translate pushed it out. The room
       kept up-left has to widen with the card or the six cards land on top of
       one another. */
    --deck-x: clamp(41px, 7vw, 62px);
    min-height: 0; display: block;
  }
  .desk { --desk-pad: 10px; --win-x: 16px; --win-y: 14px; grid-template-columns: minmax(0, 1fr) minmax(120px, 32%); }
  .stage { grid-template-columns: 1fr; gap: 18px; }
  .stage__lane { height: 104px; align-self: auto; }
  /* The pipe is vertical here, so its name sits beside it instead of above. */
  .tunnel {
    left: auto; right: calc(50% + 26px); top: 8px;
    transform: none; margin-top: 0; text-align: right;
  }
  .tunnel__row { justify-content: flex-end; }
  .tunnel__sub { text-align: right; }
  .wire__casing { stroke-width: 19; }
  .wire__bore { stroke-width: 13; }
  .wire__ribs { stroke-width: 19; }
  .wire__trail { stroke-width: 8; }
  .stage__toggle { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hero__aurora span, .wire__base, .mini__dot, .mac__bar.is-busy::after { animation: none; }
  .client, .win, .ledger { transition: none; }
}

/* Screenshot thumbnails — a live clone of the preview, scaled to fit. */
.thumb {
  position: relative; display: block; overflow: hidden; border-radius: inherit;
  background: light-dark(#fbfaff, #0f0d13);
}
.bubble__shot .thumb, .packet__img .thumb { border-radius: inherit; }
.bubble b { font-weight: 600; }
.wire__trail.is-back { stroke: var(--icon-green); }
