/* Theme variables — override these in ~/.deepsteve/themes/*.css */
:root {
  --ds-bg-primary: #0d1117;
  --ds-bg-secondary: #161b22;
  --ds-bg-tertiary: #21262d;
  --ds-border: #30363d;
  --ds-text-primary: #c9d1d9;
  --ds-text-secondary: #8b949e;
  --ds-text-bright: #f0f6fc;
  --ds-accent-green: #238636;
  --ds-accent-green-hover: #2ea043;
  --ds-accent-green-active: #1a7f37;
  --ds-accent-red: #f85149;
  --ds-accent-blue: #58a6ff;
  --ds-btn-neutral: #30363d;
  --ds-btn-neutral-hover: #3d444d;
  --ds-btn-neutral-active: #272c33;
  --ds-accent-orange: #f0883e;
  --ds-accent-green-soft: #3fb950;
  --ds-issue-bolt: #f5c518;        /* GitHub-issue ⚡ glyph — was a colored emoji until #552 flattened it to a currentColor SVG; theme-overridable */
  --ds-selected-bg: #1f3a2e;
  --ds-overlay: rgba(0, 0, 0, 0.7);
  --ds-shadow: rgba(0, 0, 0, 0.4);
  --ds-reconnect-overlay: rgba(13, 17, 23, 0.75);
  --ds-reconnect-glow: rgba(240, 136, 62, 0.3);
  --ds-reconnect-dot: var(--ds-accent-orange);

  /* Context panel (left rail) — fully theme-overridable. Base theme keeps it a
     flush, square-edged column; themes (e.g. retro-monitor) round it and add a
     gap/shadow so it reads like a distinct panel. */
  --ds-context-width: 200px;
  --ds-context-bg: var(--ds-bg-secondary);
  --ds-context-border: 1px solid var(--ds-border);   /* full shorthand so a theme can set a thick bezel */
  --ds-context-radius: 0px;
  --ds-context-gap: 0px;
  --ds-context-shadow: none;
}

* { margin: 0; box-sizing: border-box; }
html, body { overscroll-behavior: none; }  /* Prevent swipe back/forward gestures */
body { background: var(--ds-bg-primary); color: var(--ds-text-primary); font-family: system-ui; height: 100vh; overflow: hidden; touch-action: none; }

/* App container - flexbox for layout switching.
   Always a row: [ #context-rail | #app-main ]. #app-main owns the horizontal /
   vertical tab-layout switch (it is the column that #tabs + #content-row live in),
   so the context rail can sit full-height to the left of everything. */
#app-container { display: flex; flex-direction: row; height: 100vh; }
#app-main { display: flex; flex-direction: column; flex: 1; min-width: 0; min-height: 0; }

/* Tabs - horizontal layout (default) */
#tabs { display: flex; gap: 2px; padding: 4px 8px; background: var(--ds-bg-secondary); align-items: center; flex-shrink: 0; }
#tabs-list-wrapper { display: flex; min-width: 0; overflow: hidden; align-items: center; gap: 6px; }
#tabs-list { display: flex; gap: 2px; overflow-x: auto; min-width: 0; scrollbar-width: none; }
#tabs-list::-webkit-scrollbar { display: none; }

/* Tab scroll arrows */
#tabs-arrows { display: none; align-items: center; gap: 2px; flex-shrink: 0; }
#tabs-arrows.visible { display: flex; }
.tabs-arrow { display: flex; align-items: center; justify-content: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--ds-border); border-radius: 50%; cursor: pointer; background: var(--ds-bg-tertiary); color: var(--ds-text-secondary); font-size: 12px; line-height: 1; }
.tabs-arrow:hover:not(.disabled) { background: var(--ds-border); color: var(--ds-text-bright); }
.tabs-arrow.disabled { opacity: 0.3; cursor: default; }
.tabs-arrow::after { font-family: system-ui; }
#tabs-arrow-start::after { content: '\2039'; }
#tabs-arrow-end::after { content: '\203A'; }

#tabs-spacer { flex: 1; }

/* Layout toggle button */
.layout-btn { padding: 4px 8px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-secondary); border-radius: 4px; cursor: pointer; font-size: 14px; margin-right: 8px; line-height: 1; }
.layout-btn:hover { background: var(--ds-border); color: var(--ds-text-primary); }

/* ── Nav buttons: the tab strip's chrome ───────────────────────────────────────────────────────
   Every chrome button in #tabs — #context-toggle, #layout-toggle, #new-btn, #issue-btn, the
   .dropdown-btns, #settings-btn, and mod-manager's .mod-toolbar-btns — is an [icon][label] pair,
   the same shape .tab already uses. The icon is unconditional: it is the one thing the button
   always has, in every layout. Only the LABEL varies. Making the icon conditional too is what
   turns this into a per-button branch, which is how the cluster ended up in three alignments and
   two insets (#552). Icons are inline SVG in index.html; here they are only sized. */
.nav-btn { display: inline-flex; align-items: center; gap: 6px; }
.btn-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 16px; height: 16px; }
.btn-icon > svg { width: 100%; height: 100%; display: block; }
/* .mod-toolbar-btn's icon is a character from tabIcon(), not an SVG — a mod's identity is derived
   from its name, not authored. Sized into the same 16px box so the rail's chrome column stays one
   width. No chip behind the monogram, unlike .tab .tab-icon: these are chrome, and the bare mark
   matches the SVGs beside them. */
.btn-icon.is-text { font-size: 11px; font-weight: 600; line-height: 1; }
.btn-icon.is-text.is-emoji { font-size: 13px; font-weight: 400; }

/* The label drops in exactly two places: the horizontal strip, for buttons it has always identified
   by their glyph alone (.is-glyph — those pixels belong to #tabs-list), and the collapsed rail, for
   everyone. display:none rather than the `font-size: 0` this replaced — font-size is a TEXT trick,
   so any theme setting `font-size: …!important` on these buttons defeated it. themes/ascii-art.css
   does exactly that, and under it the 48px rail rendered the full word "Sessions" crammed into 36px
   with the rail's glyph on top of it. display:none on a span can't be reached by a font-size
   override, so the bug is gone by construction rather than patched for one theme (#552). */
#app-container:not(.vertical-layout) .nav-btn.is-glyph > .btn-label,
#app-container.vertical-layout.icon-rail .nav-btn > .btn-label { display: none; }

/* The layout is already a class on #app-container, so the toggle's icon is DERIVED from it rather
   than mirrored into it. Both icons ship in the markup and this picks one. Until #552 the glyph had
   three owners: layout-manager.js set `▤` in one branch and `⬜` in the other, and index.html
   carried a third copy — which is the same two-constants-that-must-agree shape as the 140px floor
   this issue opened with. */
#app-container .icon-layout-v,
#app-container.vertical-layout .icon-layout-h { display: none; }
#app-container.vertical-layout .icon-layout-v { display: inline-flex; }

/* Sidebar resizer - hidden in horizontal mode */
#sidebar-resizer { display: none; }

/* Tab styling */
.tab { padding: 6px 12px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 6px 6px 0 0; cursor: pointer; color: var(--ds-text-secondary); font-size: 13px; display: flex; align-items: center; gap: 6px; flex-shrink: 1; min-width: 80px; max-width: 250px; user-select: none; }
.tab.active { background: var(--ds-bg-primary); color: var(--ds-text-bright); border-bottom-color: var(--ds-bg-primary); }
.tab .close { opacity: 0.5; cursor: pointer; font-size: 11px; }
.tab .close:hover { opacity: 1; color: var(--ds-accent-red); }
.tab .badge { width: 8px; height: 8px; background: var(--ds-accent-blue); border-radius: 50%; display: inline-block; visibility: hidden; flex-shrink: 0; }
.tab .badge.visible { visibility: visible; }
.tab .speaker-icon { display: none; flex-shrink: 0; width: 13px; height: 13px; color: var(--ds-accent-blue); }
.tab .speaker-icon.active { display: inline-flex; align-items: center; }
.tab .speaker-icon svg { width: 100%; height: 100%; }
.tab .tab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Per-tab identity (see tabIcon() in tab-manager.js), hidden everywhere by default. It is shown in
   exactly one place — the collapsed icon rail — where it is all that's left of the tab. Anywhere a
   label is visible the glyph is redundant at best and duplicated at worst: `⏰ ASO Daily Report`
   would render its emoji as both the icon and the first character of its own label. */
.tab .tab-icon { display: none; }
.tab.placeholder { animation: tab-connecting 1.2s ease-in-out infinite; }
@keyframes tab-connecting { 0%, 100% { opacity: 0.4; } 50% { opacity: 0.8; } }
/* Connection down (#556): the badge slot becomes a pulsing dot. Must follow
   .tab .badge.visible (equal specificity) so it overrides the blue
   unseen-activity dot while the socket is down; blue returns on reconnect
   since the .visible class is untouched underneath. */
.tab.reconnecting .badge { visibility: visible; background: var(--ds-reconnect-dot); animation: pulse 1.5s ease-in-out infinite; }
.tab.dragging { opacity: 0.3; }
.tab-drag-ghost { opacity: 0.9; box-shadow: 0 4px 12px rgba(0,0,0,0.5); }
#tabs-list.tab-drag-active { user-select: none; }
#tabs-list.tab-drag-active .tab:not(.dragging) { pointer-events: none; transition: transform 0.15s ease; }
#tabs.tab-switch-mode { outline: 2px solid var(--ds-accent-blue); outline-offset: -2px; border-radius: 4px; }

/* Vertical layout mode — #app-container is always a row; the horizontal/vertical
   switch flips #app-main (the tabs+content column) into a row so #tabs becomes a
   left sidebar. The context rail stays left of #app-main in both modes. */
#app-container.vertical-layout #app-main { flex-direction: row; }

/* No height here on purpose: #tabs is a child of #app-main, not of the viewport, so 100vh
   overflowed every theme that insets the app (body padding + bezel) and the overflow was
   clipped away — taking the ⚙ with it (#550). #app-main is a flex row in this mode, so its
   default align-items:stretch already gives #tabs exactly the right height. */
/* --ds-rail-width is the ONE floor shared by BOTH collapsible rails — the vertical tab
   bar (#552) and the context rail (#569) — and CSS owns it: layout-manager.js and
   context-views.js both read it back with getComputedStyle instead of keeping a copy, so
   the two rails collapse to identical squares. It lives on the base #app-container (not
   the .vertical-layout variant) because the context rail exists in both layouts. #550
   shipped a JS `MIN_SIDEBAR_WIDTH = 140` *and* a CSS `min-width: 140px` that had to agree
   by hand — and because the JS floor was applied on drag AND re-applied to the restored
   value on init, the sidebar could not be taken below 140px by dragging or by editing
   localStorage. Collapsing was unreachable by construction (#552). Themes can override this
   var; nothing else may reintroduce a second floor. */
