.boot-screen,
.gate-screen {
  display: grid;
  min-height: 100dvh;
  place-items: center;
  padding: 24px;
}

.boot-screen { align-content: center;color: var(--text-muted);}
.boot-screen p { margin: 12px 0 0;}

.brand-mark {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border-radius: 9px;
  background: var(--purple);
  color: white;
  font-size: 1rem;
  font-weight: 850;
  letter-spacing: -.04em;
}

.brand-mark-large { width: 44px;height: 44px;border-radius: 12px;font-size: 1.3125rem;}

.gate-card {
  display: flex;
  width: min(100%, 380px);
  flex-direction: column;
  align-items: flex-start;
  padding: 28px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}

.gate-card .eyebrow { margin-top: 22px;}
.gate-card h1 { margin: 7px 0 8px;font-size: 1.75rem;letter-spacing: -.035em;}
.gate-card p.muted { margin: 0 0 24px;}

.primary-link,
.primary-button {
  display: inline-flex;
  min-height: 42px;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  border-radius: var(--radius-sm);
  background: var(--purple);
  color: white;
  cursor: pointer;
  font-weight: 750;
  text-decoration: none;
}

.quiet-link { align-self: center;margin-top: 16px;color: var(--text-muted);font-size: 0.75rem;}

.app-shell {
  display: grid;
  width: 100vw;
  height: 100dvh;
  grid-template-columns: var(--rail-width) var(--context-width) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  overflow: hidden;
  background: var(--bg);
}

/* Home is an app-composed dashboard, not a second chat index. Chat keeps the
   full conversation/workspace navigator; Home gives that width to widgets.
   The inbox is in the same family, and more pointedly so: it IS a navigator —
   a list of the chats wanting something — so the conversation panel beside it
   would be a second, worse copy of the same job. Hiding the panel is not enough
   on its own; the column track survives an element that is display:none, which
   left the canvas at 340px of a 1440px window. */
.app-shell[data-surface="home"],
.app-shell[data-surface="inbox"],
.app-shell[data-surface="projects"],
.app-shell[data-surface="events"],
.app-shell[data-surface="settings"] {
  grid-template-columns: var(--rail-width) minmax(0, 1fr);
}

.product-rail {
  z-index: 20;
  display: flex;
  min-width: 0;
  flex-direction: column;
  align-items: center;
  border-right: 1px solid var(--border);
  background: var(--surface-0);
}

.rail-brand { display: grid;height: 72px;place-items: center;text-decoration: none;}
.rail-nav { display: flex;width: 100%;flex: 1;flex-direction: column;gap: 5px;padding: 8px;}

.rail-item {
  position: relative;
  display: flex;
  min-height: 52px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 0.625rem;
}

/* The inbox count. In shell.css rather than inbox.css because it has to be
   right before the surface it belongs to has ever been opened — a badge that
   appears only after you visit the page is not a badge. */
.nav-badge { position: absolute;top: 3px;right: 7px;min-width: 16px;padding: 0 4px;border-radius: 999px;background: var(--state-attention);color: var(--bg);font-family: var(--font-mono);font-size: 0.5625rem;font-weight: 700;line-height: 15px;text-align: center;}

.rail-item:hover { background: var(--surface-2);color: var(--text-soft);}
.rail-item.is-active { background: var(--surface-2);color: var(--claude);}
.rail-item.is-active::before { position: absolute;left: -8px;width: 2px;height: 28px;border-radius: 2px;background: var(--claude);content: "";}

/* Header overflow. It is also the phone's compact route to chat management and
   quick forking, so it stays in the header at every width. */
.chat-overflow-wrap { position: relative;display: block;flex: none;}
.chat-overflow-button { font-size: 0.9375rem;line-height: 1;}
.chat-overflow-menu { position: absolute;z-index: 40;top: calc(100% + 8px);right: 0;width: 244px;padding: 6px;border: 1px solid var(--border-strong);border-radius: var(--radius-lg);background: var(--surface-2);box-shadow: var(--shadow-panel);animation: chat-overflow-in .13s ease-out;}
.chat-overflow-menu[hidden] { display: none;}
.chat-overflow-label { margin: 0;padding: 8px 9px 4px;color: var(--text-muted);font-size: 0.5625rem;font-weight: 700;letter-spacing: .07em;text-transform: uppercase;}
.chat-overflow-server-label{display:flex;align-items:center;justify-content:space-between;gap:10px}.chat-overflow-server-label b{max-width:15ch;overflow:hidden;color:var(--text-soft);font-weight:600;letter-spacing:0;text-overflow:ellipsis;text-transform:none;white-space:nowrap}
.chat-overflow-server{display:grid;grid-template-columns:repeat(3,1fr);gap:5px;padding:3px 5px 6px}.chat-overflow-server>span{display:flex;min-width:0;min-height:42px;flex-direction:column;justify-content:center;gap:2px;padding:6px 7px;border:1px solid var(--border);border-radius:8px;background:var(--surface-1)}.chat-overflow-server small{color:var(--text-muted);font-size:.5rem;font-weight:700;text-transform:uppercase}.chat-overflow-server b{color:var(--text);font-size:.6875rem;font-variant-numeric:tabular-nums}
.chat-overflow-row { display: flex;width: 100%;min-height: 33px;align-items: center;justify-content: space-between;gap: 10px;padding: 0 9px;border: 0;border-radius: 8px;background: transparent;color: var(--text-soft);cursor: pointer;font-size: 0.75rem;text-align: left;}
.chat-overflow-row:hover { background: var(--surface-3);color: var(--text);}
.chat-overflow-row b { color: var(--text);font-weight: 600;}
.chat-overflow-row.is-danger:hover { color: var(--danger);}
.chat-overflow-sep { height: 1px;margin: 5px 4px;background: var(--border);}
@keyframes chat-overflow-in { from { opacity: 0;transform: translateY(-4px);} to { opacity: 1;transform: none;} }

/* Live strip. Sits directly under the nav rather than above the avatar so it
   reads as "your surfaces, then your running work" instead of floating orphaned
   in the middle of the rail. .rail-nav is flex:1, so this is pushed to the
   bottom of the nav's own space and stays put as the list grows and shrinks.
   The whole rail is display:none under 560px, so none of this reaches a phone. */
.rail-fleet { width: 100%;padding: 12px 0 4px;border-top: 1px solid var(--border);}
.rail-fleet[hidden] { display: none;}
.rail-fleet-label { margin: 0;color: var(--text-muted);font-size: 0.5rem;font-weight: 700;letter-spacing: .08em;text-align: center;text-transform: uppercase;}
.rail-fleet-list { display: flex;flex-direction: column;align-items: center;gap: 8px;margin-top: 9px;}
.rail-fleet-chip { position: relative;display: grid;width: 34px;height: 34px;place-items: center;border: 1px solid var(--border);border-radius: 10px;background: var(--surface-1);color: var(--text-soft);cursor: pointer;font-size: 0.8125rem;transition: border-color .2s ease,box-shadow .2s ease,transform .16s ease;}
.rail-fleet-chip:hover { transform: translateY(-1px);border-color: var(--border-strong);}
.rail-fleet-chip.is-selected { background: var(--surface-3);color: var(--text);}
/* Run state gets its own hue channel — never --claude/--codex, which answer
   "which provider" and nothing else. */
.rail-fleet-chip.is-working { border-color: var(--state-working);}
/* The ring lives on a pseudo-element so the pulse can be transform+opacity. See
   the keyframes below for why it is not a box-shadow. */
.rail-fleet-chip.is-working::after { position: absolute;inset: -1px;border: 1px solid var(--state-working);border-radius: inherit;content: "";pointer-events: none;animation: rail-fleet-breathe 2.6s ease-in-out infinite;}
.rail-fleet-chip.is-attention { border-color: var(--state-attention);box-shadow: 0 0 0 3px color-mix(in srgb, var(--state-attention) 18%, transparent);}
.rail-fleet-chip.is-stalled { border-color: var(--danger);box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 20%, transparent);}
.rail-fleet-badge { position: absolute;top: -3px;right: -3px;width: 9px;height: 9px;border: 2px solid var(--surface-0);border-radius: 50%;opacity: 0;transform: scale(.4);transition: opacity .2s ease,transform .2s ease;}
.rail-fleet-chip.is-attention .rail-fleet-badge { background: var(--state-attention);opacity: 1;transform: none;}
.rail-fleet-chip.is-stalled .rail-fleet-badge { background: var(--danger);opacity: 1;transform: none;}
/* Breathing, not blinking: a slow swell says "alive" without pulling the eye off
   the transcript. The global reduced-motion reset in base.css stops it dead.

   transform+opacity ONLY. This was a box-shadow swell, which is NOT
   compositor-only whatever the old comment here claimed: shadow spread cannot be
   composited, so every frame repainted the chip — forever, on every working
   chat. See .claude/skills/ui-performance. */
@keyframes rail-fleet-breathe {
  0%, 100% { opacity: 0;transform: scale(1);}
  50% { opacity: .5;transform: scale(1.22);}
}

.rail-footer { display: flex;flex-direction: column;align-items: center;gap: 14px;padding: 16px 0;}

.avatar {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface-3);
  color: var(--text-soft);
  font-size: 0.6875rem;
  font-weight: 800;
  cursor: pointer;
}

.avatar img { width: 100%;height: 100%;object-fit: cover;}
.avatar:hover { border-color: var(--text-muted);color: var(--text);}
.avatar.is-active { border-color: var(--purple);box-shadow: 0 0 0 3px color-mix(in srgb, var(--purple) 18%, transparent);}

.context-panel {
  position: relative;
  z-index: 15;
  display: flex;
  min-width: 0;
  flex-direction: column;
  border-right: 1px solid var(--border);
  background: var(--surface-1);
  contain: layout paint;
}

.context-head { position: relative;display: flex;min-height: 72px;align-items: center;justify-content: space-between;padding: 0 16px 0 18px;border-bottom: 1px solid var(--border);}
.context-head h1 { margin: 4px 0 0;font-size: 1rem;letter-spacing: -.02em;}
.context-actions { position: relative;}

.icon-button {
  display: inline-grid;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-soft);
  cursor: pointer;
}

.icon-button:hover { border-color: var(--border);background: var(--surface-2);color: var(--text);}

.provider-picker {
  position: absolute;
  z-index: 45;
  top: calc(100% + 8px);
  right: 0;
  width: min(270px, calc(100vw - 32px));
  padding: 8px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  box-shadow: var(--shadow-panel);
}

.provider-picker-label { margin: 4px 7px 8px;color: var(--text-muted);font-size: 0.625rem;font-weight: 750;letter-spacing: .06em;text-transform: uppercase;}
.provider-picker-head{display:flex;align-items:center;justify-content:space-between;gap:12px}
.provider-picker-head .provider-picker-label{margin-right:0}
.provider-picker-close{display:grid;width:32px;height:32px;flex:0 0 auto;place-items:center;border-radius:8px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:1.25rem;line-height:1}
.provider-picker-close:hover{background:var(--surface-3);color:var(--text)}
.provider-picker-agent-label{margin-top:12px;padding-top:11px;border-top:1px solid var(--border)}
.new-chat-workspace{display:grid;gap:6px;margin:0 7px}
.new-chat-workspace>span{color:var(--text-soft);font-size:0.6875rem;font-weight:700}
.new-chat-workspace select{width:100%;height:38px;padding:0 32px 0 10px;border:1px solid var(--border-strong);border-radius:8px;background:var(--surface-0);color:var(--text);font:inherit;font-size:0.75rem;cursor:pointer}
.new-chat-workspace select:disabled{cursor:wait;opacity:.55}
.new-chat-workspace small{color:var(--text-muted);font-size:0.5625rem;line-height:1.35}
.provider-choice { display: grid;width: 100%;grid-template-columns: 34px minmax(0, 1fr);align-items: center;gap: 10px;padding: 9px;border-radius: 8px;background: transparent;color: var(--text);cursor: pointer;text-align: left;}
.provider-choice:hover { background: var(--surface-3);}
.provider-choice:disabled { cursor: wait;opacity: .55;}
.provider-choice-glyph { display: grid;width: 32px;height: 32px;place-items: center;border: 1px solid var(--border);border-radius: 9px;background: var(--surface-0);color: var(--claude);font-size: 0.875rem;font-weight: 800;}
.provider-choice.is-codex .provider-choice-glyph { color: var(--codex);}
.provider-choice strong, .provider-choice small { display: block;}
.provider-choice strong { font-size: 0.8125rem;}
.provider-choice small { margin-top: 1px;color: var(--text-muted);font-size: 0.625rem;}

.conversation-tools{position:relative;display:grid;grid-template-columns:minmax(0,1fr) 42px;gap:7px;padding:14px 12px 7px}
.search-box {
  display: flex;
  height: 38px;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-0);
  color: var(--text-muted);
}

