/* ============================================================================
   BlockGenie Codex — "Night Desk"
   Art direction: docs/18-ui-redesign.md
   Cool room, warm ink, one lit instrument. Serif asks, mono reports, grotesque
   works. No saturated brand colour; hierarchy comes from surface luminance and
   type. Two gradients exist on purpose (ambient room wash, scroll scrim) and
   neither sits on a component.
   ========================================================================== */

:root {
  /* ---- palette (6 named + support) ---- */
  --ink: #0b0d11;
  --room: #10131a;
  --panel: #171b23;
  --panel-2: #1d222b;
  --edge: #262c37;
  --bone: #edeae4;

  --edge-soft: #1a1f28;
  --edge-strong: #333a46;
  --bone-dim: #a7aeb9;
  /* mono micro labels live at 11px, so this has to clear 4.5:1 on every
     surface in the ramp — including --panel-2, the brightest one (4.76:1) */
  --faint: #848d9a;
  --glacier: #8fb9cf;
  --glacier-dim: #6d93a8;
  --glacier-sunk: #1b2b34;
  --ember: #d9705e;
  --ember-sunk: #2c1a18;
  /* semantic tokens (docs/52) — night values; shell.css owns the day values */
  --on-bone: #14171d; --bone-hi: #ffffff; --on-ember: #1a0f0d; --ember-hi: #e58472; --ember-soft: #f0b3a8;
  --code-fg: #d7dbe2; --strong-fg: #ffffff; --tok-kw: #a8c4dd; --tok-str: #b9cfae; --tok-num: #dcc39a;
  --wash: rgba(143, 185, 207, .052); --scrim: rgba(6, 8, 11, .62); --tap: rgba(143, 185, 207, .12);
  --slab-sheen: rgba(255, 255, 255, .035);
  --lamp-bg: #edeae4; --lamp-fg: #14171d; --lamp-tape: #4b5563; --lamp-sub: #1f2937; --lamp-link: #1d4d66; --lamp-edge: #c9c5bd; --lamp-hi: #ffffff;

  /* ---- type ---- */
  --serif: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  --sans: "Schibsted Grotesk", "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-display: clamp(2.5rem, 5.2vw, 3.75rem); /* docs/53: the one serif line reads as display */
  --t-title: 1.0625rem;
  --t-body: 1rem;
  --t-ui: 0.9375rem;
  --t-sm: 0.8125rem;
  --t-micro: 0.6875rem;

  /* ---- space (4px scale) ---- */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 20px;
  --s6: 24px; --s7: 32px; --s8: 40px; --s9: 56px; --s10: 72px;

  /* ---- radius ---- */
  --r-sm: 3px; --r-md: 6px; --r-lg: 10px; --r-xl: 14px; --r-pill: 6px; /* docs/53: pills are gone; the alias means "a control" */

  /* ---- elevation: hairlines for structure, soft layered shadow for float ---- */
  --sh-1: 0 1px 2px rgba(0, 0, 0, .34);
  --sh-2: 0 2px 8px rgba(0, 0, 0, .3), 0 14px 34px -10px rgba(0, 0, 0, .5);
  --sh-3: 0 4px 14px rgba(0, 0, 0, .34), 0 26px 60px -16px rgba(0, 0, 0, .66);

  --measure: 46rem;
  --rail: 264px;
  --gutter: 30px;

  --e-out: cubic-bezier(.22, .68, .28, 1);
  --e-in: cubic-bezier(.55, .06, .68, .19);
  /* motion scale — docs/33-motion-and-icons.md. Press is felt, not seen;
     hover is a state layer; entrances stay under 300ms; loops are the only
     motion allowed to run longer, and only while the machine is really busy */
  --d-press: 100ms; --d-hover: 140ms; --d-enter: 200ms; --d-panel: 160ms;

  /* z scale — the only one in the file */
  --z-jump: 20; --z-composer: 30; --z-topbar: 25; --z-rail: 60; --z-menu: 80; --z-boot: 90;
}

* { box-sizing: border-box; }

/* every layout class below sets an explicit display, so [hidden] needs teeth */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--room);
  color: var(--bone);
  font-family: var(--sans);
  font-size: var(--t-ui);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

/* the room light — one ambient wash, fixed, never on a component */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(115% 58% at 50% -14%, var(--wash), transparent 62%);
}

h1, h2, h3, p, ol, ul { margin: 0; }
button, input, textarea, select { font: inherit; color: inherit; }
a { color: var(--glacier); text-decoration-color: color-mix(in srgb, var(--glacier) 40%, transparent); text-underline-offset: 2px; }
a:hover { text-decoration-color: var(--glacier); }

/* outline, not box-shadow, so it survives scroll containers; it follows each
   element's own radius — never force a radius here or the round buttons square off */
:focus-visible {
  outline: 2px solid var(--glacier);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
  position: fixed; left: var(--s4); top: -60px; z-index: var(--z-boot);
  padding: var(--s2) var(--s4); border-radius: var(--r-sm);
  background: var(--panel-2); border: 1px solid var(--edge); color: var(--bone);
  text-decoration: none; transition: top 140ms var(--e-out);
}
.skip-link:focus { top: var(--s4); }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ic { width: 16px; height: 16px; flex: none; display: block; }

/* mono utility voice — the machine reporting */
.tape {
  font-family: var(--mono);
  font-size: var(--t-micro);
  font-weight: 400;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--faint);
}

.display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: var(--t-display);
  line-height: 1.02;
  letter-spacing: -.016em;
  text-wrap: balance;
  color: var(--bone);
}

kbd {
  font-family: var(--mono);
  font-size: .6875rem;
  padding: 1px 5px;
  border: 1px solid var(--edge);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  background: var(--panel);
  color: var(--bone-dim);
}

/* ── buttons ──────────────────────────────────────────────────────────── */
.btn-solid, .btn-outline, .btn-quiet, .btn-danger {
  display: inline-flex; align-items: center; gap: var(--s2);
  min-height: 40px; padding: 0 var(--s4);
  border-radius: var(--r-md); border: 1px solid transparent;
  font-size: var(--t-ui); font-weight: 500; cursor: pointer;
  transition: background-color 140ms var(--e-out), border-color 140ms var(--e-out),
              color 140ms var(--e-out), transform 140ms var(--e-out);
}
.btn-solid { background: var(--bone); color: var(--on-bone); }
.btn-solid:hover { background: var(--bone-hi); }
.btn-solid:active { transform: translateY(1px); }
.btn-outline { background: transparent; border-color: var(--edge-strong); color: var(--bone); }
.btn-outline:hover { background: var(--panel-2); border-color: var(--faint); }
.btn-quiet { background: transparent; color: var(--bone-dim); }
.btn-quiet:hover { background: var(--panel-2); color: var(--bone); }
.btn-danger { background: var(--ember); color: var(--on-ember); }
.btn-danger:hover { background: var(--ember-hi); }
.btn-solid:disabled, .btn-outline:disabled, .btn-quiet:disabled {
  opacity: .42; cursor: not-allowed; transform: none;
}

.ghost-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 4px 0;
  font-size: var(--t-sm); color: var(--bone-dim); cursor: pointer;
  border-radius: 6px;
  transition: color 140ms var(--e-out);
}
.ghost-btn:hover { color: var(--bone); }

.icon-btn {
  display: inline-grid; place-items: center;
  width: 34px; height: 34px; flex: none;
  border-radius: var(--r-sm); border: 1px solid transparent;
  background: transparent; color: var(--bone-dim); cursor: pointer;
  transition: background-color var(--d-hover) var(--e-out), color var(--d-hover) var(--e-out),
              transform var(--d-press) var(--e-out);
}
.icon-btn:hover { background: var(--panel-2); color: var(--bone); }
/* press feedback: a 4% dip on the glyph buttons only — a state layer lights
   the hover, the press is felt on release. Gated to real pointers so a tap on
   glass never leaves a button half-scaled. */
@media (hover: hover) and (pointer: fine) {
  .icon-btn:active, .act:active, .attach-btn:active, .btn-stop:active,
  .later-drop:active, .project-item:active, .command-option:active { transform: scale(.96); }
}

/* ── loaders: the machine's honest waits ──────────────────────────────
   One vocabulary, wired to real state (never a timer):
     hairline sweep  .is-busy::after   — a request is in flight, no progress known
     dotted ring     [data-phase=queued] — waiting in line, not running
     pulsing ring    [data-phase=thinking] — the worker is on this turn (1.5s linear, the only looping node)
     caret           .caret            — tokens are arriving
     type pulse      .is-busy > strong — a label whose value is being refetched */
.is-busy::after {
  content: ""; display: inline-block; vertical-align: middle;
  width: 22px; height: 1px; margin-left: var(--s2);
  background: var(--glacier); transform-origin: left;
  animation: sweep 1.4s var(--e-out) infinite;
}
.btn-solid.is-busy, .btn-outline.is-busy, .btn-danger.is-busy, .btn-quiet.is-busy {
  position: relative; color: transparent !important; pointer-events: none;
}
.btn-solid.is-busy .ic, .btn-outline.is-busy .ic, .btn-danger.is-busy .ic, .btn-quiet.is-busy .ic { opacity: 0; }
.btn-solid.is-busy::after, .btn-outline.is-busy::after, .btn-danger.is-busy::after, .btn-quiet.is-busy::after {
  position: absolute; left: 50%; top: 50%; margin: 0;
  transform: translate(-50%, -50%);
  animation: sweep-center 1.2s var(--e-out) infinite;
}
.btn-solid.is-busy::after { background: var(--on-bone); }
.btn-danger.is-busy::after { background: var(--on-ember); }
.btn-outline.is-busy::after, .btn-quiet.is-busy::after { background: var(--bone); }
.project-switcher.is-busy strong, .list-status.is-busy { animation: type-pulse 1.6s ease-in-out infinite; }
.project-switcher.is-busy::after { display: none; }
[aria-busy="true"].chat-list { opacity: .6; transition: opacity var(--d-hover) var(--e-out); }