#app-container { --ds-rail-width: 48px; }

#app-container.vertical-layout #tabs {
  flex-direction: column;
  align-items: stretch;
  padding: 12px 10px;
  gap: 2px;
  flex-shrink: 0;
  min-width: var(--ds-rail-width);
  border-right: none;
  box-shadow: 1px 0 0 0 var(--ds-border);
}

/* align-items:stretch is load-bearing — the base rule's `center` is for the horizontal strip, where
   the cross axis is vertical. Flipped to a column here the cross axis becomes horizontal, so
   `center` sized #tabs-list to its max-content (the widest tab's full label) and centred it,
   overhanging this wrapper equally on both sides. overflow:hidden then cropped both ends, so a name
   lost its start AND its end: `deepsteve-experimental` rendered as `epsteve-experimen` (#550).
   Stretching constrains the list to the sidebar; .tab-label then shrinks on its own (a flex item's
   automatic minimum size is 0 once it has overflow:hidden) and ellipsizes at the end. */
#app-container.vertical-layout #tabs-list-wrapper {
  flex-direction: column;
  align-items: stretch;
  flex: 1;
  min-height: 0;
  gap: 2px;
}

#app-container.vertical-layout #tabs-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  min-width: 0;
}

#app-container.vertical-layout #tabs-arrows { gap: 4px; justify-content: center; }
#app-container.vertical-layout .tabs-arrow { border: none; background: transparent; border-radius: 6px; transition: background 0.15s ease; }
#app-container.vertical-layout .tabs-arrow:hover:not(.disabled) { background: var(--ds-bg-tertiary); }
#app-container.vertical-layout #tabs-arrow-start::after { content: '\25B2'; }
#app-container.vertical-layout #tabs-arrow-end::after { content: '\25BC'; }

#app-container.vertical-layout #tabs-spacer { display: none; }

#app-container.vertical-layout .layout-btn { margin-right: 0; margin-bottom: 12px; border: none; background: transparent; border-radius: 8px; transition: background 0.15s ease; }
#app-container.vertical-layout .layout-btn:hover { background: var(--ds-bg-tertiary); }

#app-container.vertical-layout .tab {
  border-radius: 8px;
  width: 100%;
  max-width: none;
  min-width: 0;
  position: relative;
  padding: 8px 12px;
  padding-right: 28px;
  border: none;
  background: transparent;
  transition: background 0.15s ease;
}
#app-container.vertical-layout .tab:hover { background: var(--ds-bg-tertiary); }
#app-container.vertical-layout .tab.active {
  background: var(--ds-bg-tertiary);
}
#app-container.vertical-layout .tab.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 16px;
  background: var(--ds-accent-blue);
  border-radius: 0 3px 3px 0;
}

/* Always visible (like horizontal mode), never hover-only: there is no hover on touch or on the
   Quest browser, so a hover-gated close button cannot be reached there at all (#550). */
#app-container.vertical-layout .tab .close {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0.5;
  background: transparent;
  padding: 2px 4px;
  border-radius: 4px;
  transition: opacity 0.15s ease, background 0.15s ease;
}

#app-container.vertical-layout .tab .close:hover {
  opacity: 1;
  background: var(--ds-bg-tertiary);
}

/* ── Bottom cluster ───────────────────────────────────────────────────────────────────────────
   One shape, one alignment, one inset. Before #552 this was four rows in three alignments and two
   insets: #new-btn-group was a flex row, #issue-btn took the UA default (centred) because nothing
   ever set text-align on it, .dropdown-btn was text-align:left at a 10px inset, and #settings-btn
   was left at an 8px one — by luck, because it also carries .dropdown-btn while keeping its own
   base `padding: 0 8px`. Declaring the shape ONCE on .nav-btn is what makes them agree; every
   per-id rule below is spacing BETWEEN rows, never inside one.
   flex-shrink:0 across the cluster keeps it at its natural size; #tabs-list-wrapper is the
   flex:1/min-height:0 item, so the tab list is what shrinks. #tabs itself must NOT get an overflow
   value — .dropdown-menu escapes it via left:100% and would be clipped (#550). */
#app-container.vertical-layout .nav-btn {
  width: 100%;
  /* The 10px inset and the 16px .btn-icon are chosen together, against the rail's geometry rather
     than by eye. #tabs' rail padding is `12px 6px`, leaving 36px of content: a centred 16px icon
     lands at x=10 within it, centre 18 — and .tab's 22px rail chip lands at 7, centre 18 too. So
     in the collapsed rail the nav icons and the tab chips share one centre line, which is the
     alignment you actually see. Matching that 10px inset here keeps the icon at the same offset
     from #tabs' content edge when expanded, so collapsing reads as the labels dropping away rather
     than the icons jumping. (#tabs' own padding still goes 10px → 6px, so there is a 4px page-x
     shift; that is invisible next to the 152px the sidebar itself moves.) */
  padding: 8px 10px;
  gap: 8px;
  border: none;
  background: transparent;
  border-radius: 8px;
  /* text-align:left overrides the UA default (buttons centre their label). A centred label that
     overflows is cropped at BOTH ends, so you lose the start of the word — the part that identifies
     it — and the ellipsis only marks the tail. Left-aligned, it always reads from the start (#550). */
  text-align: left;
  font-size: 13px;   /* neutralises #settings-btn's base font-size: 20px */
  line-height: 1;
  color: var(--ds-text-secondary);
  flex-shrink: 0;
  transition: background 0.15s ease;
}
#app-container.vertical-layout .nav-btn:hover {
  background: var(--ds-bg-tertiary);
  color: var(--ds-text-primary);
}

/* The label is the only thing that can overflow, so it is the only thing that ellipsizes. Putting
   overflow on the BUTTON (as .dropdown-btn did) clips the icon out of its slot instead. min-width:0
   is load-bearing: a flex item's automatic minimum size is its content, so without it the label
   refuses to shrink and shoves the icon off the left edge. */
#app-container.vertical-layout .nav-btn > .btn-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Spacing between rows. #engines/#automations/#sessions are wrapped in a .dropdown div while
   #issue/#mods/#settings are bare siblings, so the margin has to go on whatever is actually #tabs'
   own child. */
#app-container.vertical-layout #new-btn-group {
  width: 100%;
  margin: 12px 0 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--ds-border);
  flex-shrink: 0;
}
#app-container.vertical-layout .dropdown { width: 100%; margin-top: 6px; flex-shrink: 0; }
#app-container.vertical-layout #issue-btn,
#app-container.vertical-layout #mods-btn,
#app-container.vertical-layout #settings-btn { margin: 6px 0 0 0; }

/* The green CTA is the one row that isn't a quiet ghost button, so it opts back out of .nav-btn's
   transparent fill and muted colour. flex:1's flex-basis:0 wins over .nav-btn's width:100% on the
   main axis. Both hover and active have to be restated at id specificity — .nav-btn:hover is
   (1,3,0) and would otherwise paint bg-tertiary over the green while the button is held down. */
#app-container.vertical-layout #new-btn {
  flex: 1;
  min-width: 0;
  border-radius: 8px 0 0 8px;
  background: var(--ds-accent-green);
  color: #fff;
}
#app-container.vertical-layout #new-btn:hover { background: var(--ds-accent-green-hover); color: #fff; }
#app-container.vertical-layout #new-btn:active { background: var(--ds-accent-green-active); }
#app-container.vertical-layout #new-btn-dropdown { flex-shrink: 0; border-radius: 0 8px 8px 0; }

/* Bottom-anchored, not top-anchored (#578). The bottom cluster sits at the bottom of the sidebar
   (#tabs-list-wrapper is flex:1), so a menu anchored top:0 opened downward off the bottom of the
   viewport — body{overflow:hidden} then clipped all but ~2 rows, and the max-height:300px scroll was
   off-screen. Anchoring the menu's bottom edge to the trigger opens it UPWARD into the room that
   actually exists; max-height stays the base 300px, so vertical claims exactly as much as horizontal.
   Correct for all three .dropdown-menu (engines/automations/sessions): engines/automations are short
   fixed lists, and sessions — the only one that grows — is the bottom-most trigger, so it has ~the
   whole sidebar height above it. */
#app-container.vertical-layout .dropdown-menu {
  left: 100%;
  right: auto;
  top: auto;
  bottom: 0;
  margin: 0 0 0 4px;
}

/* ── Collapsed icon rail ──────────────────────────────────────────────────────────────────────
   Dragging the sidebar down to --ds-rail-width collapses it to icons, the way Firefox's vertical
   tabs do. Every row keeps its hit target and its `title`; only the text drops out. The bottom
   cluster MUST collapse too rather than hide — a control that disappears at narrow widths is the
   unreachable-⚙ bug of #550 wearing a different hat. */
#app-container.vertical-layout.icon-rail #tabs { padding: 12px 6px; }

#app-container.vertical-layout.icon-rail .tab {
  padding: 8px 0;
  justify-content: center;
}
/* The label is display:none, not width:0 — an ellipsized 1px label still reserves space and
   knocks the icon off centre. */
#app-container.vertical-layout.icon-rail .tab .tab-label,
#app-container.vertical-layout.icon-rail .tab .close,
#app-container.vertical-layout.icon-rail #new-btn-dropdown {
  display: none;
}
/* The icon appears ONLY here, never in the expanded sidebar. Expanded, the label is already
   visible and a tab named `⏰ ASO Daily Report` would render its emoji twice — once as the derived
   icon and again as the first character of its own label. */
#app-container.vertical-layout.icon-rail .tab .tab-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  background: var(--ds-bg-tertiary);
  color: var(--ds-text-secondary);
}
/* An emoji brings its own colour and silhouette; a monogram needs the chip behind it to read as an
   icon rather than as a stray character. */
#app-container.vertical-layout.icon-rail .tab .tab-icon.is-emoji {
  background: transparent;
  font-size: 15px;
}
#app-container.vertical-layout.icon-rail .tab.active .tab-icon {
  background: var(--ds-accent-blue);
  color: var(--ds-bg-primary);
}
#app-container.vertical-layout.icon-rail .tab.active .tab-icon.is-emoji { background: transparent; }