.search-box .icon { width: 16px;height: 16px;}
.search-box input { min-width: 0;flex: 1;border: 0;outline: 0;background: transparent;font-size: 0.75rem;}
.search-box input::placeholder { color: var(--text-muted);}
.search-box kbd { padding: 1px 5px;border: 1px solid var(--border);border-radius: 4px;color: var(--text-muted);font-family: var(--font-ui);font-size: 0.625rem;}

.conversation-filter-toggle{position:relative;display:grid;width:42px;height:38px;place-items:center;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface-0);color:var(--text-muted);cursor:pointer}
.conversation-filter-toggle:hover,.conversation-filter-toggle.is-active{border-color:var(--border-strong);background:var(--surface-2);color:var(--text)}
.conversation-filter-toggle .icon{width:18px;height:18px}
.conversation-filter-toggle b{position:absolute;top:-5px;right:-5px;min-width:17px;padding:0 4px;border:2px solid var(--surface-1);border-radius:999px;background:var(--purple);color:white;font-size:.5rem;line-height:14px;text-align:center}
.conversation-filter-menu{position:absolute;z-index:46;top:calc(100% + 2px);right:12px;left:12px;max-height:min(680px,calc(100dvh - 116px));overflow:hidden;border:1px solid var(--border-strong);border-radius:14px;background:var(--surface-2);box-shadow:var(--shadow-panel)}
.conversation-filter-menu[hidden]{display:none}
.filter-menu-head{display:flex;min-height:58px;align-items:center;justify-content:space-between;padding:8px 8px 8px 14px;border-bottom:1px solid var(--border)}
.filter-menu-head .eyebrow{margin:0 0 2px;font-size:.5rem}.filter-menu-head strong{font-size:.8125rem}.filter-menu-head .icon-button{width:36px;height:36px}
.filter-menu-body{max-height:calc(min(680px,100dvh - 116px) - 58px);overflow-y:auto;padding:12px}
.filter-scope{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:4px;margin:0;padding:3px;border:0;border-radius:9px;background:var(--surface-0)}
.filter-scope legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.scope-button{display:flex;min-width:0;align-items:center;justify-content:center;gap:7px;border-radius:7px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:0.6875rem;font-weight:650}
.scope-button:hover{color:var(--text-soft)}
.scope-button.is-active{background:var(--surface-3);color:var(--text)}
.scope-button .count-badge{background:transparent}
.scope-button.is-active .count-badge{background:var(--surface-1);color:var(--text-soft)}
.filter-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin-top:12px}
.filter-grid label{display:grid;min-width:0;gap:5px;color:var(--text-muted);font-size:.5625rem;font-weight:750;letter-spacing:.045em;text-transform:uppercase}
.filter-grid select{min-width:0;width:100%;height:34px;padding:0 25px 0 8px;border:1px solid var(--border);border-radius:7px;background:var(--surface-0);color:var(--text-soft);font:600 .6875rem var(--font-ui);text-transform:none}
.filter-clear{width:100%;min-height:34px;margin-top:10px;border:1px solid var(--border);border-radius:7px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:.6875rem;font-weight:650}.filter-clear:hover{background:var(--surface-3);color:var(--text)}
.filter-workspaces{margin-top:12px;padding-top:8px;border-top:1px solid var(--border)}
.filter-workspaces .workspace-list{max-height:190px;margin-top:2px;overflow-y:auto}
.active-filters{display:flex;flex:0 0 auto;gap:5px;padding:0 12px 6px;overflow-x:auto;scrollbar-width:none}.active-filters::-webkit-scrollbar{display:none}.active-filter{min-height:27px;flex:0 0 auto;padding:0 9px;border:1px solid var(--border);border-radius:999px;background:var(--surface-2);color:var(--text-soft);cursor:pointer;font-size:.625rem;font-weight:650}.active-filter:hover{border-color:var(--border-strong);background:var(--surface-3);color:var(--text)}

.context-section { min-height: 0;padding: 8px;}
.open-section { display:flex;flex:1 1 auto;flex-direction:column;overflow:hidden;padding-top:0;}
.section-heading { display: flex;height: 30px;align-items: center;justify-content: space-between;padding: 0 8px;}
.section-heading h2 { margin: 0;color: var(--text-soft);font-size: 0.6875rem;font-weight: 750;letter-spacing: .04em;text-transform: uppercase;}
.count-badge { min-width: 20px;padding: 1px 6px;border-radius: 10px;background: var(--surface-3);color: var(--text-muted);font-size: 0.625rem;text-align: center;}

.chat-list{display:flex;min-height:0;flex:1;flex-direction:column;gap:2px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain;padding-top:2px;scrollbar-width:thin}
.queue-heading{display:flex;min-height:28px;flex:0 0 auto;align-items:center;justify-content:space-between;padding:8px 5px 3px;color:var(--text-soft)}
.queue-heading strong{display:flex;align-items:center;gap:7px;font-size:.625rem;font-weight:800;letter-spacing:.095em;text-transform:uppercase}.queue-heading span{color:var(--text-muted);font-size:.5625rem}
/* Needs-you, working and waiting are operational queues, not filing labels.
   Give each a compact banner and a state sigil so accepted work reads as a
   separate layer above quiet history even before any row copy is legible. */
.queue-heading[data-queue=needs],.queue-heading[data-queue=working],.queue-heading[data-queue=waiting]{min-height:36px;margin:8px 2px 2px;padding:5px 8px;border:1px solid color-mix(in srgb,var(--queue-signal) 35%,var(--border));border-radius:9px;background:linear-gradient(100deg,color-mix(in srgb,var(--queue-signal) 14%,var(--surface-2)),color-mix(in srgb,var(--queue-signal) 3%,var(--surface-0)) 72%);box-shadow:inset 3px 0 0 var(--queue-signal)}
.queue-heading[data-queue=needs]{--queue-signal:var(--state-attention)}
.queue-heading[data-queue=working]{--queue-signal:var(--state-working)}
.queue-heading[data-queue=waiting]{--queue-signal:var(--state-waiting)}
.queue-heading[data-queue=needs] strong,.queue-heading[data-queue=working] strong,.queue-heading[data-queue=waiting] strong{color:color-mix(in srgb,var(--queue-signal) 82%,white)}
.queue-heading[data-queue=needs] strong::before,.queue-heading[data-queue=working] strong::before,.queue-heading[data-queue=waiting] strong::before{display:grid;width:20px;height:20px;flex:0 0 auto;place-items:center;border-radius:6px;background:var(--queue-signal);color:var(--surface-0);font-size:.75rem;font-weight:950;letter-spacing:0;content:"!"}
.queue-heading[data-queue=working] strong::before{border-radius:50%;content:"\21BB";animation:queue-working-turn 2.4s linear infinite}
.queue-heading[data-queue=waiting] strong::before{border-radius:50%;background:transparent;box-shadow:inset 0 0 0 2px var(--queue-signal);color:var(--queue-signal);content:"\2022"}
@keyframes queue-working-turn{to{transform:rotate(360deg)}}
.archive-shortcut{display:grid;min-height:42px;flex:0 0 auto;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:9px;margin:6px 3px 0;padding:0 9px;border:0;border-top:1px solid var(--border);background:transparent;color:var(--text-soft);cursor:pointer;font-size:.6875rem;text-align:left}.archive-shortcut:hover{color:var(--text)}.archive-shortcut b{color:var(--text-muted);font-family:var(--font-mono);font-size:.625rem}.archive-shortcut i{color:var(--text-muted);font-size:1rem;font-style:normal}

.chat-row{position:relative;display:grid;min-height:62px;grid-template-columns:36px minmax(0,1fr) auto;align-items:center;gap:6px 10px;width:100%;padding:8px 10px 8px 12px;border:1px solid color-mix(in srgb,var(--row-accent,var(--text-muted)) 26%,var(--border));border-radius:10px;background:linear-gradient(108deg,color-mix(in srgb,var(--row-accent,var(--text-muted)) 15%,var(--surface-1)),color-mix(in srgb,var(--row-accent,var(--text-muted)) 4%,var(--surface-1)) 74%);color:var(--text-soft);cursor:pointer;text-align:left}
/* display:contents keeps the button's UA alignment in the inheritance chain. */
.chat-row-main{display:contents;text-align:left}

.chat-row:hover{border-color:color-mix(in srgb,var(--row-accent,var(--text-muted)) 42%,var(--border));background:linear-gradient(108deg,color-mix(in srgb,var(--row-accent,var(--text-muted)) 20%,var(--surface-2)),color-mix(in srgb,var(--row-accent,var(--text-muted)) 6%,var(--surface-2)) 74%)}
/* Selection is TEXTURE, not just hue: a violet workspace tints its rows in
   almost exactly selection purple, so a flat purple fill dissolves there. No
   other card has any texture, so the reading card gets two layers nothing can
   imitate — a fine diagonal weave, and a static glassy sheen across the upper
   half. Deliberately unanimated: motion belongs to run state (orbs, attention
   pulse); the open chat is a place, and places hold still. */
.chat-row.is-active{border-color:color-mix(in srgb,var(--purple) 62%,var(--border));background:repeating-linear-gradient(135deg,rgb(203 188 255/13%) 0 2px,transparent 2px 11px),linear-gradient(115deg,transparent 30%,rgb(203 188 255/20%) 46%,transparent 63%),linear-gradient(108deg,color-mix(in srgb,var(--purple) 28%,var(--surface-3)),color-mix(in srgb,var(--purple) 11%,var(--surface-3)) 74%);color:var(--text)}
/* Workspace still owns identity in the glyph, chips, and base tint. Operational
   state is deliberately much larger: attention gets a bright signal blade;
   working gets the animated perimeter below. Both wash the whole card while
   idle rows keep their old silhouette. */
.chat-row.is-attention{--chat-signal:var(--state-attention);border-width:2px;border-color:color-mix(in srgb,var(--chat-signal) 88%,var(--border));background:linear-gradient(96deg,color-mix(in srgb,var(--chat-signal) 20%,var(--surface-2)),color-mix(in srgb,var(--chat-signal) 7%,var(--surface-1)) 52%,color-mix(in srgb,var(--row-accent,var(--text-muted)) 6%,var(--surface-1)))}
.chat-row.is-working{--chat-signal:var(--state-working);border-width:2px;border-color:color-mix(in srgb,var(--chat-signal) 54%,var(--border));background:linear-gradient(96deg,color-mix(in srgb,var(--chat-signal) 13%,var(--surface-2)),color-mix(in srgb,var(--chat-signal) 4%,var(--surface-1)) 52%,color-mix(in srgb,var(--row-accent,var(--text-muted)) 6%,var(--surface-1)))}
/* Held, not running: the frame is dashed for the same reason the perimeter is —
   a solid border is what a row that owns something looks like. */
.chat-row.is-waiting{--chat-signal:var(--state-waiting);border-width:2px;border-style:dashed;border-color:color-mix(in srgb,var(--chat-signal) 46%,var(--border));background:linear-gradient(96deg,color-mix(in srgb,var(--chat-signal) 9%,var(--surface-2)),color-mix(in srgb,var(--chat-signal) 3%,var(--surface-1)) 52%,color-mix(in srgb,var(--row-accent,var(--text-muted)) 6%,var(--surface-1)))}
.chat-row:not([data-depth="1"]):not([data-depth="2"]).is-attention::before{position:absolute;z-index:2;top:9px;bottom:9px;left:-2px;display:block;width:7px;border-radius:0 999px 999px 0;background:var(--chat-signal);box-shadow:0 0 14px color-mix(in srgb,var(--chat-signal) 62%,transparent);content:"";pointer-events:none}
/* Selected AND working/attention: the frame keeps saying what the chat is
   doing (it stays blue or amber), while the weave keeps saying you are in it.
   Source order alone would let the state wash win the whole card. */
.chat-row.is-active.is-working,.chat-row.is-active.is-attention{background:repeating-linear-gradient(135deg,rgb(203 188 255/13%) 0 2px,transparent 2px 11px),linear-gradient(115deg,transparent 30%,rgb(203 188 255/16%) 46%,transparent 63%),linear-gradient(96deg,color-mix(in srgb,var(--purple) 25%,var(--surface-3)),color-mix(in srgb,var(--chat-signal) 8%,var(--surface-2)) 74%)}
@keyframes chat-attention-signal{0%,100%{opacity:.46;transform:scale(.78)}50%{opacity:1;transform:scale(1)}}
:root[data-v2-attention-motion="still"] .queue-heading[data-queue=working] strong::before,:root[data-v2-attention-motion="still"] .chat-row.is-attention .chat-status::before{animation:none}
:root[data-v2-page-visible="false"] .chat-row.is-attention .chat-status::before{animation-play-state:paused}
.chat-row::before{display:none;content:""}