@keyframes sweep-center {
  0%   { transform: translate(-50%, -50%) scaleX(.2); opacity: .35; }
  50%  { transform: translate(-50%, -50%) scaleX(1);  opacity: 1; }
  100% { transform: translate(-50%, -50%) scaleX(.2); opacity: .35; }
}
@keyframes type-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

.error-text {
  margin-top: var(--s2);
  font-size: var(--t-sm);
  color: var(--ember);
}

.dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--faint); flex: none; display: inline-block;
}
.dot.is-on { background: var(--glacier); }
.dot.is-off { background: var(--ember); }

/* ── boot ─────────────────────────────────────────────────────────────── */
.boot {
  position: fixed; inset: 0; z-index: var(--z-boot);
  display: grid; place-content: center; justify-items: center; gap: var(--s4);
  background: var(--ink);
}
.boot-node {
  width: 14px; height: 14px; border-radius: 50%;
  border: 1.5px solid var(--glacier);
  animation: pulse-node 1.5s linear infinite;
}
.boot-tape { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }

/* the thinking ring breathes in opacity only — never scale, never spin (docs/53) */
@keyframes pulse-node {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}

/* ── gate ─────────────────────────────────────────────────────────────── */
.gate {
  position: fixed; inset: 0; z-index: var(--z-menu);
  display: flex;
  overflow-y: auto;
  background: var(--ink);
  padding: var(--s8) var(--s5);
}
.gate-col {
  width: 100%; max-width: 31rem; margin: auto;   /* auto margins centre without clipping */
  animation: rise 320ms var(--e-out) both;
}
.gate-head { margin-bottom: var(--s7); }
.wordmark {
  display: flex; flex-direction: column; gap: 3px;
  font-size: var(--t-sm); font-weight: 600; letter-spacing: .01em; color: var(--bone);
}
.wordmark span {
  font-family: var(--mono); font-size: var(--t-micro); font-weight: 400;
  letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.wordmark a {
  color: var(--faint);
  text-decoration-color: transparent;
  transition: color 140ms var(--e-out), text-decoration-color 140ms var(--e-out);
}
.wordmark a:hover { color: var(--glacier); text-decoration-color: currentColor; }
.gate-head .display { margin: var(--s6) 0 var(--s3); }
.gate-lede { font-size: var(--t-ui); color: var(--bone-dim); max-width: 52ch; }
.gate-lede em { color: var(--bone); font-style: italic; }
.gate-back { margin-top: var(--s5); }
.gate-back .ic { transform: rotate(90deg); }

.steps { list-style: none; padding: 0; display: grid; gap: 1px; background: var(--edge-soft); border-radius: var(--r-lg); overflow: hidden; border: 1px solid var(--edge-soft); }
.step { background: var(--room); padding: var(--s5); transition: opacity 200ms var(--e-out); }
.step.is-locked { opacity: .46; }
.step.is-locked .step-body { pointer-events: none; }
.step-top { display: flex; align-items: baseline; gap: var(--s3); }
.step-num { font-family: var(--mono); font-size: var(--t-micro); color: var(--glacier-dim); letter-spacing: .1em; }
.step-top h2 { font-size: var(--t-title); font-weight: 600; flex: 1; }
.step.is-done .step-top .tape { color: var(--glacier); }
.step-body { padding-left: 30px; margin-top: var(--s2); }
.step-note { font-size: var(--t-sm); color: var(--bone-dim); margin-bottom: var(--s4); }
.step-note em { color: var(--bone); font-style: italic; }

.step-body label {
  display: block; font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .09em; text-transform: uppercase; color: var(--faint); margin-bottom: 6px;
}
.field-row { display: flex; gap: var(--s2); flex-wrap: wrap; }
.field-row input {
  flex: 1 1 12rem; min-width: 0; min-height: 40px;
  padding: 0 var(--s3);
  background: var(--ink); color: var(--bone);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  transition: border-color 140ms var(--e-out), background-color 140ms var(--e-out);
}
.field-row input::placeholder { color: var(--faint); }
.field-row input:hover { border-color: var(--edge-strong); }
.field-row input:focus-visible { border-color: var(--glacier); outline-offset: 1px; }

.acct-line { font-size: var(--t-sm); color: var(--bone-dim); margin-bottom: var(--s3); }

.device {
  margin-top: var(--s5); padding: var(--s5);
  background: var(--panel); border: 1px solid var(--edge); border-radius: var(--r-md);
  animation: rise 220ms var(--e-out) both;
}
.device-code-row { display: flex; align-items: center; justify-content: space-between; gap: var(--s4); margin: var(--s3) 0 var(--s4); flex-wrap: wrap; }
.device-code {
  font-family: var(--mono); font-weight: 500;
  font-size: clamp(1.5rem, 6vw, 1.875rem); letter-spacing: .2em;
  color: var(--bone);
}
.device-url { display: flex; flex-direction: column; gap: 3px; font-size: var(--t-sm); word-break: break-all; }
.device-wait { margin-top: var(--s3); font-family: var(--mono); font-size: var(--t-sm); color: var(--glacier); }
.device-wait.is-busy::after { margin-left: var(--s3); }
#githubStatus.is-busy::after, #filesStatus.is-busy::after, #capabilitySubtitle.is-busy::after, .files-empty.is-busy::after { vertical-align: middle; }

.gate-foot { margin-top: var(--s5); font-size: var(--t-sm); color: var(--faint); }
.gate-foot code { font-family: var(--mono); color: var(--bone-dim); }

/* ── app shell ────────────────────────────────────────────────────────── */
.app {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: var(--rail) minmax(0, 1fr);
  /* the row must be bounded by the shell, not by its tallest child — otherwise
     a long thread list makes the whole page 1171px tall and the composer is
     pushed below the fold */
  grid-template-rows: minmax(0, 1fr);
  height: 100dvh;
  overflow: hidden;
}

.scrim {
  position: fixed; inset: 0; z-index: calc(var(--z-rail) - 1);
  background: var(--scrim);
  backdrop-filter: blur(2px);
  animation: fade 160ms var(--e-out) both;
}

/* ── sidebar: recedes (darker than the room) ──────────────────────────── */
/* arrival order is argument order (docs/30 §2): the transcript lands first,
   the composer second, then the chrome — topbar, and the rail last */
.sidebar {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--ink);
  border-right: 1px solid var(--edge-soft);
  padding: var(--s4) var(--s3) var(--s3);
  animation: rise 280ms 200ms var(--e-out) both;
}
.side-top { display: flex; align-items: flex-start; justify-content: space-between; padding: var(--s1) var(--s2) var(--s5); }
.side-close { display: none; }

.project-switch { position: relative; margin-bottom: var(--s2); }
.project-switcher {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  width: 100%; min-height: 48px; padding: var(--s2) var(--s3);
  border: 1px solid var(--edge-soft); border-radius: var(--r-md);
  background: var(--room); color: var(--bone); cursor: pointer; text-align: left;
  transition: background-color 140ms var(--e-out), border-color 140ms var(--e-out);
}
.project-switcher:hover, .project-switcher[aria-expanded="true"] { background: var(--panel); border-color: var(--edge); }
.project-switcher > span { display: grid; min-width: 0; flex: 1; }
.project-switcher strong { font-size: var(--t-sm); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.project-switcher .ic { color: var(--faint); }
.project-switcher .project-ic { color: var(--glacier-dim); }
.project-switcher .chev { transition: transform var(--d-hover) var(--e-out); }
.project-switcher[aria-expanded="true"] .chev { transform: rotate(180deg); }
.project-panel {
  margin-top: var(--s2); padding: var(--s2);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  background: var(--room);
  transform-origin: top center;
  animation: pop var(--d-panel) var(--e-out) both;
}
.project-list { display: grid; gap: 2px; max-height: 12rem; overflow-y: auto; }
.project-item, .project-panel-actions button {
  display: flex; align-items: center; gap: var(--s2); width: 100%; min-height: 34px;
  padding: 0 var(--s2); border: 0; border-radius: 6px;
  background: transparent; color: var(--bone-dim); cursor: pointer; text-align: left;
  font-size: var(--t-sm);
  transition: background-color var(--d-hover) var(--e-out), color var(--d-hover) var(--e-out),
              transform var(--d-press) var(--e-out);
}
.project-item:hover, .project-panel-actions button:hover { background: var(--panel); color: var(--bone); }
.project-item[aria-selected="true"] { background: var(--panel-2); color: var(--bone); }
.project-item .project-dot { width: 6px; height: 6px; border: 1px solid var(--glacier-dim); border-radius: 50%; flex: none; }
.project-item[aria-selected="true"] .project-dot { background: var(--glacier); border-color: var(--glacier); }
.project-item .project-copy { min-width: 0; display: grid; }
.project-item .project-copy span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.project-item .project-copy small { font-family: var(--mono); font-size: 10px; color: var(--faint); }
.project-panel-actions { display: grid; gap: 2px; margin-top: var(--s2); padding-top: var(--s2); border-top: 1px solid var(--edge-soft); }
.project-panel-actions .ic { width: 14px; height: 14px; color: var(--faint); }

.new-thread {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; min-height: 40px; padding: 0 var(--s3);
  margin-bottom: var(--s3);
  background: var(--panel); color: var(--bone);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  font-weight: 500; cursor: pointer;
  transition: background-color 140ms var(--e-out), border-color 140ms var(--e-out);
}
.new-thread:hover { background: var(--panel-2); border-color: var(--edge-strong); }

.side-search {
  display: flex; align-items: center; gap: var(--s2);
  padding: 0 var(--s3); min-height: 38px; margin-bottom: var(--s4);
  border: 1px solid transparent; border-radius: var(--r-md);
  background: var(--room); color: var(--faint);
  transition: border-color 140ms var(--e-out);
}
.side-search:focus-within { border-color: var(--edge-strong); }
.side-search input {
  flex: 1; min-width: 0; background: none; border: 0; outline: none;
  font-size: var(--t-sm); color: var(--bone);
}
.side-search input::placeholder { color: var(--faint); }
.side-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.chat-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 0 calc(var(--s1) * -1); padding: 0 var(--s1) var(--s2); }
/* the list rises once as a block when a *different* project's threads land —
   never per row, never on a refresh of the same list */