/* The attention badge is the reason a collapsed rail is usable at all — it's how you see which
   session wants you without reading a name. Float it onto the icon instead of letting it take
   its own column. */
#app-container.vertical-layout.icon-rail .tab .badge {
  position: absolute;
  top: 4px;
  right: 6px;
  z-index: 1;
}

/* The cluster keeps its rows and drops its words. One rule, because every row is now the same
   shape — this replaces `font-size: 0` plus five per-id ::before glyph rules, i.e. a second icon
   set living in CSS that had to be kept in step with the markup's by hand. The width:100% this
   block also used to restate is already on .nav-btn/.dropdown/#new-btn-group above; .icon-rail
   only ever adds a class, so those rules apply here too. */
#app-container.vertical-layout.icon-rail .nav-btn {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
  gap: 0;
}
#app-container.vertical-layout.icon-rail #new-btn { border-radius: 8px; }

/* The muted active-context label (context-views.js injects it as #tabs' own child, right after
   #context-toggle, so align-items:stretch makes it a full-width row) is a word, and 36px is not a
   place for a word — it renders as a cropped fragment of a context name. Hiding it is not the
   unreachable-⚙ of #550: it is a readout, not a control, and the ◧ directly above it still opens
   the rail that shows the whole thing. */
#app-container.vertical-layout.icon-rail #context-indicator { display: none; }

#app-container.vertical-layout #content-row {
  flex: 1;
  min-width: 0;
  min-height: 0;
}

#app-container.vertical-layout #terminals {
  flex: 1;
  min-width: 0;
}

/* Sidebar resizer for vertical layout */
/* 6px, not 2px — a 2px transparent strip is a fiddly drag target (#550). */
#app-container.vertical-layout #sidebar-resizer {
  display: block;
  width: 6px;
  background: transparent;
  cursor: col-resize;
  flex-shrink: 0;
  transition: background 0.15s ease;
}

#app-container.vertical-layout #sidebar-resizer:hover {
  background: rgba(88, 166, 255, 0.5);
}

/* Issue Button */
#issue-btn { padding: 4px 8px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-secondary); border-radius: 4px; cursor: pointer; font-size: 15px; line-height: 1; flex-shrink: 0; }
#issue-btn:hover { background: var(--ds-border); color: var(--ds-text-primary); }
/* The bolt glyph keeps its own color (like the ⚡ emoji did before #552) instead of
   inheriting the button's muted currentColor — set on the icon so button hover chrome
   is unaffected and the label (shown in the rail) stays normal text color. */
#issue-btn .btn-icon { color: var(--ds-issue-bolt); }

/* Sessions Dropdown */
.dropdown { position: relative; flex-shrink: 0; }
.dropdown-btn { padding: 4px 10px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-secondary); border-radius: 4px; cursor: pointer; font-size: 13px; white-space: nowrap; }
.dropdown-btn:hover { background: var(--ds-border); color: var(--ds-text-primary); }
#engines-btn { transition: all 0.15s ease; white-space: nowrap; }
#mods-btn { flex-shrink: 0; }
#settings-btn { padding: 0 8px; font-size: 20px; background: transparent; border: none; flex-shrink: 0; }
#settings-btn:hover { background: transparent; }
.dropdown-menu { display: none; position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 6px; min-width: 220px; z-index: 200; box-shadow: 0 8px 24px var(--ds-shadow); max-height: 300px; overflow-y: auto; }
.dropdown-menu.open { display: block; }
.dropdown-item { padding: 8px 12px; font-size: 13px; color: var(--ds-text-primary); display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--ds-bg-tertiary); }
.dropdown-item:last-child { border-bottom: none; }
.dropdown-item .session-info { display: flex; flex-direction: column; gap: 2px; overflow: hidden; }
.dropdown-item .session-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.session-agent-badge { font-size: 10px; background: var(--ds-bg-tertiary); color: var(--ds-text-secondary); padding: 1px 6px; border-radius: 8px; margin-left: 4px; vertical-align: middle; }
.dropdown-item .session-status { font-size: 11px; color: var(--ds-text-secondary); }
.dropdown-item .session-status.active { color: var(--ds-accent-green-soft); }
.dropdown-item .session-status.other-window { color: var(--ds-accent-blue); }
.dropdown-item .session-close { opacity: 0.5; cursor: pointer; padding: 2px 6px; font-size: 11px; }
.dropdown-item .session-close:hover { opacity: 1; color: var(--ds-accent-red); }
.dropdown-item.clickable { cursor: pointer; }
.dropdown-item.clickable:hover { background: var(--ds-bg-tertiary); }
.dropdown-item.connected { background: var(--ds-bg-tertiary); }
.dropdown-item.closed { opacity: 0.6; }
.dropdown-item .session-status.closed { color: var(--ds-text-muted); }
.dropdown-empty { padding: 12px; text-align: center; color: var(--ds-text-secondary); font-size: 13px; }
.dropdown-clear-disconnected { padding: 8px 12px; font-size: 12px; color: var(--ds-accent-red); text-align: center; cursor: pointer; border-bottom: 1px solid var(--ds-border); }
.dropdown-clear-disconnected:hover { background: var(--ds-bg-tertiary); }
.dropdown-clear-disconnected.disabled { color: var(--ds-text-muted); cursor: default; opacity: 0.5; }
.dropdown-clear-disconnected.disabled:hover { background: none; }

/* Context Menu */
.context-menu { position: fixed; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 6px; padding: 4px 0; min-width: 140px; z-index: 200; box-shadow: 0 8px 24px var(--ds-shadow); }
.context-menu-item { padding: 8px 12px; cursor: pointer; font-size: 13px; color: var(--ds-text-primary); }
.context-menu-item:hover { background: var(--ds-bg-tertiary); }
.context-menu-item.disabled { color: var(--ds-text-secondary); opacity: 0.5; cursor: default; }
.context-menu-item.disabled:hover { background: transparent; }
.context-menu-has-submenu { position: relative; }
.context-menu-arrow { float: right; margin-left: 12px; font-size: 10px; }
.context-menu-arrow::after { content: '\25B6'; }
.context-menu.context-submenu { min-width: 160px; white-space: nowrap; }
.context-submenu .context-menu-item { padding: 8px 12px; }

/* Split button group (+ / ▾) */
#new-btn-group { display: flex; margin-left: 4px; flex-shrink: 0; }
#new-btn { padding: 4px 10px; background: var(--ds-accent-green); border: none; color: white; border-radius: 4px 0 0 4px; cursor: pointer; font-size: 13px; user-select: none; }
#new-btn:hover { background: var(--ds-accent-green-hover); }
#new-btn:active { background: var(--ds-accent-green-active); }
#new-btn-dropdown { padding: 4px 6px; background: var(--ds-accent-green); border: none; border-left: 1px solid rgba(255,255,255,0.2); color: white; border-radius: 0 4px 4px 0; cursor: pointer; font-size: 10px; user-select: none; }
#new-btn-dropdown:hover { background: var(--ds-accent-green-hover); }
#new-btn-dropdown:active { background: var(--ds-accent-green-active); }

/* New-tab menu extras */
.context-menu-header { padding: 6px 12px 4px; font-size: 11px; color: var(--ds-text-secondary); text-transform: uppercase; letter-spacing: 0.5px; }
.context-menu-separator { height: 1px; background: var(--ds-border); margin: 4px 0; }
.new-tab-menu { max-height: 70vh; overflow-y: auto; }
.context-menu-more { text-align: center; color: var(--ds-text-secondary); font-size: 12px; }

/* Issue picker */
.issue-list { background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; max-height: 360px; overflow-y: auto; margin-bottom: 16px; }
.issue-item { padding: 10px 12px; cursor: pointer; border-bottom: 1px solid var(--ds-bg-tertiary); display: flex; align-items: flex-start; gap: 10px; }
.issue-item:last-child { border-bottom: none; }
.issue-item:hover { background: var(--ds-bg-tertiary); }
.issue-item.selected { background: var(--ds-selected-bg); border-color: var(--ds-accent-green); }
.issue-number { color: var(--ds-text-secondary); font-size: 13px; font-weight: 600; flex-shrink: 0; min-width: 36px; }
.issue-info { flex: 1; min-width: 0; }
.issue-title { color: var(--ds-text-primary); font-size: 13px; }
.issue-link { color: var(--ds-text-secondary); text-decoration: none; font-size: 14px; flex-shrink: 0; padding: 0 2px; opacity: 0.5; transition: opacity 0.15s; }
.issue-link:hover { opacity: 1; color: var(--ds-accent-green); }
.issue-labels { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.issue-label { font-size: 11px; padding: 1px 6px; border-radius: 12px; background: var(--ds-bg-tertiary); color: var(--ds-text-secondary); border: 1px solid var(--ds-border); }
.issue-empty { padding: 16px; text-align: center; color: var(--ds-text-secondary); font-size: 13px; }
.issue-loading { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 16px; gap: 12px; }
.issue-loading::before { content: ''; width: 24px; height: 24px; border: 2.5px solid var(--ds-border); border-top-color: var(--ds-accent-green); border-radius: 50%; animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.issue-loading-text { color: var(--ds-text-secondary); font-size: 13px; }
/* Infinite-scroll sentinel: a 0-height IntersectionObserver target when idle; the
   ".is-loading" class reveals a spinner + label row while the next page is fetching. */
.issue-sentinel { height: 0; }
.issue-sentinel.is-loading { height: auto; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 16px; color: var(--ds-text-secondary); font-size: 13px; border-top: 1px solid var(--ds-bg-tertiary); }
.issue-sentinel.is-loading::before { content: ''; width: 16px; height: 16px; border: 2px solid var(--ds-border); border-top-color: var(--ds-accent-green); border-radius: 50%; animation: spin 0.7s linear infinite; flex-shrink: 0; }
.issue-sentinel.is-loading::after { content: 'Loading more…'; }
.issue-error { padding: 24px 16px; text-align: center; color: var(--ds-text-secondary); font-size: 13px; }
.issue-error-message { color: #e06c75; margin-bottom: 12px; }
.issue-retry { padding: 6px 16px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-primary); border-radius: 4px; cursor: pointer; font-size: 12px; }
.issue-retry:hover { background: var(--ds-bg-secondary); }
.issue-repo-selector { margin-bottom: 12px; }
.issue-repo-select { width: 100%; padding: 8px 12px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); font-size: 13px; font-family: monospace; cursor: pointer; }
.issue-repo-select:focus { outline: none; border-color: var(--ds-accent-green); }

/* Content row — terminals + panel side by side */
#content-row { display: flex; flex: 1; min-height: 0; }

/* Terminal containers */
#terminals { flex: 1; min-height: 0; min-width: 0; position: relative; }
.terminal-container { position: absolute; inset: 0; display: none; }
.terminal-container.active { display: flex; flex-direction: column; }
.terminal-container .xterm { flex: 1; }
.terminal-container.reconnecting::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--ds-reconnect-overlay);
  z-index: 10;
  pointer-events: none;
}
.terminal-container.reconnecting::after {
  content: 'Reconnecting...';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--ds-bg-secondary);
  color: var(--ds-text-bright);
  padding: 16px 32px;
  border-radius: 8px;
  border: 1px solid var(--ds-accent-orange);
  font-size: 16px;
  font-weight: 600;
  z-index: 11;
  box-shadow: 0 0 20px var(--ds-reconnect-glow);
  animation: pulse 1.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

