/* ---- The app-window mock's sheet. ----
   Every `.a-appwin*` rule: the window shell and its chrome, the panes and
   their transcripts, the two keyframes, the narrow-width overrides and the
   reduced-motion opt-out. Extracted verbatim from direction-a.css, which is
   left with none.

   Imported by BOTH entries — marketing/landing-prototype/src/main.js and
   marketing/video/src/main.js. The video's window mock is styled from this
   sheet rather than from video.css, so dropping either import leaves that
   surface unstyled with no error and no build failure.

   The rules read --sg-* from tokens.css and --a-font-display / --a-font-mono
   from their .direction-a / .tour / .vid-frame host, so this sheet declares no
   tokens of its own — but it must be imported after tokens.css in both
   entries. */

/* ---- Hero stage: mock of the real Deck window (Tokyo Night). ----
   Tokens ported from the app's src/styles.css fallbacks; sizes designed at
   a 1000px-wide window and expressed in cqw so the whole mock scales
   proportionally. Flat by design: hairlines only, no drop shadows. */

.a-appwin {
  position: relative;
  z-index: 2;
  display: flex;
  width: 100%;
  /* 56rem, not the frame's full width. The window covers whatever it stands
     on, so the rim IS the painting as far as a visitor is concerned — sized
     until the ridge and the plain either side of the hut are legible above and
     beside the mock. */
  max-width: 56rem;
  flex-direction: column;
  min-width: 0;
  aspect-ratio: 1000 / 620;
  margin: 0;
  overflow: hidden;
  color: var(--sg-fg);
  background: var(--sg-bg);
  border: 1px solid var(--sg-hairline);
  border-radius: 8px;
  container-type: inline-size;
  font-family: var(--a-font-display);
}

/* The frame is the head of the navigation column (DL-18.3 mirror): it sits on
   the rail's ground and paints no seam of its own — the shell's structural
   line is vertical now, on the stage's left edge below. */
.a-appwin__titlebar {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: space-between;
  height: 3.4cqw;
  padding: 0 1.3cqw;
}

.a-appwin__lights {
  display: flex;
  gap: 0.8cqw;
}

.a-appwin__lights i {
  width: 1.2cqw;
  height: 1.2cqw;
  border-radius: 50%;
}

.a-appwin__lights i:nth-child(1) {
  background: #ff5f57;
}

.a-appwin__lights i:nth-child(2) {
  background: #febc2e;
}

.a-appwin__lights i:nth-child(3) {
  background: #28c840;
}

.a-appwin__actions {
  display: flex;
  align-items: center;
  gap: 1cqw;
  color: var(--sg-fg-dim);
}

.a-appwin__iconbtn {
  display: inline-flex;
}

.a-appwin__iconbtn svg {
  width: 1.3cqw;
  height: 1.3cqw;
}

.a-appwin__actionsep {
  width: 1px;
  height: 1.4cqw;
  background: var(--sg-hairline);
}

.a-appwin__body {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* The navigation column: frame on top, workspace list under it, one plane.
   275/1100 in the app → 25cqw here. */
.a-appwin__sidebar {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  width: 25cqw;
  min-height: 0;
}

/* The stage's left edge carries the shell's one structural line, running the
   window's full height — whatever sits beside the rail (the hero's and the
   tour's stage wrapper, the video's scene wrapper) takes it.

   `--sg-seam-column` since the 2026-08-20 redesign, not the soft alpha
   hairline: this is the app's `--sidebar-seam` (02-shell.css:112-120), the ONE
   structural line the shell draws, and it is vertical. A shared alpha edge is
   what the pane splits use; the shell's own line is its own token. */
.a-appwin__sidebar + * {
  border-left: 1px solid var(--sg-seam-column);
}

.a-appwin__wslist {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  gap: 0.35cqw;
  padding: 0.8cqw;
}

.a-appwin__wsitem {
  display: flex;
  align-items: center;
  gap: 0.8cqw;
  min-width: 0;
  padding: 0.7cqw 0.8cqw;
  /* --radius-control (10px at the 1000px design width). */
  border-radius: 1cqw;
  color: var(--sg-fg-dim);
}

/* DL-21.1 mirror: selection is the full wash — 15% of the neutral tone, mixed
   from white like the app's --tab-active-bg, never from the foreground. */
.a-appwin__wsitem.is-active {
  color: var(--sg-fg);
  background: color-mix(in srgb, #ffffff 15%, transparent);
}

.a-appwin__wslogo {
  width: 2.4cqw;
  height: 2.4cqw;
  flex: 0 0 auto;
  border-radius: 50%;
}

.a-appwin__wslogo--mono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ws-tint);
  background: color-mix(in srgb, var(--ws-tint) 18%, transparent);
  font-size: 1.1cqw;
  font-weight: 700;
}

.a-appwin__wstext {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.15cqw;
}

.a-appwin__wslabel {
  overflow: hidden;
  font-size: max(1.2cqw, 8px);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__wspath {
  overflow: hidden;
  color: var(--sg-fg-faint);
  font-size: max(1cqw, 7px);
  white-space: nowrap;
}

.a-appwin__wsclose {
  margin-left: auto;
  color: var(--sg-fg-faint);
  font-size: 1.4cqw;
  line-height: 1;
}

.a-appwin__wsadd {
  display: flex;
  align-items: center;
  gap: 0.7cqw;
  padding: 0.7cqw 0.8cqw;
  color: var(--sg-fg-faint);
  font-size: max(1.15cqw, 8px);
}

/* The pane grid, as the app actually draws it (06-stage-panes.css:263-268):
   panes are FLUSH — no gap, no card border, no radius — and a 1px
   `--seam-divider` hairline is the only thing between them. The mock says the
   same with a 1px grid gap over a seam-coloured ground; each pane's own
   `--sg-bg` covers everything but the lines. `--sg-hairline` IS the landing's
   `--seam-divider` (its comment claims the role), so no second token. */
.a-appwin__grid {
  display: grid;
  flex: 1;
  min-width: 0;
  min-height: 0;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--sg-hairline);
}

.a-appwin__col {
  display: flex;
  min-width: 0;
  min-height: 0;
  flex-direction: column;
  gap: 1px;
}

.a-appwin__pane {
  display: flex;
  flex: 1;
  min-width: 0;
  min-height: 0;
  flex-direction: column;
  padding: 0.9cqw 1.1cqw;
  background: var(--sg-bg);
  font-family: var(--a-font-mono);
}