.chat-list.is-fresh { animation: rise var(--d-enter) var(--e-out) both; }
.group-label { padding: var(--s4) var(--s2) var(--s2); }
.group-label:first-child { padding-top: 0; }

.chat-item {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0 var(--s2);
  width: 100%; text-align: left; padding: var(--s2) var(--s3);
  margin-bottom: 2px; border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--bone-dim); cursor: pointer;
  transition: background-color 130ms var(--e-out), color 130ms var(--e-out);
}
.chat-item:hover { background: var(--panel); color: var(--bone); }
.chat-item.is-active { background: var(--panel-2); color: var(--bone); }
.chat-item .ttl {
  grid-column: 1; font-size: var(--t-sm); font-weight: 500; color: inherit;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-item .when { grid-column: 2; grid-row: 1; font-family: var(--mono); font-size: var(--t-micro); color: var(--faint); font-variant-numeric: tabular-nums; }
.chat-item .meta {
  grid-column: 1 / -1; font-size: var(--t-micro); color: var(--faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px;
}
.chat-item .meta b {
  font-family: var(--mono); font-weight: 400; font-size: 10px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--glacier-dim);
}
.chat-item.is-live .meta b { color: var(--glacier); }
/* a live thread carries its node in the rail too: running breathes, queued sits */
.chat-item.is-live .meta b::before {
  content: ""; display: inline-block; width: 5px; height: 5px; margin-right: 5px;
  border-radius: 50%; vertical-align: 1px;
  background: var(--glacier); animation: pulse-node 1.5s linear infinite;
}
.chat-item.is-live[data-live="queued"] .meta b::before,
.chat-item.is-live[data-live="pending"] .meta b::before {
  background: none; border: 1px dotted var(--glacier-dim); animation: none;
}

.list-status { padding: var(--s2) var(--s3) 0; }
/* docs/59: the empty rail is a starting point — note plus a way out, in a
   dashed field so it reads as a place rather than a stalled list */
.rail-empty {
  display: grid; gap: var(--s3); min-width: 0;
  margin: var(--s2) var(--s1) 0; padding: var(--s4) var(--s3);
  border: 1px dashed var(--edge); border-radius: var(--r-md);
}
.rail-empty .tape { color: var(--faint); line-height: 1.5; overflow-wrap: normal; }
.rail-empty-actions { display: flex; flex-wrap: wrap; gap: var(--s2); min-width: 0; }
.rail-empty-actions .btn-outline, .rail-empty-actions .btn-quiet { min-height: 34px; padding: 0 var(--s3); font-size: var(--t-sm); white-space: nowrap; }

.later {
  border-top: 1px solid var(--edge-soft);
  margin-top: var(--s1);
  padding: var(--s2) var(--s1) var(--s1);
  max-height: 9rem;
  overflow-y: auto;
}
.later .group-label { padding-top: var(--s2); }
.later-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 0 2px;
  padding: 4px var(--s2);
  border-radius: var(--r-sm);
}
.later-row:hover { background: var(--panel); }
.later-go {
  display: grid; gap: 1px; min-width: 0;
  padding: 0; border: 0; background: none;
  text-align: left; cursor: pointer; color: inherit;
}
.later-go .when {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .08em; text-transform: uppercase; color: var(--glacier-dim);
}
.later-go .msg {
  font-size: var(--t-micro); color: var(--faint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.later-drop {
  width: 28px; height: 28px; margin-top: 1px;
  border: 0; border-radius: 6px;
  background: transparent; color: var(--faint); cursor: pointer;
  display: grid; place-items: center;
}
.later-drop:hover { background: var(--ember-sunk); color: var(--ember); }
.later-drop .ic { width: 12px; height: 12px; }

.side-foot {
  border-top: 1px solid var(--edge-soft); margin-top: var(--s2);
  padding: var(--s3) var(--s3) var(--s2);
  display: grid; gap: var(--s2); justify-items: start;
}
.who-name { font-size: var(--t-sm); font-weight: 500; }
.who-plan { display: flex; align-items: center; gap: 6px; margin-top: 2px; }

/* ── stage ────────────────────────────────────────────────────────────── */
.stage {
  position: relative; min-width: 0;
  display: grid;
  /* the nowrap title has a wide min-content; without a 0-min column the whole
     stage is dragged past the viewport on narrow screens */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  isolation: isolate;
}
/* rows are assigned, not implied: the banner is display:none most of the time,
   and without this the transcript slid into the auto row and the composer into
   the 1fr row — which collapsed to 0 once a thread was taller than the screen */
.stage > .topbar { grid-row: 1; }
.stage > .banner { grid-row: 2; }
.stage > .transcript { grid-row: 3; }
.stage > .composer-wrap { grid-row: 4; }

.topbar {
  position: relative; z-index: var(--z-topbar); min-width: 0;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--s5);
  min-height: 56px;
  border-bottom: 1px solid transparent;
  transition: border-color 160ms var(--e-out);
  animation: rise 300ms 150ms var(--e-out) both;
}
/* no border at rest; a hairline appears only once the transcript has scrolled
   under it, so the bar tells the truth about where the conversation went */
.topbar.is-scrolled { border-bottom-color: var(--edge-soft); }
.rail-toggle { display: none; }
.top-title { min-width: 0; flex: 1; }
.top-title h1 {
  font-size: var(--t-title); font-weight: 600; letter-spacing: -.005em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.top-title .tape { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.top-right { display: flex; align-items: center; gap: var(--s2); flex: none; }
.palette-trigger {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 var(--s2);
  border: 1px solid var(--edge-soft); border-radius: var(--r-sm);
  background: transparent; color: var(--faint); cursor: pointer; font-size: var(--t-sm);
}
.palette-trigger { transition: background-color var(--d-hover) var(--e-out), color var(--d-hover) var(--e-out), border-color var(--d-hover) var(--e-out); }
.palette-trigger:hover { background: var(--panel); color: var(--bone-dim); border-color: var(--edge); }
.palette-trigger .ic { width: 14px; height: 14px; }
.palette-trigger kbd { padding: 0 4px; border-width: 0; background: transparent; }
/* docs/52: one palette trigger per screen. The product bar's "Search or jump…"
   hands off to this button (Shell.openPalette clicks it), so when the bar is
   mounted the topbar copy is hidden — still in the DOM, still ⌘K's target. */
body:has(.pbar) .top-right .palette-trigger { display: none; }

.status-tape {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em;
  text-transform: uppercase; color: var(--faint);
  padding: 4px var(--s2);
}
.status-tape.is-live { color: var(--glacier); }
.status-tape.is-live .dot { background: var(--glacier); animation: pulse-node 1.5s linear infinite; }
.status-tape.is-bad { color: var(--ember); }
.status-tape.is-bad .dot { background: var(--ember); }
#statusClock { color: var(--faint); font-variant-numeric: tabular-nums; }

.banner {
  margin: 0 var(--s5) var(--s3);
  padding: var(--s3) var(--s4);
  border: 1px solid color-mix(in srgb, var(--ember) 35%, var(--edge));
  border-radius: var(--r-md);
  background: var(--ember-sunk);
  color: var(--ember-soft);
  font-size: var(--t-sm);
  animation: rise 180ms var(--e-out) both;
}

/* ── transcript ───────────────────────────────────────────────────────── */
.transcript {
  min-width: 0;
  overflow-y: auto; overflow-x: hidden; overscroll-behavior-y: contain;
  padding: var(--s2) var(--s5) var(--s8);
  scroll-padding-bottom: var(--s8);
  animation: rise 320ms var(--e-out) both;
}
.turns {
  position: relative;
  max-width: calc(var(--measure) + var(--gutter));
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-top: var(--s5);
}
/* the work rail — the machine's log, drawn once */
.turns.has-rail::before {
  content: "";
  position: absolute; left: 9px; top: var(--s6); bottom: var(--s6);
  width: 1px; background: var(--edge-soft);
}

/* rhythm: the gap inside a question→answer pair is smaller than the gap
   between pairs, so the transcript reads as exchanges, not a stack of blocks */
.turn { position: relative; padding-bottom: var(--s8); }
.turn:last-child { padding-bottom: var(--s4); }
.turn-node {
  position: absolute; left: calc(var(--gutter) * -1); top: 2px;
  width: 19px; height: 19px; border-radius: 50%;
  border: 1.5px solid var(--edge); background: var(--room);
  display: grid; place-items: center;
}
.turn-node::after {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--edge-strong);
  transition: background-color 160ms var(--e-out);
}
/* a live node is drawn by phase so queued ≠ thinking ≠ streaming — the shape
   carries it, not the colour (forced-colors keeps the shapes). Same table as
   the lane node in docs/43 §0.1:
     sending / queued / starting  — dotted ring, dim dot, still
     thinking                     — glacier ring, opacity pulse 1.5s linear (the only looping node)
     streaming                    — filled glacier dot; the caret in the reply carries the motion
     stopping                     — filled dot, half-dim, still
     reconnecting                 — dashed ring, bone-dim, still */
.turn.is-live .turn-node { border-color: var(--glacier); animation: node-in 180ms var(--e-out) both; }
.turn.is-live .turn-node::after { background: var(--glacier); }
.turn.is-live[data-phase="sending"] .turn-node,
.turn.is-live[data-phase="queued"] .turn-node,
.turn.is-live[data-phase="starting"] .turn-node { border-style: dotted; border-color: var(--glacier-dim); }
.turn.is-live[data-phase="sending"] .turn-node::after,
.turn.is-live[data-phase="queued"] .turn-node::after,
.turn.is-live[data-phase="starting"] .turn-node::after { background: var(--glacier-dim); }
.turn.is-live[data-phase="thinking"] .turn-node { animation: node-in 180ms var(--e-out) both, pulse-node 1.5s linear 180ms infinite; }
.turn.is-live[data-phase="streaming"] .turn-node { background: var(--glacier); }
.turn.is-live[data-phase="streaming"] .turn-node::after { background: var(--glacier); }
.turn.is-live[data-phase="stopping"] .turn-node { background: var(--glacier); border-color: var(--glacier); opacity: .5; }
.turn.is-live[data-phase="reconnecting"] .turn-node { border-style: dashed; border-color: var(--bone-dim); }
.turn.is-live[data-phase="reconnecting"] .turn-node::after { background: var(--bone-dim); }
@keyframes node-in { from { opacity: 0; transform: scale(.9); } to { opacity: 1; transform: none; } }
.turn.is-failed .turn-node { border-color: var(--ember); }
.turn.is-failed .turn-node::after { background: var(--ember); }
/* stopping is a decision, not an error — it gets the quiet treatment */
.turn.is-stopped .turn-node { border-color: var(--edge-strong); }
.turn.is-stopped .turn-node::after { background: var(--faint); }

/* the tape: which model did this, and how long it took */
.turn-tape {
  display: flex; align-items: center; gap: var(--s2);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em;
  text-transform: uppercase; color: var(--faint);
  margin-bottom: var(--s2);
  opacity: 0; transition: opacity 160ms var(--e-out);
}
.turn.is-live .turn-tape { opacity: 1; color: var(--glacier-dim); }
.turn:hover .turn-tape, .turn:focus-within .turn-tape { opacity: 1; }
.turn-tape .clock { color: var(--faint); font-variant-numeric: tabular-nums; }
.turn-tape .clock:empty { display: none; }
/* the phase word — thinking / streaming / stopping — is the honest thinking
   state; it is the only thing on the tape that changes while a turn runs */
.turn-tape .phase { color: var(--glacier); }
.turn.is-failed .turn-tape .phase { color: var(--ember); }

.turn-body {
  font-size: var(--t-body); line-height: 1.68; color: var(--bone);
  overflow-wrap: break-word;
  animation: rise 200ms var(--e-out) both;
}

/* user turn: right-aligned bubble on a raised surface; a shorter measure than
   the reply so an ask reads as an ask, not another paragraph */
.turn[data-role="user"] { padding-bottom: var(--s5); }
.turn[data-role="user"] .turn-body {
  margin-left: auto; max-width: 76%; width: fit-content;
  padding: var(--s3) var(--s4);
  line-height: 1.55;
  background: var(--panel-2);
  border: 1px solid var(--edge-soft);
  border-radius: var(--r-lg);
  white-space: pre-wrap;
}
.turn[data-role="user"] .turn-actions,
.turn[data-role="user"] .turn-tape { justify-content: flex-end; }
.turn-shots {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin: 0 0 8px;
}
.turn[data-role="user"] .turn-shots { justify-content: flex-end; }
.turn-shots img {
  width: 56px; height: 56px; object-fit: cover;
  border-radius: 8px; border: 1px solid var(--edge);
  background: var(--ink);
}

/* hover actions: hidden on old turns, resting at half strength on the latest
   reply so the affordance is discoverable without shouting */
.turn-actions {
  display: flex; align-items: center; gap: var(--s1);
  margin-top: var(--s2); margin-left: calc(var(--s2) * -1);
  opacity: 0;
  transition: opacity 140ms var(--e-out);
}
.turn.is-last .turn-actions { opacity: .55; }
.turn:hover .turn-actions, .turn:focus-within .turn-actions { opacity: 1; }
.turn.is-live .turn-actions { opacity: 0; pointer-events: none; }

.act {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 30px; padding: 0 var(--s2);
  background: transparent; border: 0; border-radius: var(--r-sm);
  font-size: var(--t-sm); color: var(--bone-dim); cursor: pointer;
  transition: background-color 130ms var(--e-out), color 130ms var(--e-out), transform var(--d-press) var(--e-out);
}
.act:hover { background: var(--panel); color: var(--bone); }
.act:active { background: var(--panel-2); }
.act.is-done { color: var(--glacier); }
.act.is-done .ic { color: var(--glacier); }
.act .ic { width: 14px; height: 14px; color: var(--faint); transition: color 130ms var(--e-out); }
.act:hover .ic { color: var(--bone); }

.turn-error {
  margin-top: var(--s3); padding: var(--s3) var(--s4);
  border: 1px solid color-mix(in srgb, var(--ember) 32%, var(--edge));
  border-left-width: 2px;
  border-radius: var(--r-sm);
  background: var(--ember-sunk);
  font-family: var(--mono); font-size: var(--t-sm); color: var(--ember-soft);
  white-space: pre-wrap;
}

.turn.is-stopped .turn-error {
  border-color: var(--edge);
  background: var(--panel);
  color: var(--bone-dim);
}

/* the trace: what Codex measurably did on the host — commands, file changes,
   tool calls — quoted from the job events, collapsed under the tape. It is
   deliberately not styled like the reply: mono, hairline, no bubble. The
   essay describes; the trace records. docs/45 finding 2 */
.trace {
  margin: 0 0 var(--s3);
  border: 1px solid var(--edge-soft);
  border-left: 2px solid var(--edge-strong);
  border-radius: var(--r-sm);
  background: var(--panel);
  font-family: var(--mono); font-size: var(--t-sm);
}
.trace.is-running { border-left-color: var(--glacier-dim); }
.trace.has-failed { border-left-color: var(--ember); }
.trace-sum {
  display: flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s3);
  font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase;
  color: var(--bone-dim); cursor: pointer; list-style: none;
}
.trace-sum::-webkit-details-marker { display: none; }
.trace-sum::before {
  content: ""; width: 6px; height: 6px; border: 1.5px solid currentColor; border-width: 0 1.5px 1.5px 0;
  transform: rotate(-45deg); transition: transform 140ms var(--e-out); flex: none; margin-right: 2px;
}
.trace[open] .trace-sum::before { transform: rotate(45deg); }
.trace-sum:hover { color: var(--bone); }
.trace-sum:focus-visible { outline: 2px solid var(--glacier); outline-offset: -2px; border-radius: var(--r-sm); }
.trace-list { margin: 0; padding: 0 var(--s3) var(--s2); list-style: none; }
.trace-list > li {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: var(--s2) var(--s3);
  padding: var(--s2) 0; border-top: 1px solid var(--edge-soft);
}
.trace-tag { color: var(--faint); }
.trace-code { font-family: var(--mono); color: var(--bone); overflow-wrap: anywhere; white-space: pre-wrap; }
.trace-meta { color: var(--faint); justify-self: end; white-space: nowrap; }
.trace-download {
  grid-column: 2 / -1;
  justify-self: start;
  color: var(--glacier);
  font-family: var(--sans);
  font-size: var(--t-sm);
  text-decoration: none;
}
.trace-download:hover { text-decoration: underline; text-underline-offset: 3px; }
.trace-download:focus-visible { outline: 2px solid var(--glacier); outline-offset: 3px; }
.trace-list > li[data-state="running"] .trace-meta { color: var(--glacier); }
.trace-list > li[data-state="failed"] .trace-meta,
.trace-list > li[data-state="failed"] .trace-tag { color: var(--ember); }
.trace-out, .trace .hunk {
  grid-column: 1 / -1;
}
.turn-generated {
  margin: 0 0 var(--s3);
  display: block;
  width: min(100%, 34rem);
  border: 1px solid var(--edge-soft);
  border-radius: 8px;
  overflow: hidden;
  background: var(--room);
}
.turn-generated a { display: block; color: inherit; text-decoration: none; }
.turn-generated img {
  display: block;
  width: 100%;
  height: auto;
}
.turn-generated figcaption {
  padding: var(--s2) var(--s3);
  border-top: 1px solid var(--edge-soft);
  font-family: var(--mono);
  font-size: var(--t-micro);
  color: var(--faint);
}
.trace-out {
  margin: 0; padding: var(--s2) var(--s3);
  background: var(--room); border: 1px solid var(--edge-soft); border-radius: 6px;
  font-size: var(--t-micro); line-height: 1.55; color: var(--bone-dim);
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 16rem; overflow: auto;
}
.trace .hunk summary { font-size: var(--t-micro); color: var(--faint); cursor: pointer; padding: 2px 0; }
.trace .hunk summary:hover { color: var(--bone); }
.trace .hunk[open] summary { margin-bottom: var(--s1); }
.turn.is-live .trace { animation: rise 200ms var(--e-out) both; }

/* the workspace viewer says where a file came from before it shows it */
.files-origin { margin: 0 0 var(--s2); color: var(--faint); }

/* the composer hint states the next Send's blast radius for a code thread */
.hint-radius strong { color: var(--bone-dim); font-weight: 600; }
.hint-radius.is-write strong { color: var(--ember); }

.think {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-family: var(--mono); font-size: var(--t-sm); color: var(--bone-dim);
}
.think::after {
  content: ""; width: 22px; height: 1px; background: var(--glacier);
  animation: sweep 1.4s var(--e-out) infinite;
}
/* in line is not at work: the queued label carries a still dotted rule */
.think[data-phase="sending"]::after, .think[data-phase="queued"]::after, .think[data-phase="starting"]::after {
  background: none; height: 0; border-top: 1px dotted var(--glacier-dim); animation: none;
}
.think[data-phase="stopping"]::after { background: var(--faint); }
.caret {
  display: inline-block; width: 2px; height: 1.05em;
  margin-left: 2px; vertical-align: -.18em;
  background: var(--glacier);
  animation: blink 1.05s steps(2, end) infinite;
}

@keyframes blink { 50% { opacity: 0; } }
@keyframes sweep {
  0% { transform: scaleX(.2); opacity: .3; transform-origin: left; }
  50% { transform: scaleX(1); opacity: 1; transform-origin: left; }
  100% { transform: scaleX(.2); opacity: .3; transform-origin: left; }
}

/* ── markdown inside a reply ──────────────────────────────────────────── */
.turn-body > :first-child { margin-top: 0; }
.turn-body > :last-child { margin-bottom: 0; }
.turn-body p { margin: 0 0 var(--s4); }
.turn-body h1, .turn-body h2, .turn-body h3, .turn-body h4 {
  margin: var(--s6) 0 var(--s3); font-weight: 600; line-height: 1.25; letter-spacing: -.008em;
}
.turn-body h1 { font-size: 1.375rem; }
.turn-body h2 { font-size: 1.1875rem; }
.turn-body h3 { font-size: 1.0625rem; }
.turn-body h4 { font-size: 1rem; color: var(--bone-dim); }
.turn-body ul, .turn-body ol { margin: 0 0 var(--s4); padding-left: 1.35em; }
.turn-body li { margin-bottom: var(--s2); }
.turn-body li::marker { color: var(--faint); }
.turn-body strong { font-weight: 600; color: var(--strong-fg); }
.turn-body em { font-style: italic; }
.turn-body blockquote {
  margin: 0 0 var(--s4); padding: var(--s1) 0 var(--s1) var(--s4);
  border-left: 2px solid var(--edge-strong); color: var(--bone-dim);
}
.turn-body hr { border: 0; border-top: 1px solid var(--edge-soft); margin: var(--s6) 0; }
.turn-body code {
  font-family: var(--mono); font-size: .875em;
  padding: .12em .34em; border-radius: var(--r-sm);
  background: var(--panel); border: 1px solid var(--edge-soft);
  color: var(--code-fg);
}
.turn-body table {
  width: 100%; border-collapse: collapse; margin: 0 0 var(--s4);
  font-size: var(--t-sm);
}
.turn-body th, .turn-body td {
  text-align: left; padding: var(--s2) var(--s3);
  border-bottom: 1px solid var(--edge-soft);
}
.turn-body th { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.turn-body td { font-variant-numeric: tabular-nums; }

/* a code block is inset content, not a floating object: hairline, no shadow */
.turn-body pre {
  position: relative;
  margin: 0 0 var(--s4); padding: var(--s4);
  background: var(--panel); border: 1px solid var(--edge-soft);
  border-radius: var(--r-md);
  overflow-x: auto;
}
/* the language, reported in the machine's voice */
.turn-body pre[data-lang]::before {
  content: attr(data-lang);
  position: absolute; top: var(--s2); left: var(--s3);
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); pointer-events: none;
}
.turn-body pre[data-lang] { padding-top: var(--s7); }
.turn-body pre code {
  padding: 0; background: none; border: 0; border-radius: 0;
  font-size: .8125rem; line-height: 1.6; color: var(--code-fg);
}
.code-copy {
  position: absolute; top: 6px; right: 6px;
  min-height: 26px; padding: 0 var(--s2);
  border: 1px solid var(--edge); border-radius: var(--r-sm);
  background: var(--panel-2); color: var(--faint);
  font-family: var(--mono); font-size: 11px; cursor: pointer;
  opacity: 0;
  transition: opacity 140ms var(--e-out), color 140ms var(--e-out), background-color 140ms var(--e-out);
}
.turn-body pre:hover .code-copy, .code-copy:focus-visible, .code-copy.is-done { opacity: 1; }
.code-copy:hover { color: var(--bone); background: var(--edge); }
.code-copy.is-done { color: var(--glacier); border-color: var(--glacier-dim); }
.tok-kw { color: var(--tok-kw); }
.tok-str { color: var(--tok-str); }
.tok-num { color: var(--tok-num); }
.tok-com { color: var(--faint); font-style: italic; }

/* ── empty state ──────────────────────────────────────────────────────── */
/* pulled back out of the rail gutter so the headline lines up with the slab */
.empty, .state-block { margin-left: calc(var(--gutter) * -1); }

.empty {
  max-width: calc(var(--measure) + var(--gutter));
  padding: clamp(var(--s7), 8vh, var(--s10)) 0 var(--s7);
  animation: rise 300ms 80ms var(--e-out) both;
}
.empty .display { margin-bottom: var(--s4); max-width: 24ch; }
/* a re-read of the lane is a handoff on the display line, not a second arrival wave */
.empty.is-handoff, .empty.is-handoff .empty-rail { animation: none; }
/* the work rail, idle, before the first turn (docs/30 move 1): one node in the
   gutter where the first reply's node will sit, plus the tape reporting the
   slot. Real state — the worker is serialized and this is its one slot. */
.empty-rail {
  display: flex; align-items: center; gap: var(--s3);
  margin-bottom: var(--s6);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint);
  animation: rise 240ms 120ms var(--e-out) both;
}
.empty-rail .turn-node { position: relative; left: auto; top: auto; flex: none; }
.empty-rail .turn-node::after { background: var(--edge-strong); }
/* held by another thread: the same "thinking" ring as a live turn, pulsing */
.empty-rail.is-live .turn-node { border-color: var(--glacier); animation: pulse-node 1.5s linear infinite; }
.empty-rail.is-live .turn-node::after { background: var(--glacier); }
.empty-rail b { font-weight: 400; color: var(--bone-dim); }
.empty-rail .rail-line { flex: 1; height: 1px; background: var(--edge-soft); max-width: 120px; }
.empty-lede { font-size: var(--t-ui); color: var(--bone-dim); max-width: 56ch; margin-bottom: var(--s6); }
.empty-lede em { color: var(--bone); font-style: normal; }