/* Loading banner for GitHub issue tabs */
.loading-banner { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--ds-bg-secondary); border-bottom: 1px solid var(--ds-border); color: var(--ds-text-secondary); font-size: 13px; font-family: monospace; z-index: 5; transition: opacity 0.3s ease; flex-shrink: 0; }
.loading-banner-dismiss { opacity: 0; }
.loading-banner-spinner { display: inline-block; width: 14px; height: 14px; border: 2px solid var(--ds-border); border-top-color: var(--ds-accent-blue); border-radius: 50%; animation: spin 0.8s linear infinite; flex-shrink: 0; }
.loading-banner-override { margin-left: auto; padding: 2px 10px; font-size: 12px; font-family: inherit; color: var(--ds-text-secondary); background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; cursor: pointer; flex-shrink: 0; }
.loading-banner-override:hover { color: var(--ds-text-primary); border-color: var(--ds-accent-blue); }

/* Pending new-session banner (#563): shown when "New session" can't reach the
   server; the create is queued by the WS retry loop, this makes it visible. */
.pending-session-banner { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 6px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35); color: var(--ds-text-secondary); font-size: 13px; font-family: monospace; z-index: 2600; }
.pending-session-banner-cancel { padding: 2px 10px; font-size: 12px; font-family: inherit; color: var(--ds-text-secondary); background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; cursor: pointer; flex-shrink: 0; }
.pending-session-banner-cancel:hover { color: var(--ds-text-primary); border-color: var(--ds-accent-blue); }

/* Global reconnect banner (#556): shown when any session's socket has been
   down past the grace period. Same recipe/position as .pending-session-banner —
   safe because only one ever shows (ConnectionStatus is suppressed while
   pending creates are on screen). */
.reconnect-banner { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-accent-orange); border-radius: 6px; box-shadow: 0 0 20px var(--ds-reconnect-glow); color: var(--ds-text-primary); font-size: 13px; font-family: monospace; z-index: 2600; }

/* Top-of-page progress bar (automation prefill) */
#ds-progress-bar { position: fixed; top: 0; left: 0; width: 100%; height: 3px; z-index: 10000; pointer-events: none; opacity: 0; transition: opacity 0.4s ease; }
#ds-progress-bar.active { opacity: 1; }
.ds-progress-bar-fill { width: 100%; height: 100%; background: var(--ds-accent-blue); box-shadow: 0 0 8px var(--ds-accent-blue); transform: scaleX(0); transform-origin: left; transition: transform 0.2s ease; }

/* Reload spinner */
.reload-spinner { width: 32px; height: 32px; border: 3px solid var(--ds-border); border-top-color: var(--ds-accent-blue); border-radius: 50%; animation: spin 0.8s linear infinite; margin: 0 auto; }
@keyframes spin { to { transform: rotate(360deg); } }
/* Reload overlay — absolute (not fixed) so it centers within #terminals (position: relative),
   the same reference box as .terminal-container.reconnecting::after (#572). */
.reload-overlay { position: absolute; inset: 0; background: var(--ds-overlay); display: flex; align-items: center; justify-content: center; z-index: 100; }
/* Modal */
.modal-overlay { position: fixed; inset: 0; background: var(--ds-overlay); display: flex; align-items: center; justify-content: center; z-index: 100; }
.modal { background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 8px; padding: 20px; width: 420px; }
.modal h2 { font-size: 16px; margin-bottom: 16px; color: var(--ds-text-bright); }
.path-wrap { display: flex; gap: 8px; margin-bottom: 8px; }
.modal input[type="text"] { flex: 1; padding: 8px 12px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); font-size: 13px; font-family: monospace; }
.modal input[type="text"]:focus { outline: none; border-color: var(--ds-accent-green); }
.path-up, .new-folder { padding: 8px 12px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 4px; cursor: pointer; color: var(--ds-text-secondary); }
.path-up:hover, .new-folder:hover { background: var(--ds-border); color: var(--ds-text-primary); }
.dir-tree { background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; max-height: 240px; overflow-y: auto; margin-bottom: 12px; }
.dir-item { padding: 8px 12px; cursor: pointer; font-size: 13px; font-family: monospace; color: var(--ds-text-primary); display: flex; align-items: center; gap: 8px; border-bottom: 1px solid var(--ds-bg-tertiary); }
.dir-item:last-child { border-bottom: none; }
.dir-item:hover { background: var(--ds-bg-tertiary); }
.dir-icon { opacity: 0.6; }
.dir-empty { padding: 16px; text-align: center; color: var(--ds-text-secondary); font-size: 13px; }
.modal label { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ds-text-secondary); margin-bottom: 16px; cursor: pointer; }
.modal input[type="checkbox"] { accent-color: var(--ds-accent-green); }
.modal-buttons { display: flex; gap: 8px; justify-content: flex-end; }
.modal button { padding: 6px 14px; border-radius: 4px; border: 1px solid var(--ds-border); cursor: pointer; font-size: 13px; }
.modal .btn-primary { background: var(--ds-accent-green); color: white; border-color: var(--ds-accent-green); }
.modal .btn-primary:hover { background: var(--ds-accent-green-hover); }
.modal .btn-secondary { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); }
.modal .btn-secondary:hover { background: var(--ds-border); }
.modal .btn-danger { background: var(--ds-accent-red); color: white; border-color: var(--ds-accent-red); }
.modal .btn-danger:hover { background: #da3633; }

/* Settings modal */
.settings-option { display: flex; align-items: center; gap: 8px; padding: 8px 0; }
.settings-option input[type="radio"] { accent-color: var(--ds-accent-green); }
.settings-option label { font-size: 13px; color: var(--ds-text-primary); cursor: pointer; }
.settings-custom { margin-top: 8px; }
.settings-custom input { width: 100%; }

/* Window restore modal */
.window-list { background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; max-height: 300px; overflow-y: auto; margin-bottom: 16px; }
.window-item { padding: 12px; cursor: pointer; border-bottom: 1px solid var(--ds-bg-tertiary); }
.window-item:last-child { border-bottom: none; }
.window-item:hover { background: var(--ds-bg-tertiary); }
.window-item .window-title { font-size: 14px; color: var(--ds-text-bright); margin-bottom: 4px; }
.window-item .window-sessions { font-size: 12px; color: var(--ds-text-secondary); }
.window-item .session-name { display: inline-block; background: var(--ds-bg-tertiary); padding: 2px 6px; border-radius: 3px; margin-right: 4px; margin-top: 4px; }

/* Recover-everything restore modal (#560) */
.modal.modal-wide { width: 560px; max-width: calc(100vw - 40px); }
.modal-wide .restore-list { max-height: 60vh; }
.restore-subtitle { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 13px; color: var(--ds-text-secondary); margin-bottom: 12px; }
.restore-select-links { white-space: nowrap; }
.restore-select-links a { color: var(--ds-accent-blue); cursor: pointer; }
.restore-select-links a:hover { text-decoration: underline; }
.restore-section { border-bottom: 1px solid var(--ds-border); }
.restore-section:last-child { border-bottom: none; }
.modal .restore-section-header { display: flex; align-items: center; gap: 8px; margin: 0; padding: 8px 12px; cursor: pointer; background: var(--ds-bg-secondary); position: sticky; top: 0; z-index: 1; }
.restore-section-header .restore-section-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ds-text-bright); }
.restore-section-header .restore-section-meta { font-size: 11px; color: var(--ds-text-secondary); opacity: 0.8; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal .window-item { display: flex; align-items: flex-start; gap: 10px; margin: 0; padding: 10px 12px; font-size: 13px; }
.modal .window-item input[type="checkbox"] { margin-top: 2px; flex-shrink: 0; }
.window-item.checked { background: var(--ds-bg-tertiary); }
.restore-row-body { min-width: 0; }
.restore-row-title { font-size: 13px; color: var(--ds-text-bright); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.restore-row-title.restore-row-derived { font-style: italic; color: var(--ds-text-primary); }
.window-item.session-closed { opacity: 0.55; }
.window-item.session-closed.checked { opacity: 0.85; }

/* Theme selector in settings */
.settings-section { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--ds-border); }
.settings-section h3 { font-size: 14px; color: var(--ds-text-bright); margin-bottom: 8px; }
.theme-select { width: 100%; padding: 8px 12px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); font-size: 13px; cursor: pointer; }
.theme-select:focus { outline: none; border-color: var(--ds-accent-green); }

/* Version info in settings */
.version-info { font-size: 13px; color: var(--ds-text-secondary); }
.version-status { font-size: 11px; padding: 1px 6px; border-radius: 10px; border: 1px solid currentColor; }
.version-ok { color: var(--ds-accent-green-soft); }
.version-update { color: var(--ds-accent-blue); }
.version-failed { color: var(--ds-text-secondary); }

/* Update-available badge on the settings button */
#settings-btn.update-available { position: relative; }
#settings-btn.update-available::after {
  content: "";
  position: absolute;
  top: 3px;
  right: 3px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ds-accent-blue);
  box-shadow: 0 0 0 1px var(--ds-bg-primary);
}
/* Anchored to the ⚙, not to the button's right edge — vertical makes #settings-btn width:100%, so
   `right: 3px` put the dot ~180px away from the icon it is supposed to badge. The icon sits at the
   same 10px inset in both the expanded sidebar and the rail, so one rule covers both. */
#app-container.vertical-layout #settings-btn.update-available::after {
  top: 6px;
  right: auto;
  left: 20px;
}