/* Working sends three packet trains around the full measured perimeter. Their
   long-running motion is generated as transform-only WAAPI keyframes; action
   cards can still add the finite burst trail below when real tool state lands. */
.chat-working-perimeter{position:absolute;z-index:3;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.chat-working-perimeter path{fill:none;vector-effect:non-scaling-stroke}
.chat-working-perimeter-base{stroke:color-mix(in srgb,var(--state-working) 20%,transparent);stroke-width:1.25}
.chat-working-orb{fill:color-mix(in srgb,var(--state-working) 84%,white);transform-box:view-box;transform-origin:0 0;will-change:transform}
.chat-working-burst{stroke:color-mix(in srgb,var(--state-working) 74%,white);stroke-width:6;stroke-linecap:round;stroke-dasharray:7 93;opacity:0;animation:chat-working-burst-lap .78s cubic-bezier(.18,.78,.16,1) both}
@keyframes chat-working-burst-lap{0%{opacity:0;stroke-dashoffset:5}12%{opacity:1}74%{opacity:.95}100%{opacity:0;stroke-dashoffset:-100}}
:root[data-v2-attention-motion="still"] .chat-working-orb{opacity:.72}
:root[data-v2-attention-motion="still"] .chat-working-burst{animation-play-state:paused}
:root[data-v2-page-visible="false"] .chat-working-burst{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){
  .chat-working-burst{animation:none}
  .chat-working-orb{opacity:.72}
}
@media (forced-colors:active){
  .chat-working-perimeter{filter:none;forced-color-adjust:none}
  .chat-working-perimeter-base,.chat-working-burst{stroke:Highlight}
  .chat-working-orb{fill:Highlight}
}

/* Waiting is the same perimeter with the travel taken out of it: Portal holds
   this chat's work and another part of Portal has the resource. Three packets
   sit just past the top-left corner — at the gate — and breathe in sequence,
   while the ring itself never moves, because nothing is moving. Drained blue
   rather than a fourth hue: it is the same KIND of live work as Working, minus
   the energy, so the rail separates moving from held on saturation alone.
   Opacity is the only animated property (.claude/skills/ui-performance) — this
   state stays on for as long as the box is busy, which is measured in hours. */
.chat-waiting-perimeter{position:absolute;z-index:3;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.chat-waiting-perimeter path{fill:none;vector-effect:non-scaling-stroke}
.chat-waiting-perimeter-base{stroke:color-mix(in srgb,var(--state-waiting) 26%,transparent);stroke-width:1.25;stroke-dasharray:1.1 1.9}
.chat-waiting-hold{stroke:color-mix(in srgb,var(--state-waiting) 88%,white);stroke-width:7;stroke-linecap:round;stroke-dasharray:.1 99.9;animation:chat-waiting-hold-breathe 2.6s ease-in-out var(--hold-delay) infinite}
.chat-waiting-hold:nth-of-type(2){--hold-delay:0s;stroke-dashoffset:-1.4}
.chat-waiting-hold:nth-of-type(3){--hold-delay:-.26s;stroke-dashoffset:-4.2;stroke-width:5.2}
.chat-waiting-hold:nth-of-type(4){--hold-delay:-.52s;stroke-dashoffset:-7;stroke-width:3.6}
@keyframes chat-waiting-hold-breathe{0%,100%{opacity:.22}46%{opacity:1}}
:root[data-v2-attention-motion="still"] .chat-waiting-hold{animation-play-state:paused}
:root[data-v2-page-visible="false"] .chat-waiting-hold{animation-play-state:paused}
@media (prefers-reduced-motion:reduce){.chat-waiting-hold{animation:none;opacity:.72}}
@media (forced-colors:active){
  .chat-waiting-perimeter{forced-color-adjust:none}
  .chat-waiting-perimeter-base,.chat-waiting-hold{stroke:GrayText}
}
/* Workspace palette, excluding the provider hues. green/orange are legacy
   folder values, shifted clear of the provider marks. */
[data-accent="violet"]{--row-accent:#9478ff}
[data-accent="cyan"]{--row-accent:#55bfd0}
[data-accent="amber"]{--row-accent:#d5a94e}
[data-accent="rose"]{--row-accent:#d87391}
[data-accent="green"]{--row-accent:#5fb37d}
[data-accent="blue"]{--row-accent:#689ee8}
[data-accent="orange"]{--row-accent:#e0a355}
[data-accent="pink"]{--row-accent:#ce78c5}
[data-accent="home"]{--row-accent:#707789}
.chat-glyph{display:grid;width:36px;height:36px;place-items:center;border:1px solid color-mix(in srgb,var(--row-accent) 52%,var(--border));border-radius:10px;background:color-mix(in srgb,var(--row-accent) 10%,var(--surface-0));color:var(--claude);font-size:1rem}
.chat-copy{min-width:0}
.chat-heading{display:flex;min-width:0;align-items:center;gap:6px}
.chat-role{display:inline;flex:0 0 auto;color:var(--text-muted);font-size:.5625rem;font-weight:850;letter-spacing:.09em;text-transform:uppercase}
/* Two lines before the ellipsis: the eyebrow owns identity now, so the title
   is the only fact with nowhere else to live — give it the room. Short titles
   pay nothing; long ones grow the card one line instead of losing their end. */
.chat-title{display:-webkit-box;min-width:0;flex:1 1 auto;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:2;font-size:0.8125rem;font-weight:680;line-height:1.3}
.chat-action-chip{display:inline-flex;min-height:18px;flex:0 0 auto;align-items:center;padding:0 6px;border:1px solid color-mix(in srgb,var(--purple) 44%,var(--border));border-radius:5px;background:color-mix(in srgb,var(--purple) 16%,var(--surface-3));color:color-mix(in srgb,var(--purple) 56%,white);font:850 .5rem/1 var(--font-ui);letter-spacing:.045em;text-transform:uppercase;white-space:nowrap}
.chat-action-chip[data-kind=deploy]{border-color:color-mix(in srgb,var(--danger) 50%,var(--border));background:color-mix(in srgb,var(--danger) 15%,var(--surface-3));color:color-mix(in srgb,var(--danger) 62%,white)}
/* ── Placeline ──────────────────────────────────────────────────────────────
   The two flagship facts share the card's first line: workspace left, model
   right, a dotted leader tying them together. Both are plain type at full
   card width — the old pill row capped the workspace at 9.5ch, which cut the
   name the card most exists to show. Run state keeps the sub-line below. */
.chat-eyebrow{display:flex;grid-column:1/-1;min-width:0;align-items:baseline;gap:8px}
.chat-workspace{flex:0 1 auto;overflow:hidden;color:color-mix(in srgb,var(--row-accent) 82%,white);font-size:.625rem;font-weight:850;letter-spacing:.12em;text-overflow:ellipsis;text-transform:uppercase;white-space:nowrap}
/* The dotted leader is a pseudo-element, not a node: at 100 rows a decorative
   span is a hundred nodes against the v2-performance budget. order sorts it
   between the place (0) and the engine (2, 3). */
.chat-eyebrow::before{order:1;flex:1 1 14px;min-width:14px;border-bottom:1px dotted color-mix(in srgb,var(--row-accent) 36%,var(--border-strong));content:"";transform:translateY(-3px)}
.chat-provider{order:2}
.chat-effort{order:3}
/* The engine, set in mono: a machine id, not a shout. Hue still means provider
   and nothing else; capability stays the prominence channel — loud (the models
   against the weekly limit) keeps a filled tag so those chats stay findable
   from across the list, quiet fades toward the metadata grey. */
.chat-provider{--agent:var(--claude);flex:0 0 auto;color:color-mix(in srgb,var(--agent) 76%,var(--text-soft));font-family:var(--font-mono);font-size:.625rem;font-weight:700;letter-spacing:.02em;white-space:nowrap}
.chat-row[data-provider=codex] .chat-glyph{color:var(--codex)}
.chat-row[data-provider=codex] .chat-provider{--agent:var(--codex)}
.chat-provider[data-tier=loud]{padding:1px 5px;border-radius:4px;background:var(--agent);color:var(--bg);font-weight:800}
.chat-provider[data-tier=strong]{color:var(--agent)}
.chat-provider[data-tier=quiet]{color:var(--text-muted)}
.chat-effort{flex:0 0 auto;color:var(--text-muted);font-size:.5625rem;font-weight:750;letter-spacing:.07em;text-transform:uppercase}
.chat-sub{display:flex;min-width:0;flex-wrap:wrap;align-items:center;gap:4px 8px;margin-top:4px;overflow:visible;color:var(--text-muted);font-size:0.5625rem}
/* State is all the sub-line carries now; a row with nothing to say drops it. */
.chat-sub:not(:has(.chat-status:not(:empty),.chat-mode,.chat-state)){display:none}
/* Status shares the meta line with verify and spawn mode instead of boxing
   itself full-width: the card's frame, tint and glow already carry the state,
   so the word is a label, not a second alarm. The dot is what makes it read
   as live rather than as one more grey fact. */
.chat-status{flex:0 0 auto;font-weight:800;text-transform:uppercase}.chat-status:empty{display:none}
.chat-row.is-working .chat-status,.chat-row.is-attention .chat-status,.chat-row.is-waiting .chat-status{display:inline-flex;align-items:center;gap:5px;color:color-mix(in srgb,var(--chat-signal) 84%,white);font-weight:900;letter-spacing:.07em}
.chat-row.is-working .chat-status::before,.chat-row.is-attention .chat-status::before{width:5px;height:5px;flex:0 0 auto;border-radius:50%;background:var(--chat-signal);box-shadow:0 0 7px color-mix(in srgb,var(--chat-signal) 70%,transparent);content:""}
.chat-row.is-attention .chat-status::before{transform:scale(.78);animation:chat-attention-signal 2.2s ease-in-out infinite}
/* A hollow ring where working and attention have a filled dot: the same mark
   with nothing in it, which is the state in one glyph. */
.chat-row.is-waiting .chat-status::before{width:5px;height:5px;flex:0 0 auto;border:1px solid var(--chat-signal);border-radius:50%;content:""}
.chat-waiting-link{display:grid;width:100%;min-width:0;grid-column:2/-1;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:6px;justify-self:stretch;margin:-2px 0 1px;padding:0;border:0;background:transparent;color:color-mix(in srgb,var(--state-waiting) 78%,white);font:700 .5625rem/1.35 var(--font-ui);text-align:left;cursor:pointer}
.chat-waiting-reason{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.chat-waiting-open{white-space:nowrap}
.chat-waiting-link:hover{text-decoration:underline;text-underline-offset:2px}.chat-waiting-link:focus-visible{border-radius:3px;outline:2px solid var(--state-waiting);outline-offset:2px}.chat-waiting-link:disabled{color:var(--text-muted);cursor:default;text-decoration:none}
/* Visible from the list without opening the chat. Healthy-green, the same hue
   the locks sheet uses for a lease this chat owns — "held" reads as the calm,
   deliberate state it is, not an alarm. */
.chat-lock-badge{display:block;width:100%;min-width:0;grid-column:2/-1;justify-self:stretch;margin:-2px 0 1px;padding:0;overflow:hidden;border:0;background:transparent;color:color-mix(in srgb,var(--state-healthy) 78%,white);font:700 .5625rem/1.35 var(--font-ui);text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}
.chat-lock-badge:hover{text-decoration:underline;text-underline-offset:2px}.chat-lock-badge:focus-visible{border-radius:3px;outline:2px solid var(--state-healthy);outline-offset:2px}
.chat-time{align-self:start;padding-top:3px;color:var(--text-muted);font-size:0.5625rem}
.chat-state { display:none;flex:0 0 auto;width:6px;height:6px;border-radius:50%;background:var(--text-muted);opacity:0}
.chat-state.is-working { background: var(--state-working);opacity:1;animation: chat-working 1.2s ease-in-out infinite;}
@keyframes chat-working { 50% { opacity: .3;transform: scale(.75);} }
.chat-state.is-attention { background: var(--state-attention);opacity:1}


/* ── Lineage ─────────────────────────────────────────────────────────────────
   Every hue in this list already answers a question: --claude/--codex = which
   agent, the accent stripe = which workspace, blue/amber = what is it doing.
   Structure is a fourth question and there is no hue left, so it gets none —
   rails, connectors, chevrons and counts are grey by design, and the two state
   channels stay free to say something about the subtree on top of them.

   Division of labour on a parent row: the sub-line says what THIS chat is doing
   (unchanged), the pill says what its CHILDREN are doing. Nothing merges, so an
   amber mark is never ambiguous about whose turn it is. */

/* Absolutely positioned, so a row without children pays nothing for a control
   it doesn't have — a reserved column would cost every row ~46px of title at
   390px, and most rows have no children. */
/* Full row height, so the target stays generous, but the pill itself anchors
   to the bottom corner: the timestamp owns the title line's right edge now,
   and the meta line already reserves this corner via .chat-sub's padding. */
.chat-disclosure{position:absolute;z-index:2;top:0;right:0;bottom:0;display:grid;width:84px;padding:0 7px 9px 0;place-items:end;background:transparent;cursor:pointer}
.chat-disclosure[hidden]{display:none}
.chat-row.is-swiped .chat-disclosure{opacity:0;pointer-events:none}
.chat-pill{position:relative;display:inline-flex;height:20px;align-items:center;gap:4px;padding:0 7px 0 6px;border:1px solid transparent;border-radius:999px;background:var(--surface-3);color:var(--text-soft);font:750 0.625rem/1 var(--font-ui)}
.chat-pill-label{color:var(--text-muted);font-weight:650}
.chat-row:has(.chat-disclosure:not([hidden])) .chat-sub{padding-right:58px}
.chat-pill i{width:0;height:0;border:3.5px solid transparent;border-right-width:0;border-left-color:currentColor;transition:transform .16s ease}
.chat-row.is-expanded .chat-pill i{transform:rotate(90deg) translateX(1px)}
.chat-disclosure:hover .chat-pill{background:var(--border);color:var(--text)}
.chat-disclosure:focus-visible{outline:2px solid var(--purple);outline-offset:-4px;border-radius:10px}

/* Subtree working. The count keeps meaning "how many children", so run state is
   carried by the pill's outline and by motion — the same channel the state dot
   already uses — instead of by recolouring a number. Outlined, not filled: a
   child that is merely busy must stay quieter than one that wants you. */
.chat-row.has-child-working .chat-pill{border-color:color-mix(in srgb,var(--state-working) 85%,transparent);background:color-mix(in srgb,var(--state-working) 16%,var(--surface-3));color:var(--state-working);animation:chat-subtree 1.7s ease-in-out infinite}
/* Fades the whole pill rather than re-mixing its border and background: those
   two repaint every frame, and this runs on every row with a busy child, for as
   long as that child runs. .claude/skills/ui-performance. */
@keyframes chat-subtree{50%{opacity:.55}}

/* The borrowed status word. Same hue as the self state — it IS that state, just
   one level down — but never the filled dot, which stays reserved for "this row". */
.chat-row.is-subtree-working .chat-status{color:var(--state-working)}
.chat-row.is-subtree-waiting .chat-status{color:var(--state-waiting)}
.chat-row.has-child-waiting:not(.has-child-working):not(.has-child-attention) .chat-pill{border-color:color-mix(in srgb,var(--state-waiting) 60%,var(--border));color:var(--state-waiting)}
.chat-row.is-subtree-attention .chat-status{color:var(--state-attention)}
.chat-row.is-subtree-ready .chat-status,.chat-row.has-archive-action .chat-status{color:var(--state-healthy)}
.chat-row.has-child-ready:not(.has-child-working):not(.has-child-attention) .chat-pill{border-color:color-mix(in srgb,var(--state-healthy) 45%,var(--border));color:var(--state-healthy)}

/* Subtree attention. NOT the count in amber: "3" means three children, and
   tinting it makes it read as three things needing you. A corner dot is a
   second mark for a second fact, and costs no width. */
.chat-pill-alert{position:absolute;top:-3px;right:-3px;width:9px;height:9px;border:2px solid var(--surface-1);border-radius:50%;background:var(--state-attention);opacity:0}
.chat-row.has-child-attention .chat-pill-alert{opacity:1}
.chat-row.has-child-attention .chat-pill{color:var(--text)}
.chat-row.is-active .chat-pill-alert{border-color:var(--surface-3)}

/* Descendants are compact subrows, not more root cards. A coordinator uses the
   first inset; its leaves use the second rail and a deeper content indent. */
.chat-row:is([data-depth="1"],[data-depth="2"]){
  --rail-x:7px;--rail-ink:#596071;
  min-height:clamp(46px,2.7vw,56px);
  grid-template-columns:clamp(26px,1.55vw,30px) minmax(0,1fr) auto;
  gap:3px clamp(7px,.5vw,9px);
  width:calc(100% - 20px);
  margin-left:20px;
  padding:4px 8px 4px 22px;
  border-color:color-mix(in srgb,var(--row-accent,var(--text-muted)) 18%,var(--border));
  border-radius:0 8px 8px 0;
  background:linear-gradient(100deg,color-mix(in srgb,var(--row-accent,var(--text-muted)) 10%,var(--surface-0)),color-mix(in srgb,var(--row-accent,var(--text-muted)) 3%,var(--surface-0)) 78%);
}
.chat-row.is-expanded:has(+ .chat-row[data-depth="1"]){margin-bottom:0;border-bottom-left-radius:5px}
.chat-row:not([data-depth="1"]):not([data-depth="2"]) + .chat-row[data-depth="1"]{margin-top:-2px}
.chat-row:is([data-depth="1"],[data-depth="2"]) + .chat-row:is([data-depth="1"],[data-depth="2"]){margin-top:-2px;border-top-right-radius:0}
.chat-row:is([data-depth="1"],[data-depth="2"]):has(+ .chat-row:is([data-depth="1"],[data-depth="2"])){border-bottom-right-radius:0}
.chat-row:is([data-depth="1"],[data-depth="2"]):not(:has(+ .chat-row:is([data-depth="1"],[data-depth="2"]))){margin-bottom:5px}
.chat-row:is([data-depth="1"],[data-depth="2"]):hover{border-color:color-mix(in srgb,var(--row-accent,var(--text-muted)) 35%,var(--border));background:linear-gradient(100deg,color-mix(in srgb,var(--row-accent,var(--text-muted)) 14%,var(--surface-2)),color-mix(in srgb,var(--row-accent,var(--text-muted)) 4%,var(--surface-1)) 78%)}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-active{border-color:color-mix(in srgb,var(--purple) 58%,var(--border));background:repeating-linear-gradient(135deg,rgb(203 188 255/13%) 0 2px,transparent 2px 11px),linear-gradient(115deg,transparent 30%,rgb(203 188 255/16%) 46%,transparent 63%),linear-gradient(100deg,color-mix(in srgb,var(--purple) 25%,var(--surface-3)),color-mix(in srgb,var(--purple) 10%,var(--surface-1)) 78%)}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-attention{border-color:color-mix(in srgb,var(--state-attention) 82%,var(--border))}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-working{border-color:color-mix(in srgb,var(--state-working) 68%,var(--border))}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-waiting{border-color:color-mix(in srgb,var(--state-waiting) 62%,var(--border))}

/* Hovering any row lights the WHOLE family, because the family is the object —
   the same reason leaving it closes it. The pointer is on one row; what it is
   pointing at is the group, and this is what makes that legible before anything
   collapses. The rail brightening is the part that reads as "one card": it is
   the only mark that spans every row in the family. */
.chat-row.is-family-hover{border-color:color-mix(in srgb,var(--row-accent,var(--text-muted)) 46%,var(--border))}
.chat-row.is-family-hover:is([data-depth="1"],[data-depth="2"]){--rail-ink:#7d879c}
/* The vertical rail answers "same family"; each elbow answers "this row is a
   child". The last rail ends at its elbow so it cannot point into the next root. */
.chat-row:is([data-depth="1"],[data-depth="2"])::after{position:absolute;z-index:2;top:-2px;bottom:-2px;left:var(--rail-x);width:2px;background:var(--rail-ink);content:"";pointer-events:none}
.chat-row:is([data-depth="1"],[data-depth="2"])::before{position:absolute;z-index:2;top:50%;left:var(--rail-x);display:block;width:12px;height:2px;background:var(--rail-ink);content:"";pointer-events:none}
.chat-row:is([data-depth="1"],[data-depth="2"]):not(:has(+ .chat-row[data-depth="2"]))::after{bottom:auto;height:calc(50% + 1px);border-bottom-left-radius:2px}
.chat-row[data-depth="2"]{--rail-x:27px;padding-left:42px}
.chat-row[data-depth="2"]::before{left:7px;width:32px}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-glyph{width:clamp(26px,1.55vw,30px);height:clamp(26px,1.55vw,30px);border-radius:8px;font-size:clamp(.75rem,.3vw + .65rem,.875rem)}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-heading{gap:5px}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-role{display:inline}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-title{font-size:clamp(.75rem,.28vw + .67rem,.875rem);font-weight:660}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-action-chip{min-height:16px;padding-inline:5px;font-size:.46875rem}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-sub{gap:3px 6px;margin-top:2px;font-size:clamp(.5rem,.2vw + .46rem,.625rem)}
/* Children inherit their place from the rail; the name stays for scanning but
   drops to a whisper so the parent remains the family's loud copy. line-height:1
   plus the compact paddings above keep the subrow visibly shorter than its
   parent even though both now carry an eyebrow line. */
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-eyebrow{gap:6px;line-height:1}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-workspace{color:color-mix(in srgb,var(--row-accent) 42%,var(--text-muted));font-size:.5625rem}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-provider{font-size:.5625rem}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-effort{font-size:.5rem}
.chat-row:is([data-depth="1"],[data-depth="2"]) .chat-time{padding-top:1px;font-size:clamp(.5rem,.16vw + .47rem,.625rem)}
.chat-mode{flex:0 0 auto;color:var(--text-muted);font-weight:650;letter-spacing:.02em;opacity:.85}
.chat-mode:empty{display:none}

/* ── Current chat: an open tab into the transcript ───────────────────────────
   Workspace still owns the surface, and attention/working still own the frame.
   Selection therefore gets a third channel: explicit language plus shape. The
   row shortens just enough to leave its pointer inside the list's overflow
   boundary, so it reads as opening toward the transcript without widening the
   drawer or stealing status colour. */
.chat-reading{display:inline-flex;width:max-content;align-items:center;gap:5px;color:color-mix(in srgb,var(--purple) 62%,white);font-size:.5rem;font-weight:900;letter-spacing:.1em;text-transform:uppercase}
.chat-reading::before{width:5px;height:5px;border-radius:50%;background:color-mix(in srgb,var(--purple) 65%,white);box-shadow:0 0 7px color-mix(in srgb,var(--purple) 75%,transparent);content:""}
.chat-row.is-active{width:calc(100% - 9px);overflow:visible;border-radius:10px 3px 3px 10px;outline:1px solid color-mix(in srgb,var(--purple) 55%,transparent);outline-offset:-1px}
.chat-row.is-active .chat-eyebrow::before{border-bottom-color:color-mix(in srgb,var(--purple) 42%,var(--border-strong))}
.chat-row.is-active .chat-sub{color:var(--text-soft)}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-active{width:calc(100% - 29px);border-radius:0 3px 3px 0}
.chat-row.is-active .chat-title{color:var(--text)}
.chat-row.is-active .chat-row-main{border-radius:10px 3px 3px 10px}
.chat-row:is([data-depth="1"],[data-depth="2"]).is-active .chat-row-main{border-radius:0 3px 3px 0}
.chat-selection-arrow{position:absolute;z-index:4;top:50%;right:-7px;width:14px;height:14px;border-top:1px solid color-mix(in srgb,var(--purple) 50%,white);border-right:1px solid color-mix(in srgb,var(--purple) 50%,white);background:color-mix(in srgb,var(--purple) 13%,var(--surface-3));transform:translateY(-50%) rotate(45deg);pointer-events:none}
.chat-row.is-swiped .chat-selection-arrow{display:none}

/* ── Row menu (desktop only) ──────────────────────────────────────────────────
   The phone archives by swiping (swipe-archive.js, which never binds a mouse
   pointer), so the kebab is display:none in the base rules and only exists
   inside the desktop query. Nothing here can reach a 560px viewport.

   It takes the eyebrow's model corner rather than a grid column of its own: a
   reserved column would cost every row ~20px of title width for a control that
   is invisible until you hover, and swapping the two means hovering a row never
   moves the title or the lineage pill. z-index clears .chat-disclosure, whose
   46px hit area covers this corner on rows that have children. */
.chat-row-menu-button{display:none}
.chat-row-archive{position:absolute;z-index:3;right:7px;bottom:6px;min-height:30px;padding:0 9px;border:1px solid color-mix(in srgb,var(--state-healthy) 48%,var(--border));border-radius:7px;background:color-mix(in srgb,var(--state-healthy) 10%,var(--surface-1));color:var(--state-healthy);font-size:.625rem;font-weight:800;cursor:pointer}
.chat-row-archive[hidden]{display:none}.chat-row-archive:hover{background:color-mix(in srgb,var(--state-healthy) 18%,var(--surface-1));color:var(--text)}
.chat-row.has-archive-action .chat-copy{padding-right:68px}
@media (min-width: 561px) {
  .chat-row-menu-button{position:absolute;z-index:3;top:4px;right:4px;display:grid;width:20px;height:18px;place-items:center;border:0;border-radius:6px;background:transparent;color:var(--text-muted);font-size:0.8125rem;line-height:1;cursor:pointer;opacity:0;transition:opacity .12s ease}
  .chat-provider,.chat-effort{transition:opacity .12s ease}
  .chat-row:hover .chat-row-menu-button,.chat-row.is-menu-open .chat-row-menu-button,.chat-row-menu-button:focus-visible{opacity:1}
  .chat-row:hover .chat-provider,.chat-row:hover .chat-effort,.chat-row.is-menu-open .chat-provider,.chat-row.is-menu-open .chat-effort{opacity:0}
  .chat-row-menu-button:hover{background:var(--surface-0);color:var(--text)}
  .chat-row-menu-button:focus-visible{outline:2px solid var(--purple);outline-offset:-2px;opacity:1}
}
@media (max-width:560px){.chat-row.has-archive-action{min-height:86px}.chat-row-archive{right:8px;bottom:5px;min-height:44px;padding-inline:11px}.chat-row.has-archive-action .chat-copy{padding-right:78px}}
.chat-mode::before{margin-right:5px;content:"·"}

.workspace-row{display:grid;width:100%;grid-template-columns:minmax(0,1fr) 28px 28px;align-items:center;border-radius:6px;color:var(--text-soft);font-size:0.75rem}
.workspace-row:hover{background:var(--surface-2)}
.workspace-row.is-active{background:var(--surface-3);color:var(--text)}
.workspace-open{display:grid;min-width:0;min-height:34px;grid-template-columns:20px minmax(0,1fr) auto;align-items:center;gap:8px;padding:4px 5px 4px 8px;background:transparent;color:inherit;cursor:pointer;text-align:left}
.workspace-settings{width:26px;height:26px;border-radius:6px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:0.625rem;letter-spacing:-1px}
.workspace-settings:hover{background:var(--surface-3);color:var(--text)}
.workspace-theme-toggle{display:grid;width:26px;height:26px;place-items:center;border-radius:6px;background:transparent;cursor:pointer}.workspace-theme-toggle:hover,.workspace-theme-toggle[aria-expanded=true]{background:var(--surface-3)}.workspace-theme-toggle i{width:12px;height:12px;border:2px solid color-mix(in srgb,var(--row-accent) 58%,white);border-radius:4px;background:var(--row-accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--row-accent) 16%,transparent)}
.workspace-quick-palette{display:flex;grid-column:1/-1;align-items:center;justify-content:flex-end;gap:6px;padding:5px 7px 8px}.workspace-quick-palette[hidden]{display:none}.workspace-quick-palette button{--swatch:var(--row-accent);width:24px;height:24px;border:2px solid transparent;border-radius:7px;background:var(--swatch);cursor:pointer}.workspace-quick-palette button:hover{transform:translateY(-1px)}.workspace-quick-palette button.is-active{border-color:var(--text);box-shadow:0 0 0 2px var(--surface-1)}.workspace-quick-palette button:disabled{cursor:wait;opacity:.55}.workspace-row.is-theme-error .workspace-theme-toggle{box-shadow:inset 0 0 0 1px var(--danger)}
/* Where the colour→workspace mapping the chat stripes rely on is legible. */
.workspace-icon{width:20px;color:var(--row-accent,var(--text-soft));text-align:center}
.workspace-name{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.workspace-count{color:var(--text-muted);font-size:0.625rem}
.workspace-filter{display:flex;align-items:center;gap:7px;width:calc(100% - 16px);min-height:28px;margin:0 8px 6px;padding:4px 6px 4px 9px;border:1px solid var(--border);border-radius:999px;background:var(--surface-2);color:var(--text-soft);cursor:pointer;font-size:0.6875rem;text-align:left}
.workspace-filter:hover{border-color:var(--border-strong);background:var(--surface-3);color:var(--text)}
.workspace-filter-dot{width:7px;height:7px;flex:0 0 auto;border-radius:50%;background:var(--row-accent,var(--purple))}
.workspace-filter-name{min-width:0;flex:1;overflow:hidden;font-weight:650;text-overflow:ellipsis;white-space:nowrap}
.workspace-filter-clear{flex:0 0 auto;color:var(--text-muted);font-size:0.8125rem;line-height:1}
.list-empty{margin:24px 12px;color:var(--text-muted);font-size:0.75rem;text-align:center}

/* grid-template-columns is not decoration: without it the single column is
   IMPLICIT and auto-sized, so it sizes to the widest row — three staged
   attachments made the column 906px inside a 390px phone, and the header, the
   transcript and the composer all rode along. overflow:hidden then clips it
   silently, and a focus scroll drags the whole chat sideways. minmax(0,1fr)
   pins every row to the canvas, so a wide child scrolls inside its own box. */
.main-canvas{position:relative;display:grid;min-width:0;min-height:0;height:100%;grid-template-columns:minmax(0,1fr);grid-template-rows:72px auto minmax(0,1fr) auto;overflow:hidden;background:radial-gradient(680px 260px at 9% 0,color-mix(in srgb,var(--row-accent,var(--purple)) 10%,transparent),transparent 68%),var(--bg);box-shadow:inset 0 3px var(--row-accent,var(--purple));contain:layout paint}
/* Every row is placed EXPLICITLY. The children rail (row 2) is display:none in
   the common case — a chat with no children — and a display:none element is not
   a grid item at all, so with auto-placement the transcript and composer would
   each slide up a track and the composer would inherit the 1fr. Naming the rows
   makes a hidden rail collapse its track to 0 and move nothing. */
.conversation-head{grid-row:1}
.children-rail{grid-row:2}
.surface-body{grid-row:3}
.composer-dock{grid-row:4}

/* App pages already carry their own identity, description, and actions. The
   chat header repeated the page name over a non-interactive "Home" subtitle,
   spending 62px on a phone and 90px on desktop before the useful surface even
   began. The active product-nav item supplies location; the page hero supplies
   the title. Keep the full four-row grid only where it has chat meaning. */
.app-shell:not([data-surface="chat"]) .main-canvas{grid-template-rows:minmax(0,1fr)}
.app-shell:not([data-surface="chat"]) .conversation-head{display:none}
.app-shell:not([data-surface="chat"]) .surface-body{grid-row:1}

.conversation-head{z-index:5;display:flex;min-width:0;align-items:center;gap:12px;padding:3px clamp(16px,3vw,40px) 0;border-bottom:1px solid color-mix(in srgb,var(--row-accent,var(--border)) 24%,var(--border));background:color-mix(in srgb,var(--row-accent,var(--purple)) 3%,var(--surface-0))}
.conversation-identity{min-width:0;flex:1}
.workspace-kicker{display:flex;min-width:0;align-items:center;gap:6px;margin:0 0 3px;color:var(--row-accent,var(--text-soft));font-size:.5625rem;font-weight:800;letter-spacing:.075em;line-height:1;text-transform:uppercase}
.workspace-theme-shortcut{display:flex;min-width:0;align-items:center;gap:6px;padding:2px 4px 2px 2px;border-radius:5px;background:transparent;color:inherit;cursor:pointer;font:inherit;letter-spacing:inherit;line-height:inherit;text-transform:inherit}.workspace-theme-shortcut:hover{background:color-mix(in srgb,var(--row-accent,var(--purple)) 12%,transparent)}.workspace-theme-shortcut>span{opacity:.42;font-size:.625rem}.workspace-theme-shortcut:hover>span{opacity:1}.workspace-theme-shortcut:disabled{cursor:default}.workspace-theme-shortcut:disabled>span{display:none}
.workspace-kicker .meta-dot{width:7px;height:7px;border-radius:2px;box-shadow:0 0 0 3px color-mix(in srgb,var(--row-accent,var(--purple)) 12%,transparent)}
.workspace-kicker b{flex:0 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.workspace-kicker a{min-width:0;overflow:hidden;color:var(--text-muted);font-family:var(--font-mono);font-size:.5rem;font-weight:600;letter-spacing:0;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap}.workspace-kicker a:hover{color:var(--text-soft);text-decoration:underline}
.title-line{display:flex;min-width:0;align-items:center;gap:9px}
.title-line h1{min-width:0;overflow:hidden;margin:0;font-size:0.9375rem;letter-spacing:-.015em;text-overflow:ellipsis;white-space:nowrap}
.conversation-meta{margin:3px 0 0;color:var(--text-muted);font-size:0.6875rem}

/* The identity tile: the chat's own emoji over its workspace accent. Desktop
   only — base is display:none, so the phone header gains no width at all. */
.conversation-glyph{display:none}

/* The chip row replaces a grey sentence. On the phone it stays a sentence in
   footprint — borderless, 10px, same line height the <p> had — and only the
   colour separates the channels. Desktop opts into real chips below. */
.conversation-chips{display:flex;min-width:0;align-items:center;gap:8px;margin:3px 0 0;font-size:0.6875rem;line-height:1.35}
.meta-chip{display:flex;min-width:0;align-items:center;gap:5px;color:var(--text-muted);font-size:inherit;white-space:nowrap}
.meta-chip b{min-width:0;overflow:hidden;font-weight:600;text-overflow:ellipsis}
.meta-dot{width:6px;height:6px;flex:0 0 auto;border-radius:50%;background:var(--row-accent,var(--text-muted))}
.is-status .meta-dot{background:var(--text-muted)}
/* "Ready" is muted because it means nothing is owed. A parent with children in
   flight is owed something either way, so it stops being muted — loudly when a
   child is stopped waiting on you, calmly when it is still working. */
.meta-chip.is-working{color:var(--state-working)}
.meta-chip.is-working .meta-dot{background:var(--state-working)}
.meta-chip.is-attention,.meta-chip.is-waiting{color:var(--state-attention);font-weight:600}
.meta-chip.is-attention .meta-dot,.meta-chip.is-waiting .meta-dot{background:var(--state-attention)}
.meta-chip.is-delegated{color:var(--state-working);font-weight:600}
.meta-chip.is-delegated .meta-dot{background:var(--state-working)}
.meta-chip.is-archived{color:var(--text-muted)}
/* Effort compared, not spelled: five segments of the provider's own ladder.
   One rule set drives every meter — row, chip and cockpit — so the ladder can
   never mean two different things in two places.

   ONE element, not six. The chat list renders a meter per row, and six nodes ×
   every row is what pushed the shell past the 3,000-node budget v2-performance
   guards. So the segments are a repeating gradient and the rank is simply how
   much of the bright layer gets painted over the dim one: 3px bar, 2px gap,
   5 bars = 23px. */
.effort-meter{display:inline-block;width:23px;height:8px;flex:0 0 auto;background-image:repeating-linear-gradient(90deg,var(--text-soft) 0 3px,transparent 3px 5px),repeating-linear-gradient(90deg,var(--border-strong) 0 3px,transparent 3px 5px);background-repeat:no-repeat;background-size:0 100%,100% 100%}
.effort-meter[data-rank="1"]{background-size:3px 100%,100% 100%}
.effort-meter[data-rank="2"]{background-size:8px 100%,100% 100%}
.effort-meter[data-rank="3"]{background-size:13px 100%,100% 100%}
.effort-meter[data-rank="4"]{background-size:18px 100%,100% 100%}
.effort-meter[data-rank="5"]{background-size:23px 100%,100% 100%}
.effort-meter[data-rank="0"]{display:none}
.meta-chip.is-id{position:relative;border:0;background:transparent;cursor:pointer;font-family:var(--font-mono)}
.meta-chip.is-id:hover{color:var(--text)}
.meta-chip.is-id.is-copied::after{position:absolute;display:grid;border-radius:5px;background:var(--surface-3);color:var(--text);content:"Copied";inset:-2px -5px;font-family:var(--font-ui);place-items:center}
.meta-chip.is-cwd{font-family:var(--font-mono);text-decoration:none}
.meta-chip.is-cwd:hover{color:var(--text);text-decoration:underline}
/* Which model is loud, not which colour it is: the hue stays provider-only, so
   capability rides prominence instead. Loud = fable/pro, the models against the
   weekly limit — the badge is telling you what this chat costs. */
.provider-badge{--agent:var(--claude);padding:2px 7px;border:1px solid currentColor;border-radius:10px;color:var(--agent);font-size:0.5625rem;font-weight:750}
.provider-badge.is-codex{--agent:var(--codex)}
.provider-badge[data-tier="quiet"]{border-color:var(--border);color:var(--text-muted)}
.provider-badge[data-tier="strong"]{background:color-mix(in srgb,var(--agent) 14%,transparent)}
.provider-badge[data-tier="loud"]{border-color:var(--agent);background:var(--agent);color:var(--bg);letter-spacing:.06em;text-transform:uppercase}
/* The phone gets the two chips that answer "where am I" and "what is it doing";
   the rest would cost transcript width to say what one tap already says. */
.meta-chip.is-id,.meta-chip.is-cwd{display:none}
.meta-chip.is-effort{color:var(--text-soft)}

/* The runtime cockpit — same instrument grammar as .chat-health next to it
   (uppercase label over a strong value), because they are read together: what
   this chat is, and what it is spending. Desktop only; the compact badge by the
   title covers narrower widths. */
.chat-runtime{--agent:var(--claude);display:none;min-height:48px;flex:none;align-items:stretch;overflow:hidden;padding:0;border:1px solid var(--border);border-radius:11px;background:var(--surface-1);cursor:pointer}
.chat-runtime.is-codex{--agent:var(--codex)}
.chat-runtime:hover{border-color:var(--border-strong);background:var(--surface-2)}
/* Line heights are explicit and the vertical inset is deliberately compact so
   even the padded loud-model badge fits inside .chat-health's 48px at Large
   text. The two boxes then keep one baseline instead of turning into a stair. */
.chat-runtime-item{display:grid;min-width:96px;align-content:center;gap:2px;padding:4px 12px;text-align:left}
.chat-runtime-item+.chat-runtime-item{border-left:1px solid var(--border)}
.chat-runtime-label{color:var(--text-muted);font-size:0.625rem;font-weight:700;letter-spacing:.025em;line-height:1.1;text-transform:uppercase}
.chat-runtime-value{display:flex;align-items:center;gap:7px}
.chat-runtime strong{color:var(--text);font-size:0.8125rem;font-weight:650;line-height:1.2}
/* Prominence again, at cockpit scale: every model is named, and how loudly it is
   named is what separates them. Only `loud` gets the fill. */
.chat-runtime-agent[data-tier=quiet]{color:var(--text-muted)}
.chat-runtime-agent[data-tier=normal],.chat-runtime-agent[data-tier=strong]{color:var(--agent)}
.chat-runtime-agent[data-tier=loud]{justify-self:start;padding:2px 7px;border-radius:6px;background:var(--agent);color:var(--bg);font-size:0.75rem;font-weight:750;letter-spacing:.04em;text-transform:uppercase}

@media (min-width: 561px) {
  .conversation-glyph{display:grid;width:34px;height:34px;flex:0 0 auto;place-items:center;border:1px solid color-mix(in srgb,var(--row-accent,var(--border-strong)) 45%,var(--border));border-radius:10px;background:color-mix(in srgb,var(--row-accent,var(--purple)) 16%,var(--surface-2));font-size:1rem}
  .conversation-chips{gap:7px}
  .meta-chip{padding:2px 8px;border:1px solid var(--border);border-radius:999px;background:var(--surface-1)}
  .meta-chip b{max-width:24ch}
  .meta-chip.is-effort,.meta-chip.is-id{display:flex}
  .meta-chip.is-id:hover,.meta-chip.is-cwd:hover{border-color:var(--border-strong);background:var(--surface-2)}
}

/* The cwd is the widest chip and the least urgent, so it waits for a width that
   can spend the room without pushing the others off the row. */
@media (min-width: 1200px) {
  .meta-chip.is-cwd{display:flex}
}
.activity-dot{position:absolute;top:7px;right:7px;width:7px;height:7px;border:2px solid var(--surface-0);border-radius:50%;background:var(--claude)}
#v2InspectorToggle{position:relative}

.surface-body{min-height:0;overflow:auto;overscroll-behavior:contain}
.empty-state { display: flex;width: min(100% - 32px, 560px);min-height: 100%;flex-direction: column;align-items: flex-start;justify-content: center;margin: 0 auto;padding: 48px 0 110px;}
.empty-mark { display: grid;width: 38px;height: 38px;place-items: center;margin-bottom: 20px;border: 1px solid var(--border-strong);border-radius: 11px;color: var(--purple);font-size: 1.125rem;font-weight: 850;}
.empty-state h2 { margin: 8px 0 10px;font-size: clamp(1.5rem, 4vw, 2.375rem);letter-spacing: -.04em;line-height: 1.08;}
.empty-state > p:last-child { max-width: 520px;margin: 0;color: var(--text-muted);font-size: 0.875rem;}

.composer-dock { position:relative;z-index:6;width:min(calc(100% - 32px),var(--composer-width));margin:0 auto;padding:12px 0 max(14px,env(safe-area-inset-bottom));background:linear-gradient(0deg,var(--bg) 72%,transparent)}
.composer-box { display:grid;min-height:76px;overflow:visible;border:1px solid color-mix(in srgb,var(--row-accent,var(--purple)) 38%,var(--border));border-radius:16px;background:var(--surface-1);box-shadow:0 0 0 3px color-mix(in srgb,var(--row-accent,var(--purple)) 4%,transparent),0 12px 34px rgb(0 0 0 / 14%);cursor:text;transition:border-color .18s ease,box-shadow .18s ease}
.composer-box:focus-within { border-color:color-mix(in srgb,var(--row-accent,var(--purple)) 64%,var(--border));box-shadow:0 0 0 3px color-mix(in srgb,var(--row-accent,var(--purple)) 12%,transparent),0 16px 40px rgb(0 0 0 / 20%)}
.composer-accessory-row { display:flex;min-height:31px;align-items:center;justify-content:space-between;gap:12px;padding:5px 8px 0 14px;color:var(--text-muted);font-size:0.625rem}
.composer-place{display:flex;min-width:0;align-items:center;gap:7px}.composer-place b{flex:0 0 auto;color:var(--row-accent,var(--purple));font-size:.5625rem;font-weight:800;letter-spacing:.065em;text-transform:uppercase}.composer-place b::after{margin-left:7px;color:var(--border-strong);content:"·"}.composer-place span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.composer-context-button { display:flex;min-height:25px;align-items:center;gap:6px;padding:0 8px;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--text-muted);cursor:pointer;font-size:0.625rem}
.composer-context-button:hover:not(:disabled),.composer-context-button[aria-expanded="true"] { border-color:var(--border);background:var(--surface-2);color:var(--text)}
.composer-context-button .icon { width:13px;height:13px}
.composer-context-button i { display:none;width:6px;height:6px;border-radius:50%;background:var(--purple)}
.composer-context-button.has-message-context i { display:block}
.composer-context-button:disabled { cursor:default;opacity:.45}
.composer-input-row { display:flex;min-height:44px;align-items:flex-end;gap:10px;padding:0 8px 8px 14px}
.composer-box textarea { min-height: 34px;max-height: 168px;min-width: 0;flex: 1;resize: none;border: 0;outline: 0;background: transparent;line-height: 1.45;padding: 7px 0 5px;overflow-y: auto;}
.composer-box textarea:disabled { color: var(--text-muted);opacity: 1;}
.send-button, .attach-button { display: grid;width: 36px;height: 36px;flex: 0 0 auto;place-items: center;border-radius: 8px;cursor: pointer;}
.send-button { background: var(--claude);color: white;transition:transform .14s cubic-bezier(.23,1,.32,1);}
.send-button:active:not(:disabled) { transform:scale(.97);}
.attach-button { background: transparent;color: var(--text-muted);}
.attach-button:hover:not(:disabled) { background: var(--surface-3);color: var(--text);}
.send-button:disabled { background: var(--surface-3);color: var(--text-muted);}
.attach-button:disabled { cursor: default;opacity: .45;}
.composer-dock > p { margin: 7px 0 0;color: var(--text-muted);font-size: 0.625rem;text-align: center;}

.inspector-panel { z-index: 30;display: flex;width: var(--inspector-width);min-width: 0;flex-direction: column;border-left: 1px solid var(--border);background: var(--surface-1);contain: layout paint;}
.inspector-head { display: flex;min-height: 72px;align-items: center;justify-content: space-between;padding: 0 14px 0 18px;border-bottom: 1px solid var(--border);}
.inspector-head h2 { margin: 4px 0 0;font-size: 1rem;}
/* Terminal is the inspector's stable working surface. Less frequent tools live
   in one labelled menu, so another tool never makes Terminal smaller. */
.inspector-tool-strip { position: relative;z-index: 4;display: grid;grid-template-columns: minmax(0, 1fr) minmax(92px, 34%);border-bottom: 1px solid var(--border);background: var(--surface-1);}
.inspector-primary-tool, .inspector-more-tool { display: flex;width: 100%;min-width: 0;min-height: 50px;align-items: center;justify-content:center;gap: 7px;border-bottom: 2px solid transparent;background: transparent;color: var(--text-muted);cursor:pointer;font-size: 0.6875rem;font-weight: 680;}
.inspector-primary-tool .icon, .inspector-more-tool .icon { width: 15px;height: 15px;flex: none;}
.inspector-primary-tool.is-active, .inspector-more-tool.is-active { border-color: var(--purple);background: color-mix(in srgb, var(--purple) 6%, transparent);color: var(--text);}
.inspector-tool-picker { position: relative;min-width: 0;}
.inspector-tool-picker > summary { list-style:none;}
.inspector-tool-picker > summary::-webkit-details-marker { display:none;}
.inspector-tools-menu { position: absolute;z-index: 8;top: calc(100% + 7px);right: 8px;width: min(250px, calc(100vw - 24px));padding: 7px;border: 1px solid var(--border-strong);border-radius: 12px;background: var(--surface-2);box-shadow: var(--shadow-panel);}
.inspector-tools-menu > p { margin: 4px 7px 7px;color: var(--text-muted);font-size: 0.5625rem;font-weight: 750;letter-spacing: .08em;text-transform: uppercase;}
.inspector-tool-row { display: grid;width: 100%;min-height: 42px;grid-template-columns: 24px minmax(0, 1fr) auto;align-items: center;gap: 8px;padding: 0 9px;border-radius: 8px;background: transparent;color: var(--text-soft);font-size: 0.75rem;text-align:left;}
.inspector-tool-row:hover, .inspector-tool-row:focus-visible { background: var(--surface-3);color: var(--text);}
.inspector-tool-row.is-active { background: color-mix(in srgb, var(--purple) 12%, transparent);color: var(--text);}
.inspector-tool-row .icon { width: 16px;height: 16px;color: var(--text-muted);}
/* Lives in shell.css, not docs.css: the count has to be readable before the
   Documents panel is opened, and docs.css loads lazily with that panel. */
.inspector-tab-count { min-width: 15px;padding: 0 4px;border-radius: 999px;background: var(--surface-3);color: var(--text-soft);font: 700 0.5rem/0.9375rem var(--font-ui);font-style: normal;text-align: center;white-space: nowrap;}
.inspector-tab-count[data-open="1"] { background: color-mix(in srgb, var(--state-attention) 24%, transparent);color: var(--state-attention);}
.inspector-tool-row.is-active .inspector-tab-count { color: var(--text);}
.inspector-body { padding: 16px;overflow: auto;}
.detail-card { display: flex;flex-direction: column;gap: 3px;padding: 14px;border: 1px solid var(--border);border-radius: var(--radius-md);background: var(--surface-0);}
.detail-card-head { display: flex;align-items: center;justify-content: space-between;gap: 12px;}
.detail-label { color: var(--text-muted);font-size: 0.625rem;font-weight: 750;letter-spacing: .06em;text-transform: uppercase;}
.detail-state-icon { display: grid;width: 28px;height: 28px;place-items: center;border: 1px solid color-mix(in srgb, var(--purple) 35%, var(--border));border-radius: 8px;background: color-mix(in srgb, var(--purple) 10%, transparent);color: var(--purple);}
.detail-state-icon .icon { width: 14px;height: 14px;}
.detail-card strong { margin-top: 5px;font-size: 1rem;letter-spacing: -.015em;}
.detail-card .muted { font-size: 0.6875rem;}
.detail-list { margin: 16px 0 0;}
.detail-list div { display: flex;min-height: 38px;align-items: center;justify-content: space-between;gap: 16px;border-bottom: 1px solid var(--border);}
.detail-list dt { display: flex;align-items: center;gap: 8px;color: var(--text-muted);font-size: 0.6875rem;}
.detail-list dt .icon { width: 15px;height: 15px;color: var(--text-soft);}
.detail-list dd { min-width: 0;overflow: hidden;margin: 0;font-size: 0.6875rem;text-align: right;text-overflow: ellipsis;white-space: nowrap;}
.detail-management { margin-top: 22px;}
.detail-management > .detail-label { display: block;margin: 0 0 8px;}
.management-button { display: grid;width: 100%;grid-template-columns: 34px minmax(0, 1fr);align-items: center;gap: 10px;padding: 11px;border: 1px solid var(--border);border-radius: var(--radius-md);background: var(--surface-0);color: var(--text);cursor: pointer;text-align: left;}
.management-button:hover { border-color: var(--border-strong);background: var(--surface-2);}
.management-button + .management-button { margin-top: 8px;}
.management-button:disabled { cursor: wait;opacity: .6;}
.management-icon { display: grid;width: 32px;height: 32px;place-items: center;border-radius: 9px;background: color-mix(in srgb, var(--claude) 10%, transparent);color: var(--claude);}
.management-icon .icon { width: 16px;height: 16px;}
.management-button.is-restore .management-icon { background: color-mix(in srgb, var(--codex) 10%, transparent);color: var(--codex);}
.management-button.is-restore .management-icon .icon { transform: rotate(180deg);}
.management-copy, .management-copy strong, .management-copy small { display: block;min-width: 0;}
.management-copy strong { font-size: 0.75rem;}
.management-copy small { margin-top: 2px;color: var(--text-muted);font-size: 0.625rem;line-height: 1.35;}
.management-status { display: block;margin-top: 8px;color: var(--claude);font-size: 0.6875rem;}

.terminal-panel { display: flex;min-height: 0;flex: 1;flex-direction: column;background: #090a0e;}
.terminal-toolbar { flex: none;border-bottom: 1px solid var(--border);background: #0d0e13;color: var(--text-muted);font-family: var(--font-mono);font-size: 0.625rem;}
.terminal-session-status { display: flex;min-height: 32px;align-items: center;justify-content: space-between;gap: 12px;padding: 0 12px;}
.terminal-session-status > span:first-child { display: inline-flex;align-items: center;gap: 7px;color: var(--text-soft);}
.terminal-dot { width: 7px;height: 7px;border-radius: 50%;background: var(--text-muted);}
.terminal-panel.is-connected .terminal-dot { background: var(--codex);}
.terminal-actions { display: flex;min-height: 42px;align-items:center;justify-content:flex-end;gap: 7px;padding: 0 9px 7px;}
.terminal-feedback { min-width:0;margin-right:auto;overflow:hidden;color:var(--text-muted);font-size:0.5625rem;text-overflow:ellipsis;white-space:nowrap;}
.terminal-feedback.is-error { color:var(--state-attention);}
.terminal-action { display:inline-flex;min-height:32px;align-items:center;justify-content:center;gap:6px;padding:0 10px;border:1px solid var(--border);border-radius:8px;background:var(--surface-2);color:var(--text-soft);font:650 0.625rem/1 var(--font-ui);white-space:nowrap;}
.terminal-action:hover:not(:disabled) { border-color:var(--border-strong);background:var(--surface-3);color:var(--text);}
.terminal-action.is-primary { border-color:color-mix(in srgb, var(--purple) 46%, var(--border));background:color-mix(in srgb, var(--purple) 16%, var(--surface-2));color:var(--text);}
.terminal-action:disabled { opacity:.42;}
.terminal-action .icon { width:13px;height:13px;}
.terminal-search { display:grid;min-height:42px;grid-template-columns:16px minmax(0,1fr) auto 30px 30px 30px;align-items:center;gap:5px;padding:0 9px 8px;}
.terminal-search[hidden] { display:none;}
.terminal-search > .icon { width:14px;height:14px;color:var(--text-muted);}
.terminal-search input { min-width:0;height:32px;padding:0 9px;border:1px solid var(--border-strong);border-radius:8px;background:var(--surface-0);color:var(--text);font:600 0.6875rem var(--font-mono);outline:none;}
.terminal-search input:focus { border-color:color-mix(in srgb,var(--purple) 70%,var(--border));box-shadow:0 0 0 2px color-mix(in srgb,var(--purple) 13%,transparent);}
.terminal-search output { min-width:42px;color:var(--text-muted);font-size:0.5625rem;text-align:center;white-space:nowrap;}
.terminal-search button { display:grid;width:30px;height:30px;place-items:center;border:1px solid var(--border);border-radius:7px;background:var(--surface-2);color:var(--text-soft);font:700 0.75rem var(--font-ui);}
.terminal-search button:hover:not(:disabled) { border-color:var(--border-strong);background:var(--surface-3);color:var(--text);}
.terminal-search button:disabled { opacity:.35;}
.terminal-host { min-height:0;flex:1;padding: 10px 8px 8px;overflow: hidden;}
.terminal-host .xterm, .terminal-host .xterm-viewport, .terminal-host .xterm-screen { height: 100% !important;}

.panel-scrim { position: fixed;z-index: 25;inset: 0;background: rgb(0 0 0 / 52%);cursor: default;}
.mobile-nav { display: none;}
.compact-only { display: none;}

/* Family mode — the household product, for an account that is allowed in but is
   not the owner (docs/roadmap.md §B1a). Home is everything it has, so the
   navigation to everywhere else goes rather than being disabled: a rail of
   buttons that all refuse is a worse answer than no rail.

   Stated once, over the CONTAINERS, so a nav item added later is hidden by
   default rather than by remembering to opt out. V1 did the same and never
   leaked an owner tab. The chat column goes too — it is the conversation list,
   which a family account has none of and cannot fetch. */
.app-shell.is-family .product-rail,
.app-shell.is-family .mobile-nav,
.app-shell.is-family .context-panel,
.app-shell.is-family .inspector-panel { display: none;}
/* The track has to go too, not just the element in it: a display:none child
   still leaves its grid column, which is the bug that left the canvas at 340px
   of a 1440px window when Home first hid the conversation panel. Last, and
   with the attribute selectors above it, so it wins for every surface. */
.app-shell.is-family,
.app-shell.is-family[data-surface="home"] { grid-template-columns: minmax(0, 1fr);}

.surface-placeholder { display: grid;min-height: 100%;place-items: center;padding: 32px;text-align: center;}
.surface-placeholder div { max-width: 420px;}
.surface-placeholder h2 { margin: 8px 0;font-size: 1.75rem;letter-spacing: -.035em;}
.surface-placeholder p { margin: 0;color: var(--text-muted);}

@media (min-width: 1440px) {
  .app-shell.terminal-active { --inspector-width: min(640px, 42vw);}
  .app-shell.has-inspector { grid-template-columns: var(--rail-width) var(--context-width) minmax(0, 1fr) var(--inspector-width);}
  .app-shell:not(.has-inspector) .inspector-panel { display: none;}
  .app-shell.has-inspector .inspector-panel { grid-column: 4;}
  .app-shell.has-inspector .panel-scrim { display: none !important;}
}

@media (max-width: 1439px) {
  .inspector-panel { position: fixed;top: 0;right: 0;bottom: 0;transform: translateX(100%);}
  .app-shell.has-inspector .inspector-panel { transform: translateX(0);box-shadow: var(--shadow-panel);}
  .app-shell.terminal-active .inspector-panel { width: min(720px, 92vw);}
}

@media (max-width: 959px) {
  .app-shell { grid-template-columns: var(--rail-width) minmax(0, 1fr);}
  .context-panel { position: fixed;z-index: 30;top: 0;bottom: 0;left: var(--rail-width);width: var(--context-width);transform: translateX(-110%);box-shadow: var(--shadow-panel);}
  .app-shell.has-context .context-panel { transform: translateX(0);}
  .compact-only { display: inline-grid;}
}

@media (max-width: 560px) {
  .app-shell { display: block;padding-bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom));}
  .product-rail { display: none;}
  .context-panel { left: 0;width: min(88vw, 330px);}
  .conversation-tools{grid-template-columns:minmax(0,1fr) 42px;padding:11px 10px 6px}
  .conversation-filter-menu{position:fixed;top:auto;right:8px;bottom:calc(var(--mobile-nav-height) + env(safe-area-inset-bottom) + 8px);left:8px;max-height:min(72dvh,620px);border-radius:16px}
  .filter-menu-body{max-height:calc(min(72dvh,620px) - 58px)}
  .filter-grid{gap:8px}
  .active-filters{padding-inline:10px}
  .main-canvas { --canvas-height: calc(100dvh - var(--mobile-nav-height) - env(safe-area-inset-bottom));height: var(--canvas-height);grid-template-rows: 56px auto minmax(0, 1fr) auto;}
  /* The phone header is one priority row: drawer, title + run-state dot,
     context, inspector, actions. Workspace/model/effort already have complete
     labelled rows in the overflow menu, so repeating them here only clipped a
     second metadata line under the divider on 390px screens. */
  .conversation-head{gap:7px;padding:0 8px}
  .conversation-head>.icon-button{width:40px;height:40px}
  .conversation-head .chat-overflow-button{width:40px;height:40px}
  .conversation-identity{display:flex;align-items:center;gap:7px}
  .title-line{min-width:0;flex:1}
  .title-line h1{min-width:0;flex:1;font-size:.875rem}
  .provider-badge,.workspace-kicker,.conversation-meta{display:none}
  .conversation-chips{flex:0 0 auto;gap:0;margin:0;font-size:.625rem}
  .conversation-chips>:not(.is-status){display:none!important}
  .meta-chip.is-status{position:relative;width:10px;height:10px;flex:0 0 10px;gap:0;overflow:visible}
  .meta-chip.is-status .meta-dot{width:8px;height:8px}
  .meta-chip.is-status b{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}
  .workspace-row{grid-template-columns:minmax(0,1fr) 44px 44px}
  .workspace-settings,.workspace-theme-toggle{width:44px;height:44px}
  .workspace-theme-toggle i{width:16px;height:16px}.workspace-quick-palette{justify-content:space-between;padding:7px 8px 10px}.workspace-quick-palette button{width:34px;height:34px;border-radius:9px}
  .workspace-open{min-height:44px}
  .new-chat-workspace{gap:7px;margin-inline:9px}
  .new-chat-workspace>span{font-size:0.75rem}
  .new-chat-workspace select{height:42px;font-size:0.8125rem}
  /* A create flow is a decision, not another menu. Dim the drawer it came from
     and give the form nearly the full drawer width so workspace/model labels do
     not wrap into noise. It remains anchored below the drawer header, keeping
     the + button available as the familiar close affordance. */
  .context-panel:has(.provider-picker:not([hidden]))::after{position:absolute;z-index:44;inset:0;background:rgb(5 6 10 / 68%);content:"";pointer-events:none;backdrop-filter:blur(2px)}
  .provider-picker{position:fixed;top:68px;right:12px;left:12px;width:auto;max-height:calc(100dvh - 80px);padding:12px;overflow-y:auto;border-radius:16px}
  .provider-picker-close{width:40px;height:40px}
  .empty-state { width: min(100% - 36px, 480px);align-items: center;padding: 36px 0 80px;text-align: center;}
  .empty-state h2 { font-size: 1.75rem;}
  /* The dock's row is auto-sized, so with the keyboard up a Portal context and a
     couple of attachments grew it past the canvas and overflow:hidden ate the
     bottom of it — you were typing into a box whose text and Send button were
     below the clip. Capped here to leave the header and a sliver of transcript,
     and laid out so the extras are what shrinks: the input is never the thing
     that loses room. */
  .composer-dock { display: flex;width: 100%;max-height: calc(var(--canvas-height) - 116px);flex-direction: column;min-height: 0;padding: 8px 10px 10px;background: var(--bg);}
  .composer-dock > p { display: none;}
  /* Shrink order, tightest space last: the Portal context collapses first (it is
     a disclosure, and it scrolls), then the tray — which should never need to,
     but absorbs the drift if a card ever grows taller than the budget below
     assumes. The box is the one thing that never gives up room. */
  .composer-prepend-host { min-height: 0;flex: 0 100 auto;overflow-y: auto;}
  .composer-attachment-host { min-height: 0;flex: 0 1 auto;overflow: auto;}
  .composer-attachment-host:not([hidden]) { min-height:80px;flex-shrink:0;margin-bottom:6px;}
  .composer-box { flex:0 0 auto;min-height:72px;border-radius:14px}
  .composer-accessory-row { min-height:29px;padding-left:11px}
  .composer-input-row { gap:6px;padding-right:6px;padding-left:8px}
  /* A phone that has given half its height to the keyboard cannot spend 168px on
     the draft, so the cap is what the dock can actually hand the box: the canvas
     less the reserved header and transcript sliver (116), the dock's padding and
     the box's own chrome (36), the collapsed context row's margin (8) — and 100
     more once a tray of attachments sits above it. Full-height phones land on
     the 168 they always had. resizeInput() reads this back, so the JS and the
     stylesheet cannot disagree about how tall the draft is. */
  .composer-box textarea { max-height: clamp(34px, calc(var(--canvas-height) - 160px), 168px);}
  .composer-dock.has-attachments .composer-box textarea { max-height: clamp(34px, calc(var(--canvas-height) - 260px), 168px);}
  .inspector-panel { width: min(92vw, 350px);}
  .app-shell.terminal-active .inspector-panel { width: 100vw;}
  .mobile-nav { position: fixed;z-index: 20;right: 0;bottom: 0;left: 0;display: grid;height: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom));grid-template-columns: repeat(4, minmax(0, 1fr));padding: 5px 6px env(safe-area-inset-bottom);border-top: 1px solid var(--border);background: var(--surface-0);}
  .mobile-nav button { position: relative;display: flex;min-width:0;flex-direction: column;align-items: center;justify-content: center;gap: 3px;background: transparent;color: var(--text-muted);font-size: 0.625rem;}
  .mobile-nav button.is-active { color: var(--claude);}
  .mobile-nav .icon { width: 20px;height: 20px;}
}

@media (min-width: 960px) {
  :root {
    --rail-width: 76px;
    --context-width: 340px;
    --inspector-width: 380px;
    --reading-width: 900px;
    --composer-width: 900px;
  }

  body { font-size: 0.9375rem;}
  .rail-brand { height: 84px;}
  .rail-brand .brand-mark { width: 38px;height: 38px;border-radius: 11px;font-size: 1.1875rem;}
  .rail-nav { gap: 7px;padding: 10px;}
  .rail-item { min-height: 64px;gap: 5px;font-size: 0.6875rem;}
  .rail-item .icon { width: 23px;height: 23px;}
  .rail-item.is-active::before { left: -10px;height: 34px;}
  .rail-footer { gap: 17px;padding: 20px 0;}
  .avatar { width: 34px;height: 34px;font-size: 0.75rem;}

  .context-head { min-height: 84px;padding: 0 18px 0 22px;}
  .context-head h1 { font-size: 1.1875rem;}
  .icon-button { width: 40px;height: 40px;}
  .icon-button .icon { width: 22px;height: 22px;}
  .conversation-tools{grid-template-columns:minmax(0,1fr) 44px;padding:16px 14px 8px}
  .search-box { height: 44px;padding: 0 12px;}
  .conversation-filter-toggle{width:44px;height:44px}
  .search-box input { font-size: 0.8125rem;}
  .search-box .icon { width: 18px;height: 18px;}
  .context-section { padding: 12px 10px;}
  .provider-picker { width: 290px;padding: 10px;}
  .provider-picker-label { margin: 4px 9px 9px;font-size: 0.6875rem;}
  .provider-choice { grid-template-columns: 38px minmax(0, 1fr);gap: 11px;padding: 10px;}
  .provider-choice-glyph { width: 36px;height: 36px;font-size: 0.9375rem;}
  .provider-choice strong { font-size: 0.875rem;}
  .provider-choice small { font-size: 0.6875rem;}
  .scope-button { gap: 8px;font-size: 0.8125rem;}
  .section-heading { height: 36px;padding: 0 9px;}
  .section-heading h2 { font-size: 0.75rem;}
  .count-badge { min-width: 24px;padding: 2px 7px;font-size: 0.6875rem;}
  .chat-row { min-height: 72px;grid-template-columns: 40px minmax(0, 1fr) auto;gap: 11px;padding: 9px 10px 9px 13px;}
  .chat-glyph { width: 40px;height: 40px;border-radius: 11px;font-size: 1.0625rem;}
  .chat-title { font-size: 0.9375rem;}
  .chat-sub { gap: 6px;margin-top: 5px;font-size: 0.625rem;}
  .chat-time { font-size: 0.625rem;}
  .chat-state { width: 7px;height: 7px;}
  .workspace-row { min-height: 44px;gap: 10px;padding: 5px 9px;font-size: 0.875rem;}
  .workspace-icon { width: 22px;font-size: 0.9375rem;}
  .workspace-count { font-size: 0.75rem;}

  .main-canvas { grid-template-rows: 90px auto minmax(0, 1fr) auto;}
  .conversation-head { gap: 14px;padding: 3px clamp(22px, 3vw, 48px) 0;}
  .title-line { gap: 11px;}
  .title-line h1 { font-size: 1.25rem;}
  .conversation-meta { margin-top: 4px;font-size: 0.75rem;}
  .conversation-chips { margin-top: 5px;font-size: 0.6875rem;}
  .conversation-glyph { width: 42px;height: 42px;border-radius: 12px;font-size: 1.25rem;}
  /* The cockpit takes over from the badge here: it says strictly more, and two
     controls for one fact is how they drift apart. */
  .provider-badge { display: none;}
  .chat-runtime { display: flex;}
  .meta-chip.is-effort { display: none;}
  .empty-mark { width: 44px;height: 44px;font-size: 1.3125rem;}
  .empty-state > p:last-child { font-size: 0.9375rem;}
  .composer-dock { padding-top: 14px;}
  .composer-box { min-height: 60px;padding: 10px 10px 10px 17px;}
  .composer-box textarea { min-height: 38px;padding: 8px 0 6px;font-size: 0.9375rem;line-height: 1.45;}
  .send-button, .attach-button { width: 40px;height: 40px;}
  .composer-dock > p { font-size: 0.6875rem;}

  .inspector-head { min-height: 84px;padding: 0 16px 0 22px;}
  .inspector-head h2 { font-size: 1.25rem;}
  .inspector-primary-tool, .inspector-more-tool { min-height:56px;font-size:0.75rem;}
  .inspector-primary-tool .icon, .inspector-more-tool .icon { width:17px;height:17px;}
  .inspector-body { padding: 21px;}
  .detail-card { min-height: 118px;gap: 5px;justify-content: center;padding: 20px;}
  .detail-label { font-size: 0.6875rem;}
  .detail-state-icon { width: 36px;height: 36px;border-radius: 10px;}
  .detail-state-icon .icon { width: 18px;height: 18px;}
  .detail-card strong { margin-top: 7px;font-size: 1.25rem;}
  .detail-card .muted, .detail-list dt, .detail-list dd { font-size: 0.8125rem;}
  .detail-list { display: grid;gap: 8px;margin-top: 20px;}
  .detail-list div { min-height: 52px;padding: 0 13px;border: 1px solid var(--border);border-radius: 10px;background: var(--surface-0);}
  .detail-list dt { gap: 9px;}
  .detail-list dt .icon { width: 17px;height: 17px;}
  .detail-list dd { max-width: 55%;font-weight: 650;}
  .detail-management { margin-top: 26px;}
  .detail-management > .detail-label { margin-bottom: 10px;}
  .management-button { grid-template-columns: 40px minmax(0, 1fr);gap: 12px;padding: 14px;}
  .management-icon { width: 38px;height: 38px;border-radius: 10px;}
  .management-icon .icon { width: 19px;height: 19px;}
  .management-copy strong { font-size: 0.875rem;}
  .management-copy small { margin-top: 3px;font-size: 0.75rem;}
  .management-status { font-size: 0.75rem;}
  .terminal-toolbar { font-size: 0.6875rem;}
  .terminal-session-status { min-height:36px;padding:0 15px;}
  .terminal-actions { min-height:46px;padding:0 11px 8px;}
  .terminal-action { min-height:34px;padding-inline:12px;font-size:0.6875rem;}
  .terminal-host { padding: 12px 10px 10px;}
}

/* The ladder used to step 900 → 1280 at 1800px, so every ordinary monitor read
   at the 900px width chosen for a 960px laptop. This is the tier that was
   missing: past 1600px the canvas has hundreds of pixels of margin to spend. */
@media (min-width: 1600px) {
  :root {
    --reading-width: 1040px;
    --composer-width: 1040px;
  }
}

@media (min-width: 1800px) {
  :root {
    --rail-width: 84px;
    --context-width: 400px;
    --inspector-width: 440px;
    --reading-width: 1600px;
    --composer-width: 1440px;
  }

  body { font-size: 1rem;}
  .app-shell:not(.has-inspector) { --reading-width: 1800px;}
  .rail-nav { padding-inline: 12px;}
  .rail-item { font-size: 0.75rem;}
  .context-head { padding: 0 22px 0 27px;}
  .context-head h1, .inspector-head h2 { font-size: 1.375rem;}
  .context-head .eyebrow, .inspector-head .eyebrow { font-size: 0.75rem;}
  .context-head .icon-button, .inspector-head .icon-button { width: 44px;height: 44px;}
  .context-head .icon-button .icon, .inspector-head .icon-button .icon { width: 24px;height: 24px;}
  .conversation-tools{grid-template-columns:minmax(0,1fr) 50px;padding:18px 16px 9px}
  .search-box { height: 50px;padding: 0 14px;gap: 10px;}
  .conversation-filter-toggle{width:50px;height:50px}
  .search-box input { font-size: 0.9375rem;}
  .search-box .icon { width: 20px;height: 20px;}
  .search-box kbd { padding: 2px 6px;font-size: 0.6875rem;}
  .provider-picker { width: 310px;}
  .provider-choice { grid-template-columns: 44px minmax(0, 1fr);padding: 12px;}
  .provider-choice-glyph { width: 42px;height: 42px;border-radius: 11px;font-size: 1.0625rem;}
  .provider-choice strong { font-size: 1rem;}
  .provider-choice small { font-size: 0.75rem;}
  .context-section { padding: 13px 12px;}
  .scope-button { font-size: 0.875rem;}
  .section-heading { height: 40px;padding: 0 11px;}
  .section-heading h2 { font-size: 0.8125rem;}
  .count-badge { min-width: 26px;padding: 3px 8px;font-size: 0.75rem;}
  .chat-list { gap: 4px;}
  .chat-row { min-height: 80px;grid-template-columns: 44px minmax(0, 1fr) auto;gap: 13px;padding: 11px 14px 11px 16px;}
  .chat-glyph { width: 44px;height: 44px;border-radius: 12px;font-size: 1.1875rem;}
  .chat-title { font-size: 1rem;font-weight: 680;}
  .chat-sub { gap: 7px;margin-top: 6px;font-size: 0.6875rem;}
  .chat-time { padding-top: 4px;font-size: 0.6875rem;}
  .chat-state { width: 8px;height: 8px;}
  .workspace-row { min-height: 52px;gap: 12px;padding: 7px 11px;font-size: 0.9375rem;}
  .workspace-icon { width: 24px;font-size: 1.0625rem;}
  .workspace-count { font-size: 0.8125rem;}
  .conversation-head { padding-inline: clamp(28px, 2.5vw, 60px);}
  .title-line h1 { font-size: 1.4375rem;}
  .inspector-head { padding: 0 20px 0 27px;}
  .inspector-primary-tool, .inspector-more-tool { min-height:62px;font-size:0.8125rem;}
  .inspector-primary-tool .icon, .inspector-more-tool .icon { width:19px;height:19px;}
  .inspector-body { padding: 28px;}
  .detail-card { min-height: 148px;gap: 7px;padding: 24px;}
  .detail-label { font-size: 0.75rem;}
  .detail-state-icon { width: 42px;height: 42px;border-radius: 12px;}
  .detail-state-icon .icon { width: 21px;height: 21px;}
  .detail-card strong { margin-top: 9px;font-size: 1.5rem;}
  .detail-card .muted { font-size: 0.875rem;}
  .detail-list { gap: 10px;margin-top: 24px;}
  .detail-list div { min-height: 64px;padding: 0 16px;border-radius: 12px;}
  .detail-list dt, .detail-list dd { font-size: 0.875rem;}
  .detail-list dt { gap: 11px;}
  .detail-list dt .icon { width: 19px;height: 19px;}
  .detail-management { margin-top: 30px;}
  .management-button { grid-template-columns: 46px minmax(0, 1fr);gap: 14px;padding: 16px;}
  .management-icon { width: 44px;height: 44px;border-radius: 12px;}
  .management-icon .icon { width: 22px;height: 22px;}
  .management-copy strong { font-size: 1rem;}
  .management-copy small { font-size: 0.8125rem;}
}

.surface-error{display:grid;min-height:100%;align-content:center;justify-items:center;gap:12px;padding:32px;text-align:center}
.surface-error p{max-width:34ch;margin:0;color:var(--text-muted);font-size:0.8125rem}
.surface-error .primary-button{width:auto;padding:0 22px;align-self:center}

/* Desktop scrollbars. The platform bar is a grey slab that ignores the theme;
   this is a floating rounded thumb on a transparent track, sized by a
   transparent border so it reads as inset. Phones keep their overlay bar. */
@media (min-width: 561px) {
  ::-webkit-scrollbar { width: 12px; height: 12px; }
  ::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
  ::-webkit-scrollbar-thumb {
    border: 3px solid transparent;
    border-radius: 999px;
    background: var(--border-strong);
    background-clip: padding-box;
  }
  ::-webkit-scrollbar-thumb:hover { background: #4a5163; background-clip: padding-box; }
  ::-webkit-scrollbar-thumb:active { background: var(--purple); background-clip: padding-box; }
  /* The transcript is centred, so a scrollbar appearing must not shove it
     sideways — reserve the gutter on both edges and it stays put. */
  .surface-body { scrollbar-gutter: stable both-edges; }
}