/* the desk, reported: real state from /v1/meta, /v1/auth/account and the
   thread list — not decoration */
.desk {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
  margin-bottom: var(--s7);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase;
  color: var(--faint);
}
.desk span { display: inline-flex; align-items: center; gap: 6px; }
.desk b { font-weight: 400; color: var(--bone-dim); }
.desk .dot { width: 5px; height: 5px; }

/* starters as an editorial list — hairlines, not a card grid */
.empty .tape { margin-bottom: var(--s2); }
.prompts { display: grid; border-top: 1px solid var(--edge-soft); }
.prompt {
  display: grid; grid-template-columns: 3.25rem minmax(0, 1fr) auto 14px; align-items: baseline; column-gap: var(--s4);
  width: 100%; text-align: left;
  padding: var(--s3) var(--s2) var(--s3) 0;
  background: transparent;
  border: 0; border-bottom: 1px solid var(--edge-soft); border-radius: 0;
  cursor: pointer;
  position: relative; isolation: isolate;
}
/* hover surface bleeds 8px past the hairlines on a pseudo-element, so the text
   never moves and only opacity animates */
.prompt::before {
  content: ""; position: absolute; inset: 2px calc(var(--s2) * -1); z-index: -1;
  border-radius: var(--r-sm); background: var(--panel);
  opacity: 0; transition: opacity 150ms var(--e-out);
}
.prompt:hover::before, .prompt:focus-visible::before { opacity: 1; }
.prompt:focus-visible { outline-offset: 4px; border-radius: 2px; }
/* docs/59: every child is pinned to its column, so a missing or extra node
   can never shove copy into the 14 px chevron track */