/* Auto-apply update toast */
.auto-apply-toast {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 2000;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--ds-bg-secondary);
  border: 1px solid var(--ds-accent-blue);
  border-radius: 6px;
  padding: 10px 14px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
  font-size: 12px;
  color: var(--ds-text-primary);
  max-width: 420px;
}
.auto-apply-toast-body { display: flex; flex-direction: column; gap: 2px; }
.auto-apply-toast-countdown { color: var(--ds-text-secondary); font-size: 11px; }
.auto-apply-toast-actions { display: flex; gap: 6px; }

/* Auto-cycle "switching soon" toast (#500) — orange accent to match Action Required */
.auto-cycle-toast {
  border-color: #f0883e;
  bottom: 16px;
}

/* Settings modal — scrollable with pinned header/footer */
.settings-modal {
  width: 480px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
}
.settings-header {
  padding: 20px 20px 0;
  flex-shrink: 0;
}
.settings-tabs {
  display: flex;
  gap: 0;
  margin-top: 12px;
  border-bottom: 1px solid var(--ds-border);
}
.settings-tab {
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ds-text-secondary);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}
.settings-tab:hover {
  color: var(--ds-text-primary);
}
.settings-tab.active {
  color: var(--ds-accent-green);
  border-bottom-color: var(--ds-accent-green);
}
.settings-tab-content {
  display: none;
}
.settings-tab-content.active {
  display: block;
}
.settings-body {
  flex: 1;
  overflow-y: auto;
  padding: 0 20px 8px;
  min-height: 0;
}
.settings-body::-webkit-scrollbar { width: 6px; }
.settings-body::-webkit-scrollbar-track { background: transparent; }
.settings-body::-webkit-scrollbar-thumb { background: var(--ds-border); border-radius: 3px; }
.settings-body::-webkit-scrollbar-thumb:hover { background: var(--ds-text-secondary); }
.settings-modal .modal-buttons {
  padding: 12px 20px 20px;
  border-top: 1px solid var(--ds-border);
  flex-shrink: 0;
}

/* Settings section cards */
.settings-modal .settings-section {
  margin-top: 12px;
  padding: 12px;
  border-top: none;
  border: 1px solid var(--ds-border);
  border-radius: 6px;
  background: var(--ds-bg-primary);
}
.settings-modal .settings-section h3 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--ds-text-secondary);
  margin-bottom: 10px;
}

/* Keyboard shortcut badges */
kbd {
  display: inline-block;
  padding: 2px 6px;
  font-size: 11px;
  font-family: inherit;
  line-height: 1.2;
  color: var(--ds-text-primary);
  background: var(--ds-bg-secondary);
  border: 1px solid var(--ds-border);
  border-radius: 3px;
  box-shadow: 0 1px 0 var(--ds-border);
}

/* Mod system */
#mod-container { flex: 1; min-height: 0; display: none; }
#mod-container iframe { width: 100%; height: 100%; border: none; }

/* Panel container (side panel for panel-mode mods) */
#panel-container { display: none; flex-shrink: 0; width: 360px; overflow: hidden; border-left: 1px solid var(--ds-border); position: relative; }
#panel-container iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: none; }