/* The app marks focus with NO ring: the ring was removed there because three
   of its four sides land under other chrome (06-stage-panes.css:327-334). The
   `is-focused` class stays in the markup — the narrow-viewport rule below
   keys off it — but paints nothing. */

.a-appwin__transcript {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

.a-appwin__lines {
  display: flex;
  flex-direction: column;
  gap: 0.55cqw;
}

.a-appwin__line {
  overflow: hidden;
  color: var(--sg-fg-dim);
  font-size: max(1.15cqw, 7px);
  line-height: 1.5;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__line.t-body {
  color: var(--sg-fg);
}

.a-appwin__line.t-user {
  color: var(--sg-fg);
}

/* Neutral on purpose (owner, 2026-08-20): the CLIs themselves print their
   transcripts in the terminal's plain foreground — Claude Code's tool calls,
   codex's applied-patch lines — and the purple/green/blue the mock used to
   borrow from the theme's ANSI read as syntax highlighting the real window
   never shows. Weight and dimness carry the hierarchy instead.

   Scoped to `.a-appwin__line`, never a bare `.t-dim` — an unscoped class
   would repaint anything that borrowed the word. */
.a-appwin__line.t-agent {
  color: var(--sg-fg-dim);
  font-weight: 600;
}

.a-appwin__line.t-tool {
  color: var(--sg-fg);
}

.a-appwin__line.t-dim {
  color: var(--sg-fg-faint);
}

.a-appwin__line.t-ok {
  color: var(--sg-fg);
}

.a-appwin__spinner {
  margin-top: 0.55cqw;
  color: var(--sg-yellow);
  font-size: max(1.15cqw, 7px);
  line-height: 1.5;
}

.a-appwin__spinner[hidden] {
  display: none;
}

.a-appwin__panefoot {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  gap: 0.45cqw;
  margin-top: 0.8cqw;
}

.a-appwin__promptbox {
  display: flex;
  align-items: center;
  gap: 0.6cqw;
  padding: 0.55cqw 0.8cqw;
  border: 1px solid var(--sg-hairline);
  border-radius: 0.4cqw;
  color: var(--sg-fg);
  font-size: max(1.15cqw, 7px);
}

.a-appwin__cursor {
  width: 0.55cqw;
  height: 1.3cqw;
  background: var(--sg-fg);
}

.a-appwin__footline {
  overflow: hidden;
  color: var(--sg-fg-dim);
  font-size: max(1.05cqw, 6px);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__footline.t-dim {
  color: var(--sg-fg-faint);
}

.a-appwin__status {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.9cqw;
  height: 2.8cqw;
  padding: 0 1.3cqw;
  border-top: 1px solid var(--sg-hairline-soft);
  color: var(--sg-fg-dim);
  /* --chrome-1 mirror: the status bar is a raised step off the ground. */
  background: color-mix(in srgb, #ffffff 5%, transparent);
  font-size: max(1.05cqw, 6px);
}

.a-appwin__seg {
  display: inline-flex;
  align-items: center;
  gap: 0.5cqw;
  white-space: nowrap;
}

.a-appwin__seg--cwd {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.a-appwin__gitdot {
  width: 0.7cqw;
  height: 0.7cqw;
  flex: 0 0 auto;
  background: var(--sg-green);
  border-radius: 50%;
}

.a-appwin__vsep {
  width: 1px;
  height: 1.2cqw;
  flex: 0 0 auto;
  background: var(--sg-hairline);
}

.a-appwin__statusright {
  display: flex;
  align-items: center;
  gap: 0.9cqw;
  margin-left: auto;
}

.a-appwin__hint {
  color: var(--sg-fg-faint);
}

.a-appwin__kbd {
  padding: 0.15cqw 0.4cqw;
  border: 1px solid var(--sg-hairline);
  /* --radius-control: the app's chips got rounder with DL-20.1. */
  border-radius: 1cqw;
  color: var(--sg-fg-dim);
  font-family: inherit;
  font-size: inherit;
}

/* ============================================================================
   The 2026-08-20 chrome: frame row, agent rail, tab strip.

   Everything above this line draws the July window and is kept because the
   marketing video still renders it (marketing/video/src/stage-driver.js).
   Everything below draws the shipped one, and the two sets share
   `.a-appwin`, `.a-appwin__body`, `.a-appwin__lights` and the pane rules and
   nothing else — so neither can quietly restyle the other. In particular
   NOTHING here changes a declaration of `.a-appwin__titlebar`,
   `.a-appwin__actions`, `.a-appwin__actionsep`, `.a-appwin__iconbtn` or
   `.a-appwin__lights`: `renderStageTitlebar` still emits all five for the
   video, and this sheet is imported by the video entry.

   SIZES. The mock is designed at a 1000px-wide window, so an app pixel is
   one tenth of a cqw: the app's 34px frame row is `3.4cqw`, its 17px grid
   slot `1.7cqw`, its 7px gap `0.7cqw`. Every geometry number below is the
   app's own, restated in that unit — read `04a-agent-rail.css`,
   `04b-agent-rail-rows.css`, `02-shell.css` and `05-tab-bar-toolbar.css`
   beside it. Hairlines stay a literal 1px, as `.a-appwin__pane`'s border
   already does: a scaled hairline is a blur.

   TYPE. Chrome text carries a `max(Ncqw, 9px)` floor, one rung above the
   transcript's 7px. The floor is not decoration: the page's SMALLEST chrome
   type is at a 768 viewport, which sits ABOVE the 47.5rem breakpoint and so
   receives none of the narrow overrides — pure `cqw` in a 159px rail.
   ========================================================================== */

/* ---- The stage wrapper. ----
   MEASURED, not theoretical: this element had no rules at all when the rail
   and the strip landed, so `.a-appwin__grid`'s own `flex: 1; min-height: 0`
   resolved against a plain block and `.a-appwin__strip` rendered 669.5 x 4338
   px at a 1440 viewport. It is the rail's sibling — `.a-appwin__sidebar + *`
   selects THIS element, which is what carries the window's structural seam —
   and a flex column holding the strip above the work area.

   `min-width: 0` is the half a `border-left` cannot supply: a chip label is
   `white-space: nowrap`, and without the floor a flex child's automatic
   minimum size is its content width, so one long sentence pushes the whole
   window wide instead of ellipsizing inside the strip. */
.a-appwin__stage {
  display: flex;
  flex: 1;
  min-width: 0;
  min-height: 0;
  flex-direction: column;
}

/* The hero's scene switcher hides its resting regions with the `hidden`
   attribute, whose UA `display: none` loses to the flex above — so the
   attribute is restated here at equal specificity, later in the sheet. */
.a-appwin__stage[hidden] {
  display: none;
}

/* ---- The frame row (DL-18.3 mirror). ----
   Traffic lights, the sidebar toggle, `New`, then the drag spacer. It stands
   INSIDE the rail rather than above the body, and shares the rail's ground,
   which is what makes the window's top-left corner seamless (02-shell.css
   :35-42). Its height is the strip's height, so the two chrome rows either
   side of the seam sit on one line. */
.a-appwin__framerow {
  display: flex;
  box-sizing: border-box;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.8cqw;
  /* The chrome row's own floor, and the frame row and the strip MUST carry the
     same one: a bare `3.4cqw` is 10.08px in the hero and 8.59px in a panel at a
     390 viewport, and neither can hold the 8px type the narrow query floors
     this chrome at. The number is derivable, not chosen: the 8px floor's line
     box is 9px, + the chip's 1px border top and bottom = an 11px chip, + the
     strip's 1px seam = 12, + 1px so nothing sits flush. Above the breakpoint
     `3.4cqw` always wins (15.8px at 560, 21.7px at 768, 30.4px at 1440), so
     this changes nothing there. */
  height: max(3.4cqw, 13px);
  /* The trailing 8px is `.deck-frame`'s own; the leading inset is the macOS
     traffic-light gutter, which the app reserves as `--frame-lights-w` and
     the mock actually draws. */
  padding: 0 0.8cqw 0 1.2cqw;
  background: var(--sg-rail);
}

/* Reuse, not restyle: `.a-appwin__lights` keeps every declaration the video's
   titlebar gives it, and only its flex behaviour in THIS row is stated — a
   shrinking traffic-light cluster is the first thing a narrow rail would
   squash. */
.a-appwin__framerow .a-appwin__lights {
  flex: 0 0 auto;
}

/* The drag region: the app's `.deck-frame__spacer`, which is why the frame
   row ends in nothing. */
.a-appwin__framespacer {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---- Icon controls. ----
   `.a-appwin__ctl`, never `.a-appwin__iconbtn` (§3.3 rule 6): the July
   titlebar's five buttons still ship to the video under that older name, and
   restyling it would redraw the film. The 24px box and the 13px glyph are
   `.iconbtn` (05-tab-bar-toolbar.css:258-262) and `CHROME_ICON`
   (deck-icon.tsx:47). */
.a-appwin__ctl {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 2.4cqw;
  height: 2.4cqw;
  border-radius: 1cqw;
  color: var(--sg-fg-dim);
}

.a-appwin__ctl svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* `More` is the one toolbar control drawn at FEATURE_ICON rather than
   CHROME_ICON (feature-toolbar.tsx:276), and it is the strip's first action;
   the dock toggle beside it keeps the chrome rung. */
.a-appwin__stripactions .a-appwin__ctl:first-child svg {
  width: 1.5cqw;
  height: 1.5cqw;
}

/* ---- `New` (02-shell.css:81-96). ---- */
.a-appwin__new {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.4cqw;
  /* `min-height`, not `height`, for the reason the chip below states: at 390
     this box is 7.11px and its own floored 8px line box does not fit in it. A
     control grows to its label; it does not spill out of itself. */
  min-height: 2.4cqw;
  padding: 0 0.6cqw;
  border-radius: 1cqw;
  color: var(--sg-fg-dim);
  font-size: max(1.25cqw, 9px);
  font-weight: 540;
  line-height: 1;
  white-space: nowrap;
}

/* The glyph element ALREADY carries its SVG (`renderStageFrameRow`), so this
   is a box and nothing else — a `content` here would draw a second plus. */
.a-appwin__newglyph {
  display: flex;
  flex: none;
}

.a-appwin__newglyph svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* ---- The rail. ----
   DL-18.7: the frame and the rail are one continuous side surface and the
   stage keeps `--bg`, so the terminal is the deepest plane and every chrome
   surface rises off it. Only `.a-appwin__rail` takes the ground — the July
   `.a-appwin__sidebar` the video still renders stays transparent. */
.a-appwin__rail {
  background: var(--sg-rail);
}

/* Asymmetric padding on purpose (04a:63-72): 8px leads, 2px trails, because
   the trailing side is a stack — this padding, the rail's reserved scrollbar
   gutter, the row's own trailing inset and the 1.5px of centring a 14px glyph
   in a 17px slot. Do not tidy it to a pair.

   A grid with ONE `minmax(0, 1fr)` column, not a plain block: an implicit
   column is `auto`, and an auto track's item keeps `min-width: auto`, so a
   `white-space: nowrap` sentence would push the cluster past the rail instead
   of ellipsizing inside it (04a:108-122 records the measured 558px-in-229px
   version of exactly that). */
.a-appwin__raillist {
  display: grid;
  flex: 1;
  min-height: 0;
  align-content: start;
  grid-template-columns: minmax(0, 1fr);
  /* The break between two projects: 10px here + the header's 6px top
     padding (1.1.1's rhythm pass, 04a:117-129). */
  gap: 1cqw;
  padding: 0.8cqw 0.2cqw 0.7cqw 0.8cqw;
  overflow: hidden;
}

/* The same floor one level down: both containers declare it or the row
   overflows the inner one (04a:132-142). The gap is one CARD to the next
   inside a project. */
.a-appwin__cluster {
  display: grid;
  align-content: start;
  grid-template-columns: minmax(0, 1fr);
  gap: 0.6cqw;
}

/* ---- The cluster header. ----
   TWO tracks holding TWO children (1.1, `rail-create-consolidation`): the
   toggle spans both, so its own caret lands in the last 17px slot, and the
   close is pinned into that same slot on top of it. The middle track that
   held DL-27.18's `+` went with that control — every checkout now carries its
   own create control on its card (04a:175-205 at build/v1.1.1).

   The header HUGS the card under it: `margin-bottom` pulls it back by the
   cluster's own gap, so it sits 2px off the card it names while two
   checkouts of one project keep their full gap (1.1.1's rhythm pass). */
.a-appwin__clusterhead {
  display: grid;
  box-sizing: border-box;
  align-items: center;
  grid-template-columns: minmax(0, 1fr) 1.7cqw;
  gap: 0.7cqw;
  margin-bottom: -0.6cqw;
  padding: 0.6cqw 0.4cqw 0.2cqw 0.7cqw;
}

/* The first project starts the rail; a full top inset there reads as a dent
   in an otherwise empty column (04a:377-381). */
.a-appwin__cluster:first-child .a-appwin__clusterhead {
  padding-top: 0.2cqw;
}

/* A live header's spanning toggle and a remembered one's still label draw the
   SAME line and differ only in which tracks they occupy: the toggle bleeds
   across both so its own caret lands in the last slot, while the still label
   stops at track 1 so it can never run under the close (04a:188-239). */
.a-appwin__clustertoggle,
.a-appwin__clusterstill {
  display: flex;
  min-width: 0;
  grid-row: 1;
  align-items: center;
  gap: 0.7cqw;
  overflow: hidden;
  color: var(--sg-fg-dim);
  font-weight: 560;
  line-height: 1.2;
  white-space: nowrap;
}

.a-appwin__clustertoggle {
  grid-column: 1 / -1;
}

.a-appwin__clusterstill {
  grid-column: 1;
}

/* `min-width: 0` plus `flex: 1` is what pushes the caret to the toggle's
   right edge AND lets a long project name ellipsize rather than shove it
   (04a:330-335). */
.a-appwin__clustername {
  min-width: 0;
  flex: 1;
  overflow: hidden;
  font-size: max(1.3cqw, 9px);
  text-overflow: ellipsis;
}

/* Fixed 17px boxes so the folder mark sits over the status dot's centre line
   and the caret over the agent glyph's: the header reads as the same row
   shape one rung up (04a:337-345). The glyphs inside them are the app's own
   rungs — FEATURE_ICON for the folder, CHROME_ICON for the caret.

   SQUARE, and the height is not decoration — MEASURED 2026-08-20. The caret
   below is `rotate(90deg)` when its cluster is expanded, and a rotation swaps
   the rendered box: with a width but no height the slot was 15.19 x 11.61 and
   the turned caret painted 11.61 x 15.19, i.e. 0.66px TALLER than the toggle
   containing it. The toggle is `overflow: hidden`, so that surfaced as a 1px
   vertical scroll container at 1024 and 1440 — the same defect class as the
   chip strip's, from a rotated glyph rather than a floored font. A square slot
   cannot change size when its contents turn. The app never met this because
   its rows are a fixed 34px with slack to spare; a cqw box has none.

   Two rejected alternatives, both measured: raising the toggle's line-height
   absorbs the overflow at some sizes and not others (it fixed 1440, left 1024,
   and `normal` was worse than either), and dropping the rotation removes a
   real behaviour — a turned caret is what says "expanded". */
.a-appwin__clusterfolder,
.a-appwin__clustercaret {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 1.7cqw;
  height: 1.7cqw;
}

.a-appwin__clusterfolder svg {
  display: block;
  width: 1.5cqw;
  height: 1.5cqw;
}

.a-appwin__clustercaret svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* The header's close, pinned into the caret's track (column 2). A remembered
   header leaves that track empty; a live one trades it with the caret on
   hover, so nothing reflows. Neutral, never `--red`: forgetting a folder is
   undoable by reopening it (DL-21.2, 04a:272-330). */
.a-appwin__clusterremove {
  display: flex;
  grid-row: 1;
  grid-column: 2;
  z-index: 1;
  align-items: center;
  justify-content: center;
  width: 1.7cqw;
  height: 1.7cqw;
  border-radius: 1cqw;
  color: var(--sg-fg-faint);
}

.a-appwin__clusterremove svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* Rest is folder + name and nothing else: both controls keep their 17px boxes
   at all times and only their INK fades in, so the pointer can never reflow
   the header (04a:341-365). `.is-hover` is the same reveal baked into the
   data, which is how a still drawing says what the live page does on hover; a
   COLLAPSED cluster keeps its caret, since with its cards gone the turned
   caret is the only thing saying "folded, not empty".

   The app's `:focus-visible` half of these reveals is deliberately NOT ported:
   the mock's controls are `<span>`s inside `aria-hidden="true"`, so nothing
   here can take focus and the rule could never match. */
.a-appwin__clustercaret,
.a-appwin__clusterremove {
  opacity: 0;
}

.a-appwin__cluster:hover .a-appwin__clustercaret,
.a-appwin__cluster:hover .a-appwin__clusterremove,
.a-appwin__clusterhead.is-hover .a-appwin__clustercaret,
.a-appwin__clusterhead.is-hover .a-appwin__clusterremove,
.a-appwin__cluster.is-collapsed .a-appwin__clustercaret {
  opacity: 1;
}

/* Under the pointer the live header's close takes the caret's slot, the way
   a row's close swaps in over its glyph (04a:324-327). A still header has no
   caret to hide. */
.a-appwin__cluster:hover .a-appwin__clusterhead:not(.is-still) .a-appwin__clustercaret,
.a-appwin__clusterhead.is-hover:not(.is-still) .a-appwin__clustercaret {
  opacity: 0;
}

/* CaretRight turned down means expanded, exactly as `[aria-expanded="true"]`
   does in the app (04a:387-389). The mock states the fold on the cluster, so
   the selector is its inverse. */
.a-appwin__cluster:not(.is-collapsed) .a-appwin__clustercaret {
  transform: rotate(90deg);
}

/* ---- The checkout card (DL-27.23/DL-27.24, 1.1). ----
   Ported from `src/styles/04c-rail-worktree-card.css` at build/v1.1.1, one
   app pixel to 0.1cqw — the mock's design width is 1000px, so every number
   below is the app's own divided by ten. Classes are the landing's
   (`a-appwin__card*`), shaped like the app's `asr-card__*` one for one.

   `box-sizing` is declared on everything that takes a width beside a
   padding: `src/styles.css` has no global reset, and neither does this page's
   stage (AGENTS.md, Known traps). */
.a-appwin__card {
  --card-tone: var(--sg-fg);
  /* The busy hue is NEUTRAL (04c:55): colour stays reserved for the two
     states that want the reader's eyes. */
  --card-busy: color-mix(in srgb, var(--card-tone) 62%, transparent);

  display: grid;
  box-sizing: border-box;
  grid-template-columns: minmax(0, 1fr);
  gap: 1px;
  padding: 0.6cqw 0.9cqw 0.7cqw;
  border-radius: 0.6cqw;
  background: var(--sg-tab-rest);
  box-shadow: inset 0 0 0 1px var(--sg-hairline);
}

.a-appwin__card:hover {
  box-shadow: inset 0 0 0 1px var(--sg-hair-strong);
}

.a-appwin__card[data-open="true"] {
  background: var(--sg-raised);
  box-shadow: inset 0 0 0 1px var(--sg-hair-strong);
}

/* The ACTIVE checkout — the one the window is working in — framed in the
   worktree identity colour, green by default (04c:61, :227-230). Border
   only: the background already says open or closed. */
.a-appwin__card[data-active="true"],
.a-appwin__card[data-active="true"]:hover {
  box-shadow: inset 0 0 0 1px
    color-mix(in srgb, var(--worktree-color, var(--sg-green)) 72%, transparent);
}

/* The head: mark, name, badge and an always-visible chevron (DL-27.25). */
.a-appwin__cardhead {
  display: grid;
  box-sizing: border-box;
  min-width: 0;
  grid-template-columns: 1.4cqw minmax(0, 1fr) auto 1.3cqw;
  align-items: center;
  column-gap: 0.6cqw;
  min-height: 2.4cqw;
}

/* The mark and the bare row's twin: a 14px box painting a 9px dot. */
.a-appwin__cardmark,
.a-appwin__baremark {
  position: relative;
  width: 1.4cqw;
  height: 1.4cqw;
}

.a-appwin__cardmark::before,
.a-appwin__baremark::before {
  content: "";
  position: absolute;
  inset: 0;
  width: 0.9cqw;
  height: 0.9cqw;
  margin: auto;
  border-radius: 50%;
  background: var(--worktree-color, color-mix(in srgb, var(--sg-fg) 26%, transparent));
}

/* Live: work is moving somewhere in this checkout. Read off the card's own
   state marks with `:has()` rather than a flag written at render, so the
   hero's streamed card goes quiet the moment its last pane does. A worktree
   colour, once chosen, wins over both (04d:66-73). */
.a-appwin__card:has([data-state="working"]) .a-appwin__cardmark::before {
  background: var(--worktree-color, var(--card-busy));
}

.a-appwin__cardname {
  overflow: hidden;
  color: var(--sg-fg);
  font-size: max(1.25cqw, 9px);
  font-weight: 620;
  line-height: 1.25;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__cardchevron {
  display: grid;
  place-items: center;
  width: 1.3cqw;
  height: 1.3cqw;
  color: var(--sg-fg-dim);
}

.a-appwin__cardchevron svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

.a-appwin__card[data-open="true"] .a-appwin__cardchevron {
  transform: rotate(90deg);
}

/* The badge — the fact the name did not say. `max-width` lets a long branch
   truncate before the checkout's own name does (04c:137-184). */
.a-appwin__cardbadge,
.a-appwin__barebadge {
  display: grid;
  box-sizing: border-box;
  grid-auto-flow: column;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  max-width: 13.2cqw;
  column-gap: 0.3cqw;
  padding: 0.1cqw 0.5cqw 0.1cqw 0.4cqw;
  border-radius: 0.3cqw;
  background: color-mix(in srgb, var(--sg-fg) 8%, transparent);
  color: var(--sg-fg-dim);
  font-size: max(1.05cqw, 8px);
  font-weight: 500;
  line-height: 1.5;
}

.a-appwin__cardbadge svg,
.a-appwin__barebadge svg {
  display: block;
  width: 1.2cqw;
  height: 1.2cqw;
}

.a-appwin__cardbadge span,
.a-appwin__barebadge span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__cardbadge[data-kind="role"],
.a-appwin__barebadge[data-kind="role"] {
  grid-template-columns: minmax(0, 1fr);
  padding: 0.1cqw 0.5cqw;
}

.a-appwin__card[data-active="true"] .a-appwin__cardbadge {
  background: color-mix(in srgb, var(--worktree-color, var(--sg-green)) 15%, transparent);
  color: color-mix(in srgb, var(--worktree-color, var(--sg-green)) 78%, var(--sg-fg));
}

/* The age alone, aligned to the checkout name: 14px mark + 8px gap. */
.a-appwin__cardmeta {
  margin: -1px 0 0;
  padding-left: 2.2cqw;
  color: var(--sg-fg-faint);
  font-size: max(1.05cqw, 8px);
  font-weight: 450;
  line-height: 1.4;
}

/* ---- Closed: the agents as ONE segmented bar. ----
   Each segment is one agent KIND (glyph, corner dot, `×N`, the bars when it
   works), the divider a `border-left` so it runs the full height. The strip
   is indented under the checkout name, and its `max-width` is taken off that
   indent rather than off the card, or a full strip hangs past the card's
   edge where the list's own clip hides it (04c:344-363). */
.a-appwin__cardstrip {
  display: flex;
  box-sizing: border-box;
  min-width: 0;
  align-items: stretch;
  width: fit-content;
  max-width: calc(100% - 2.2cqw);
  margin: 0.5cqw 0 0.1cqw 2.2cqw;
  border-radius: 0.6cqw;
  box-shadow: inset 0 0 0 1px var(--sg-hairline);
}

.a-appwin__cardseg {
  display: grid;
  box-sizing: border-box;
  grid-auto-flow: column;
  align-items: center;
  column-gap: 0.6cqw;
  min-height: 2.4cqw;
  padding: 0 0.8cqw;
}

.a-appwin__cardseg + .a-appwin__cardseg {
  border-left: 1px solid var(--sg-hairline);
}

/* The merge count: muted, never the accent — `+N` spends the accent on a
   count of what is NOT shown, and the two numbers must not read alike. */
.a-appwin__cardtimes {
  color: var(--sg-fg-dim);
  font-size: max(1.05cqw, 8px);
  font-weight: 560;
  line-height: 1;
  white-space: nowrap;
}

/* The overflow tail: the one colour no state mark uses. */
.a-appwin__cardseg--more {
  place-items: center;
  color: var(--sg-accent);
  font-size: max(1.05cqw, 8px);
  font-weight: 560;
  line-height: 1;
  white-space: nowrap;
}

/* The checkout's `+` — it creates, it does not report, so it takes the muted
   ink of the `New agent` row's glyph. */
.a-appwin__cardseg--add {
  place-items: center;
  color: var(--sg-fg-dim);
}

.a-appwin__cardseg--add svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* ---- Open: the count, one row per agent, then `New agent`. ---- */
.a-appwin__cardcount {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.3cqw;
  padding: 0.2cqw 0.6cqw 0.3cqw 0.8cqw;
  color: var(--sg-fg-faint);
  font-size: max(1.05cqw, 8px);
  font-weight: 450;
  line-height: 1.3;
  white-space: nowrap;
}

/* DL-27.21: glyph, label, then one shared state slot. `min-height`, never a
   fixed height: a cqw box stops holding its own floored type at 390. */
.a-appwin__cardrow,
.a-appwin__cardnew {
  display: grid;
  box-sizing: border-box;
  min-width: 0;
  grid-template-columns: 1.4cqw minmax(0, 1fr) 1.6cqw;
  align-items: center;
  column-gap: 0.7cqw;
  min-height: 2.8cqw;
  margin-top: 1px;
  padding: 0 0.6cqw 0 0.8cqw;
  border-radius: 0.6cqw;
}

.a-appwin__cardrow {
  background: color-mix(in srgb, var(--sg-fg) 5%, transparent);
}

.a-appwin__cardrow:hover,
.a-appwin__cardnew:hover {
  background: color-mix(in srgb, var(--sg-fg) 9%, transparent);
}

/* The agent holding the keyboard: one louder wash (DL-27.22, candidate A). */
.a-appwin__cardrow[data-focused="true"] {
  background: color-mix(in srgb, var(--sg-fg) 20%, transparent);
}

/* A busy row keeps one static hairline; the motion is the bars'. Read off the
   status cell, which is the node the stream engine repaints — the row itself
   never learns its state changed. */
.a-appwin__cardrow:has(> .a-appwin__cardstatus[data-state="working"]) {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sg-fg) 21%, transparent);
}

/* The label is the pane's latest sentence, trimmed by the layout and never by
   slicing the string (DL-27.4). It is a `[data-tail]` hook, rewritten with
   `textContent`, so nothing may be nested inside it. */
.a-appwin__cardlabel {
  min-width: 0;
  overflow: hidden;
  color: var(--sg-fg);
  font-size: max(1.1cqw, 8px);
  font-weight: 500;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__cardnew,
.a-appwin__cardnew .a-appwin__cardlabel {
  color: var(--sg-fg-dim);
}

/* The glyph slot. A segment's glyph carries the corner dot, so it is the
   positioning context for it. */
.a-appwin__cardglyph {
  position: relative;
  display: grid;
  place-items: center;
}

.a-appwin__cardglyph svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

.a-appwin__cardlogo {
  box-sizing: border-box;
  width: 1.4cqw;
  height: 1.4cqw;
  object-fit: contain;
}

/* ---- The card's state marks. ----
   The corner dot: 5px of solid fill in a 1.5px ring of the rail's ground,
   badged on a segment's glyph and standing alone in a row's state slot. The
   bars: three staggered 2px bars for `working`. Both are in the DOM in every
   state and the parent's `data-state` decides which paints — `idle` paints
   nothing at all (04c:631-756). */
.a-appwin__carddot {
  position: absolute;
  bottom: -0.2cqw;
  left: -0.2cqw;
  box-sizing: content-box;
  width: 0.5cqw;
  height: 0.5cqw;
  border: 0.15cqw solid var(--sg-rail);
  border-radius: 50%;
}

.a-appwin__cardstatus {
  display: grid;
  width: 1.6cqw;
  height: 1.6cqw;
  place-items: center;
}

.a-appwin__cardstatus > * {
  grid-area: 1 / 1;
}

.a-appwin__cardstatus > .a-appwin__carddot {
  position: static;
  border-color: transparent;
}

[data-state="working"] > .a-appwin__cardglyph > .a-appwin__carddot {
  background: var(--card-busy);
}

[data-state="asked"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="asked"] > .a-appwin__carddot {
  background: var(--sg-yellow);
}

[data-state="failed"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="failed"] > .a-appwin__carddot {
  background: var(--sg-red);
}

[data-state="done"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="done"] > .a-appwin__carddot,
[data-state="ended"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="ended"] > .a-appwin__carddot {
  background: color-mix(in srgb, var(--sg-fg) 42%, var(--sg-rail));
}

/* Ended is a stop SQUARE, distinct from the round done dot (DL-27.3). */
[data-state="ended"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="ended"] > .a-appwin__carddot {
  border-radius: 0.2cqw;
}

.a-appwin__cardstatus[data-state="working"] > .a-appwin__carddot,
[data-state="idle"] > * > .a-appwin__carddot,
.a-appwin__cardstatus[data-state="idle"] > .a-appwin__carddot {
  display: none;
}

.a-appwin__cardload {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.2cqw;
}

.a-appwin__cardstatus:not([data-state="working"]) > .a-appwin__cardload {
  display: none;
}

.a-appwin__cardload > i {
  width: 0.2cqw;
  height: 0.6cqw;
  border-radius: 999px;
  background: var(--card-busy);
}

.a-appwin__cardload > i:nth-child(2) {
  --load-delay: -150ms;
  height: 1cqw;
}

.a-appwin__cardload > i:nth-child(3) {
  --load-delay: -300ms;
  height: 0.8cqw;
}

/* ---- A checkout with nothing open. ----
   The head row's shape alone, on the card head's mark track and gap, so a
   bare `main` starts on the same left edge as every card under it. */
.a-appwin__bare {
  display: grid;
  box-sizing: border-box;
  min-width: 0;
  grid-template-columns: 1.4cqw minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 0.6cqw;
  min-height: 2.6cqw;
  padding: 0 0.9cqw;
}

.a-appwin__barename {
  overflow: hidden;
  color: var(--sg-fg-dim);
  font-size: max(1.3cqw, 9px);
  font-weight: 500;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- The status mark. ----
   The Agent Board's cards still draw this one (`RailStatusMark`): one 14px
   box in EVERY state — the working ring's own size — so a ring and a dot
   trade places without moving the text beside them; the resting dot keeps its
   9px of ink, painted centred by the `::before` rather than by the box
   (04a:674-703).

   The mock has NO `--spinner` modifier class: `data-state` is the whole
   switch, which is what lets the stream engine repaint a pane's status by
   writing one attribute. So every rule about the working state is written as
   the attribute — `.a-appwin__mark[data-state="working"]` — and never as a
   modifier selector, which would match nothing here. */
.a-appwin__mark {
  position: relative;
  display: block;
  width: 1.4cqw;
  height: 1.4cqw;
  flex: none;
}

.a-appwin__mark::before {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.9cqw;
  height: 0.9cqw;
  border-radius: 50%;
}

/* failed — the loudest thing a row can say, and no halo: the halo means
   "answer me", and a crashed agent is not asking a question (DL-3.2). */
.a-appwin__mark[data-state="failed"]::before {
  background: var(--sg-red);
}

/* asked — the unread dot. A question and a finished run nobody has read are
   one state here, and this is the token that state wears. */
.a-appwin__mark[data-state="asked"]::before {
  background: var(--sg-yellow);
}

/* done and idle — one quiet dot. Neither asks for anything, so neither spends
   a hue; they differ only in the word a tooltip would say (04a:739-742).
   ended — the agent's process left the pane — is the same ink as a stop
   SQUARE, so a card that can be restarted reads apart from one that finished. */
.a-appwin__mark[data-state="done"]::before,
.a-appwin__mark[data-state="idle"]::before,
.a-appwin__mark[data-state="ended"]::before {
  background: var(--sg-quiet-dot);
}

.a-appwin__mark[data-state="ended"]::before {
  border-radius: 0.2cqw;
}

/* working — the ring IS the mark, so the dot withdraws entirely. */
.a-appwin__mark[data-state="working"]::before {
  content: none;
}

/* The ring's SVG is in the DOM in every state; this is the switch that shows
   it. `--text-primary` ink at the full 14px since 2026-08-20 — at 12px in
   `--text-muted` it read as a smudge beside the age rather than as a state. */
.a-appwin__wsspinner {
  display: none;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  color: var(--sg-fg);
  fill: currentColor;
}

.a-appwin__mark[data-state="working"] .a-appwin__wsspinner {
  display: block;
}

/* NOTHING ROTATES (DL-27.3, owner 2026-08-20): the eight dots are still and a
   bright head appears to travel because each runs the same opacity ramp one
   slot later. `--dot` is zero-based, so slot 0 starts at -1.2s and the ring is
   already mid-cycle on its first painted frame — at 1…8 the whole ring would
   pop in. Copied from 02-shell.css:444-480; only `opacity` animates, which is
   DL-1.2's list. */
.a-appwin__wsdot {
  animation: a-appwin-wschase 1.2s linear infinite;
  animation-delay: calc((var(--dot) - 8) * 0.15s);
}

/* ---- Agent monograms. ----
   A declared agent that ships no brand file wears its letter instead — the
   same fallback the app's rail rows and chips use. Untinted: the hero's agent
   row (`.hero-agents__mark--mono`, hero-copy-column.css) makes the same call,
   and a per-agent tint would invent an identity the catalog does not have.
   No hero fixture reaches this branch; a fixture passing an id outside the
   stage's five marks does. */
.a-appwin__cardlogo--mono,
.a-appwin__chiplogo--mono {
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--sg-chrome-2);
  color: var(--sg-fg-dim);
  font-size: max(0.9cqw, 7px);
  font-weight: 600;
  line-height: 1;
  user-select: none;
}

/* ---- The tab strip. ----
   One row of one chip shape (DL-18.10), the same height as the frame row
   across the seam. It closes with `--seam-divider`, the SAME line the pane
   splits draw, so the strip reads as chrome rather than as something floating
   in the work area (06-stage-panes.css:52-60) — the soft hairline the panes
   use for their own edges would read as a rendering artefact here. */
.a-appwin__strip {
  display: flex;
  box-sizing: border-box;
  flex: 0 0 auto;
  align-items: center;
  gap: 0.8cqw;
  min-width: 0;
  /* The frame row's floor, restated so the two chrome rows either side of the
     seam stay on one line at every width — the property a screenshot gate can
     check with one number. See `.a-appwin__framerow` for where 13 comes from. */
  height: max(3.4cqw, 13px);
  padding: 0 0.8cqw;
  border-bottom: 1px solid var(--sg-hairline);
}

.a-appwin__chips {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 0.4cqw;
  overflow: hidden;
}

/* The three-state ladder (DL-21.7): 3% at rest, 6% on hover, the raised plane
   plus a hairline frame when selected. Not transparent at rest — a chip
   floats alone on the stage's `--bg` with no neighbouring rows to compare
   against, so "no wash" read as "nothing here" rather than "not selected".
   The 1px border is on EVERY chip and only its colour changes, so selection
   costs no height and shifts no label (05-tab-bar-toolbar.css:33-60). */
/* `min-height` and an explicit `line-height`, never a fixed `height` — MEASURED,
   2026-08-20. A `cqw` box stops containing its own text the moment the type
   hits a floor: at a 390 viewport the label floors at 8px, whose `normal` line
   box is 9px, while `2.5cqw` gave the chip a 5.41px content box in the hero and
   4.31px in a panel. The line box spilled 1.59px / 2.69px past the chip and so
   past `.a-appwin__chips`, which is a scroll container — the 1px-overflow class
   of defect AGENTS.md records, arriving through a floored font rather than
   through a padding. `min-height` is what the rail rows two blocks up already
   use for exactly this reason: the box grows to the line box (9px at the 8px
   floor, plus the 1px border top and bottom = an 11px chip) instead of the
   line box spilling out of the box. Above the breakpoint `2.5cqw` exceeds the
   line box at every width, so the chip's rendered height there is unchanged.

   `line-height: 1` was tried here first and REVERTED, measured: a line-height
   under the font's own content area makes the inline box overflow its line
   box, which turned the label — `overflow: hidden`, for its ellipsis — into a
   fresh 1px overflow at 1024 that did not exist before. The line box stays
   `normal`; the box is what moves. */
.a-appwin__chip {
  display: flex;
  box-sizing: border-box;
  min-width: 0;
  max-width: 21cqw;
  min-height: 2.5cqw;
  align-items: center;
  gap: 0.6cqw;
  padding: 0 0.4cqw 0 0.6cqw;
  border: 1px solid transparent;
  /* --radius-flat (DL-20.1's fourth role): a chip packed with a sentence
     cannot afford a corner that its padding has to hold the text off. */
  border-radius: 0.2cqw;
  background: var(--sg-tab-rest);
  color: var(--sg-fg-dim);
  font-size: max(1.1cqw, 9px);
}

.a-appwin__chip:hover {
  color: var(--sg-fg);
  background: color-mix(in srgb, #ffffff 6%, transparent);
}

/* DL-21.1 amended 2026-08-16: the wash, plus a NEUTRAL hairline frame. Not
   `--accent` — this is not the retired accent marker coming back — and it
   traces the chip rather than sitting beside it. */
.a-appwin__chip.is-active {
  color: var(--sg-fg);
  background: var(--sg-raised);
  border-color: var(--sg-hair-strong);
}

/* ONE glyph slot whatever the chip opened — a brand mark, a file-type icon,
   the globe — so a strip of mixed chips keeps one left edge for its labels
   (DL-18.6). One class covers both branches of the markup: an `<img>` for a
   terminal chip, a `<span>` wrapping an SVG for the other two. */
.a-appwin__chiplogo {
  display: grid;
  place-items: center;
  width: 1.5cqw;
  height: 1.5cqw;
  flex: none;
  border-radius: 0.8cqw;
  object-fit: contain;
  color: var(--sg-fg-dim);
}

.a-appwin__chiplogo svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* The chip's own `max-width` is the cap, so the label shrinks with it rather
   than carrying a second, smaller number of its own. This node is a
   `[data-tail]` hook on the active terminal chip: text only. */
.a-appwin__chiplabel {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.a-appwin__chipclose {
  display: grid;
  place-items: center;
  width: 1.6cqw;
  height: 1.6cqw;
  flex: none;
  margin-left: 0.2cqw;
  border-radius: 1cqw;
  color: var(--sg-fg-dim);
}

.a-appwin__chipclose svg {
  display: block;
  width: 1.3cqw;
  height: 1.3cqw;
}

/* `margin-left: auto` and nothing else (06-stage-panes.css:69-74): a long tab
   list shortens itself before the actions move. */
.a-appwin__stripactions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  margin-left: auto;
}

@media (prefers-reduced-motion: no-preference) {
  .a-appwin__cursor {
    animation: a-appwin-blink 1.1s steps(2, start) infinite;
  }

  .a-appwin__spinner {
    animation: a-appwin-pulse 1.2s ease-in-out infinite;
  }

  /* The card's working bars (04c:740-756). ADDED here rather than switched
     off under reduced motion: without motion the three static heights still
     read as "working" (DL-1.5). Only `transform` animates. */
  .a-appwin__cardload > i {
    transform-origin: center;
    animation: a-appwin-bar 900ms ease-in-out infinite alternate;
    animation-delay: var(--load-delay, 0ms);
  }
}

@keyframes a-appwin-bar {
  from {
    transform: scaleY(0.4);
  }

  to {
    transform: scaleY(1);
  }
}

@keyframes a-appwin-blink {
  50% {
    opacity: 0;
  }
}

@keyframes a-appwin-pulse {
  50% {
    opacity: 0.45;
  }
}

/* The working ring's ink cycle (02-shell.css:463-471). Prefixed like the two
   above so this sheet owns every name it declares; a grep for `wschase` still
   finds it. */
@keyframes a-appwin-wschase {
  from {
    opacity: 1;
  }

  to {
    opacity: 0.15;
  }
}

@media (max-width: 47.5rem) {
  .a-appwin {
    width: 100%;
    aspect-ratio: 1000 / 780;
    border-radius: 5px;
  }

  /* THE RAIL STAYS. Until the 2026-08-20 redesign this block hid it outright
     — with it the frame row, and with that the stage's left seam — which
     proved nothing about the rail on the one page whose subject is the rail.
     The honest compression is FEWER PANES, not less rail: the column widens
     to 42cqw, the grid drops to the focused pane, and a sentence truncates
     with an ellipsis exactly as `.asr-row__msg` does in the app.

     A glyph-only collapsed rail was the rejected alternative: the app's own
     narrow behaviour is `sidebarCollapsed`, which takes the column to width
     0, so a middle state would be inventing a product.

     The arithmetic, at a 390 viewport: `.a-appwin` measures 298.4px, so
     42cqw is 125.3px of rail and ~172px for the single pane — wider than the
     two-column layout's 149px panes. 390 is a MARKETING-page check width;
     the app's own minimum is 480 and this sheet makes no claim about it. */
  .a-appwin__rail {
    width: 42cqw;
  }

  .a-appwin__grid {
    grid-template-columns: 1fr;
  }

  .a-appwin__grid .a-appwin__pane:not(.is-focused) {
    display: none;
  }

  .a-appwin__line,
  .a-appwin__spinner,
  .a-appwin__promptbox {
    font-size: 8px;
  }

  /* Chrome bottoms out on the transcript's own two floors rather than on the
     9px the wide page carries: below the breakpoint the whole window is
     298px, and the rail's job here is to stay READABLE at ~24 characters
     before it ellipsizes, not to hold a rung. */
  .a-appwin__clustername,
  .a-appwin__cardname,
  .a-appwin__cardlabel,
  .a-appwin__barename,
  .a-appwin__chiplabel,
  .a-appwin__new {
    font-size: 8px;
  }

  .a-appwin__footline,
  .a-appwin__status,
  .a-appwin__cardmeta,
  .a-appwin__cardbadge,
  .a-appwin__barebadge,
  .a-appwin__cardcount,
  .a-appwin__cardtimes,
  .a-appwin__cardseg--more {
    font-size: 7px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .a-appwin__cursor,
  .a-appwin__spinner {
    animation: none;
  }

  /* The ring stops and states its own state by dimming instead, mirroring
     02-shell.css:474-479. Written as the attribute, not as a `--spinner`
     modifier: the mock has no such class, so that selector would match
     nothing and the gate would pass on a rule that does not exist. */
  .a-appwin__wsdot {
    animation: none;
    opacity: 0.5;
  }

  .a-appwin__mark[data-state="working"] {
    opacity: 0.6;
  }
}