.prompt .pk { grid-column: 1; font-family: var(--mono); font-size: 10px; letter-spacing: .11em; text-transform: uppercase; color: var(--glacier-dim); }
.prompt .pt { grid-column: 2; min-width: 0; font-size: var(--t-ui); font-weight: 500; color: var(--bone); }
.prompt .pp { grid-column: 3; font-size: var(--t-sm); color: var(--faint); white-space: nowrap; }
.prompt .ic { grid-column: 4; align-self: center; width: 14px; height: 14px; color: var(--faint); transform: rotate(-90deg); transition: transform 150ms var(--e-out), color 150ms var(--e-out); }
.prompt:hover .ic { color: var(--bone); transform: translateX(2px) rotate(-90deg); }

.state-block { max-width: calc(var(--measure) + var(--gutter)); padding: var(--s9) 0; }
.state-block h2 { font-size: var(--t-title); font-weight: 600; margin-bottom: var(--s2); }
.state-block p { font-size: var(--t-ui); color: var(--bone-dim); max-width: 52ch; }
.state-block .tape { margin-bottom: var(--s3); }

/* ── jump to latest ───────────────────────────────────────────────────── */
.jump {
  position: absolute; left: 50%; bottom: calc(var(--s10) + var(--s8)); z-index: var(--z-jump);
  transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 32px; padding: 0 var(--s3);
  border-radius: var(--r-md); border: 1px solid var(--edge);
  background: var(--panel-2); color: var(--bone-dim);
  font-size: var(--t-sm); cursor: pointer;
  box-shadow: var(--sh-2);
  animation: rise 160ms var(--e-out) both;
  transition: color 140ms var(--e-out), border-color 140ms var(--e-out);
}
.jump:hover { color: var(--bone); border-color: var(--edge-strong); }

/* ── composer: the one lit instrument ─────────────────────────────────── */
.composer-wrap {
  position: relative; z-index: var(--z-composer);
  padding: 0 var(--s5) var(--s4);
  animation: rise 340ms 90ms var(--e-out) both;
}
/* functional scrim so the transcript doesn't guillotine into the slab */
.composer-wrap::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 56px;
  pointer-events: none;
  background: linear-gradient(to top, var(--room), transparent);
}
.composer { max-width: 48rem; margin: 0 auto; }

.slab {
  display: grid; gap: var(--s2);
  /* the single track must be allowed to shrink below its content, or the
     foot row's nowrap controls push Send off a phone screen */
  grid-template-columns: minmax(0, 1fr);
  padding: var(--s3) var(--s3) var(--s2);
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-2);
  isolation: isolate;
  transition: border-color 160ms var(--e-out), box-shadow 160ms var(--e-out);
}
/* machined top highlight — 1px, not a glow */
.slab { background-image: linear-gradient(to bottom, var(--slab-sheen), transparent 2px); }
.slab:focus-within { border-color: var(--edge-strong); box-shadow: var(--sh-3); }
/* the textarea has no ring of its own, so keyboard focus lights the whole slab */
.slab:has(textarea:focus-visible) { border-color: var(--glacier-dim); }
.composer.is-live .slab { border-color: var(--glacier-dim); }