/* Panel tabs (right edge vertical tab strip) */
#panel-tabs { display: none; flex-direction: column; flex-shrink: 0; background: var(--ds-bg-secondary); border-left: 1px solid var(--ds-border); }
.panel-tab { writing-mode: vertical-rl; padding: 12px 6px; background: transparent; border: none; border-left: 2px solid transparent; color: var(--ds-text-secondary); font-size: 12px; cursor: pointer; white-space: nowrap; position: relative; }
.panel-tab:hover { color: var(--ds-text-primary); background: var(--ds-bg-tertiary); }
.panel-tab.active { color: var(--ds-accent-blue); border-left-color: var(--ds-accent-blue); background: var(--ds-bg-tertiary); }
.panel-tab-badge { display: none; position: absolute; top: 6px; right: 2px; min-width: 8px; height: 8px; background: var(--ds-accent-red, #f85149); border-radius: 50%; font-size: 0; }
.panel-tab-badge.visible { display: block; }

/* Panel resizer */
#panel-resizer { display: none; width: 4px; background: var(--ds-border); cursor: col-resize; flex-shrink: 0; transition: background 0.15s; }
#panel-resizer:hover { background: var(--ds-accent-blue); }

/* Mods button (right side, near Sessions) */
.mod-toggle-item { cursor: pointer; }
.mod-toggle-item:hover { background: var(--ds-bg-tertiary); }
.mod-toggle-label { cursor: pointer; flex-shrink: 0; }
.mod-toggle-label input[type="checkbox"] { accent-color: var(--ds-accent-green); cursor: pointer; }

/* Mod toolbar buttons (left side, registered by enabled mods) */
.mod-toolbar-btn { padding: 4px 10px; background: var(--ds-btn-neutral); border: none; color: var(--ds-text-primary); border-radius: 4px; cursor: pointer; font-size: 13px; margin-left: 4px; user-select: none; flex-shrink: 0; line-height: 1; box-sizing: border-box; }
.mod-toolbar-btn:hover { background: var(--ds-btn-neutral-hover); }
.mod-toolbar-btn:active { background: var(--ds-btn-neutral-active); }
.mod-toolbar-btn.active { background: var(--ds-accent-blue); color: #fff; }

/* Mod back button */
.mod-back-btn { padding: 4px 10px; background: var(--ds-btn-neutral); border: none; color: var(--ds-accent-blue); border-radius: 4px; cursor: pointer; font-size: 13px; user-select: none; }
.mod-back-btn:hover { background: var(--ds-btn-neutral-hover); }

/* Vertical layout mod buttons. These are .nav-btn too (mod-manager.js builds them with an icon
   derived from tabIcon()), so the shape/width/fill/ellipsis all come from the .nav-btn rules and
   only the spacing and the active state are left here. `margin: 6px 0 0 0` also resets the base
   rule's margin-left:4px, which is horizontal-strip spacing. */
#app-container.vertical-layout .mod-toolbar-btn { margin: 6px 0 0 0; }
/* color has to be restated: .nav-btn's `color: var(--ds-text-secondary)` is (1,2,0) and would beat
   the base .mod-toolbar-btn.active (0,2,0), greying out the text on the blue fill. */
#app-container.vertical-layout .mod-toolbar-btn.active { background: var(--ds-accent-blue); color: #fff; }
#app-container.vertical-layout .mod-back-btn { width: 100%; margin-bottom: 6px; border: none; background: transparent; border-radius: 8px; transition: background 0.15s ease; }
#app-container.vertical-layout .mod-back-btn:hover { background: var(--ds-bg-tertiary); }

/* Mod settings button (gear icon in mods dropdown) */
.mod-settings-btn { background: transparent; border: none; color: var(--ds-text-secondary); cursor: pointer; font-size: 24px; padding: 1px 8px; border-radius: 3px; line-height: 1; flex-shrink: 0; }
.mod-settings-btn:hover { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); }

/* Mod versioning */
.mod-incompatible { opacity: 0.5; }
.mod-incompatible input[type="checkbox"] { pointer-events: none; }
.mod-version { color: var(--ds-text-secondary); }
.mod-warning { font-size: 11px; color: var(--ds-accent-red); margin-top: 2px; }

/* Mod settings modal */
.mod-setting-item { display: flex; align-items: flex-start; gap: 10px; padding: 12px 0; border-bottom: 1px solid var(--ds-border); }
.mod-setting-item:last-child { border-bottom: none; }
.mod-setting-toggle { flex-shrink: 0; margin-top: 2px; accent-color: var(--ds-accent-green); cursor: pointer; width: 16px; height: 16px; }
.mod-setting-label { font-size: 13px; color: var(--ds-text-primary); cursor: pointer; }
.mod-setting-desc { font-size: 12px; color: var(--ds-text-secondary); margin-top: 2px; }

/* Marketplace modal */
.marketplace-modal { width: 860px; max-height: 80vh; display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.marketplace-header { display: flex; align-items: center; gap: 12px; padding: 20px 20px 0; }
.marketplace-header h2 { margin: 0; flex-shrink: 0; }
.marketplace-search { flex: 1; }
.marketplace-search input { width: 100%; padding: 7px 12px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); font-size: 13px; }
.marketplace-search input:focus { outline: none; border-color: var(--ds-accent-blue); }
.marketplace-search input::placeholder { color: var(--ds-text-secondary); }
.marketplace-filters { display: flex; gap: 6px; padding: 12px 20px 0; }
.filter-pill { padding: 4px 12px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 12px; color: var(--ds-text-secondary); font-size: 12px; cursor: pointer; }
.filter-pill:hover { color: var(--ds-text-primary); border-color: var(--ds-text-secondary); }
.filter-pill.active { background: var(--ds-accent-blue); color: #fff; border-color: var(--ds-accent-blue); }
.marketplace-list { flex: 1; overflow-y: auto; padding: 12px 20px; min-height: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; align-content: start; }
.mod-card { padding: 12px; border: 1px solid var(--ds-border); border-radius: 6px; background: var(--ds-bg-primary); }
.mod-card:hover { border-color: var(--ds-text-secondary); }
.mod-card-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mod-card-info { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mod-card-name { font-size: 14px; font-weight: 600; color: var(--ds-text-bright); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mod-badge { font-size: 10px; padding: 1px 6px; border-radius: 8px; white-space: nowrap; font-weight: 500; }
.mod-badge.built-in { background: var(--ds-bg-tertiary); color: var(--ds-text-secondary); border: 1px solid var(--ds-border); }
.mod-badge.official { background: rgba(88, 166, 255, 0.15); color: var(--ds-accent-blue); border: 1px solid rgba(88, 166, 255, 0.3); }
.mod-badge.experimental { background: rgba(227, 179, 65, 0.15); color: #e3b341; border: 1px solid rgba(227, 179, 65, 0.3); }
.mod-badge.skill { background: rgba(163, 113, 247, 0.15); color: #a371f7; border: 1px solid rgba(163, 113, 247, 0.3); }
.mod-card-version { font-size: 11px; color: var(--ds-text-secondary); }
.mod-card-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.mod-card-toggle { position: relative; width: 36px; height: 20px; }
.mod-card-toggle input { opacity: 0; width: 0; height: 0; }
.mod-card-toggle .toggle-slider { position: absolute; inset: 0; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 10px; cursor: pointer; transition: background 0.2s, border-color 0.2s; }
.mod-card-toggle .toggle-slider::before { content: ''; position: absolute; width: 14px; height: 14px; left: 2px; top: 2px; background: var(--ds-text-secondary); border-radius: 50%; transition: transform 0.2s, background 0.2s; }
.mod-card-toggle input:checked + .toggle-slider { background: var(--ds-accent-green); border-color: var(--ds-accent-green); }
.mod-card-toggle input:checked + .toggle-slider::before { transform: translateX(16px); background: #fff; }
.mod-card-toggle input:disabled + .toggle-slider { opacity: 0.4; cursor: not-allowed; }
.mod-card-description { font-size: 12px; color: var(--ds-text-secondary); margin-top: 6px; line-height: 1.4; }

/* Skill view button & content modal */
.skill-view-btn { background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-secondary); font-size: 11px; padding: 2px 8px; border-radius: 4px; cursor: pointer; transition: background 0.15s, color 0.15s; }
.skill-view-btn:hover { background: var(--ds-bg-hover); color: var(--ds-text-primary); }
.skill-content-modal { max-width: 700px; width: 90vw; }
.skill-content-body { max-height: 60vh; overflow: auto; padding: 12px 16px; }
.skill-content-body pre { margin: 0; white-space: pre-wrap; word-wrap: break-word; font-size: 12px; line-height: 1.5; color: var(--ds-text-primary); font-family: var(--ds-font-mono, monospace); }

/* Mod dependency tags */
.mod-card-deps { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; margin-top: 6px; font-size: 11px; color: var(--ds-text-secondary); }
.dep-tag { display: inline-block; padding: 1px 7px; border-radius: 8px; font-size: 10px; font-weight: 500; }
.dep-tag-green { background: rgba(63, 185, 80, 0.15); color: var(--ds-accent-green-soft); border: 1px solid rgba(63, 185, 80, 0.3); }
.dep-tag-orange { background: rgba(240, 136, 62, 0.15); color: var(--ds-accent-orange); border: 1px solid rgba(240, 136, 62, 0.3); }
.dep-tag-red { background: rgba(248, 81, 73, 0.15); color: var(--ds-accent-red); border: 1px solid rgba(248, 81, 73, 0.3); }

/* Mod dependency notices */
.mod-dep-notice { margin-top: 8px; padding: 6px 10px; border-radius: 4px; font-size: 11px; animation: dep-notice-fade 4s ease-out forwards; }
.mod-dep-notice-info { background: rgba(88, 166, 255, 0.1); color: var(--ds-accent-blue); border: 1px solid rgba(88, 166, 255, 0.2); }
.mod-dep-notice-error { background: rgba(248, 81, 73, 0.1); color: var(--ds-accent-red); border: 1px solid rgba(248, 81, 73, 0.2); }
@keyframes dep-notice-fade { 0%, 75% { opacity: 1; } 100% { opacity: 0; } }
.mod-card-footer { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--ds-border); }
.mod-card-footer .btn-install { padding: 4px 12px; background: var(--ds-accent-green); border: none; color: #fff; border-radius: 4px; cursor: pointer; font-size: 12px; }
.mod-card-footer .btn-install:hover { background: var(--ds-accent-green-hover); }
.mod-card-footer .btn-install:disabled { opacity: 0.5; cursor: not-allowed; }
.mod-card-footer .btn-install.loading { background: var(--ds-bg-tertiary); color: var(--ds-text-secondary); border: 1px solid var(--ds-border); }
.mod-card-footer .btn-uninstall { padding: 4px 12px; background: transparent; border: 1px solid var(--ds-accent-red); color: var(--ds-accent-red); border-radius: 4px; cursor: pointer; font-size: 12px; }
.mod-card-footer .btn-uninstall:hover { background: rgba(248, 81, 73, 0.1); }
.mod-card-footer .btn-update { padding: 4px 12px; background: var(--ds-accent-blue); border: none; color: #fff; border-radius: 4px; cursor: pointer; font-size: 12px; }
.mod-card-footer .btn-update:hover { opacity: 0.9; }
.mod-card-incompatible { opacity: 0.5; }
.marketplace-modal .modal-buttons { padding: 12px 20px 20px; border-top: 1px solid var(--ds-border); }
.marketplace-empty { padding: 32px 16px; text-align: center; color: var(--ds-text-secondary); font-size: 13px; }

/* Automations chip row */
.automations-section { padding: 12px 20px; border-bottom: 1px solid var(--ds-border); }
.automations-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ds-text-secondary); margin-bottom: 8px; }
.automations-row { display: flex; gap: 8px; overflow-x: auto; align-items: center; padding-bottom: 4px; }
.automations-row::-webkit-scrollbar { height: 4px; }
.automations-row::-webkit-scrollbar-thumb { background: var(--ds-border); border-radius: 2px; }
.automation-chip { display: flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 16px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); color: var(--ds-text-primary); font-size: 13px; white-space: nowrap; cursor: pointer; transition: border-color 0.15s, background 0.15s; }
.automation-chip:hover { border-color: var(--ds-accent-blue); background: var(--ds-bg-secondary); }
.automation-chip-icon { font-size: 14px; }
.automation-add-btn { width: 32px; height: 32px; border-radius: 50%; border: 1px dashed var(--ds-border); background: transparent; color: var(--ds-text-secondary); font-size: 18px; cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: border-color 0.15s, color 0.15s; }
.automation-add-btn:hover { border-color: var(--ds-accent-blue); color: var(--ds-accent-blue); }
.automations-empty { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.automations-empty-btn { width: 48px; height: 48px; border-radius: 8px; border: 1px dashed var(--ds-border); background: transparent; color: var(--ds-text-secondary); font-size: 24px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: border-color 0.15s, color 0.15s; }
.automations-empty-btn:hover { border-color: var(--ds-accent-blue); color: var(--ds-accent-blue); }
.automations-empty-label { font-size: 12px; color: var(--ds-text-secondary); }

/* Automation edit/create modal */
.automation-modal { width: 560px; }
.automation-modal-header { font-size: 16px; font-weight: 600; color: var(--ds-text-bright); padding: 20px 20px 0; }
.automation-modal-form { display: flex; flex-direction: column; gap: 16px; padding: 20px 24px; }
.automation-modal-form label { font-size: 13px; color: var(--ds-text-secondary); display: flex; flex-direction: column; gap: 6px; }
.automation-modal-form input, .automation-modal-form textarea { width: 100%; box-sizing: border-box; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); padding: 10px 12px; font-family: inherit; font-size: 14px; }
.automation-modal-form textarea { min-height: 200px; resize: vertical; font-family: var(--ds-font-mono, monospace); font-size: 13px; }
.automation-modal-form input:focus, .automation-modal-form textarea:focus { outline: none; border-color: var(--ds-accent-blue); }
.automation-modal-footer { display: flex; gap: 8px; justify-content: flex-end; padding: 12px 20px 20px; }
.automation-modal-footer button { padding: 8px 18px; font-size: 14px; }

/* Emoji picker */
.emoji-picker-btn { padding: 6px 10px; border-radius: 4px; border: 1px solid var(--ds-border); background: var(--ds-bg-tertiary); color: var(--ds-text-primary); font-size: 16px; cursor: pointer; line-height: 1; transition: border-color 0.15s, background 0.15s; }
.emoji-picker-btn:hover { border-color: var(--ds-accent-blue); background: var(--ds-bg-secondary); }
.emoji-picker-popup { position: fixed; z-index: 10001; display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; padding: 8px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,0.4); max-width: 320px; }
.emoji-picker-popup button { width: 34px; height: 34px; border: none; background: transparent; font-size: 18px; cursor: pointer; border-radius: 4px; display: flex; align-items: center; justify-content: center; transition: background 0.1s; }
.emoji-picker-popup button:hover { background: var(--ds-bg-tertiary); }

/* Empty state (no tabs open) */
#empty-state { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; user-select: none; background: #0d0d0d; animation: empty-state-fade-in 0.4s ease-out; }
#empty-state.hidden { display: none; }
#empty-state pre { margin: 0; font-family: monospace; line-height: 1.1; }
#empty-state .empty-state-icon { color: var(--ds-accent-blue); opacity: 0.7; font-size: 14px; }
#empty-state .empty-state-title { color: var(--ds-accent-blue); opacity: 0.4; font-size: 12px; margin-top: 8px; }
#empty-state .empty-state-btn { margin-top: 24px; padding: 8px 20px; font-size: 14px; font-family: inherit; color: var(--ds-text-primary); background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 6px; cursor: pointer; opacity: 0.7; transition: opacity 0.15s, background 0.15s; }
#empty-state .empty-state-btn:hover { opacity: 1; background: var(--ds-bg-secondary); }
/* Recent-sessions restore list (issue #533): empty state */
#empty-state .empty-state-recent { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; justify-content: center; max-width: 600px; }
#empty-state .empty-state-recent:empty { display: none; }
#empty-state .empty-state-recent .recent-session-btn { padding: 6px 16px; font-size: 13px; font-family: inherit; color: var(--ds-text-primary); background: transparent; border: 1px solid var(--ds-border); border-radius: 6px; cursor: pointer; opacity: 0.7; transition: opacity 0.15s, background 0.15s; }
#empty-state .empty-state-recent .recent-session-btn:hover { opacity: 1; background: var(--ds-bg-tertiary); }
#empty-state .empty-state-restore { margin-top: 12px; padding: 6px 16px; font-size: 13px; font-family: inherit; color: var(--ds-text-secondary); background: transparent; border: 1px solid var(--ds-border); border-radius: 6px; cursor: pointer; opacity: 0.6; transition: opacity 0.15s, background 0.15s; }
#empty-state .empty-state-restore:hover { opacity: 1; background: var(--ds-bg-tertiary); }
#empty-state .empty-state-restore:disabled { opacity: 0.4; cursor: default; }
/* Empty-context reuse (#534): when #empty-state covers a stale terminal for an active
   context with no matching tabs, lift it above the absolutely-positioned
   .terminal-container siblings and drop the recent-sessions shortcuts (cross-repo /
   global, not context-scoped) so the view focuses on "+ New" in this context. */
#empty-state.context-empty { z-index: 12; }
#empty-state.context-empty .empty-state-recent { display: none; }
#empty-state.context-empty .empty-state-restore { display: none; }

/* Directory-picker quick-pick section: the active context's repos (#573). The
   per-session "Recent sessions" list that also used these classes was removed in #575. */
.modal .recent-section { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
.modal .recent-section .recent-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ds-text-secondary); opacity: 0.7; margin-bottom: 2px; }
.modal .recent-section .recent-session-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; padding: 6px 10px; font-family: inherit; color: var(--ds-text-primary); background: transparent; border: 1px solid var(--ds-border); border-radius: 6px; cursor: pointer; transition: background 0.15s; }
.modal .recent-section .recent-session-btn:hover { background: var(--ds-bg-tertiary); }
.modal .recent-section .recent-name { font-size: 13px; }
.modal .recent-section .recent-meta { font-size: 11px; color: var(--ds-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.modal .recent-separator { border-bottom: 1px solid var(--ds-border); margin-bottom: 12px; }
@keyframes empty-state-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* File drop zone overlay */
.file-drop-zone {
  position: absolute;
  inset: 0;
  z-index: 50;
  border: 2px dashed var(--ds-accent-green);
  background: rgba(35, 134, 54, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}
.file-drop-zone.visible { opacity: 1; }
/* Scroll-to-bottom floating button */
.scroll-to-bottom {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  padding: 4px 16px;
  background: var(--ds-bg-secondary);
  border: 1px solid var(--ds-border);
  border-radius: 16px;
  color: var(--ds-text-secondary);
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
  box-shadow: 0 2px 8px var(--ds-shadow);
}
.scroll-to-bottom.visible { opacity: 1; pointer-events: auto; }
.scroll-to-bottom:hover { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); border-color: var(--ds-accent-blue); }

/* Terminal search bar */
.terminal-search-bar { position: absolute; top: 8px; right: 20px; z-index: 10; display: flex; align-items: center; gap: 4px; padding: 4px 8px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 6px; box-shadow: 0 2px 8px var(--ds-shadow); }
.terminal-search-input { background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); padding: 4px 8px; font-size: 13px; font-family: system-ui, sans-serif; width: 200px; outline: none; }
.terminal-search-input:focus { border-color: var(--ds-accent-blue); }
.terminal-search-btn { background: var(--ds-btn-neutral); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-secondary); cursor: pointer; padding: 2px 8px; font-size: 13px; line-height: 1.4; }
.terminal-search-btn:hover { background: var(--ds-btn-neutral-hover); color: var(--ds-text-primary); }
.terminal-search-close { font-size: 11px; }

.file-drop-zone-content {
  background: var(--ds-bg-secondary);
  color: var(--ds-text-bright);
  padding: 16px 32px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 600;
  border: 1px solid var(--ds-accent-green);
}

/* Command Palette */
.command-palette-overlay { position: fixed; inset: 0; background: var(--ds-overlay); z-index: 250; display: flex; justify-content: center; padding-top: 15vh; }
.command-palette { width: 500px; max-height: 400px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 8px; box-shadow: 0 8px 32px var(--ds-shadow); display: flex; flex-direction: column; overflow: hidden; align-self: flex-start; }
.command-palette-input { padding: 12px 16px; background: var(--ds-bg-primary); border: none; border-bottom: 1px solid var(--ds-border); color: var(--ds-text-bright); font-size: 14px; font-family: inherit; outline: none; }
.command-palette-input::placeholder { color: var(--ds-text-secondary); }
.command-palette-list { flex: 1; overflow-y: auto; padding: 4px 0; }
.command-palette-list::-webkit-scrollbar { width: 6px; }
.command-palette-list::-webkit-scrollbar-track { background: transparent; }
.command-palette-list::-webkit-scrollbar-thumb { background: var(--ds-border); border-radius: 3px; }
.command-palette-item { padding: 8px 16px; cursor: pointer; display: flex; align-items: center; gap: 10px; }
.command-palette-item:hover, .command-palette-item.selected { background: var(--ds-bg-tertiary); }
.command-palette-item-name { font-size: 13px; color: var(--ds-text-primary); white-space: nowrap; }
.command-palette-item-desc { font-size: 12px; color: var(--ds-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Keyboard Shortcuts Help (#549) — z-index above the palette (250) and modals (100): it's a global surface reachable with either open */
.shortcuts-help-overlay { position: fixed; inset: 0; background: var(--ds-overlay); z-index: 260; display: flex; justify-content: center; padding-top: 12vh; }
.shortcuts-help { width: 560px; max-height: 70vh; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 8px; box-shadow: 0 8px 32px var(--ds-shadow); display: flex; flex-direction: column; overflow: hidden; align-self: flex-start; outline: none; }
.shortcuts-help-header { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 12px 16px; background: var(--ds-bg-primary); border-bottom: 1px solid var(--ds-border); }
.shortcuts-help-title { font-size: 14px; font-weight: 600; color: var(--ds-text-bright); }
.shortcuts-help-hint { font-size: 11px; color: var(--ds-text-secondary); }
.shortcuts-help-body { flex: 1; overflow-y: auto; padding: 8px 0 12px; }
.shortcuts-help-body::-webkit-scrollbar { width: 6px; }
.shortcuts-help-body::-webkit-scrollbar-thumb { background: var(--ds-border); border-radius: 3px; }
.shortcuts-help-group-title { padding: 12px 16px 4px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ds-text-secondary); }
.shortcuts-help-row { display: flex; align-items: baseline; gap: 12px; padding: 5px 16px; }
.shortcuts-help-keys { flex: 0 0 180px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px; }
.shortcuts-help-key { padding: 2px 6px; background: var(--ds-bg-tertiary); border: 1px solid var(--ds-border); border-radius: 4px; font-family: inherit; font-size: 12px; color: var(--ds-text-bright); white-space: nowrap; }
.shortcuts-help-sep { font-size: 10px; color: var(--ds-text-secondary); }
.shortcuts-help-desc { flex: 1; font-size: 13px; color: var(--ds-text-primary); }

/* Overview Mode */
#terminals.overview-mode { display: grid; grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); grid-auto-rows: minmax(250px, 1fr); gap: 8px; padding: 8px; overflow-y: auto; }
#terminals.overview-mode .terminal-container.overview-visible { position: relative; inset: auto; display: flex; flex-direction: column; border: 2px solid var(--ds-border); border-radius: 6px; overflow: hidden; cursor: pointer; transition: border-color 0.15s; }
#terminals.overview-mode .terminal-container.overview-visible.overview-focused { border-color: var(--ds-accent-blue); }
#terminals.overview-mode #empty-state { display: none; }
.overview-label { position: absolute; top: 0; left: 0; right: 0; padding: 4px 10px; background: var(--ds-bg-secondary); border-bottom: 1px solid var(--ds-border); font-size: 12px; color: var(--ds-text-primary); z-index: 5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
.overview-waiting { position: absolute; top: 6px; right: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--ds-accent-green); z-index: 6; animation: overview-pulse 2s ease-in-out infinite; pointer-events: none; }
@keyframes overview-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }

/* Hash Commands (#) autocomplete */
.hash-command-popup { position: absolute; bottom: 8px; left: 16px; right: 16px; max-width: 420px; background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); border-radius: 6px; box-shadow: 0 4px 20px var(--ds-shadow); z-index: 200; display: flex; flex-direction: column; font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', Menlo, monospace; overflow: hidden; }
.hash-command-input { padding: 10px 14px; border-bottom: 1px solid var(--ds-border); font-size: 14px; color: var(--ds-text-bright); white-space: pre; line-height: 1.4; }
.hash-command-prefix { color: var(--ds-accent-green); font-weight: 600; }
.hash-command-name-highlight { color: var(--ds-accent-blue); }
.hash-command-cursor { display: inline-block; width: 7px; height: 16px; background: var(--ds-text-bright); vertical-align: text-bottom; animation: hash-cursor-blink 1s step-end infinite; margin-left: 1px; }
@keyframes hash-cursor-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
.hash-command-list { max-height: 200px; overflow-y: auto; padding: 4px 0; }
.hash-command-list::-webkit-scrollbar { width: 5px; }
.hash-command-list::-webkit-scrollbar-track { background: transparent; }
.hash-command-list::-webkit-scrollbar-thumb { background: var(--ds-border); border-radius: 3px; }
.hash-command-item { padding: 6px 14px; cursor: pointer; display: flex; align-items: baseline; gap: 8px; }
.hash-command-item:hover, .hash-command-item.selected { background: var(--ds-bg-tertiary); }
.hash-command-item.selected { border-left: 2px solid var(--ds-accent-green); padding-left: 12px; }
.hash-command-item-name { font-size: 13px; color: var(--ds-accent-green); white-space: nowrap; font-weight: 500; }
.hash-command-item-arg { font-size: 12px; color: var(--ds-text-secondary); font-style: italic; white-space: nowrap; }
.hash-command-item-desc { font-size: 12px; color: var(--ds-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-left: auto; }

/* Overview Mode */
#terminals.overview-mode { display: grid; gap: 8px; padding: 8px; overflow-y: auto; }
#terminals.overview-mode .terminal-container.overview-visible { position: relative; inset: auto; display: flex; flex-direction: column; border: 2px solid var(--ds-border); border-radius: 6px; overflow: hidden; cursor: pointer; transition: border-color 0.15s; }
#terminals.overview-mode .terminal-container.overview-visible.overview-focused { border-color: var(--ds-accent-blue); }
#terminals.overview-mode #empty-state { display: none; }
.overview-label { position: absolute; top: 0; left: 0; right: 0; padding: 4px 10px; background: var(--ds-bg-secondary); border-bottom: 1px solid var(--ds-border); font-size: 12px; color: var(--ds-text-primary); z-index: 5; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; }
.overview-waiting { position: absolute; top: 6px; right: 10px; width: 8px; height: 8px; border-radius: 50%; background: var(--ds-accent-green); z-index: 6; animation: overview-pulse 2s ease-in-out infinite; pointer-events: none; }
@keyframes overview-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
#terminals.overview-mode .terminal-container.overview-visible .xterm { padding-top: 25px; }
/* Tall layout — vertical stacking, auto-fill columns */
#terminals.overview-mode.overview-tall { grid-template-columns: repeat(auto-fill, minmax(400px, 1fr)); grid-auto-rows: minmax(250px, 1fr); }
/* Tiled layout — 2 rows, items flow left-to-right (row-major) */
#terminals.overview-mode.overview-tiled { grid-template-rows: 1fr 1fr; grid-template-columns: repeat(var(--overview-cols, 2), 1fr); overflow-y: hidden; }
/* Overview layout switcher button */
#overview-layout-btn { display: grid; place-items: center; font-size: 14px; line-height: 1; padding: 4px 6px; background: transparent; border: 1px solid var(--ds-border); color: var(--ds-text-secondary); border-radius: 4px; cursor: pointer; }
#overview-layout-btn:hover { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); }
#overview-exit-btn { font-size: 14px; line-height: 1; padding: 4px 6px; background: transparent; border: 1px solid var(--ds-border); color: var(--ds-text-secondary); border-radius: 4px; cursor: pointer; }
#overview-exit-btn:hover { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); }

/* ---- Context Views (#522) ---- */
#context-toggle.active { color: var(--ds-accent-blue); background: var(--ds-bg-tertiary); }

/* Muted active-context label shown next to the toggle when the rail is closed (#531) */
#context-indicator {
  font-size: 11px;
  color: var(--ds-text-secondary);
  cursor: pointer;
  margin-left: 2px;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: none;
}
#context-indicator:hover { color: var(--ds-text-primary); }
#context-indicator.hidden { display: none; }

/* Ruled terminal-title variant of the closed-context label — hidden by default;
   only the retro-monitor theme reveals it as a dashed rule at the top of the
   terminal instead of the tab-strip #context-indicator (#535). */
#context-rule-title { display: none; }

/* Filtered-out tabs (not in the active context) */
.tab.context-hidden { display: none !important; }

/* Left context panel — full-height column, left of everything (first child of
   #app-container). Look is driven entirely by the --ds-context-* custom
   properties so a theme can restyle it (width, colour, rounding, gap, shadow)
   without touching this rule. */
#context-rail {
  display: none;
  flex-direction: column;
  flex-shrink: 0;
  width: var(--ds-context-width);
  margin: var(--ds-context-gap);
  background: var(--ds-context-bg);
  border: var(--ds-context-border);
  border-radius: var(--ds-context-radius);
  box-shadow: var(--ds-context-shadow);
  overflow-y: auto;
  overflow-x: hidden;
  user-select: none;  /* rail items are buttons — a press-drag (incl. row drag-to-reorder, #532) must never become a text selection (#564) */
}
.context-rail-header { font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--ds-text-secondary); padding: 10px 12px 6px; }
/* Inset + round the rows proportionally to the rail's corner radius so a row's
   full-width highlight can never reach — and bleed past — the rounded bezel
   (#577). A bordered scroll container doesn't reliably clip children at rounded
   corners, so we keep the paint inside the arc instead of relying on the clip.
   Derived from --ds-context-radius: 0 when the rail is square (default theme,
   unchanged), scaling up for any rounded theme (e.g. retro-monitor → 3px/6px). */
.context-list { display: flex; flex-direction: column; padding: calc(var(--ds-context-radius) / 6) calc(var(--ds-context-radius) / 3); }
.context-row { display: flex; align-items: center; gap: 6px; padding: 7px 12px; cursor: pointer; color: var(--ds-text-secondary); font-size: 13px; border-left: 3px solid transparent; border-radius: calc(var(--ds-context-radius) / 2); }
.context-row:hover { background: var(--ds-bg-tertiary); color: var(--ds-text-primary); }
.context-row.active { color: var(--ds-text-bright); background: var(--ds-bg-tertiary); border-left-color: var(--ds-accent-blue); }
.context-row:active { background: var(--ds-border); }  /* after .context-row.active: equal specificity, source order lets the press show on the selected row too */
.context-row-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Drag-to-reorder (#532): dim the row being dragged; the real DOM row moves
   live between slots as the pointer crosses each sibling's midpoint. */
.context-row.dragging { opacity: 0.4; }
/* Tab-count badge (#529). --ds-border (not --ds-bg-tertiary) so the pill stays
   legible on active/hover rows, which use --ds-bg-tertiary as their background. */
.context-row-count {
  flex-shrink: 0;              /* label is flex:1 and truncates; badge must not shrink */
  min-width: 18px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--ds-border);
  color: var(--ds-text-secondary);
  font-size: 10px;
  line-height: 16px;
  text-align: center;
  font-variant-numeric: tabular-nums; /* 1- vs 2-digit counts don't jitter */
}
.context-empty-note { padding: 8px 12px; font-size: 11px; color: var(--ds-text-secondary); cursor: pointer; line-height: 1.4; }
.context-empty-note:hover { color: var(--ds-text-primary); }
.context-empty-note:active { background: var(--ds-border); }
.context-add { margin-top: auto; padding: 9px 12px; cursor: pointer; color: var(--ds-accent-green-soft); font-size: 13px; border-top: 1px solid var(--ds-border); }
.context-add:hover { background: var(--ds-bg-tertiary); }
.context-add:active { background: var(--ds-border); }
.context-hint { padding: 6px 12px 10px; font-size: 10px; color: var(--ds-text-secondary); opacity: 0.7; }

/* Context rail drag handle (#569) — the same 6px col-resize strip as #sidebar-resizer,
   so the two rails read as one system. It's a flex sibling between #context-rail and
   #app-main; context-views.js (setSidebar) flips display to block whenever the rail is
   open, in BOTH layouts (hence gated in JS, not by a .vertical-layout selector). */
#context-resizer {
  display: none;
  width: 6px;
  flex-shrink: 0;
  background: transparent;
  cursor: col-resize;
  transition: background 0.15s ease;
}
#context-resizer:hover { background: rgba(88, 166, 255, 0.5); }

/* Per-context icon square (#569). Copies .tab .tab-icon (see the vertical-tabs icon rail)
   so a collapsed context rail and a collapsed tab rail are pixel-identical. Hidden by
   default; shown next to the name in the EXPANDED rail only for a chosen icon (.has-icon),
   and shown for every row in the collapsed rail (#context-rail.collapsed rules below). */
.context-row-icon {
  display: none;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  background: var(--ds-bg-tertiary);
  color: var(--ds-text-secondary);
}
/* An emoji brings its own colour/silhouette; a monogram needs the chip to read as an icon. */
.context-row-icon.is-emoji { background: transparent; font-size: 15px; }
.context-row.has-icon .context-row-icon { display: inline-flex; }

/* ── Collapsed context icon rail (#569) ───────────────────────────────────────────────────
   Dragging the rail down to --ds-rail-width collapses it to icon squares, mirroring the
   vertical tabs (#552). Chrome COLLAPSES rather than vanishes (#550): the header/hint drop
   out and "+ New context" shrinks to a centred +, but every hit target survives. */
#context-rail.collapsed .context-rail-header,
#context-rail.collapsed .context-hint,
#context-rail.collapsed .context-empty-note { display: none; }

/* Keep the base (radius-derived) .context-list inset when collapsed too, so the
   selected/hover/pressed background stays inside the rounded bezel (#577). It's 0
   for a square rail and ~6px horizontal for retro-monitor, which still leaves the
   22px icon square centred in the 48px rail. */