.slab textarea {
  width: 100%; resize: none; border: 0; outline: none;
  background: none; color: var(--bone);
  font-size: var(--t-body); line-height: 1.6;
  padding: var(--s2) var(--s2) 0;
  max-height: 240px; overflow-y: auto;
}
.slab textarea::placeholder { color: var(--faint); }
.slab textarea:disabled { color: var(--bone-dim); }

.attach-chips {
  display: flex; flex-wrap: wrap; gap: var(--s2);
  padding: 2px var(--s2) var(--s1);
}
.attach-chip {
  position: relative;
  width: 44px; height: 44px; flex: none;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--edge);
  background: var(--ink);
}
.attach-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.attach-chip .drop {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; padding: 0;
  border: 0; border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--ink) 72%, transparent); color: var(--bone);
  cursor: pointer; display: grid; place-items: center;
}
.attach-chip .drop .ic { width: 10px; height: 10px; }

.attach-btn {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; flex: none;
  border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--faint); cursor: pointer;
  transition: background-color 140ms var(--e-out), color 140ms var(--e-out), transform var(--d-press) var(--e-out);
}
.attach-btn:hover { background: var(--panel-2); color: var(--bone); }
.attach-btn.is-on { color: var(--bone); }

.slab-foot { display: flex; align-items: center; gap: var(--s1); min-width: 0; }
.slab-left { display: flex; align-items: center; gap: var(--s1); min-width: 0; flex: 1 1 auto; }
.slab-right { display: flex; align-items: center; gap: var(--s2); flex: none; }

/* the controls inside the slab are all one quiet ghost family — no wells, no
   pills fighting Send; only the checked segment and the hover surface light up */
.seg {
  display: inline-flex; padding: 2px; flex: none; gap: 1px;
  border-radius: var(--r-md);
}
.seg button {
  min-height: 26px; padding: 0 var(--s3);
  border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--faint);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase;
  cursor: pointer;
  transition: background-color 140ms var(--e-out), color 140ms var(--e-out);
}
.seg button { display: inline-flex; align-items: center; }
.seg button:hover { color: var(--bone-dim); background: var(--panel-2); }
.seg button[aria-checked="true"] { background: var(--edge); color: var(--bone); }

.kind-chip {
  flex: none; padding: 0 var(--s3); min-height: 30px;
  display: inline-flex; align-items: center;
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em;
  text-transform: uppercase; color: var(--faint);
}

.sandbox-chip {
  flex: none; min-height: 30px; padding: 0 var(--s3);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  background: transparent; color: var(--bone-dim);
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .06em;
  text-transform: uppercase; cursor: pointer;
}
.sandbox-chip:hover { background: var(--panel-2); color: var(--bone); }
.sandbox-chip.is-write { border-color: var(--ember); color: var(--ember-soft); background: var(--ember-sunk); }
.sandbox-chip:focus-visible { outline: 2px solid var(--glacier); outline-offset: 2px; }

.model-btn {
  display: inline-flex; align-items: center; gap: 6px;
  flex: 0 1 auto; min-width: 0;
  min-height: 30px; padding: 0 var(--s2) 0 var(--s3);
  border: 1px solid transparent; border-radius: var(--r-md);
  background: transparent; color: var(--bone-dim);
  font-size: var(--t-sm); cursor: pointer;
  white-space: nowrap; overflow: hidden;
  transition: background-color 140ms var(--e-out), border-color 140ms var(--e-out), color 140ms var(--e-out);
}
.model-btn:hover { background: var(--panel-2); color: var(--bone); }
.model-btn[aria-expanded="true"] { background: var(--panel-2); border-color: var(--edge); color: var(--bone); }
.model-btn > span { overflow: hidden; text-overflow: ellipsis; }
.model-btn .sep { color: var(--edge-strong); flex: none; }
.model-btn .effort { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.model-btn .chev { width: 14px; height: 14px; color: var(--faint); }

.btn-send {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 34px; height: 34px; flex: none; padding: 0;
  border: 0; border-radius: var(--r-md);
  background: var(--bone); color: var(--on-bone); cursor: pointer;
  transition: background-color 140ms var(--e-out), color 140ms var(--e-out), transform 140ms var(--e-out);
}
.btn-send:hover { background: var(--bone-hi); }
.btn-send:active { transform: scale(.94); }
.btn-send:disabled { background: var(--panel-2); color: var(--faint); cursor: not-allowed; transform: none; }
.btn-send.is-steer {
  width: auto; padding: 0 var(--s3) 0 var(--s2); border-radius: var(--r-md);
  font-size: var(--t-sm); font-weight: 500;
}
.btn-send.is-steer .ic { width: 14px; height: 14px; }

.btn-stop {
  display: grid; place-items: center;
  width: 34px; height: 34px; flex: none;
  border: 1px solid var(--edge-strong); border-radius: var(--r-md);
  background: transparent; color: var(--bone); cursor: pointer;
  transition: background-color 140ms var(--e-out), border-color 140ms var(--e-out), transform var(--d-press) var(--e-out);
  animation: pop var(--d-hover) var(--e-out) both;
}
.btn-stop:hover { background: var(--panel-2); border-color: var(--bone-dim); }
.btn-stop .ic { width: 12px; height: 12px; }

.hint { margin-top: var(--s2); font-size: var(--t-micro); color: var(--faint); text-align: center; }
.composer .error-text { text-align: center; }

/* ── menus ────────────────────────────────────────────────────────────── */
.menu {
  position: fixed; z-index: var(--z-menu); top: 0; left: 0;
  min-width: 15rem; max-width: min(22rem, calc(100vw - 24px));
  padding: var(--s2);
  background: var(--panel-2);
  border: 1px solid var(--edge-strong);
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);
  animation: pop 140ms var(--e-out) both;
}
.menu-sec + .menu-sec { border-top: 1px solid var(--edge); margin-top: var(--s2); padding-top: var(--s2); }
.menu-label { padding: var(--s1) var(--s2) var(--s2); }
.menu-opts { display: grid; gap: 1px; }
.menu-opts button {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; text-align: left;
  min-height: 34px; padding: 0 var(--s2);
  border: 0; border-radius: 6px;
  background: transparent; color: var(--bone-dim);
  font-size: var(--t-sm); cursor: pointer;
  transition: background-color 130ms var(--e-out), color 130ms var(--e-out);
}
.menu-opts button:hover { background: var(--panel); color: var(--bone); }
.menu-opts button[aria-checked="true"] { color: var(--bone); }
.menu-opts .mk { flex: none; width: 14px; height: 14px; color: var(--glacier); opacity: 0; }
.menu-opts button[aria-checked="true"] .mk { opacity: 1; }
.menu-opts .ml { flex: 1; min-width: 0; }
.menu-opts .mr { font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.menu-foot { padding: var(--s2) var(--s2) var(--s1); font-size: var(--t-micro); color: var(--faint); border-top: 1px solid var(--edge); margin-top: var(--s2); }

.thread-menu { min-width: 13rem; }
.thread-menu button {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; text-align: left; min-height: 34px; padding: 0 var(--s2);
  border: 0; border-radius: 6px; background: transparent; color: var(--bone-dim);
  font-size: var(--t-sm); cursor: pointer;
  transition: background-color 130ms var(--e-out), color 130ms var(--e-out);
}
.thread-menu button:hover { background: var(--panel); color: var(--bone); }
.thread-menu button .ic { width: 14px; height: 14px; color: var(--faint); flex: none; }
.thread-menu button:hover .ic { color: var(--bone-dim); }
.thread-menu button.danger { color: var(--ember); }
.thread-menu button.danger .ic, .thread-menu button.danger:hover .ic { color: var(--ember); }
.thread-menu button.danger:hover { background: var(--ember-sunk); }
.menu-rule { height: 1px; background: var(--edge); margin: var(--s2) 0; }

/* ── dialogs ──────────────────────────────────────────────────────────── */
.modal {
  width: min(28rem, calc(100vw - 32px));
  padding: var(--s6);
  border: 1px solid var(--edge-strong); border-radius: var(--r-lg);
  background: var(--panel); color: var(--bone);
  box-shadow: var(--sh-3);
}
.modal::backdrop { background: var(--scrim, rgba(6, 8, 11, .68)); }
.modal[open] { animation: pop 160ms var(--e-out) both; }
.modal h2 { font-size: var(--t-title); font-weight: 600; margin-bottom: var(--s2); }
.modal p { font-size: var(--t-ui); color: var(--bone-dim); }
.modal label {
  display: block; margin: var(--s5) 0 6px;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .09em; text-transform: uppercase; color: var(--faint);
}
.modal input[type="text"], .modal input:not([type]) {
  width: 100%; min-height: 40px; padding: 0 var(--s3);
  background: var(--ink); color: var(--bone);
  border: 1px solid var(--edge); border-radius: var(--r-md);
}
.modal select {
  width: 100%; min-height: 40px; padding: 0 var(--s3);
  background: var(--ink); color: var(--bone);
  border: 1px solid var(--edge); border-radius: var(--r-md);
}
.modal-actions { display: flex; justify-content: flex-end; gap: var(--s2); margin-top: var(--s6); }
.share-members {
  margin-top: var(--s4);
  padding-top: var(--s3);
  border-top: 1px solid var(--edge);
  font-size: var(--t-sm) !important;
}

.command-dialog {
  width: min(38rem, calc(100vw - 24px)); max-height: min(34rem, calc(100dvh - 40px));
  margin: max(10vh, 32px) auto auto; padding: 0;
  border: 1px solid var(--edge-strong); border-radius: var(--r-lg);
  background: var(--panel); color: var(--bone); box-shadow: var(--sh-3); overflow: hidden;
}
.command-dialog::backdrop { background: var(--scrim, rgba(6, 8, 11, .64)); backdrop-filter: blur(2px); }
/* ⌘K is a hundred-times-a-day action: no travel, no scale. A 90ms opacity
   fade is the most it gets, and close is a hard cut. */
.command-dialog[open] { animation: fade 90ms var(--e-out) both; }
.command-search {
  display: flex; align-items: center; gap: var(--s3); min-height: 58px;
  padding: 0 var(--s4); border-bottom: 1px solid var(--edge);
}
.command-search .tape { color: var(--glacier-dim); }
.command-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; font-size: var(--t-body); }
.command-search input::placeholder { color: var(--faint); }
.command-results { max-height: min(27rem, calc(100dvh - 120px)); overflow-y: auto; padding: var(--s2); }
.command-group { padding: var(--s2) var(--s2) var(--s1); }
.command-option {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s2);
  width: 100%; min-height: 42px; padding: 0 var(--s3);
  border: 0; border-radius: var(--r-sm); background: transparent; color: var(--bone-dim);
  text-align: left; cursor: pointer;
  transition: transform var(--d-press) var(--e-out);
}
.command-option:hover, .command-option.is-active { background: var(--panel-2); color: var(--bone); }
.command-option .ic { display: none; }
.command-option::before { content: ""; position: absolute; left: 0; top: 11px; bottom: 11px; width: 1.5px; background: var(--glacier); opacity: 0; }
.command-option.is-active::before { opacity: 1; }
.command-empty.is-busy::after { display: block; margin: var(--s3) auto 0; }
.command-option .command-label { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.command-option .command-meta { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--faint); }
.command-empty { padding: var(--s6); text-align: center; color: var(--faint); font-size: var(--t-sm); }