#context-rail.collapsed .context-row {
  justify-content: center;
  padding: 8px 0;
  gap: 0;
  border-left-width: 0; /* the 3px active accent border would knock the square off centre */
}
#context-rail.collapsed .context-row-label,
#context-rail.collapsed .context-row-count { display: none; }

/* Show a square for every row — chosen icon or derived glyph. */
#context-rail.collapsed .context-row-icon { display: inline-flex; }
#context-rail.collapsed .context-row.active .context-row-icon {
  background: var(--ds-accent-blue);
  color: var(--ds-bg-primary);
}
#context-rail.collapsed .context-row.active .context-row-icon.is-emoji { background: transparent; }

#context-rail.collapsed .context-add {
  text-align: center;
  padding: 9px 0;
  font-size: 0; /* hide the "+ New context" text node; ::before supplies the glyph */
}
#context-rail.collapsed .context-add::before { content: '+'; font-size: 18px; line-height: 1; }

/* Icon picker popover (#569) — right-click a context → Set icon…. Reuses .context-menu
   chrome (position/bg/border/z-index); adds a preset emoji grid + a free-text input. */
.context-icon-picker { padding: 8px; width: 200px; }
.context-icon-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 2px; margin-bottom: 8px; }
.context-icon-choice {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 1; padding: 0;
  background: transparent; border: 1px solid transparent; border-radius: 5px;
  cursor: pointer; font-size: 16px; line-height: 1;
}
.context-icon-choice:hover { background: var(--ds-bg-tertiary); }
.context-icon-choice.selected { border-color: var(--ds-accent-blue); }
.context-icon-input {
  width: 100%; box-sizing: border-box; margin-bottom: 6px;
  padding: 5px 6px; font-size: 14px; font-family: system-ui;
  background: var(--ds-bg-primary); border: 1px solid var(--ds-border);
  border-radius: 4px; color: var(--ds-text-primary);
}
.context-icon-actions { display: flex; gap: 6px; }
.context-icon-actions button {
  flex: 1; padding: 5px 8px; font-size: 12px; cursor: pointer;
  border-radius: 4px; border: 1px solid var(--ds-border);
  background: var(--ds-bg-tertiary); color: var(--ds-text-primary);
}
.context-icon-apply { border-color: var(--ds-accent-blue); }
.context-icon-actions button:hover { background: var(--ds-border); }

/* Context switch toast */
.context-toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: var(--ds-bg-secondary); border: 1px solid var(--ds-border); color: var(--ds-text-bright); padding: 8px 16px; border-radius: 8px; font-size: 13px; box-shadow: 0 2px 12px var(--ds-shadow); z-index: 2000; opacity: 0; pointer-events: none; transition: opacity 0.15s; }
.context-toast.visible { opacity: 1; }

/* Context editor / chooser modal extras */
.context-editor .context-name-input { width: 100%; font-family: system-ui; margin-bottom: 12px; }
.context-dirs { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; max-height: 220px; overflow-y: auto; }
.context-dirs-empty { color: var(--ds-text-secondary); font-size: 12px; padding: 4px 0; }
.context-dir-row { display: flex; align-items: center; gap: 8px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; padding: 6px 8px; }
.context-dir-path { flex: 1; font-size: 12px; font-family: monospace; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.context-dir-remove { background: transparent; border: none; color: var(--ds-text-secondary); cursor: pointer; font-size: 12px; padding: 0 2px; }
.context-dir-remove:hover { color: var(--ds-accent-red); }
.context-add-dir { display: flex; gap: 8px; margin-bottom: 16px; }
.context-recent-select { flex: 1; padding: 6px; background: var(--ds-bg-primary); border: 1px solid var(--ds-border); border-radius: 4px; color: var(--ds-text-primary); font-size: 12px; }
.context-dir-chooser .context-choose-dir { display: block; width: 100%; text-align: left; margin-bottom: 6px; font-family: monospace; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