.capability-body { display: grid; gap: 1px; overflow: hidden; border: 1px solid var(--edge-soft); border-radius: var(--r-md); background: var(--edge-soft); }
.capability-body dl { display: contents; margin: 0; }
.capability-row { display: grid; grid-template-columns: 10rem minmax(0, 1fr); gap: var(--s3); padding: var(--s3) var(--s4); background: var(--room); }
.capability-row dt { font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.capability-row dd { margin: 0; color: var(--bone-dim); overflow-wrap: anywhere; }
.capability-row code { font-family: var(--mono); font-size: var(--t-sm); color: var(--bone); }

/* docs/59: flex, not a fixed-column grid. A stale index.html once carried an
   extra leading icon into a `minmax(0,1fr) 14px` grid and the copy landed in
   the 14 px chevron column ("Connectt IDE"). Flex places any number of icons
   beside the copy; the copy keeps a real floor and the title never breaks. */
.ide-entry {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; min-width: 0; padding: var(--s3); margin-bottom: var(--s3);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  background: var(--room); color: var(--bone-dim); text-align: left; cursor: pointer;
}
.ide-entry:hover { border-color: var(--edge-strong); color: var(--bone); }
.ide-entry .ic { flex: none; width: 14px; height: 14px; color: var(--glacier-dim); }
.ide-entry .ic:last-child { margin-left: auto; }
.ide-entry > span { flex: 1 1 auto; display: grid; gap: 2px; min-width: min(10ch, 100%); }
.ide-entry strong {
  font-size: var(--t-sm); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  overflow-wrap: normal; word-break: normal;
}
.ide-entry small { color: var(--faint); font-family: var(--mono); font-size: var(--t-micro); overflow-wrap: normal; }
.ide-entry .ide-url {
  font-family: var(--mono); font-size: var(--t-micro); color: var(--bone-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ide-card .ide-copy-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); }
.ide-card .ide-copy-row code { flex: 1 1 12ch; min-width: 0; }
.ide-card .ide-copy-row .btn-quiet { flex: none; }
.ide-card { display: grid; gap: var(--s4); }
.ide-card code { font-family: var(--mono); color: var(--bone); overflow-wrap: anywhere; }
.ide-card dl { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1px; margin: 0; background: var(--edge-soft); border: 1px solid var(--edge-soft); border-radius: var(--r-md); overflow: hidden; }
.ide-card dl div { padding: var(--s4); background: var(--room); }
.ide-card dt { margin-bottom: var(--s2); font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--faint); }
.ide-card dd { margin: 0; color: var(--bone-dim); line-height: 1.5; }
.ide-actions { display: flex; flex-wrap: wrap; gap: var(--s2); }
.ide-actions a { text-decoration: none; }

.modal-wide { width: min(52rem, calc(100vw - 32px)); }
/* a filesystem path is data, not a label — never upper-case it */
#filesPath {
  text-transform: none; letter-spacing: 0; font-size: var(--t-sm);
  color: var(--bone-dim); word-break: break-all; margin-top: 2px;
}
.modal .upload-label {
  margin: 0; text-transform: none; letter-spacing: normal;
  font-family: var(--sans); font-size: var(--t-ui); color: var(--bone);
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s4); }
.files-body {
  display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 1px;
  background: var(--edge-soft);
  border: 1px solid var(--edge-soft); border-radius: var(--r-md);
  overflow: hidden;
  min-height: 18rem;
}
.files-list { background: var(--ink); overflow-y: auto; max-height: 24rem; padding: var(--s2); }
.files-list button {
  display: flex; align-items: center; gap: var(--s2);
  width: 100%; text-align: left; min-height: 32px; padding: 0 var(--s2);
  border: 0; border-radius: 6px; background: transparent; color: var(--bone-dim);
  font-family: var(--mono); font-size: var(--t-sm); cursor: pointer;
  transition: background-color 130ms var(--e-out), color 130ms var(--e-out);
}
.files-list button:hover { background: var(--panel); color: var(--bone); }
.files-list button.is-active { background: var(--panel-2); color: var(--bone); }
.files-list button .ic { color: var(--faint); }
.files-list button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.files-view { background: var(--room); overflow: auto; max-height: 24rem; padding: var(--s4); }
.files-view pre { margin: 0; font-family: var(--mono); font-size: var(--t-sm); line-height: 1.6; color: var(--code-fg); white-space: pre; }
.files-empty { font-size: var(--t-sm); color: var(--faint); }
.files-download { display: inline-flex; margin: 0 0 var(--s3); text-decoration: none; }
.files-actions { align-items: center; justify-content: space-between; }
.upload-label { cursor: pointer; }

@keyframes rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes pop {
  from { opacity: 0; transform: translateY(4px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ── narrow ───────────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  :root { --rail: 240px; }
  .transcript { padding-left: var(--s4); padding-right: var(--s4); }
  .composer-wrap { padding-left: var(--s4); padding-right: var(--s4); }
  .topbar { padding-left: var(--s4); padding-right: var(--s4); }
}

@media (max-width: 720px) {
  :root { --gutter: 0px; }

  .app { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed; z-index: var(--z-rail); inset: 0 auto 0 0;
    width: min(19rem, 86vw);
    transform: translateX(-101%);
    transition: transform 220ms var(--e-out);
    animation: none;
    border-right: 1px solid var(--edge);
    padding-top: max(var(--s4), env(safe-area-inset-top));
  }
  .sidebar.is-open { transform: none; }
  .side-close { display: inline-grid; }
  .rail-toggle { display: inline-grid; }
  .ide-card dl { grid-template-columns: 1fr; }

  .topbar { min-height: 52px; padding-top: max(var(--s2), env(safe-area-inset-top)); }
  .top-title h1 { font-size: var(--t-ui); }
  #statusClock { display: none; }

  .turns { padding-left: 0; padding-top: var(--s3); }
  .turns.has-rail::before { display: none; }
  /* the rail collapses: node and tape share one line above the reply */
  .turn[data-role="assistant"] {
    display: grid; grid-template-columns: 19px minmax(0, 1fr); column-gap: var(--s2);
    align-items: center; padding-bottom: var(--s7);
  }
  .turn[data-role="assistant"] .turn-node { position: static; grid-column: 1; grid-row: 1; }
  .turn[data-role="assistant"] .turn-tape { grid-column: 2; grid-row: 1; margin: 0; min-width: 0; }
  .turn-tape > span:first-child { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  .turn-tape .phase, .turn-tape .clock { flex: none; }
  .turn[data-role="assistant"] .turn-body,
  .turn[data-role="assistant"] .turn-error,
  .turn[data-role="assistant"] .turn-actions { grid-column: 1 / -1; }
  .turn[data-role="assistant"] .turn-body { margin-top: var(--s3); }
  .turn[data-role="user"] .turn-node { display: none; }
  .turn[data-role="user"] .turn-body { max-width: 92%; }
  .turn-actions { opacity: 1; margin-left: 0; }
  .turn-tape { opacity: 1; }
  .turn-tape .phase { color: var(--glacier); }

  .topbar .status-tape { padding-right: 0; }
  .palette-trigger span, .palette-trigger kbd { display: none; }

  .composer-wrap { padding-bottom: max(var(--s3), env(safe-area-inset-bottom)); }
  .slab { border-radius: var(--r-lg); padding: var(--s3) var(--s2) var(--s2); }
  .slab textarea { font-size: 16px; }
  .seg button { padding: 0 var(--s2); min-height: 32px; }
  .model-btn { min-height: 32px; }
  .hint { display: none; }
  .jump { bottom: calc(var(--s10) + var(--s7)); }

  .empty { padding-top: var(--s6); }
  .empty .display { font-size: 2.125rem; }
  .prompt { grid-template-columns: minmax(0, 1fr) 14px; row-gap: 2px; padding-right: var(--s1); }
  .prompt .pk { grid-column: 1; }
  .prompt .pt { grid-column: 1; }
  .prompt .pp { grid-column: 1; white-space: normal; }
  .prompt .ic { grid-column: 2; grid-row: 1 / span 3; }

  .files-body { grid-template-columns: minmax(0, 1fr); }
  .files-list { max-height: 11rem; }
  .capability-row { grid-template-columns: minmax(0, 1fr); gap: 2px; }

  .icon-btn, .act, .attach-btn, .later-drop { min-height: 40px; }
  .icon-btn, .attach-btn { width: 40px; height: 40px; }
  .later-drop { width: 40px; height: 40px; }
  .gate { padding-top: var(--s7); }
}

@media (max-width: 480px) {
  /* phones: the effort still lives in the popover and the aria-label; the
     model name keeps the room so nothing ellipsizes mid-word */
  .model-btn .effort, .model-btn .sep { display: none; }
  .desk { gap: var(--s2) var(--s4); }
}

@media (hover: none) {
  .turn-actions, .code-copy, .turn-tape { opacity: 1; }
}

/* ── reduced motion: fewer and gentler, not a corpse ─────────────────────
   Entrances keep a 200ms opacity fade and lose their travel. Loops that mean
   "the machine is busy" stay visible as a slow opacity breath — a wait that
   looks finished is a lie. Anything that moves for feel (press dip, chevron
   spin, arrow nudge, rail slide) is removed outright. */
@media (prefers-reduced-motion: reduce) {
  @keyframes rise    { from { opacity: 0; } to { opacity: 1; } }
  @keyframes pop     { from { opacity: 0; } to { opacity: 1; } }
  @keyframes node-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes sweep        { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
  @keyframes sweep-center { 0%, 100% { opacity: .35; transform: translate(-50%, -50%); } 50% { opacity: 1; transform: translate(-50%, -50%); } }
  @keyframes pulse-node   { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
  @keyframes blink        { 50% { opacity: .35; } }

  .sidebar, .transcript, .topbar, .composer-wrap, .gate-col, .empty, .empty-rail,
  .turn-body, .banner, .jump, .device { animation-duration: 200ms; animation-delay: 0ms; }
  .menu, .modal[open], .project-panel, .command-dialog[open], .btn-stop { animation-duration: 120ms; }
  .think::after, .is-busy::after, .btn-solid.is-busy::after, .btn-outline.is-busy::after,
  .btn-danger.is-busy::after, .btn-quiet.is-busy::after,
  .status-tape.is-live .dot, .chat-item.is-live .meta b::before, .boot-node { animation-duration: 2s; animation-timing-function: linear; }
  .caret { animation-duration: 1.6s; }

  .sidebar { transition: none; }
  .icon-btn, .act, .attach-btn, .btn-stop, .later-drop, .project-item, .command-option,
  .btn-solid, .btn-send { transition-property: background-color, border-color, color; }
  .icon-btn:active, .act:active, .attach-btn:active, .btn-stop:active, .later-drop:active,
  .project-item:active, .command-option:active, .btn-solid:active, .btn-send:active { transform: none; }
  .project-switcher .chev { transition: none; }
  .prompt .ic { transition: color 150ms var(--e-out); }
  .prompt:hover .ic { transform: rotate(-90deg); }
  .skip-link { transition: none; }
  html, .transcript { scroll-behavior: auto !important; }
}

/* ── forced colors ────────────────────────────────────────────────────── */
@media (forced-colors: active) {
  .slab, .menu, .modal, .chat-item.is-active, .turn[data-role="user"] .turn-body,
  .turn-node, .seg button[aria-checked="true"], .btn-send, .btn-stop { border: 1px solid CanvasText; }
  .prompt { border-bottom: 1px solid CanvasText; }
  .turns.has-rail::before, body::before, .composer-wrap::before { display: none; }
  .turn-actions, .turn-tape, .code-copy { opacity: 1; }
  /* loaders must survive without colour: the hairlines and rings take CanvasText */
  .is-busy::after, .think::after, .caret, .chat-item.is-live .meta b::before { background: CanvasText; }
  .empty-rail .turn-node { border-color: CanvasText; }
  .btn-solid.is-busy::after, .btn-danger.is-busy::after, .btn-outline.is-busy::after { background: CanvasText; }
  /* the trace keeps its state as text ("failed", "running"), so colour loss is safe */
  .trace, .trace-out { border-color: CanvasText; }
  .trace-list > li[data-state="failed"] .trace-tag::after { content: " !"; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Shell integration + one-step gate (docs/43 §1, docs/44 §2–3). Appended so
   it layers over the Night Desk rules above without touching their cascade.
   ══════════════════════════════════════════════════════════════════════════ */

/* the product bar owns the top 48px; every full-height layer sits below it */
.app { height: calc(100dvh - var(--bar-h)); }
.gate, .boot { top: var(--bar-h); }
.sidebar { padding-top: var(--s3); }
.side-top { padding: 0 var(--s2) var(--s3); align-items: center; }
.side-kicker { padding-left: var(--s1); }

/* display type at editorial scale — one moment per surface (30 move 2, 43 §0.4) */
.gate-display, .empty .display {
  font-size: clamp(3rem, 6.4vw, 5.25rem);
  line-height: 1.0;
  letter-spacing: -.018em;
  text-wrap: balance;
}
.gate-kicker { margin-bottom: var(--s2); }
.gate-col { max-width: 33rem; }
.gate-head { margin-bottom: var(--s6); }
.gate-head .display { margin: var(--s3) 0 var(--s3); }
.gate-col > * { animation: rise 260ms var(--e-out) both; animation-delay: calc((var(--arrive, 1) - 1) * 60ms); }
.gate-col { animation: none; }

/* the door: name + password, one button */
.door { background: transparent; padding: 0; margin-bottom: var(--s5); }
.door.is-done { display: none; }
.login-form .fld { display: grid; gap: 6px; }
.login-grid { display: grid; gap: var(--s3); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.login-form label {
  font-family: var(--mono); font-size: var(--t-micro); letter-spacing: .09em; text-transform: uppercase; color: var(--faint);
}
.login-form input {
  width: 100%; min-height: 44px; padding: 0 var(--s3);
  background: var(--room); color: var(--bone);
  border: 1px solid var(--edge); border-radius: var(--r-md);
  transition: border-color 140ms var(--e-out), background-color 140ms var(--e-out);
}
.login-form input::placeholder { color: var(--faint); }
.login-form input:hover { border-color: var(--edge-strong); }
.login-form input:focus-visible { border-color: var(--glacier); outline-offset: 1px; }
.login-row { margin-top: var(--s4); align-items: center; }
.login-row .btn-solid { min-height: 44px; padding: 0 var(--s5); }
.login-row .btn-solid .ic { margin-left: 2px; }
.login-next { color: var(--glacier-dim); }

/* the host row: one state, one sentence, one action */
.host-row {
  display: grid; gap: var(--s3);
  padding: var(--s4) var(--s4) var(--s4) var(--s3);
  border: 1px solid var(--edge-soft); border-radius: var(--r-lg);
  background: var(--room);
  transition: opacity 200ms var(--e-out), border-color 240ms var(--e-out);
}
.host-row.is-locked { opacity: .55; }
.host-row.is-locked .host-actions, .host-row.is-locked .host-note { display: none; }
.host-row.is-connected { border-color: var(--edge-soft); }
.host-row-top { display: grid; grid-template-columns: 18px minmax(0, 1fr) auto; column-gap: var(--s3); align-items: start; }
.host-row-text h2 { font-size: var(--t-ui); font-weight: 600; }
.host-row .acct-line { margin: 2px 0 0; }
.host-state { padding-top: 3px; white-space: nowrap; }
.host-row.is-connected .host-state { color: var(--glacier); }
.host-actions { padding-left: 30px; }
.host-actions:empty { display: none; }
.host-note { padding-left: 30px; font-size: var(--t-sm); color: var(--bone-dim); }

/* the lane node — the product's one signature, at rest (docs/43 §0.1).
   Shape carries state; colour confirms it. */
.lane-node {
  position: relative; display: inline-block; width: 10px; height: 10px; margin-top: 5px;
  border-radius: 50%; border: 1.5px solid var(--faint); background: transparent;
}
.lane-node[data-state="settled"] { border-color: var(--glacier); background: var(--glacier); }
.lane-node[data-state="queued"] { border-style: dotted; }
.lane-node[data-state="thinking"] { border-color: var(--glacier); animation: pulse-node 1.5s linear infinite; }
.lane-node[data-state="failed"] { border-color: var(--ember); }

/* the lamp: the one ground change the product ever draws (43 §0.2). Bone with
   ink type in the night; in the day the same slab goes ink with bone type —
   still the one object on the page that is lit differently from the room. */
.device.lamp {
  margin: var(--s2) 0 0 30px; padding: var(--s5);
  background: var(--lamp-bg); color: var(--lamp-fg); border-color: var(--lamp-bg); border-radius: var(--r-lg);
  box-shadow: var(--sh-2);
}
.device.lamp .tape { color: var(--lamp-tape); }
.device.lamp .device-code { color: var(--lamp-fg); letter-spacing: .18em; font-size: clamp(1.5rem, 6vw, 1.875rem); }
.device.lamp .device-wait { color: var(--lamp-sub); }
.device.lamp a { color: var(--lamp-link); text-decoration-color: var(--lamp-link); }
.device.lamp .lamp-copy { color: var(--lamp-fg); border: 1px solid var(--lamp-edge); min-height: 34px; }
.device.lamp .lamp-copy:hover { background: var(--lamp-hi); color: var(--lamp-fg); }
.device.lamp .device-wait.is-busy::after { background: var(--lamp-fg); }
/* the glacier ring needs an ink offset to read on the lamp (docs/43 §8 risks) */
.device.lamp :focus-visible { outline-color: var(--lamp-link); outline-offset: 3px; }

/* the gate foot loses the mantra's weight */
.gate-foot { max-width: 52ch; }

@media (max-width: 720px) {
  .login-grid { grid-template-columns: minmax(0, 1fr); }
  .host-row-top { grid-template-columns: 18px minmax(0, 1fr); }
  .host-state { grid-column: 2; padding-top: 0; }
  .host-actions, .host-note, .device.lamp { padding-left: 0; margin-left: 0; }
  .gate-display, .empty .display { font-size: clamp(2.375rem, 11vw, 3.125rem); }
}

@media (prefers-reduced-motion: reduce) {
  .gate-col > * { animation-duration: 200ms; animation-delay: 0ms; }
  .lane-node[data-state="thinking"] { animation-duration: 2s; }
}
