@import url('./tokens.css');
@import url('./components.css');

/* Research Stack — Story // Stack shared visual language: near-white surface,
   navy text, navy header strip, sharp corners, uppercase action labels.
   All design tokens live in Brand/tokens.css (synced to ./tokens.css at build;
   see DESIGN-SYSTEM.md L5.1). Edit tokens there, not here. */

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--text-body);
  line-height: 1.5;
  min-height: 100vh;
}

/* The footer justifies to the bottom of the window on short pages and follows
   the content on long ones. Normal flow, not position:fixed — a fixed footer
   would sit on top of a long page's last rows. The body becomes the flex column
   and the footer takes the free space above it. Scoped with :has so it only
   applies to pages that actually carry a footer, leaving every workspace layout
   untouched. */
body:has(> footer) {
  display: flex;
  flex-direction: column;
}
body:has(> footer) > footer { margin-top: auto; }
/* REQUIRED, not belt-and-braces. A flex item whose cross-axis margins are `auto`
   — which is every centred `.container` in the suite (`margin: 0 auto`) — does
   NOT stretch to the container's width; it collapses to fit-content. That turned
   Suite Home's project tree into a narrow column the moment the body became a
   flex column (Joey, 2026-07-20). `width: 100%` restores the fill; `max-width`
   still caps it and the auto margins still centre it. Position:fixed children
   (the rail, side panels, modals) are not flex items and are unaffected. */
body:has(> footer) > * { width: 100%; }

a {
  color: var(--text);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}

h1, h2, h3, h4 {
  margin: 0 0 0.5em;
  font-weight: 600;
  line-height: 1.25;
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); }

code, pre {
  font-family: var(--font-mono);
  font-size: 0.9em;
}

/* ---------- slim header (all pages except home) ---------- */
/* Navy palette across all pages, matching the home-page hero. */

.app-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 32px;
  background: var(--navy-bg);
  color: var(--navy-text);
  border-bottom: 1px solid var(--navy-border);
  position: sticky;
  top: 0;
  /* Above the side panels (--z-dropdown) so the user-menu dropdown — which
     opens downward into the panels' region — isn't buried under them. Safe
     because the panels start below the header (top: --rs-ws-top), so the
     header bar never covers panel content. Still below modals/toasts. */
  z-index: calc(var(--z-dropdown) + 1);
}

.app-header .brand {
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--navy-text);
}
.app-header .brand:hover {
  text-decoration: none;
}
/* Split brand block (2026-07-04): logo → Suite Home, app name → app home.
   Two anchors are flex children of .brand (14px gap) — keep them underline-free
   and color-inherit so the wordmark + label look unchanged. */
.app-header .brand > a {
  display: flex;
  align-items: center;
  color: inherit;
  text-decoration: none;
}

.app-header .brand .wordmark-slot {
  display: flex;
  align-items: center;
  color: var(--navy-text);
}
.app-header .brand .wordmark-slot svg {
  height: 22px;
  width: auto;
  display: block;
}

.app-header .brand .app-label {
  color: var(--navy-muted);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  padding-left: 14px;
  border-left: 1px solid var(--navy-border);
}

.app-header nav {
  display: flex;
  align-items: center;
  gap: 18px;
}

.app-header nav a {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--navy-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.app-header nav a:hover {
  color: var(--navy-text);
  text-decoration: none;
}

.app-header .user-menu {
  color: var(--navy-muted);
}
.app-header .user-menu .user-name {
  color: var(--navy-text);
}
.app-header .user-menu .btn-ghost {
  background: transparent;
  border-color: var(--navy-border);
  color: var(--navy-muted);
}
.app-header .user-menu .btn-ghost:hover {
  background: var(--hairline);
  border-color: var(--navy-text);
  color: var(--navy-text);
}

.user-menu {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--text-md);
  color: var(--text-muted);
}

.user-menu .user-name {
  color: var(--text);
}

/* ---------- hero header (home page only) ---------- */

.hero {
  position: relative;
  background: var(--navy-bg);
  color: var(--navy-text);
  text-align: center;
  padding: 56px 40px 40px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero-nav-left {
  position: absolute;
  top: 16px;
  left: 40px;
  font-size: var(--text-md);
}
.hero-nav-left a {
  color: var(--navy-muted);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.hero-nav-left a:hover {
  color: var(--navy-text);
  text-decoration: none;
}

.hero-controls {
  position: absolute;
  top: 16px;
  right: 40px;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: var(--text-md);
  color: var(--navy-muted);
}

.hero-controls a {
  color: var(--navy-muted);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.hero-controls a:hover {
  color: var(--navy-text);
  text-decoration: none;
}

.hero-controls .user-name {
  opacity: 0.85;
}

.hero-controls button {
  background: none;
  border: 1px solid var(--navy-border);
  color: var(--navy-muted);
  font-size: var(--text-sm);
  font-weight: 600;
  padding: 4px 12px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-family: inherit;
  transition: color 0.15s, border-color 0.15s;
}
.hero-controls button:hover {
  color: var(--navy-text);
  border-color: var(--navy-text);
}

.hero-logo-link {
  color: inherit;
  text-decoration: none;
  display: inline-block;
}
.hero-logo-link:hover {
  text-decoration: none;
}

.hero-logo {
  color: var(--navy-text);
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero-logo svg {
  height: 120px;
  width: auto;
  display: block;
}

.hero-subtitle {
  font-size: var(--text-sm);
  letter-spacing: 0.25em;
  font-weight: 600;
  color: var(--navy-muted);
  margin-top: 14px;
  text-transform: uppercase;
}

/* ---------- containers ---------- */

.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 32px 24px;
}

.container-narrow {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 24px;
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
  gap: 16px;
}

.page-header .meta {
  color: var(--text-muted);
  font-size: var(--text-lg);
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 16px;
  font-size: var(--text-md);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  cursor: pointer;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  border-radius: 0;
  transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}
.btn:hover {
  background: var(--surface-hover);
  border-color: var(--text-muted);
  text-decoration: none;
}
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-primary {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.btn-primary:hover {
  background: var(--text);
  opacity: 0.85;
  border-color: var(--text);
}

.btn-ghost {
  background: transparent;
  border-color: var(--border);
  color: var(--text-muted);
}
.btn-ghost:hover {
  background: var(--accent-bg);
  color: var(--text);
}

.btn-danger {
  background: var(--danger);
  color: var(--on-accent);
  border-color: var(--danger);
}
.btn-danger:hover { opacity: 0.85; }

.btn-sm {
  padding: 6px 12px;
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
}

/* ---------- cards / lists ---------- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: background 0.15s, border-color 0.15s;
}

.card-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: var(--text-h3);
  color: var(--text);
}

.card-meta {
  color: var(--text-muted);
  font-size: var(--text-lg);
}

.card-actions {
  margin-top: 8px;
  display: flex;
  gap: 8px;
}

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--accent-bg);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

.chip-accent { background: var(--accent-bg); color: var(--text); border-color: var(--text-muted); }
.chip-success { background: var(--tint-success); color: var(--success); border-color: var(--tint-success-strong); }
.chip-warning { background: var(--tint-warning); color: var(--warning); border-color: var(--tint-warning-strong); }
.chip-danger { background: var(--tint-danger); color: var(--danger); border-color: var(--tint-danger-strong); }
.chip-info { background: var(--tint-info); color: var(--info); border-color: var(--tint-info-strong); }
/* Tooltip (DESIGN-SYSTEM.md L2.7). Brand-styled hover/focus hint for icon buttons;
   replaces native title=. Positioned by ui.js tooltip() (position:fixed). */
.tooltip {
  position: fixed;
  z-index: var(--z-dropdown);
  max-width: 240px;
  padding: 4px 8px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-dropdown);
  border-radius: 0;
  font-size: var(--text-md);
  line-height: 1.35;
  pointer-events: none;
}
.tooltip[hidden] { display: none; }
/* Popover surface (DESIGN-SYSTEM.md L2.7). Shared dropdown/popover panel
   (same surface as .user-menu-panel); sizes 220/320/380. Positioned by
   ui.js popover() (position:fixed). */
.popover {
  position: fixed;
  z-index: var(--z-dropdown);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-dropdown);
  border-radius: 0;
}
/* CSS-Fix-1b: popover() appends its panel to <body> at --z-dropdown (100), so a
   picker opened from inside a higher layer — the reference gallery overlay (900)
   or a .qc-modal (1000) — would render BEHIND its own parent and look dead.
   Lift only tag-picker popovers above the modal layer; plain popovers keep the
   canonical dropdown layer. (Bite Stack .chip-popover precedent.) */
.popover:has(.tag-picker) { z-index: calc(var(--z-modal) + 10); }
.popover[hidden] { display: none; }
.popover-sm { width: 220px; }
.popover-md { width: 320px; }
.popover-lg { width: 380px; }
/* Empty-state variants (DESIGN-SYSTEM.md L2.8). Base .empty-state already shared. */
.empty-state .empty-state-icon { font-size: var(--text-h1); line-height: 1; display: block; margin-bottom: 8px; }
.empty-state.inline { padding: 24px 14px; border: none; background: transparent; }
.empty-state.error .empty-state-icon { color: var(--danger); }
/* Status pill (DESIGN-SYSTEM.md L2.13). One element + [data-role]; colors from L1.1 chip tokens. */
.status-pill {
  display: inline-block;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--surface);
  color: var(--text-muted);
}
.status-pill[data-role="success"], .status-pill[data-role="approved"], .status-pill[data-role="deployed"] { background: var(--chip-success-bg); color: var(--success-text); border-color: var(--chip-success-border); }
.status-pill[data-role="warning"], .status-pill[data-role="draft"] { background: var(--chip-warning-bg); color: var(--warning-text); border-color: var(--chip-warning-border); }
.status-pill[data-role="danger"] { background: var(--chip-danger-bg); color: var(--danger-text); border-color: var(--chip-danger-border); }
.status-pill[data-role="info"], .status-pill[data-role="built"] { background: var(--chip-info-bg); color: var(--info-text); border-color: var(--chip-info-border); }
/* Field-level invalid state (DESIGN-SYSTEM.md L2.10). Used by formRow({error}). */
.form-row [aria-invalid="true"] { border-color: var(--danger); }
/* Removable chip (DESIGN-SYSTEM.md L2.6): .chip.is-removable + the .tag-remove × button (canonical = EH .tag-remove). Shared in Pass 5 S2. */
.chip.is-removable { padding-right: 6px; }
.tag-remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-body);
  line-height: 1;
  padding: 0;
  border-radius: 0;
}
.tag-remove:hover { color: var(--danger); background: var(--accent-bg); }

/* ---------- empty state ---------- */

.empty-state {
  text-align: center;
  padding: 48px 24px;
  background: var(--surface);
  border: 1px dashed var(--border);
  border-radius: 0;
  color: var(--text-muted);
}

.empty-state h3 {
  color: var(--text);
  margin-bottom: 8px;
}

/* ---------- forms ---------- */

.form-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 16px;
}

.form-row label {
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}

.form-row input,
.form-row select,
.form-row textarea {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  color: var(--text);
  font-size: var(--text-lg);
  font-family: inherit;
  transition: border-color 0.15s;
}

.form-row input:focus,
.form-row select:focus,
.form-row textarea:focus {
  border-color: var(--text);
}

.form-row textarea {
  min-height: 80px;
  resize: vertical;
}

/* Picker trigger (CSS-Fix-1b) — the button that opens a .tag-picker where a
   native dropdown used to be. Carries the canonical field box itself so it
   works inside a .form-row AND standalone. Shared class with Project Stack;
   the box below deliberately matches .form-row's field box above. The ▾ stands
   in for the native arrow. */
.picker-trigger {
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  color: var(--text);
  font-size: var(--text-lg);
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  transition: border-color 0.15s;
}
.picker-trigger::after { content: '\25BE'; opacity: 0.6; flex: 0 0 auto; }
.picker-trigger:hover { border-color: var(--text-muted); }
.picker-trigger:focus { border-color: var(--text); outline: none; }
.picker-trigger:disabled { opacity: 0.5; cursor: default; }
/* In a form row it fills the row, like the field it replaced. */
.form-row .picker-trigger { width: 100%; }
/* Compact variant for filter bars + inline cells (matches the old bare box). */
.picker-trigger.picker-sm { padding: 6px 8px; font-size: var(--text-md); }

/* .hint moved to Brand/components.css (Gov-F3) — it was form-row-scoped here,
   so hints elsewhere rendered as body text. */

.form-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 16px;
}

/* ---------- sign-in / accept-invite ---------- */

.sign-in-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--bg);
}

.sign-in-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 40px;
  width: 100%;
  max-width: 420px;
  text-align: center;
}

.sign-in-card .wordmark-slot {
  display: flex;
  justify-content: center;
  color: var(--text);
  margin-bottom: 10px;
}
.sign-in-card .wordmark-slot svg {
  display: block;
}

.sign-in-card h1 {
  text-align: center;
  margin-bottom: 4px;
  font-size: var(--text-h3);
}

.sign-in-card .subtitle {
  text-align: center;
  color: var(--text-muted);
  font-size: var(--text-md);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  margin-bottom: 28px;
}

.divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 18px 0;
  color: var(--text-dim);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.divider::before, .divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--border);
}

.google-btn {
  width: 100%;
  padding: 11px 16px;
  background: var(--bg);
  color: var(--text);
  font-weight: 600;
  border: 1px solid var(--border);
  border-radius: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: inherit;
  font-size: var(--text-base);
  transition: background 0.15s, border-color 0.15s;
}
.google-btn:hover {
  background: var(--surface-hover);
  border-color: var(--text-muted);
}
.google-btn:disabled { opacity: 0.6; cursor: not-allowed; }

.google-btn svg {
  width: 18px;
  height: 18px;
}

.email-form .btn-primary { width: 100%; }

.error-text {
  background: var(--tint-danger);
  color: var(--danger);
  border: 1px solid var(--tint-danger-strong);
  padding: 9px 12px;
  border-radius: 0;
  font-size: var(--text-base);
  margin-bottom: 12px;
}

.muted-link {
  color: var(--text-muted);
  font-size: var(--text-lg);
  text-decoration: underline;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
}

/* ---------- modal ---------- */

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  display: grid;
  place-items: center;
  z-index: 100;
  padding: 24px;
}

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow: auto;
}
/* Modal size tiers (DESIGN-SYSTEM.md L2.3). Default .modal = md (520). */
.modal-sm { max-width: 420px; }
.modal-lg { max-width: 720px; }
.modal-xl { max-width: 1100px; }
/* Side panel (DESIGN-SYSTEM.md L2.14). Docks left/right; slides via .open. */
.side-panel {
  position: fixed;
  top: 0;
  bottom: 0;
  /* Fluid, user-resizable width (DESIGN-SYSTEM.md L2.14 / D-L2.14.1). Per-panel
     --side-panel-width override; clamp() enforces the bounds so the resize drag
     only writes one variable. --width-side-panel (456px) is the default fallback. */
  --side-panel-width: var(--width-side-panel);
  --side-panel-min: 280px;
  --side-panel-max: 70vw;
  width: clamp(var(--side-panel-min), var(--side-panel-width), var(--side-panel-max));
  background: var(--surface);
  z-index: var(--z-dropdown);
  display: flex;
  flex-direction: column;
  transition: transform var(--motion-slow) ease;
}
/* Closed = slid fully off its docked edge via transform (self-tracks the
   variable width; no per-drag recompute). Open = translateX(0). */
.side-panel.dock-right { right: 0; border-left: 1px solid var(--border); box-shadow: var(--shadow-panel-right); transform: translateX(100%); }
.side-panel.dock-right.open { transform: translateX(0); }
/* L2.22: position:fixed ignores the body inset, so without --rail-inset the
   panel would sit UNDER the rail while its in-flow sibling's margin-left (which
   is content-box relative) double-counted the same 48px — an overlap and a dead
   gap at once. --rail-inset is 0 unless the rail is mounted. */
.side-panel.dock-left { left: var(--rail-inset); border-right: 1px solid var(--border); box-shadow: var(--shadow-panel-left); transform: translateX(-100%); }
.side-panel.dock-left.open { transform: translateX(0); }
/* Resize handle on the panel's inner edge (col-resize); makeResizable() wires the drag. */
.side-panel-resize { position: absolute; top: 0; bottom: 0; width: 6px; z-index: 1; cursor: col-resize; background: transparent; transition: background 80ms; }
.side-panel.dock-right .side-panel-resize { left: -3px; }
.side-panel.dock-left .side-panel-resize { right: -3px; }
.side-panel-resize:hover, .side-panel-resize.dragging { background: var(--text-muted); }
body.side-panel-resizing { cursor: col-resize; user-select: none; }
body.side-panel-resizing * { user-select: none !important; }
.side-panel-header { position: sticky; top: 0; display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); background: var(--surface); }
.side-panel-header .side-panel-title { font-weight: 700; flex: 1; min-width: 0; }
.side-panel-body { flex: 1; overflow-y: auto; overscroll-behavior: contain; padding: 16px; }
/* Reserve the scrollbar's width in the right inspector so it never overlaps +
   clips content at the right edge (Info / Highlights / Scout — whichever scrolls). */
.info-panel .side-panel-body { scrollbar-gutter: stable; }
.side-panel-footer { position: sticky; bottom: 0; padding: 12px 16px; border-top: 1px solid var(--border); background: var(--surface); }

.modal-header {
  padding: 20px 24px;
  border-bottom: 1px solid var(--border);
}
.modal-header h2 {
  margin: 0;
  font-size: var(--text-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
}

.modal-body { padding: 24px; }

.modal-error {
  margin: 0 24px 14px;
  background: var(--tint-danger);
  color: var(--danger);
  border: 1px solid var(--tint-danger-strong);
  padding: 9px 12px;
  border-radius: 0;
  font-size: var(--text-base);
}

.modal-footer {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  padding: 16px 24px;
  border-top: 1px solid var(--border);
}

.modal-text { margin: 0; color: var(--text); }

/* ---------- toast ---------- */

#toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
}

.toast {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 10px 14px;
  color: var(--text);
  font-size: var(--text-base);
  animation: toast-in 200ms ease;
  min-width: 220px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.toast-info { border-left: 3px solid var(--text); }
.toast-success { border-left: 3px solid var(--success); }
.toast-error { border-left: 3px solid var(--danger); }
.toast-warning { border-left: 3px solid var(--warning); }
/* × dismiss button on every toast (DESIGN-SYSTEM.md L2.11). */
.toast-dismiss {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-body);
  line-height: 1;
  padding: 0;
}
.toast-dismiss:hover { color: var(--text); }

.toast-leaving {
  opacity: 0;
  transition: opacity 280ms;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- project / season / episode views ---------- */

.tab-bar {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 24px;
}

.tab {
  padding: 12px 22px;
  cursor: pointer;
  color: var(--text-muted);
  border-bottom: 2px solid transparent;
  background: none;
  border-top: none;
  border-left: none;
  border-right: none;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  transition: color 0.15s, border-color 0.15s;
}
.tab:hover { color: var(--text); }

.tab.active {
  color: var(--text);
  border-bottom-color: var(--text);
}

.season-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  margin-bottom: 10px;
  overflow: hidden;
}

.season-header {
  padding: 16px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  background: var(--surface);
  transition: background 0.15s;
}

.season-header:hover { background: var(--surface-hover); }

.season-header:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }

.season-header .title {
  font-weight: 600;
  font-size: var(--text-body);
  letter-spacing: 0.02em;
}
.season-header .meta {
  color: var(--text-muted);
  font-size: var(--text-lg);
}

.season-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  color: var(--text-muted);
  font-size: var(--text-base);
  margin-right: 4px;
  user-select: none;
}

.season-body {
  padding: 0 20px 18px;
  border-top: 1px solid var(--border);
}

.season-block.collapsed .season-body {
  display: none;
}

/* Project-level collapsible block — wraps a project's season blocks on
   BS home when the user has access to more than one project. Visually
   lighter than .season-block (no card chrome — just a clickable bar with
   the project name and a caret) so the seasons inside remain the visual
   focus. */
.project-block {
  margin-bottom: 18px;
}
.project-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin: 0 0 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
  transition: background 0.15s;
}
.project-toggle:hover { background: var(--surface-hover); }
.project-toggle:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.project-toggle .title {
  font-weight: 700;
  font-size: var(--text-base);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.project-toggle .meta {
  color: var(--text-muted);
  font-size: var(--text-base);
}
.project-block.collapsed .project-body { display: none; }

.episode-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
  gap: 12px;
}
.episode-row:last-child { border-bottom: none; }

.episode-code {
  font-family: var(--font-mono);
  color: var(--text-muted);
  margin-right: 8px;
  font-size: var(--text-lg);
}

.episode-title { color: var(--text); }

/* ---------- table ---------- */

table.list {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: 1px solid var(--border);
}
table.list th,
table.list td {
  padding: 12px 14px;
  text-align: left;
  border-bottom: 1px solid var(--border);
}
table.list tr:last-child td { border-bottom: none; }
table.list th {
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--bg);
}

/* ---------- loading ---------- */

.loading {
  color: var(--text-muted);
  padding: 24px;
  text-align: center;
}

/* ---------- utility ---------- */

.row { display: flex; gap: 8px; align-items: center; }
.row-between { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.spacer { flex: 1; }
.muted { color: var(--text-muted); }
.dim { color: var(--text-dim); }
.mt-1 { margin-top: 8px; }

/* Secondary / metadata text — canonical muted body (L1.2 type scale).
   Context-scoped variants (.page-header .meta, .season-header .meta, etc.)
   override size where they need to; this is the default for bare .meta. */
.meta {
  font-size: var(--text-base);
  color: var(--text-muted);
  line-height: 1.5;
}
.mt-2 { margin-top: 16px; }
.mt-3 { margin-top: 24px; }
.mb-1 { margin-bottom: 8px; }
.mb-2 { margin-bottom: 16px; }
.mb-3 { margin-bottom: 24px; }

/* ---------- user-menu dropdown (BRANDING.md §6 nav ladder) ---------- */

.user-menu-dropdown {
  position: relative;
}

.user-menu-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 1px solid var(--navy-border);
  color: var(--navy-text);
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  padding: 6px 12px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: border-color 0.15s;
}
.user-menu-trigger:hover { border-color: var(--navy-text); }

.user-menu-trigger .avatar {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--navy-border);
  color: var(--navy-text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  overflow: hidden;
}
.user-menu-trigger .avatar img {
  width: 100%; height: 100%; object-fit: cover;
}

/* Avatar primitive (DESIGN-SYSTEM L5.2) — ui.js avatar() emits .ui-avatar:
   image, else an initials monogram on a tinted tile; never an empty box.
   Distinct class from the user-menu trigger's .avatar span. Propagated for
   parity (no in-app consumer yet) — C8. */
.ui-avatar { flex: 0 0 auto; border: 1px solid var(--border); background: var(--accent-bg); color: var(--text-muted); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; overflow: hidden; line-height: 1; }
.ui-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ui-avatar-fill { flex: 1; min-height: 0; width: 100%; height: 100%; font-size: var(--text-2xl); border: 0; }

.user-menu-panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 220px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  z-index: 50;
  display: none;
  box-shadow: var(--shadow-dropdown);
}
.user-menu-panel.open { display: block; }

.user-menu-panel .menu-header {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.user-menu-panel .menu-header .name { font-weight: 600; color: var(--text); }
.user-menu-panel .menu-header .email { font-size: var(--text-md); color: var(--text-muted); }

/* Current Org row — Session 3 of multi-tenant foundation (2026-05-20). */
.user-menu-panel .menu-current-org {
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  cursor: default;
  user-select: none;
}
.user-menu-panel .menu-current-org.is-switchable { cursor: pointer; }
.user-menu-panel .menu-current-org.is-switchable:hover { background: var(--surface-hover); }
.user-menu-panel .menu-current-org .current-org-name { color: var(--text); margin-left: 2px; }
.user-menu-panel .menu-current-org .chevron { float: right; font-size: var(--text-xs); }
.user-menu-panel .menu-current-org-list { padding: 4px 0; border-bottom: 1px solid var(--border); }
.user-menu-panel .menu-current-org-list[hidden] { display: none; }
.user-menu-panel .menu-current-org-list button {
  padding-left: 28px; font-size: var(--text-sm); font-weight: 500;
}
.user-menu-panel .menu-current-org-list button.is-current::before {
  content: '✓'; margin-left: -14px; margin-right: 6px; color: var(--accent);
}

.user-menu-panel a, .user-menu-panel button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  font-family: inherit;
  font-size: var(--text-md);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
  padding: 12px 16px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s;
}
.user-menu-panel a:hover, .user-menu-panel button:hover {
  background: var(--surface-hover);
  text-decoration: none;
}
/* When the user menu sits inside `.app-header nav` (e.g. admin pages), the
   generic `.app-header nav a` colour (muted navy) would otherwise win on
   specificity and wash the dropdown links out light. Pin them to the canonical
   dark text so the menu reads the same on every page. (2026-05-29) */
.app-header nav .user-menu-panel a,
.app-header nav .user-menu-panel button {
  color: var(--text);
}

/* ---------- responsive ---------- */

@media (max-width: 768px) {
  .app-header { padding: 12px 20px; }
  .app-header .brand .app-label { display: none; }
  .hero { padding: 36px 20px 28px; }
  .hero-controls { position: static; justify-content: center; margin-bottom: 18px; }
  .hero-logo svg { height: 72px; }
  .container, .container-narrow { padding: 20px 16px; }
  .card-grid { grid-template-columns: 1fr; }
}


/* ---------- Research Stack — episode workspace (1A) ---------- */

/* The two-pane workspace fills the viewport below the slim header. */
.episode-workspace {
  display: flex;
  align-items: stretch;
  /* Fill from the workspace's actual top (below header + ep-strip) to the
     viewport bottom. --rs-ws-top is measured by JS; 100px fallback =
     56px header + 44px ep-strip. Exact height lets the PDF reader fill it. */
  height: calc(100vh - var(--rs-ws-top, 100px));
  width: 100%;
  overflow: hidden;
  background: var(--bg);
}

/* Sources pane = canonical .side-panel.dock-left (DESIGN-SYSTEM.md L2.14 /
   D-L2.14.1). The primitive owns position/width/border/surface/flex-column/
   slide + the resize handle. These are the RS-specific overrides: clear the
   56px slim header (primitive is top:0/bottom:0), the default fluid width, and
   clip the inner scroll. drop-overlay anchors to this now-fixed panel. */
#sources-pane {
  --side-panel-width: 24%;
  /* Start below ALL fixed bars (slim header 56px + ep-strip 44px = 100px).
     JS measures the workspace top into --rs-ws-top so this stays correct
     if the header stack changes height (e.g. when filters move into it).
     bottom:0 from the .side-panel primitive fills the rest. */
  top: var(--rs-ws-top, 100px);
  overflow: hidden;
}
.sources-pane-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  user-select: none;
}
.sources-pane-header .pane-title {
  font-weight: 700;
  font-size: var(--text-base);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.sources-pane-actions { display: flex; align-items: center; gap: 6px; }

/* 1c — Sources ⇄ Pages segmented toggle + page-thumbnail rail. */
.rail-toggle {
  display: flex;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
}
.rail-toggle-btn {
  flex: 1;
  padding: 6px 10px;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  font-family: inherit;
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
}
.rail-toggle-btn + .rail-toggle-btn { border-left: none; }
.rail-toggle-btn:hover { color: var(--text); }
.rail-toggle-btn.active { background: var(--text); color: var(--bg); border-color: var(--text); }

.rail-pages {
  display: none;
  flex: 1;
  overflow-y: auto;
  padding: 12px;
}
/* In Pages mode, the sources-browsing controls give way to the thumbnails. */
.sources-pane.rail-mode-pages .rail-pages { display: block; }
.sources-pane.rail-mode-pages .url-add-box,
.sources-pane.rail-mode-pages .sources-search,
.sources-pane.rail-mode-pages .sources-controls,
.sources-pane.rail-mode-pages .upload-tray,
.sources-pane.rail-mode-pages .sources-list { display: none !important; }

.rail-pages-empty { padding: 24px 12px; text-align: center; }
.page-thumb {
  cursor: pointer;
  margin-bottom: 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  padding: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.page-thumb:hover { border-color: var(--text-muted); }
.page-thumb.active { outline: 2px solid var(--text); outline-offset: -1px; }
.page-thumb-canvas-wrap {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 48px;
  background: var(--surface);
}
.page-thumb-canvas-wrap canvas {
  max-width: 100%;
  height: auto;
  display: block;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);  /* ds-allow: one-off shadow */
}
.page-thumb-label { font-size: var(--text-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* Small icon-weight + button — sits in the pane header */
.btn-icon {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  width: 28px;
  height: 28px;
  font-size: var(--text-body);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-icon:hover { background: var(--surface-hover); }
.btn-icon:disabled { opacity: 0.5; cursor: not-allowed; }

/* URL paste box — persistent affordance above the search */
.url-add-box {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.url-add-box input[type="url"] {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 6px 10px;
  font-size: var(--text-base);
  font-family: inherit;
}
.url-add-box input[type="url"]:focus { border-color: var(--border); outline: none; box-shadow: none; }
.url-add-box input[type="url"]::placeholder { color: var(--text-muted); font-style: italic; }
.url-add-box .btn-icon { flex-shrink: 0; }

/* Search + chips block, inside the sources pane */
.sources-search {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
}
.sources-search input[type="search"] {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 6px 10px;
  font-size: var(--text-base);
  font-family: inherit;
}
.sources-search input[type="search"]:focus { border-color: var(--text-muted); }

/* Finder Filter/Search toggle (Step 3) — a small segmented control above the
   finder box. Filter = metadata list-filter; Search = content search engine. */
.finder-toggle {
  display: inline-flex;
  align-self: flex-start;
  border: 1px solid var(--border);
  overflow: hidden;
}
.finder-toggle-btn {
  padding: 4px 12px;
  font-size: var(--text-md);
  font-weight: 600;
  background: var(--surface);
  color: var(--text-muted);
  border: 0;
  cursor: pointer;
}
.finder-toggle-btn + .finder-toggle-btn { border-left: 1px solid var(--border); }
.finder-toggle-btn.active { background: var(--text); color: var(--bg); }

/* Input + return-arrow row. The row owns the border so the input + arrow read as
   one control; the arrow (Content mode) hints that Enter runs the search. */
.finder-input-row {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--border);
  background: var(--bg);
}
.finder-input-row input[type="search"] {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  outline: none; /* the row is the visible field; no inner focus ring */
}
.finder-input-row input[type="search"]:focus { border-color: transparent; outline: none; box-shadow: none; }
.finder-go-btn {
  flex-shrink: 0;
  border: 0;
  border-left: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  padding: 0 12px;
  font-size: var(--text-body);
  line-height: 1;
}
.finder-go-btn:hover { background: var(--accent-bg); }
.finder-go-btn.hidden { display: none; }

/* Cross-source search results (center pane) */
.viewer-back-results { white-space: nowrap; flex-shrink: 0; }
.search-results-title { font-size: var(--text-base); font-weight: 600; color: var(--text); }
/* Search results now live in the inspector's Search tab: a pinned header (count +
   filters + clear) over a scrolling results list — mirrors the Highlights tab. */
.info-panel.search-tab-active .side-panel-body { overflow: hidden; display: flex; flex-direction: column; padding: 0; }
.info-panel.search-tab-active #tab-search { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.search-tab-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.search-tab-header .search-results-title { flex: 1 1 auto; min-width: 0; }
.search-results {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 12px 16px 24px;
}
.search-results-empty { font-size: var(--text-base); padding: 16px 0; }
.result-group { border-bottom: 1px solid var(--border); padding: 6px 0 10px; }
.result-group-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 4px;
  cursor: pointer;
}
.result-group-head:hover { background: var(--surface); }
.result-group-caret {
  flex: 0 0 auto;
  font-size: var(--text-sm);
  color: var(--text-muted);
  transition: transform var(--motion-fast) ease;
}
.result-group.collapsed .result-group-caret { transform: rotate(-90deg); }
.result-group.collapsed .result-row { display: none; }
.result-group-title { font-size: var(--text-base); font-weight: 600; color: var(--text); }
.result-group-count { font-size: var(--text-sm); flex-shrink: 0; margin-left: auto; }
/* Prev/next source jump buttons in the Search-tab header. */
.search-source-nav { display: inline-flex; gap: 2px; flex: 0 0 auto; }
.result-row {
  display: flex;
  gap: 10px;
  padding: 6px 8px;
  cursor: pointer;
  border-left: 2px solid transparent;
}
.result-row:hover { background: var(--surface); border-left-color: var(--text-muted); }
/* The result you're currently viewing — framed so it's clear which one is in the reader. */
.result-row.active { background: var(--accent-bg); border-left-color: var(--accent); }
.result-row.active:hover { border-left-color: var(--accent); }
.result-loc {
  flex-shrink: 0;
  min-width: 74px;
  font-size: var(--text-sm);
  padding-top: 1px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  align-items: flex-start;
}
/* Highlight-match badge: a colored swatch (the highlight's own color) + label,
   so a highlight hit is visually distinct from a body (page/text) hit. */
.result-hl-badge { display: inline-flex; align-items: center; gap: 5px; font-size: var(--text-sm); font-weight: 600; color: var(--text); }
.result-hl-dot { width: 10px; height: 10px; flex-shrink: 0; background: var(--hl-solid, var(--hl-yellow-solid)); }
/* Origin tag — keyword (literal) vs contextual (found-by-meaning). */
.result-origin {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border: 1px solid var(--border);
  white-space: nowrap;
}
.result-origin-kw { color: var(--text-muted); background: var(--surface); }
.result-origin-sem { color: #6d28d9; border-color: #c4b5fd; background: rgba(196, 181, 253, 0.16); }  /* ds-allow: RS semantic-search origin palette (feature) */
@media (prefers-color-scheme: dark) {
  .result-origin-sem { color: #c4b5fd; border-color: #6d28d9; background: rgba(109, 40, 217, 0.22); }  /* ds-allow: RS semantic-search origin palette (feature) */
}
/* Toggles in the results toolbar reuse .finder-toggle styling. */
.results-scope, .results-depth { margin-left: 10px; }
.result-snippet { font-size: var(--text-md); line-height: 1.45; color: var(--text); }

/* ---------- Stack Scout — source-grounded Q&A chat (Step 4) ---------- */
/* Scout tab = a full-height chat: the panel body stops scrolling as a block; the
   log scrolls and the composer is pinned at the bottom (typical LLM chat). Scoped
   to .scout-active so the Info / Highlights / Find tabs keep their normal scroll. */
.info-panel.scout-active .side-panel-body { overflow: hidden; padding: 0; display: flex; flex-direction: column; }
.info-panel.scout-active #tab-scout { flex: 1 1 auto; min-height: 0; display: flex; }
.scout-chat { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.scout-toolbar { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-bottom: 1px solid var(--border); }
.scout-scope { flex: 1 1 auto; min-width: 0; font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scout-new { flex: 0 0 auto; }
.scout-new.hidden { display: none; }
/* scrollbar-gutter reserves the scrollbar's width so it never overlaps + clips
   the content at the right edge. */
.scout-log { flex: 1 1 auto; min-height: 0; overflow: auto; scrollbar-gutter: stable; display: flex; flex-direction: column; gap: 12px; padding: 12px 14px 12px 16px; }
/* Everything in the chat may shrink below its content size so it wraps + stays
   contained at ANY inspector width (the num/loc tags keep flex-shrink:0 below). */
.scout-log * { min-width: 0; }
.scout-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 28px 16px; margin: auto 0; }
/* Scout inspector tab = the lens glyph in brand blue (no square) instead of the
   word "Scout"; lightened in dark mode so it stays legible. */
/* No color override — the lens inherits the nav item's color (currentColor), so it
   behaves exactly like the Info / Highlights tab TEXT: muted when inactive, --text
   (navy) when hovered/selected. Just larger; the negative vertical margin keeps
   the nav row (and thus the header) the same height. */
.section-nav-item.scout-tab { display: inline-flex; align-items: center; }
.section-nav-item.scout-tab svg { width: 26px; height: 26px; display: block; margin: -6px 0; }
.scout-empty-glyph { color: var(--text-muted); line-height: 0; }
.scout-empty-glyph svg { width: 44px; height: 44px; display: block; }
.scout-empty-copy { font-size: var(--text-md); line-height: 1.5; max-width: 34ch; }
.scout-turn { font-size: var(--text-base); line-height: 1.5; }
.scout-user {
  align-self: flex-end;
  max-width: 88%;
  background: var(--accent-bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 7px 10px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.scout-scout { align-self: stretch; color: var(--text); }
.scout-pending { font-style: italic; }
.scout-error { color: var(--danger); }
.scout-answer { white-space: pre-wrap; overflow-wrap: anywhere; }
.scout-answer strong { font-weight: 700; }
.scout-answer em { font-style: italic; }
.scout-answer code.scout-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em; background: var(--surface-hover); border: 1px solid var(--border); padding: 0 3px; }
/* Inline [n] citation ref inside the answer text. */
.scout-cite-ref {
  display: inline;
  background: none;
  border: none;
  padding: 0 1px;
  font: inherit;
  font-weight: 700;
  color: var(--accent);
  cursor: pointer;
}
.scout-cite-ref:hover { text-decoration: underline; }
/* Collapsible sources under an answer — native <details>, default closed. */
.scout-citations { margin-top: 10px; }
.scout-citations-head { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); cursor: pointer; padding: 3px 0; list-style: none; user-select: none; }
.scout-citations-head::-webkit-details-marker { display: none; }
.scout-citations-head::before { content: '▸'; display: inline-block; margin-right: 5px; font-size: var(--text-xs); transition: transform 80ms; }
.scout-citations[open] .scout-citations-head::before { transform: rotate(90deg); }
.scout-citations > .scout-cite { margin-top: 6px; }
.scout-cite {
  border: 1px solid var(--border);
  border-left: 2px solid var(--text-muted);
  background: var(--surface);
  padding: 6px 8px;
  cursor: pointer;
}
.scout-cite:hover { background: var(--surface-hover); border-left-color: var(--accent); }
/* The excerpt LEADS the card — readable primary text, up to 5 lines. */
.scout-cite-snippet { font-size: var(--text-md); line-height: 1.45; color: var(--text); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
/* Source attribution footer, below the excerpt. */
.scout-cite-foot { display: flex; align-items: baseline; gap: 6px; margin-top: 6px; }
.scout-cite-num { font-size: var(--text-sm); font-weight: 700; color: var(--text-muted); flex-shrink: 0; }
.scout-cite-title { font-size: var(--text-sm); font-weight: 600; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scout-cite-loc { font-size: var(--text-sm); flex-shrink: 0; margin-left: auto; }
.scout-composer {
  flex: 0 0 auto;
  display: flex;
  gap: 6px;
  align-items: flex-end;
  padding: 8px 16px 12px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.scout-input {
  flex: 1 1 auto;
  min-width: 0;
  resize: vertical;
  min-height: 38px;
  max-height: 160px;
  font: inherit;
  font-size: var(--text-base);
  line-height: 1.4;
  padding: 8px 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
.scout-send { flex: 0 0 auto; }

/* ---------- Scout saved reports (toolbar actions + snapshot banner + library) ---------- */
.scout-toolbar-actions { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.scout-save.hidden, .scout-report-close.hidden { display: none; }
/* Save-report dialog fields — stretch full width for longer titles + notes. */
.scout-dialog-field { width: 100%; box-sizing: border-box; }
.scout-dialog-textarea {
  resize: vertical;
  min-height: 62px;
  font: inherit;
  font-size: var(--text-base);
  line-height: 1.4;
  padding: 8px 10px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
}
/* Composer frozen while a saved report is open. */
.scout-composer-disabled { opacity: 0.55; }
.scout-composer-disabled .scout-input { cursor: not-allowed; }
/* Banner above a reopened saved-report snapshot. */
.scout-report-banner {
  align-self: stretch;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 8px 10px;
  background: var(--accent-bg);
  border: 1px solid var(--border);
  border-left: 2px solid var(--accent);
}
.scout-report-banner-info { flex: 1 1 auto; min-width: 0; }
.scout-report-title { font-size: var(--text-base); font-weight: 700; color: var(--text); overflow-wrap: anywhere; }
.scout-report-meta { font-size: var(--text-sm); margin-top: 2px; }
.scout-report-desc { font-size: var(--text-md); line-height: 1.45; margin-top: 5px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.scout-report-close { flex: 0 0 auto; }
.scout-report-continue { flex: 0 0 auto; }
/* Collapsible library window under the composer — user-resizable height. */
.scout-library {
  flex: 0 0 auto;
  height: 240px;
  max-height: 60%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.scout-library.hidden { display: none; }
/* Drag handle to resize the window; the list below scrolls. */
.scout-lib-resize {
  flex: 0 0 auto;
  height: 7px;
  margin-top: -4px;
  cursor: ns-resize;
  touch-action: none;
}
.scout-lib-resize:hover { background: var(--border); }
.scout-lib-head { flex: 0 0 auto; padding: 6px 12px 0; border-bottom: 1px solid var(--border); }
.scout-lib-tabs { display: flex; gap: 4px; }
.scout-lib-tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 4px 8px 6px;
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  cursor: pointer;
}
.scout-lib-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.scout-lib-body { flex: 1 1 auto; overflow: auto; scrollbar-gutter: stable; padding: 6px 12px 10px; display: flex; flex-direction: column; gap: 4px; }
.scout-lib-empty { padding: 12px 2px; font-size: var(--text-md); }
/* Row wraps so Publish/× never clip when the panel is tight — the actions
   drop to their own line (right-aligned) instead of overflowing. */
.scout-lib-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; border: 1px solid var(--border); background: var(--surface); }
.scout-lib-row:hover { background: var(--surface-hover); }
.scout-lib-row-open { flex: 1 1 60%; min-width: 0; text-align: left; background: none; border: none; padding: 7px 8px; font: inherit; cursor: pointer; color: var(--text); }
.scout-lib-row-title { font-size: var(--text-md); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.scout-lib-row-meta { font-size: var(--text-sm); margin-top: 1px; }
.scout-lib-row-desc { font-size: var(--text-sm); margin-top: 3px; white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.scout-lib-row-actions { flex: 1 1 auto; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px; padding: 0 6px 4px; }
.scout-lib-vis { font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; white-space: nowrap; color: var(--accent); }
.scout-lib-del:hover { color: var(--danger); }

.tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.tag-chip {
  background: var(--accent-bg);
  color: var(--text-muted);
  font-size: var(--text-sm);
  padding: 3px 8px;
  border: 1px solid transparent;
  cursor: pointer;
  user-select: none;
}
.tag-chip:hover { color: var(--text); }
.tag-chip.active {
  background: var(--accent-bg);
  color: var(--text);
  border-color: var(--text-muted);
}
/* The scrollable list of source rows in the sources pane */
.sources-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.source-row {
  position: relative;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  padding: 12px 14px;
  user-select: none;
  transition: background 120ms ease, border-color 120ms ease;
}
.source-row:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.source-row-remove {
  position: absolute;
  top: 6px;
  right: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-muted);
  width: 20px;
  height: 20px;
  font-size: var(--text-body);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 80ms;
  padding: 0;
}
.source-row:hover .source-row-remove,
.source-row.selected .source-row-remove,
.source-row:focus-within .source-row-remove { opacity: 1; }
.source-row-remove:hover {
  color: var(--danger);
  border-color: var(--danger);
  background: var(--surface);
}
.source-row:hover { background: var(--surface-hover); }
.source-row.selected { background: var(--accent-bg); border-left: 3px solid var(--text); padding-left: 11px; }
/* Phase 4 fold-in — finder accent for a source with ≥1 saved highlight (rolled
   up across its renditions). Left edge in highlight-yellow; matches the selected
   row's 3px+11px so there's no layout shift, and the selected accent wins. */
.source-row.has-highlights:not(.selected) {
  border-left: 3px solid var(--hl-yellow-solid); /* .hl-color-yellow --hl-solid (highlight-yellow) */
  padding-left: 11px;
}
.source-row-title {
  flex: 1;
  min-width: 0;
  color: var(--text);
  font-weight: 600;
  font-size: var(--text-lg);
  line-height: 1.35;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* 1J-b polish — AI status pill next to the Description heading in the viewer. */
.viewer-section-heading {
  display: flex;
  align-items: center;
  gap: 8px;
}
.viewer-section-heading h4 { margin: 0; }
/* .ai-pill retired Pass 5 S6 → .status-pill[data-role] + ui.js statusPill(). */

/* 1J-b polish — "(AI)" tag next to field labels in the edit modal. */
.ai-field-tag {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 0 4px;
  margin-left: 6px;
  border-radius: 0;
  background: var(--chip-success-bg);
  color: var(--success-text);
  border: 1px solid #86efac;  /* ds-allow: success-feedback tint */
  vertical-align: 1px;
}

.source-row-meta { font-size: var(--text-sm); margin-top: 4px; color: var(--text-muted); }
.source-row-pub { font-weight: 600; color: var(--text); }

/* Manage tags & categories dialog — compact, collapsible, per-section scroll. */
.manage-tc-section { margin-bottom: 12px; border: 1px solid var(--border); }
.manage-tc-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  background: var(--surface);
  user-select: none;
}
.manage-tc-summary::-webkit-details-marker { display: none; }
.manage-tc-summary::before { content: '▸'; font-size: var(--text-xs); }
.manage-tc-section[open] > .manage-tc-summary::before { content: '▾'; }
.manage-tc-summary:hover { color: var(--text); }
.manage-tc-seccount { margin-left: auto; font-weight: 400; }
.manage-tc-list { max-height: 220px; overflow-y: auto; }
.manage-tc-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 10px;
  border-top: 1px solid var(--border);
  font-size: var(--text-md);
}
.manage-tc-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.manage-tc-count { font-size: var(--text-xs); color: var(--text-muted); white-space: nowrap; }
.manage-tc-list > .meta { padding: 6px 10px; }
.manage-tc-edit { color: var(--text-muted); }
.manage-tc-edit:hover { color: var(--text); }
.manage-tc-del { color: var(--text-muted); }
.manage-tc-del:hover { color: var(--danger); border-color: var(--danger); }
.manage-tc-add { display: flex; gap: 6px; align-items: center; padding: 6px 10px; border-top: 1px solid var(--border); }
.manage-tc-add-input {
  flex: 1;
  min-width: 0;
  padding: 4px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  font: inherit;
  font-size: var(--text-md);
  color: var(--text);
}
.manage-tc-add-input:focus { border-color: var(--text); outline: none; }
.manage-tc-hint { margin-top: 10px; font-size: var(--text-sm); }
/* Color-coded scope badge on each source row. Reuses the canonical
   .status-pill primitive (Episode = neutral / Season = info / Project =
   success); this rule only positions + sizes it for the row's bottom-right
   corner (the hover × lives top-right, so they never collide). */
.source-scope-badge {
  position: absolute;
  bottom: 9px;
  right: 12px;
  padding: 1px 7px;
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  pointer-events: none;
}
/* Source-scope picker (Phase 3) — canonical tag-picker single-select
   (DESIGN-SYSTEM.md L3.2). The chosen tier shows as a status-pill adjacent
   to a small "Change" trigger button. */
.scope-picker { display: flex; flex-direction: column; gap: 8px; }
.scope-picker-field { display: flex; align-items: center; gap: 8px; }
.scope-picker-field > span { font-size: var(--text-md); color: var(--text-muted); min-width: 58px; }
/* CSS-Fix-1: scope controls converged to .tag-picker triggers (buttons). */
.scope-picker-field select,
.scope-picker-field .scope-picker-trigger { flex: 1; width: auto; min-width: 0; }
/* Archived checkbox in the edit-source modal — a plain inline checkbox + label.
   The more-specific selector beats `.form-row label` (which would otherwise
   uppercase + mute the text and break the layout). */
.form-row label.src-archived-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-base);
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text);
  cursor: pointer;
}
.form-row label.src-archived-toggle input[type="checkbox"] { margin: 0; width: auto; }
/* Project-mode header in the ep-strip (source-scope Phase 4) — project title
   + season selector + "expand to episode" toggle, replacing the episode
   switcher when episode.html runs as the project research workspace. */
.project-mode-header { display: flex; align-items: center; gap: 18px; flex: 1; flex-wrap: wrap; }
.project-mode-title {
  font-size: var(--text-h3); font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.project-mode-season { font-size: var(--text-base); font-weight: 600; }
/* Control cell for the project Season/Episode filter rows (applied value +
   "Change" trigger) inside the sources-pane filter panel. */
.filter-row-control { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* "Project Research" entry on the Info Stack home — top of each project
   section, opens the project research workspace (source-scope Phase 4). */
.project-research-link {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 10px 14px;
  margin-bottom: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  text-decoration: none;
  color: var(--text);
}
.project-research-link:hover { background: var(--surface-hover); border-color: var(--text-muted); }
.project-research-label { font-weight: 600; font-size: var(--text-lg); }
.project-research-hint { font-size: var(--text-md); color: var(--text-muted); }
.source-row-summary {
  font-size: var(--text-md);
  color: var(--text-muted);
  font-style: italic;
  margin-top: 4px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.source-row.selected .source-row-summary { color: var(--text); }

.sources-empty {
  padding: 24px 14px;
  font-size: var(--text-base);
  color: var(--text-muted);
  text-align: center;
}

/* Sources panel collapse/expand (D-L2.14.1). The drag-resize divider + the
   narrow/wide preset were retired — the panel is now a .side-panel.dock-left
   with an edge resize handle (makeResizable). The viewer shifts to clear the
   open panel; its margin tracks the live (resizable) width via --rs-sources-w,
   falling back to the panel's default clamped width before JS sets it. */
body.rs-sources-open .viewer-pane {
  margin-left: var(--rs-sources-w, clamp(280px, 24%, 70vw));
}
/* Floating reopen affordance — sits just below the header stack (so it clears
   the ep-strip / episode switcher), top-left of the viewer. Only visible when
   the panel is collapsed. (Interim placement; a header-integrated control can
   come with the future header-filter work.) */
/* Vertically centered in the viewer's 28px top padding (midpoint = +14px,
   pulled back by half its own height) so the gap to the header above and the
   source title below is even, regardless of button height. */
#open-sources-btn { position: fixed; top: calc(var(--rs-ws-top, 100px) + 14px); left: 8px; transform: translateY(-50%); z-index: var(--z-dropdown); display: none; }
body:not(.rs-sources-open) #open-sources-btn { display: inline-flex; }
@media (max-width: 720px) {
  #sources-pane { --side-panel-max: calc(100vw - var(--rail-inset)); }
  body.rs-sources-open .viewer-pane { margin-left: 0; }
}

/* ---------- Right-side detail panel: Info | Highlights (1b) ----------
   Canonical .side-panel.dock-right. Mirrors #sources-pane: clears the fixed
   header stack via --rs-ws-top, fluid width, inner scroll clipped. The
   viewer-pane gains a matching margin-right when the panel is open. */
#info-panel {
  --side-panel-width: 26%;
  top: var(--rs-ws-top, 100px);
  overflow: hidden;
}
body.rs-info-open .viewer-pane {
  margin-right: var(--rs-info-w, clamp(280px, 26%, 70vw));
}
/* Floating reopen affordance, top-right of the viewer (mirrors #open-sources-btn). */
#open-info-btn {
  position: fixed;
  top: calc(var(--rs-ws-top, 100px) + 14px);
  right: 8px;
  transform: translateY(-50%);
  z-index: var(--z-dropdown);
  display: none;
}
body:not(.rs-info-open) #open-info-btn { display: inline-flex; }
@media (max-width: 720px) {
  #info-panel { --side-panel-max: calc(100vw - var(--rail-inset)); }
  body.rs-info-open .viewer-pane { margin-right: 0; }
}

/* Tabbed header — Info | Highlights span the width; close button on the end.
   min-height matches the PDF toolbar (46px) so the three column headers sit on
   one continuous band. */
.info-panel-header { padding: 0; align-items: stretch; min-height: 46px; box-sizing: border-box; }
.sources-pane-header { min-height: 46px; box-sizing: border-box; }
.info-tabs { display: flex; flex: 1; min-width: 0; }
.info-tab {
  flex: 1;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 13px 8px;
  font-family: inherit;
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
  cursor: pointer;
  user-select: none;
}
.info-tab:hover { color: var(--text); }
.info-tab.active { color: var(--text); border-bottom-color: var(--text); }
.info-tab-count { color: var(--text-muted); font-weight: 600; }
.info-tab.active .info-tab-count { color: var(--text-muted); }
#close-info-btn { align-self: center; margin: 0 8px; flex-shrink: 0; }
.info-tab-panel.hidden { display: none; }

/* Section nav (DESIGN-SYSTEM L2.15) + .compact panel-header variant (decision
   F2). Ported from Suite Portal for C6; .compact drives the Info|Highlights
   inspector tabs. Active state keyed on [aria-selected="true"]; navy underline. */
.section-nav {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--space-5);
}
.section-nav-item {
  appearance: none;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: var(--space-3) var(--space-4);
  font-family: inherit;
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
  cursor: pointer;
}
.section-nav-item:hover { color: var(--text); }
/* .compact — panel-header scale (F2): smaller type, tighter padding, no outer
   border/margin (the panel header supplies the divider); flexes to fill so the
   trailing collapse arrow sits at the right edge. */
.section-nav.compact {
  flex: 1;
  min-width: 0;
  border-bottom: none;
  margin-bottom: 0;
}
.section-nav.compact .section-nav-item {
  margin-bottom: 0;
  padding: var(--space-2) var(--space-3);
  font-size: var(--text-base);
}

/* Info tab — title block (source title + action buttons), leads the tab. */
.info-panel-titleblock { margin-bottom: 16px; }
.info-panel-title {
  font-size: var(--text-h3);
  font-weight: var(--weight-bold);
  line-height: 1.3;
  color: var(--text);
  margin-bottom: 10px;
  word-break: break-word;
}
.info-panel-titleblock .viewer-header-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
/* Inline editor — Cancel/Save bar sits above the title, needs breathing room. */
.info-panel-titleblock .rs-editbar { margin-bottom: 10px; }
/* Inline editor — the title input reads like the read-view title. */
.info-edit-title {
  font-size: var(--text-h3);
  font-weight: var(--weight-bold);
  line-height: 1.3;
  color: var(--text);
  width: 100%;
  margin-bottom: 10px;
}
/* Inline editor — collapsible sections (mirrors Cast Stack .cast-rec-section). */
.rs-editsections { display: flex; flex-direction: column; gap: 8px; }
.rs-editsec { border: 1px solid var(--border); background: var(--surface); }
.rs-editsec > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
  user-select: none;
}
.rs-editsec > summary::-webkit-details-marker { display: none; }
.rs-editsec > summary::before { content: '▸'; font-size: var(--text-xs); }
.rs-editsec[open] > summary::before { content: '▾'; }
.rs-editsec > summary:hover { color: var(--text); background: var(--surface-hover); }
.rs-editsec-actions { margin-left: auto; display: flex; gap: 4px; align-items: center; }
.rs-editsec-body { padding: 10px 12px; border-top: 1px solid var(--border); }
/* Tighter field rhythm inside the editor (modals keep the roomier default). */
.rs-editsec-body.form-grid { gap: 9px; }
.rs-editsec-body .form-row { margin-bottom: 0; gap: 4px; }
.rs-editsec-body .form-row input,
.rs-editsec-body .form-row select,
.rs-editsec-body .form-row textarea { padding: 7px 10px; }
.rs-editsec-body .form-row textarea { min-height: 0; }

/* Info tab — metadata definition grid. */
.info-meta-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 7px 12px;
  font-size: var(--text-base);
  margin: 2px 0 16px;
}
.info-meta-grid dt {
  color: var(--text-muted);
  white-space: nowrap;
}
.info-meta-grid dd { margin: 0; color: var(--text); word-break: break-word; }
.info-panel-thumb { margin: 0 0 14px; }
.info-panel-thumb img { max-width: 100%; height: auto; display: block; border: 1px solid var(--border); }

/* Highlights tab — view controls (sort / group) + mini-TOC. */
.hl-controls {
  display: flex;
  gap: 8px;
  margin: 10px 0;
}
.hl-controls .sources-toolbar-select { flex: 1; min-width: 0; }
.hl-toc {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0 0 12px;
}
.hl-toc-label {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  color: var(--text-muted);
  width: 100%;
  margin-bottom: 2px;
}
.hl-toc-chip {
  font-size: var(--text-sm);
  padding: 2px 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.hl-toc-chip:hover { color: var(--text); border-color: var(--text-muted); }
.hl-toc-details { width: 100%; }
.hl-toc-summary {
  list-style: none;
  cursor: pointer;
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  color: var(--text-muted);
  margin-bottom: 2px;
}
.hl-toc-summary::-webkit-details-marker { display: none; }
.hl-toc-summary::before { content: '▸'; font-size: var(--text-xs); margin-right: 4px; }
.hl-toc-details[open] > .hl-toc-summary::before { content: '▾'; }
.hl-toc-summary:hover { color: var(--text); }
.hl-toc-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.hl-group-heading {
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  color: var(--text-muted);
  font-weight: var(--weight-bold);
  margin: 16px 0 8px;
}
.hl-group-heading:first-child { margin-top: 4px; }
/* Make the whole card clickable for jump-to (action buttons stopPropagation). */
.highlight-row { cursor: pointer; }
.highlight-row .highlight-actions { cursor: default; }
/* One-shot pulse for jump-to-and-pulse (cards + on-page overlay boxes). */
.highlight-row.pulse-once { animation: focus-pulse 1.6s ease-out 1; position: relative; z-index: 1; }
.pdf-highlight-box.pulse-once { animation: hl-box-pulse 1.6s ease-out 1; }
@keyframes hl-box-pulse {
  0%   { box-shadow: 0 0 0 0 var(--navy-pulse); }
  60%  { box-shadow: 0 0 0 10px var(--navy-pulse-0); }
  100% { box-shadow: 0 0 0 0 var(--navy-pulse-0); }
}
/* New-highlight slide-in (select→save lands a card in the Highlights tab). */
.highlight-row.slide-in { animation: hl-slide-in var(--motion-slow) ease-out 1; }
@keyframes hl-slide-in {
  0%   { opacity: 0; transform: translateY(-8px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Viewer pane (right side) */
.viewer-pane {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: margin var(--motion-slow) ease;
  background: var(--bg);
  position: relative; /* anchors the modeless Find bar (top-right) */
}

/* ---------- Find in document (Search & AI initiative, Step 1) ---------- */

/* Header "⌕ Find" control — reuses .btn styling; active while the bar is open. */
.rs-find-btn { white-space: nowrap; }
.rs-find-btn.active { border-color: var(--text); background: var(--accent-bg); color: var(--text); }

/* Modeless find bar: pinned to the top-right of the reader, just under the
   toolbar. Not a modal — reading continues behind it. */
/* Docked find band — a header row directly under the viewer toolbar (not a
   floating popover), so it reads as part of the header with the Find button. */
.rs-find-bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.rs-find-bar.hidden { display: none; }
.rs-find-input {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  height: 30px;
  padding: 0 8px;
  font-size: var(--text-base);
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}
.rs-find-count {
  min-width: 62px;
  text-align: right;
  font-size: var(--text-md);
  white-space: nowrap;
}
.rs-find-nav { display: flex; gap: 2px; }

/* Transient "Find" results tab — a peer of Info | Highlights, shown only while
   Find in document is open. The list of matched rows lives in #tab-find. */
.rs-find-results-empty { font-size: var(--text-md); padding: 4px 0; }
.rs-find-results-list { display: flex; flex-direction: column; gap: 2px; }
.rs-find-row {
  display: flex;
  gap: 8px;
  padding: 6px 8px;
  cursor: pointer;
  border-left: 2px solid transparent;
}
.rs-find-row:hover { background: var(--surface); }
.rs-find-row.active { background: var(--surface); border-left-color: var(--hl-find-border); }
.rs-find-row.pulse-once { animation: focus-pulse 1.6s ease-out 1; }
.rs-find-row-loc { flex-shrink: 0; min-width: 40px; font-size: var(--text-sm); }
.rs-find-row-snippet {
  font-size: var(--text-md);
  line-height: 1.4;
  color: var(--text);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
/* Universal viewer top bar — present for every source type so the panel
   open/close affordances + header band look identical. Center holds view
   tools (PDF) or stays empty. 46px matches the panel headers (one band). */
.viewer-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  row-gap: 6px;
  padding: 8px 12px;
  min-height: 46px;
  box-sizing: border-box;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}
.viewer-toolbar-tools {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  flex: 1;
  min-width: 0;
}
.viewer-reopen { font-size: var(--text-lg); flex-shrink: 0; }
body.rs-sources-open .viewer-reopen-sources { display: none; }
body.rs-info-open .viewer-reopen-info { display: none; }
/* The toolbar always carries the reopen buttons now — retire the floating ones. */
#open-sources-btn, #open-info-btn { display: none !important; }
/* Scroll region (second child of the pane). PDFs use .pdf-canvases directly. */
.viewer-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  scrollbar-gutter: stable; /* scrollbar toggling never shifts the reader width */
  padding: 28px 36px;
  /* Phase 5c — reading-appearance typeface cascades to the article masthead,
     body, and manual notes. Falls back to the default UI font when unset (e.g.
     book/other non-text viewers, which never set --reader-font). */
  font-family: var(--reader-font, var(--font));
}
.viewer-pane > .viewer-empty { flex: 1 1 auto; min-height: 0; }
.viewer-pane > .pdf-canvases { flex: 1 1 auto; min-height: 0; }
.viewer-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  color: var(--text-muted);
  gap: 8px;
}
.viewer-empty h3 { color: var(--text-muted); font-weight: var(--weight-semibold); font-size: var(--text-h3); }
.viewer-empty p { font-size: var(--text-base); max-width: 380px; }

.viewer-source-header {
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 14px;
  margin-bottom: 18px;
}
.viewer-source-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.viewer-source-title { font-size: var(--text-h2); font-weight: var(--weight-bold); color: var(--text); flex: 1; min-width: 0; }
.viewer-header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.viewer-header-actions .btn-sm {
  font-size: var(--text-sm);
  padding: 4px 8px;
}
.viewer-source-meta { font-size: var(--text-md); color: var(--text-muted); display: flex; gap: 10px; flex-wrap: wrap; }
.viewer-source-meta .chip { font-size: var(--text-sm); }

/* Web source viewer (1C-1) */
/* .viewer-access-tier retired Pass 5 S6 → .status-pill[data-role] + ui.js statusPill(). */

.viewer-thumb {
  margin-top: 14px;
  max-width: 480px;
}
.viewer-thumb img {
  display: block;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--border);
}
.viewer-excerpt {
  font-size: var(--text-lg);
  line-height: 1.5;
  color: var(--text);
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--text-muted);
}
.viewer-url-line {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.viewer-url-text {
  word-break: break-all;
}

.viewer-ai-summary {
  font-size: var(--text-lg);
  font-style: italic;
  color: var(--text);
  line-height: 1.5;
  padding: 12px 16px;
  background: var(--accent-bg);
  border-left: 3px solid var(--text-muted);
}

.viewer-body-text {
  white-space: pre-wrap;
  font-family: inherit; /* 5c — inherits --reader-font from .viewer-scroll */
  font-size: var(--reader-size, var(--text-lg));
  line-height: var(--reader-leading, 1.5);
  color: var(--text);
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
}
/* In-app web body reader (Phase 4c) — a clean readable-article column over the
   stored plain-text body, with selection highlighting. */
.web-body-reader {
  max-width: 680px;
  margin: 8px auto 0;
  font-family: inherit; /* 5c — inherits --reader-font from .viewer-scroll */
  font-size: var(--reader-size, var(--text-lg));
  line-height: var(--reader-leading, 1.65);
  color: var(--text);
}
/* 4g(a) — web-article masthead (title + byline) above the body. */
.web-body-header {
  max-width: 680px;
  margin: 8px auto 0;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.web-body-hero {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 14px;
  border: 1px solid var(--border);
}
.web-body-title {
  font-size: 1.7em;
  line-height: 1.2;
  font-weight: 700;
  margin: 0 0 6px;
  color: var(--text);
}
.web-body-byline { font-size: var(--text-sm); color: var(--text-muted); }

/* Reading appearance (Aa) control — Phase 5c. Typeface / size / line spacing
   for the in-app text readers (web article body + manual notes). The popover
   surface comes from .popover. */
.reader-aa-btn { font-weight: 600; font-size: var(--text-md); }
.reader-aa-menu { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; }
.reader-aa-head {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 8px;
}
.reader-aa-head:first-child { margin-top: 0; }
.reader-aa-fonts { display: flex; flex-direction: column; gap: 4px; }
.reader-aa-font {
  text-align: left;
  padding: 6px 9px;
  background: var(--bg);
  border: 1px solid var(--border);
  cursor: pointer;
  font-size: var(--text-lg);
  color: var(--text);
}
.reader-aa-font:hover { border-color: var(--text-muted); }
.reader-aa-font.active { background: var(--text); color: var(--bg); border-color: var(--text); }
.reader-aa-stepper { display: flex; align-items: center; gap: 8px; }
.reader-aa-size-label {
  font-size: var(--text-md);
  color: var(--text);
  min-width: 44px;
  text-align: center;
}
.reader-aa-leadings { display: flex; gap: 4px; }
.reader-aa-lead {
  flex: 1;
  padding: 6px 4px;
  background: var(--bg);
  border: 1px solid var(--border);
  cursor: pointer;
  font-size: var(--text-md);
  color: var(--text);
}
.reader-aa-lead:hover { border-color: var(--text-muted); }
.reader-aa-lead.active { background: var(--text); color: var(--bg); border-color: var(--text); }
.reader-aa-foot { margin-top: 8px; border-top: 1px solid var(--border); padding-top: 8px; }
.reader-aa-reset {
  background: none;
  border: 0;
  cursor: pointer;
  font-size: var(--text-md);
  color: var(--text-muted);
  padding: 2px 0;
}
.reader-aa-reset:hover { color: var(--text); }
/* 4g(b) — inline placeholder shown when a hotlinked image fails to load. */
.web-body-img-failed {
  display: block;
  margin: 1em auto;
  padding: 10px 12px;
  border: 1px dashed var(--border);
  color: var(--text-muted);
  font-size: var(--text-sm);
  text-align: center;
}
.web-body-img-failed a { color: var(--text); }

.web-body-reader p { margin: 0 0 1em; }
/* 4d — reader-grade article HTML: images + structure restored. */
.web-body-reader img { max-width: 100%; height: auto; display: block; margin: 1em auto; }
.web-body-reader figure { margin: 1.25em 0; }
.web-body-reader figcaption { font-size: var(--text-sm); color: var(--text-muted); margin-top: 0.4em; text-align: center; }
.web-body-reader h1, .web-body-reader h2, .web-body-reader h3,
.web-body-reader h4, .web-body-reader h5, .web-body-reader h6 {
  line-height: 1.25; margin: 1.4em 0 0.5em; font-weight: 700;
}
.web-body-reader h1 { font-size: 1.6em; }
.web-body-reader h2 { font-size: 1.35em; }
.web-body-reader h3 { font-size: 1.15em; }
.web-body-reader ul, .web-body-reader ol { margin: 0 0 1em; padding-left: 1.5em; }
.web-body-reader li { margin: 0.25em 0; }
.web-body-reader blockquote {
  margin: 1.25em 0; padding: 0.25em 0 0.25em 1em;
  border-left: 3px solid var(--border); color: var(--text-muted); font-style: italic;
}
.web-body-reader a { color: var(--text); text-decoration: underline; }
.web-body-reader pre {
  white-space: pre-wrap; background: var(--surface); border: 1px solid var(--border);
  padding: 12px; font-size: var(--text-sm); overflow-x: auto;
}
.web-body-reader code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; }
.web-body-reader table { border-collapse: collapse; width: 100%; margin: 1em 0; font-size: var(--text-sm); }
.web-body-reader th, .web-body-reader td { border: 1px solid var(--border); padding: 6px 8px; text-align: left; }
.web-body-reader::selection,
.web-body-reader *::selection { background: rgba(11, 26, 50, 0.15); }  /* ds-allow: RS reader selection/body tint (feature) */
/* Stored highlights on the body are now real <span> elements (clickable +
   hoverable). The span carries a hl-color-* class supplying --hl-bg. */
.rs-body-hl {
  background: var(--hl-bg);
  cursor: pointer; /* hover affordance — the highlight is clickable to edit */
  border-radius: 0;
}
.rs-body-hl:hover { background: var(--hl-solid); }
/* Fallback path: any highlight we couldn't wrap is painted via the CSS Custom
   Highlight API instead (no DOM mutation), semi-transparent so text stays
   readable. */
::highlight(rs-body-yellow) { background-color: var(--hl-body-yellow); }
::highlight(rs-body-green)  { background-color: var(--hl-body-green); }
::highlight(rs-body-blue)   { background-color: var(--hl-body-blue); }
::highlight(rs-body-pink)   { background-color: var(--hl-body-pink); }
::highlight(rs-body-orange) { background-color: var(--hl-body-orange); }

/* Find-in-document hits on text bodies (web / md / docx / manual). A transient
   layer, separate from user highlights — neutral amber so it reads as "search",
   not a highlight color. The active match is a stronger amber. */
::highlight(rs-find)        { background-color: var(--hl-find); }
::highlight(rs-find-active) { background-color: var(--hl-find-active); color: inherit; }

.viewer-section { margin-top: 18px; }
/* Section-label eyebrow (L1.2 tokens). Shared treatment across the viewer's
   Description / URL / Highlights / Reference-images labels. */
.viewer-section h4 {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.viewer-actions { margin-top: 24px; display: flex; gap: 10px; }

/* Form-grid wrapper for stacked form-rows in modals */
.form-grid { display: flex; flex-direction: column; gap: 12px; }

/* ---------- Research Stack — PDF upload (1B-1) ---------- */

/* Drop overlay covers the sources pane while a file is being dragged in. */
.drop-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(11, 26, 50, 0.92);  /* ds-allow: RS reader selection/body tint (feature) */
  border: 2px dashed var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none; /* prevents flicker; events bubble to .sources-pane */
}
.drop-overlay.hidden { display: none; }
.drop-overlay-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: var(--text);
  padding: 24px;
  text-align: center;
}
.drop-overlay-icon {
  font-size: var(--text-3xl);
  line-height: 1;
}
.drop-overlay-text {
  font-size: var(--text-lg);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.drop-overlay-hint {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* Upload tray sits between the search and the sources list while uploads
   are in flight. Banner-styled so it's clearly a transient progress
   indicator, not a source row. Disappears when the last row resolves. */
.upload-tray {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--accent-bg);
}
.upload-tray.hidden { display: none; }
.upload-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.upload-row.failed { border-color: var(--danger); }
.upload-row-top {
  display: flex;
  align-items: center;
  gap: 8px;
}
.upload-row-label {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-style: italic;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.upload-row-pct {
  font-size: var(--text-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.upload-row.failed .upload-row-pct { color: var(--danger); }
.upload-row-dismiss {
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: var(--text-body);
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
}
.upload-row-dismiss:hover { color: var(--text); }
.upload-row-bar {
  height: 3px;
  background: var(--border);
  overflow: hidden;
}
.upload-row-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--text);
  transition: width 120ms ease;
}
.upload-row.failed .upload-row-bar-fill { background: var(--danger); }

/* Loading / disabled states on the open-PDF link */
.btn.loading { opacity: 0.7; pointer-events: none; }
.btn.disabled { opacity: 0.5; pointer-events: none; }

/* ---------- Research Stack — highlights (1B-5) ---------- */

/* Shared color palette. Overlay variant is the on-canvas highlight (mixed
   into the page); solid variant is for chips + dots in the UI. */
/* --hl-dark = a genuinely darker shade of each hue, for the selected-highlight
   underline (the --hl-solid variant is too close to --hl-bg to read). */
.hl-color-yellow { --hl-bg: var(--hl-yellow-bg); --hl-solid: var(--hl-yellow-solid); --hl-dark: var(--hl-yellow-dark); }
.hl-color-green  { --hl-bg: var(--hl-green-bg); --hl-solid: var(--hl-green-solid); --hl-dark: var(--hl-green-dark); }
.hl-color-blue   { --hl-bg: var(--hl-blue-bg); --hl-solid: var(--hl-blue-solid); --hl-dark: var(--hl-blue-dark); }
.hl-color-pink   { --hl-bg: var(--hl-pink-bg); --hl-solid: var(--hl-pink-solid); --hl-dark: var(--hl-pink-dark); }
.hl-color-orange { --hl-bg: var(--hl-orange-bg); --hl-solid: var(--hl-orange-solid); --hl-dark: var(--hl-orange-dark); }

/* On-canvas highlight boxes use the soft overlay variant. */
.pdf-highlight-box { background: var(--hl-bg); }

/* Highlighter tool in the PDF reader toolbar (Bite Stack parity): a toggle
   button + a color picker revealed when the tool is active. */
.pdf-hl-tool { white-space: nowrap; }
.pdf-hl-tool.active { border-color: var(--text); background: var(--accent-bg); color: var(--text); }
.pdf-hl-colors { display: inline-flex; align-items: center; gap: 4px; }
.pdf-hl-colors.hidden { display: none; }
.pdf-hl-swatch {
  width: 18px; height: 18px;
  border: 2px solid transparent;
  background: var(--hl-solid);
  cursor: pointer; box-sizing: border-box;
}
.pdf-hl-swatch:hover { border-color: var(--text-muted); }
.pdf-hl-swatch.active { border-color: var(--text); }
.pdf-toolbar-divider { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
body.rs-hl-mode .pdf-text-layer,
body.rs-hl-mode .web-body-reader { cursor: text; }

/* Click-a-highlight edit popup (Bite Stack parity). Anchored at the click;
   recolor + note + tags + cite + adjust + copy + delete. */
.hl-edit-popup {
  position: fixed;
  z-index: var(--z-dropdown, 1000);
  min-width: 220px; max-width: 300px;
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 8px;
}
.hl-edit-header { display: flex; justify-content: space-between; align-items: center; }
.hl-edit-header span {
  font-size: var(--text-sm); font-weight: var(--weight-bold); letter-spacing: var(--ls-caps);
  text-transform: uppercase; color: var(--text-muted);
}
.hl-edit-close { background: none; border: none; color: var(--text-muted); cursor: pointer; font-size: var(--text-body); padding: 0 2px; }
.hl-edit-close:hover { color: var(--text); }
.hl-edit-colors { display: flex; align-items: center; gap: 6px; }
.hl-edit-label { font-size: var(--text-sm); color: var(--text-muted); }
.hl-edit-note { font-size: var(--text-md); color: var(--text); white-space: pre-wrap; }
.hl-edit-note.empty { color: var(--text-muted); font-style: italic; }
.hl-edit-note-edit { display: flex; flex-direction: column; gap: 6px; }
.hl-edit-note-input {
  width: 100%; box-sizing: border-box; border: 1px solid var(--border); background: var(--bg);
  font-family: inherit; font-size: var(--text-md); padding: 6px 8px; color: var(--text); resize: vertical;
}
.hl-edit-note-edit .row { display: flex; justify-content: flex-end; gap: 6px; }
.hl-edit-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.hl-edit-tags.hidden { display: none; }
.hl-edit-actions { display: flex; flex-wrap: wrap; gap: 4px; border-top: 1px solid var(--border); padding-top: 8px; }
.hl-edit-action {
  background: none; border: none; color: var(--text-muted); cursor: pointer;
  font-size: var(--text-sm); padding: 2px 6px; text-transform: uppercase; letter-spacing: 0.04em;
}
.hl-edit-action:hover { background: var(--accent-bg); color: var(--text); }
.hl-edit-action-danger { color: var(--danger); }
.hl-edit-action-danger:hover { background: var(--tint-danger); color: var(--danger); }

/* Tag chips on a highlight card. */
.highlight-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.highlight-tags.empty { display: none; }
.highlight-tag {
  font-size: var(--text-sm); padding: 1px 7px;
  background: var(--accent-bg); border: 1px solid var(--border); color: var(--text-muted);
}

/* ---------- References (1J-a Chunk 4a) ---------- */
.refs-section { margin-top: 20px; }
.refs-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 0;
}
.refs-header h4 {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
.refs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.ref-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ref-tile-thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--bg);
  border-radius: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ref-tile-thumb img {
  max-width: 100%;
  max-height: 100%;
  display: block;
}
.ref-tile-missing { padding: 8px; }
.ref-tile-caption {
  font-size: var(--text-base);
  font-weight: 500;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ref-tile-note {
  font-size: var(--text-md);
  background: var(--scrim-subtle);
  padding: 6px 8px;
  border-radius: 0;
}
.ref-tile-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.ref-tile-tag {
  display: inline-block;
  padding: 2px 8px;
  background: var(--glass-white-06);
  border: 1px solid var(--glass-white-12);
  border-radius: 0;
  font-size: var(--text-sm);
}
.ref-tile-meta { font-size: var(--text-sm); }

.ref-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);  /* ds-allow: one-off scrim */
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  cursor: zoom-out;
}
.ref-lightbox img {
  max-width: 100%;
  max-height: 100%;
  display: block;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.5);  /* ds-allow: one-off shadow */
}

/* ---------- References gallery modal (1J-a Chunk 4b) ---------- */
.ref-gallery-overlay {
  position: fixed;
  inset: 0;
  background: var(--scrim-black-strong);
  z-index: 900;
  display: flex;
  align-items: stretch;
  justify-content: center;
  padding: 24px;
}
.ref-gallery-dialog {
  width: 100%;
  max-width: 1200px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.ref-gallery-header {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.ref-gallery-title {
  margin: 0;
  font-size: var(--text-h3);
  font-weight: 600;
}
.ref-gallery-meta { flex: 1; font-size: var(--text-base); }
.ref-gallery-close {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: var(--text-2xl);
  cursor: pointer;
  padding: 0 6px;
  line-height: 1;
}
.ref-gallery-close:hover { color: var(--text); }

.ref-gallery-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  align-items: center;
}
.ref-gallery-select {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 0;
  padding: 6px 10px;
  font: inherit;
  font-size: var(--text-md);
}
.ref-gallery-tag-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
/* .ref-gallery-tag-chip retired — now the shared .filter-chip (filterChip()). */
.ref-gallery-clear {
  background: transparent;
  border: 0;
  color: var(--accent);
  font: inherit;
  font-size: var(--text-md);
  cursor: pointer;
  text-decoration: underline;
  padding: 0;
  margin-left: auto;
}

.ref-gallery-grid {
  flex: 1;
  overflow-y: auto;
  padding: 16px 20px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.ref-gallery-empty {
  padding: 36px 20px;
  text-align: center;
  font-size: var(--text-lg);
}

.ref-gallery-tile {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ref-gallery-tile-thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--bg);
  border-radius: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ref-gallery-tile-thumb img {
  max-width: 100%;
  max-height: 100%;
  display: block;
}
.ref-gallery-tile-note {
  font-size: var(--text-md);
  background: var(--scrim-subtle);
  padding: 6px 8px;
  border-radius: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ref-gallery-tile-meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: var(--text-sm);
}
.ref-gallery-tile-cat {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(88, 194, 147, 0.12);  /* ds-allow: success-feedback tint */
  color: var(--accent);
  border-radius: 0;
  font-size: var(--text-xs);
  font-weight: 600;
}
.ref-gallery-tile-source { font-size: var(--text-xs); }
.ref-gallery-tile-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ref-gallery-tile-tag {
  display: inline-block;
  padding: 1px 7px;
  background: var(--glass-white-06);
  border: 1px solid var(--glass-white-12);
  border-radius: 0;
  font-size: var(--text-xs);
}
.ref-gallery-tile-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-sm);
  margin-top: auto;
  padding-top: 4px;
}
.ref-gallery-tile-open {
  color: var(--accent);
  text-decoration: none;
}
.ref-gallery-tile-open:hover { text-decoration: underline; }

/* Highlights section appended below the PDF reader. */
.highlights-section {
  margin-top: 20px;
}
.highlights-section.hidden { display: none; }

/* Highlights tab: pin the header + filters + "Jump to page" and scroll ONLY the
   list, so navigating back to a highlight is easy. Set via .hl-tab-active on the
   panel (setInfoTab); the section becomes a flex column with the list as the sole
   scroll region. */
.info-panel.hl-tab-active .side-panel-body { overflow: hidden; display: flex; flex-direction: column; }
.info-panel.hl-tab-active #tab-highlights { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.info-panel.hl-tab-active .highlights-section { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.info-panel.hl-tab-active .highlights-list { flex: 1; min-height: 0; overflow-y: auto; }
/* In the detail panel the tab name already labels the section. */
.info-tab-panel .highlights-section { margin-top: 0; }
.info-tab-panel .highlights-header { padding-top: 0; }
.highlights-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.highlights-header h4 {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0;
}
.hl-color-chips {
  display: flex;
  gap: 4px;
  margin-left: auto;
}
.hl-color-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 22px;
  padding: 0 6px;
  border: 1px solid var(--border);
  background: var(--hl-solid);
  color: var(--scrim-black-strong);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
.hl-color-chip.active { outline: 2px solid var(--text); }

/* 1E Items 3 + 4 — Inspector-scoped highlight search + a single "Filters"
   popover holding the color + tag filters (Cast Stack pattern). Search input
   mirrors .sources-search; tag chips mirror .hl-color-chip's active treatment
   and reuse .highlight-tag's surface. */
.hl-header-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.hl-search-input {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 6px 10px;
  font-size: var(--text-base);
  font-family: inherit;
  width: 160px;
  max-width: 100%;
}
.hl-search-input:focus { border-color: var(--text-muted); }
.hl-search-input.hidden { display: none; }

/* Inline filter bar (Bite Stack pattern) revealed by the "Filter" toggle —
   a Color group + a Tags group (with the "＋ Tags" dropdown). */
.hl-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 10px;
}
.hl-filter-row.hidden { display: none; }
.hl-filter-group { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.hl-filter-group.hidden { display: none; }
.hl-filter-group-label {
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Color chips sit inline in the bar (no header auto-push). */
.hl-filter-group .hl-color-chips { margin-left: 0; flex-wrap: wrap; }
.hl-tagfilter-btn { white-space: nowrap; }
.hl-tagfilter-active { display: flex; flex-wrap: wrap; gap: 4px; }
.hl-filter-clear {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: var(--text-md);
  cursor: pointer;
  padding: 2px 4px;
  margin-left: auto;
}
.hl-filter-clear:hover { color: var(--text); }

/* Tag-filter dropdown header title (shared .tag-picker chrome otherwise). */
.tag-picker-title {
  font-size: var(--text-xs); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted);
}

/* Search-term marking in highlight rows (Bite Stack parity). hl-color-yellow
   on the <mark> supplies --hl-bg (the design-system highlight-yellow token),
   so no hard-coded colour. */
.match-highlight {
  background: var(--hl-bg);
  color: var(--text);
  padding: 1px 2px;
}

.highlights-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.highlight-row {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 4px solid var(--hl-solid);
}
/* Persistent selection frame — the last-clicked card stays framed until another
   is picked. Ring uses the highlight's own color (--hl-solid, set by hl-color-*).
   A box-shadow so there's no layout shift. */
.highlight-row.hl-selected {
  border-color: var(--hl-solid);
  box-shadow: 0 0 0 2px var(--hl-solid);
  position: relative;
  z-index: 1;
}
/* Action row sits below the highlight text (1b feedback), left-aligned. */
.highlight-row .highlight-actions { justify-content: flex-start; flex-wrap: wrap; }
.highlight-swatch { display: none; } /* left border carries the color */
.highlight-body { flex: 1; min-width: 0; }
.highlight-text {
  font-size: var(--text-base);
  color: var(--text);
  line-height: 1.5;
  white-space: pre-wrap;
}
.highlight-meta {
  margin-top: 4px;
  font-size: var(--text-sm);
}
.highlight-note {
  margin-top: 6px;
  font-size: var(--text-md);
  color: var(--text);
  font-style: italic;
  padding: 6px 8px;
  background: var(--accent-bg);
  border-left: 2px solid var(--text-muted);
}
.highlight-note.empty { display: none; }

/* ── Collapse (Highlights-inspector QoL, 2026-07-08) ─────────────────
   Long cards clamp their text to ~3 lines by default; the Show more/less
   toggle (revealed only on cards whose text actually overflows, via
   .hl-has-toggle set post-render) expands it. Display-only — never touches
   highlight data. Focus mode's own collapse (collapsed-other) owns the rows
   during citation focus, so .hl-collapsed is not applied then. */
.highlight-row.hl-collapsed .highlight-text {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Compact collapsed card (Joey 2026-07-08): drop the page/person/time meta line
   + the note, tighten the vertical padding, and show the tool row only on the
   SELECTED card so a resting card is just the text preview. */
.highlight-row.hl-collapsed {
  gap: 4px;
  padding-top: 6px;
  padding-bottom: 6px;
}
.highlight-row.hl-collapsed .highlight-meta { display: none; }
.highlight-row.hl-collapsed .highlight-note { display: none; }
.highlight-row.hl-collapsed .highlight-actions { display: none; }
/* Tools appear only on selection — click the card here or the highlight in the
   viewer (Joey 2026-07-23: removed the hover/focus auto-reveal). */
.highlight-row.hl-collapsed.hl-selected .highlight-actions { display: flex; }

/* On-page indication of the selected highlight: a darker-shade underline on its
   PDF box + text-view span. Subtle, no layout shift. */
.pdf-highlight-box.hl-selected-mark { box-shadow: inset 0 -3px 0 0 var(--hl-dark); }
.rs-body-hl.hl-selected-mark {
  text-decoration: underline;
  text-decoration-color: var(--hl-dark);
  text-decoration-thickness: 2px;
  text-underline-offset: 2px;
}
.hl-expand-toggle {
  display: none;
  align-self: flex-start;
  margin-top: 4px;
  padding: 0;
  background: none;
  border: none;
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text-muted);
  cursor: pointer;
  text-decoration: underline;
}
.hl-expand-toggle:hover { color: var(--text); }
.highlight-row.hl-has-toggle .hl-expand-toggle { display: inline-block; }
/* Focus mode owns the rows during citation focus — no per-card toggle then. */
.highlight-row.focused .hl-expand-toggle,
.highlight-row.collapsed-other .hl-expand-toggle { display: none; }

/* ── Focus mode (Milestone 1G follow-up, 2026-05-23) ────────────────
   Triggered by ?highlight=<id> in the URL — typically from a footnote
   citation click. The cited highlight gets a brief pulse + lifted
   shadow; other highlights collapse to a one-line preview so the eye
   lands on the focused one even on heavy-highlight sources.
   scroll-margin-top reserves space for the sticky .app-header so
   scrollIntoView doesn't slide the ep-strip under it. */
.highlight-row.focused {
  box-shadow: 0 0 0 2px var(--navy-bg), 0 4px 12px var(--navy-shadow);
  position: relative;
  z-index: 1;
  animation: focus-pulse 1.6s ease-out 1;
  scroll-margin-top: 140px;
}
@keyframes focus-pulse {
  0%   { box-shadow: 0 0 0 0    var(--navy-pulse), 0 0 0 2px var(--navy-bg); }
  60%  { box-shadow: 0 0 0 14px var(--navy-pulse-0), 0 0 0 2px var(--navy-bg); }
  100% { box-shadow: 0 0 0 2px var(--navy-bg), 0 4px 12px var(--navy-shadow); }
}
.highlight-row.collapsed-other {
  padding-top: 6px;
  padding-bottom: 6px;
}
.highlight-row.collapsed-other .highlight-text {
  font-size: var(--text-md);
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.highlight-row.collapsed-other .highlight-meta { display: none; }
.highlight-row.collapsed-other .highlight-note { display: none; }
.highlight-row.collapsed-other .highlight-actions { opacity: 0.6; }

.focus-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--accent-bg);
  border: 1px solid var(--border);
  border-left: 3px solid var(--navy-bg);
  border-radius: 0;
  padding: 8px 12px;
  margin-bottom: 10px;
  font-size: var(--text-base);
}
.focus-banner .focus-banner-text { color: var(--text); flex: 1; min-width: 0; }
.focus-banner .focus-banner-actions { display: flex; gap: 6px; flex-shrink: 0; }
.focus-banner .focus-banner-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--text-md);
  padding: 3px 10px;
  border-radius: 0;
  cursor: pointer;
  font-family: inherit;
}
.focus-banner .focus-banner-btn:hover { background: var(--surface); border-color: var(--text); }
.highlight-note-edit {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.highlight-note-input {
  width: 100%;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 6px 8px;
  font-family: inherit;
  font-size: var(--text-md);
  resize: vertical;
}
.highlight-note-input:focus { border-color: var(--text-muted); }

.highlight-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.btn-icon-sm {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  width: 22px;
  height: 22px;
  font-size: var(--text-md);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-icon-sm:hover { background: var(--surface-hover); color: var(--text); }
.btn-icon-sm.btn-icon-danger:hover { color: var(--danger); border-color: var(--danger); }
.btn-icon-sm:disabled { opacity: 0.5; cursor: not-allowed; }

/* Mini palette inside each highlight row (recolor without opening an edit). */
.hl-mini-palette { display: inline-flex; gap: 2px; }
.hl-mini-dot {
  width: 14px;
  height: 14px;
  background: var(--hl-solid);
  border: 1px solid var(--border);
  cursor: pointer;
  display: inline-block;
}
.hl-mini-dot:hover { transform: scale(1.15); }
.hl-mini-dot.current { outline: 2px solid var(--text); outline-offset: -1px; }

/* ---------- Research Stack — inline PDF reader (1B-2) ---------- */

/* PDF view-tool styles live in the universal .viewer-toolbar / .viewer-toolbar-tools
   (see the viewer-pane block). These are the individual control elements. */
.pdf-page-indicator {
  font-size: var(--text-md);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-width: 38px;
  text-align: center;
}
.pdf-page-nav {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pdf-page-nav.hidden { display: none; }
.pdf-page-nav .btn-icon {
  width: 26px;
  height: 26px;
  font-size: var(--text-body);
}
/* Zoom controls — − 110% + with the % doubling as a reset-to-fit button. */
.pdf-zoom-controls {
  display: flex;
  align-items: center;
  gap: 4px;
}
.pdf-zoom-controls .btn-icon {
  width: 26px;
  height: 26px;
  font-size: var(--text-body);
  line-height: 1;
}
.pdf-zoom-label {
  min-width: 46px;
  padding: 3px 4px;
  font-size: var(--text-md);
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--text-muted);
  background: transparent;
  border: 1px solid transparent;
  font-family: inherit;
  cursor: pointer;
  user-select: none;
}
.pdf-zoom-label:hover { color: var(--text); border-color: var(--border); }
/* Fit width | Fit page — segmented pair. */
.pdf-fit-group { display: inline-flex; }
.pdf-fit-btn {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 4px 10px;
  font-size: var(--text-sm);
  font-family: inherit;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.pdf-fit-btn + .pdf-fit-btn { border-left: none; }
.pdf-fit-btn:hover { color: var(--text); background: var(--surface-hover); }
.pdf-fit-btn.active {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.pdf-select-mode { display: inline-flex; align-items: center; gap: 6px; }
.pdf-select-mode-label {
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.pdf-reader-spacer { flex: 1; }
.pdf-download {
  font-size: var(--text-md);
  white-space: nowrap;
}

/* Source ↔ renditions (Phase 2) — reader version switcher + Versions list.
   Only rendered when a source has 2+ renditions (progressive disclosure). */
.rendition-switcher {
  display: inline-flex;
  align-items: center;
  margin-right: 8px;
}
.rendition-chip {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 4px 10px;
  font-size: var(--text-sm);
  font-family: inherit;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.rendition-chip + .rendition-chip { border-left: none; }
.rendition-chip:hover { color: var(--text); background: var(--surface-hover); }
.rendition-chip.is-active {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
}
.rendition-chip-star { color: var(--accent); }
.rendition-chip.is-active .rendition-chip-star { color: inherit; }

.rendition-versions-note { margin-bottom: 8px; font-size: var(--text-md); }
.rendition-list { display: flex; flex-direction: column; }
.rendition-list-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.rendition-list-row:last-child { border-bottom: none; }
.rendition-list-row.is-active { background: var(--surface-hover); }
.rendition-list-name {
  background: transparent;
  border: none;
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-base);
  cursor: pointer;
  padding: 0;
  text-align: left;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rendition-list-name:hover { text-decoration: underline; }
.rendition-list-name.is-active { font-weight: 600; }
.rendition-list-format {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 1px 5px;
  white-space: nowrap;
}
.rendition-list-primary {
  font-size: var(--text-sm);
  color: var(--accent);
  white-space: nowrap;
}
.rendition-list-ai {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  border: 1px solid var(--border);
  padding: 1px 5px;
  white-space: nowrap;
}

.pdf-canvases {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  background: var(--bg);
  overflow: auto;
  /* Reserve the scrollbar gutter so toggling the vertical scrollbar never
     changes the content width. Without this, resizing a side panel to a
     threshold width makes a Fit-width re-render cross the scrollbar on/off
     point, which changes clientWidth → the ResizeObserver re-fits → toggles
     again: a flicker of the scrollbar + repainted highlights. A stable gutter
     keeps the fit width constant and breaks the loop. */
  scrollbar-gutter: stable;
}
/* Page wrapper holds canvas + highlight overlay + text layer in stacked
   absolute positioning. Wrapper sets its own width/height in JS to match
   the rendered CSS dimensions. */
.pdf-page-wrapper {
  position: relative;
  margin: 0 auto;
  background: var(--surface);
  box-shadow: 0 1px 3px var(--scrim-subtle);
  flex-shrink: 0;
}
.pdf-page-canvas {
  display: block;
  max-width: 100%;
  background: var(--surface);
}

/* Highlight overlay layer sits between the canvas and the text layer. */
.pdf-highlight-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.pdf-highlight-box {
  position: absolute;
  pointer-events: auto;
  cursor: pointer; /* hover affordance — highlights are clickable to edit */
  border-radius: 0;
  mix-blend-mode: multiply;
}
/* With the Highlighter tool ON, let selections pass through existing highlights
   (so you can select over them to make a new one); editing is via the tool-off
   click. */
body.rs-hl-mode .pdf-highlight-box { pointer-events: none; }

/* 7a — merge mode (highlights list) */
.hl-merge-toggle.active { background: var(--text); color: var(--bg); border-color: var(--text); }
.hl-merge-check { margin: 3px 6px 0 0; flex-shrink: 0; cursor: pointer; }
.highlight-row.merge-picked { outline: 2px solid var(--text); outline-offset: -2px; }
.hl-merge-bar {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: var(--accent-bg);
  border: 1px solid var(--border);
}
.hl-merge-bar-label { font-size: var(--text-md); color: var(--text-muted); line-height: 1.35; }
.hl-merge-bar-actions { display: flex; gap: 6px; flex-wrap: wrap; }

/* 7a — boundary drag-adjust overlay (sits above the PDF text layer) */
.pdf-page-wrapper.adjusting .pdf-highlight-layer { opacity: 0.2; }
.pdf-adjust-layer {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
}
.pdf-adjust-box {
  position: absolute;
  background: var(--hl-bg);
  mix-blend-mode: multiply;
  outline: 1px solid rgba(0, 0, 0, 0.28);  /* ds-allow: one-off shadow */
}
.pdf-adjust-handle {
  position: absolute;
  width: 14px;
  margin-left: -7px;
  pointer-events: auto;
  cursor: ew-resize;
  z-index: 5;
}
.pdf-adjust-handle::before { /* the vertical edge bar */
  content: '';
  position: absolute;
  left: 6px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--text);
}
.pdf-adjust-handle::after { /* the round knob */
  content: '';
  position: absolute;
  left: 0;
  width: 14px;
  height: 14px;
  background: var(--text);
  border: 2px solid var(--bg);
  border-radius: 50%;
}
.pdf-adjust-handle.start::after { top: -7px; }
.pdf-adjust-handle.end::after { bottom: -7px; }

/* Boundary drag-adjust for WEB body highlights. Handles are viewport-fixed
   (the body text flows + scrolls), the adjusting highlight's spans go
   transparent, and a CSS-highlight preview shows the live extent. */
.body-adjust-layer { position: fixed; inset: 0; z-index: var(--z-dropdown); pointer-events: none; }
.body-adjust-handle { position: fixed; }
.rs-body-hl.adjusting { background: transparent; }
.web-body-reader.body-adjusting { cursor: ew-resize; }
::highlight(rs-body-adjust-preview) { background-color: rgba(96, 165, 250, 0.5); }  /* ds-allow: RS reader selection/body tint (feature) */
.pdf-adjust-bar {
  position: fixed;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  z-index: var(--z-dropdown);
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-dropdown);
  padding: 6px 10px;
  max-width: 90vw;
}
.pdf-adjust-bar-text {
  font-size: var(--text-md);
  color: var(--text);
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Text layer overlay — PDF.js renders absolutely-positioned spans here. The
   text is transparent so the canvas remains visible; selection highlights it. */
.pdf-text-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 1;
  line-height: 1;
  text-align: initial;
  forced-color-adjust: none;
  z-index: 2;
}
.pdf-text-layer > :is(span, br) {
  color: transparent;
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}
/* Hover affordance: over a highlight, the cursor turns to a pointer — including
   over the glyph spans (which otherwise force cursor:text). Class toggled in JS
   because the text layer sits above the overlay boxes. */
.pdf-text-layer.hl-hover,
.pdf-text-layer.hl-hover > :is(span, br) { cursor: pointer; }
.pdf-text-layer span.markedContent { top: 0; height: 0; }
.pdf-text-layer ::selection {
  background: rgba(96, 165, 250, 0.4); /* soft blue selection */  /* ds-allow: RS reader selection/body tint (feature) */
}
/* Block-mode selectable layer: native selection is turned OFF entirely — it
   hit-tests to the nearest word and bounces to "everything above the cursor" over
   gaps, and its paint can't be reliably suppressed. A custom pointer drag (JS)
   drives selection at block granularity and paints the whole-block rectangles
   below instead. `::selection` transparent is a belt-and-suspenders backstop. */
.pdf-text-layer.synth-block {
  user-select: none;
  -webkit-user-select: none;
}
.pdf-text-layer.synth-block > :is(span, br) { cursor: pointer; }
.pdf-text-layer.synth-block ::selection { background: transparent; }
.pdf-text-layer.synth-block ::-moz-selection { background: transparent; }
/* Block-mode live-selection preview — clean paragraph rectangles over the scan. */
.pdf-block-select-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 2;
}
.pdf-block-select-box {
  position: absolute;
  background: rgba(96, 165, 250, 0.35);  /* ds-allow: RS reader selection/body tint (feature) */
  border-radius: 0;
}
/* PDF.js selection-quality sentinel. Parked below the layer; while a drag is
   in progress (.selecting, toggled in JS) it expands to full height so the
   browser fills the selection line-to-line across the absolutely-positioned
   spans instead of only the lines the cursor crosses. */
.pdf-text-layer .endOfContent {
  display: block;
  position: absolute;
  inset: 100% 0 0;
  z-index: -1;
  cursor: default;
  user-select: none;
}
.pdf-text-layer.selecting .endOfContent { top: 0; }

/* Find-in-document hit layer — above the text layer (z:2), below adjust (z:4).
   Amber boxes so find reads as a distinct, transient layer from user
   highlights; the active match is stronger + outlined and can pulse. */
.pdf-find-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  overflow: hidden;
}
.pdf-find-box {
  position: absolute;
  background: rgba(251, 191, 36, 0.38);  /* ds-allow: decided one-off colour */
  border-radius: 0;
}
.pdf-find-box.active {
  background: rgba(245, 158, 11, 0.55);  /* ds-allow: decided one-off colour */
  outline: 2px solid var(--hl-find-border);
  outline-offset: 0;
}
.pdf-find-box.pulse-once { animation: hl-box-pulse 1.6s ease-out 1; }
.pdf-reader-error {
  color: var(--danger);
  font-size: var(--text-base);
  padding: 16px;
  text-align: center;
}

/* ---------- Research Stack — library controls (1D) ---------- */

/* The whole controls block sits between the search input and the source list. */
.sources-controls {
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.sources-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding: 6px 14px;
}
.sources-toolbar-select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 4px 8px;
  font-family: inherit;
  font-size: var(--text-md);
  flex-shrink: 0;
  max-width: 130px;
}
.sources-toolbar-select:focus { border-color: var(--text-muted); }
/* CSS-Fix-1b: the toolbar Sort / Group-by are .tag-picker triggers (buttons)
   now — the L3.2 toolbar-utility exception was retired suite-wide (Joey,
   2026-07-15). Same box, left-aligned label + caret. */
button.sources-toolbar-select {
  display: inline-flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); text-align: left; cursor: pointer; border-radius: 0;
}
button.sources-toolbar-select::after { content: '▾'; color: var(--text-muted); flex: 0 0 auto; }
button.sources-toolbar-select:hover { border-color: var(--text-muted); }
/* Scout source-selection checkboxes (rail master + per-card) — brand dark blue,
   slightly smaller, vertically centered so they sit in a clean column even though
   the title row is baseline-aligned. */
/* Paint comes from .checkbox (Brand/components.css); only layout is local. */
.scout-select-box { flex: none; align-self: center; }
.scout-master-wrap { display: inline-flex; align-items: center; flex: none; }
.btn-icon.active {
  background: var(--text);
  color: var(--bg);
}

/* Saved views menu (Phase 5a) — the popover surface comes from .popover. */
.saved-views-menu {
  display: flex;
  flex-direction: column;
  padding: 6px 0;
  max-height: 60vh;
  overflow-y: auto;
}
/* When mounted inside the filter panel, sit as a divided full-width section
   below the filter rows (counteracts the panel's horizontal padding). */
.filter-panel > .saved-views-menu {
  margin: 2px -14px 0;
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.saved-views-head {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Collapsible saved-views section header: toggle (caret + label) left, small
   "Save view" button right. The list (.saved-views-body) shows only when open. */
.saved-views-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 12px 6px 6px;
}
.saved-views-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 2px 4px;
  color: var(--text-muted);
}
.saved-views-toggle:hover { color: var(--text); }
.saved-views-toggle:hover .saved-views-head { color: var(--text); }
.saved-views-caret { font-size: var(--text-xs); }
.saved-views-count {
  font-size: var(--text-xs);
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 0 5px;
}
.saved-views-save {
  flex-shrink: 0;
  font-size: var(--text-sm);
  padding: 3px 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.saved-views-save:hover { border-color: var(--text-muted); }
.saved-views-body.hidden { display: none; }
.saved-views-empty {
  padding: 8px 14px;
  font-size: var(--text-md);
  color: var(--text-muted);
  line-height: 1.4;
}
.saved-view-row {
  display: flex;
  align-items: center;
  gap: 4px;
  padding-right: 6px;
}
.saved-view-row:hover { background: var(--surface-hover); }
.saved-view-row.active { background: var(--accent-bg); }
.saved-view-apply {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  padding: 7px 8px 7px 14px;
  font-family: inherit;
  font-size: var(--text-base);
  color: var(--text);
}
.saved-view-icon { flex-shrink: 0; font-size: var(--text-base); }
.saved-view-name {
  flex: 0 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.saved-view-row.active .saved-view-name { font-weight: 600; }
.saved-view-by {
  flex-shrink: 0;
  margin-left: auto;
  padding-left: 8px;
  font-size: var(--text-sm);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 42%;
}
.saved-view-actions {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.saved-view-row:hover .saved-view-actions,
.saved-view-row:focus-within .saved-view-actions { opacity: 1; }
.saved-view-mini {
  background: none;
  border: 0;
  cursor: pointer;
  padding: 4px 5px;
  font-size: var(--text-md);
  line-height: 1;
  color: var(--text-muted);
}
.saved-view-mini:hover,
.saved-view-mini.active { color: var(--text); }
.saved-view-mini.danger:hover { color: var(--danger); }

/* Save / edit-view modal form */
.saved-view-form { display: flex; flex-direction: column; }
.saved-view-form .modal-input {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 7px 9px;
  font-family: inherit;
  font-size: var(--text-base);
}
.saved-view-radio {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: var(--text-base);
  cursor: pointer;
}
.saved-view-radio input { flex-shrink: 0; }
.saved-view-hint {
  font-size: var(--text-sm);
  color: var(--text-muted);
  padding: 2px 0 0 24px;
  line-height: 1.4;
}

/* Expandable filter panel (toggle via the ▾ button) */
.filter-panel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  background: var(--accent-bg);
}
.filter-panel.hidden { display: none; }
/* C5 (L3.6 F1): the sources filter set collapses behind a "FILTERS · N" button
   (shared .btn ghost-sm styling) that reveals the filter rows as an inline
   disclosure below the toolbar — References-page / Chrome-extension pattern. */
.filter-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.filter-row-actions { flex-direction: row; justify-content: flex-end; gap: 8px; }
.filter-label {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.filter-select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  padding: 5px 8px;
  font-family: inherit;
  font-size: var(--text-md);
  width: 100%;
}
.filter-select:focus { border-color: var(--text-muted); }
/* CSS-Fix-1: the vocab filters are .tag-picker triggers (buttons) — same box,
   left-aligned label + caret. (Sort / group-by were carved out as native
   toolbar utilities here; that L3.2 exception was retired suite-wide in
   CSS-Fix-1b — Joey, 2026-07-15 — so they're triggers too.) */
button.filter-select {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  text-align: left; cursor: pointer; border-radius: 0;
}
button.filter-select::after { content: '▾'; color: var(--text-muted); flex: 0 0 auto; }
button.filter-select:hover { border-color: var(--text-muted); }
button.filter-select.filter-active { border-color: var(--accent); }
.filter-chip-group {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
/* Filter toggle chip (DESIGN-SYSTEM.md L2.6) — canonical, built by ui.js
   filterChip() as <button aria-pressed>. Active state keyed on [aria-pressed],
   not a .active class. Supersedes the old .ref-gallery-tag-chip / .refs-tag-chip
   green-rounded toggle styles (Pass 5 filter-chip consolidation, 2026-05-29). */
.filter-chip {
  display: inline-block;
  background: var(--accent-bg);
  color: var(--text-muted);
  border: 1px solid var(--border);
  border-radius: 0;
  font: inherit;
  font-size: var(--text-sm);
  padding: 3px 8px;
  cursor: pointer;
  user-select: none;
}
.filter-chip:hover { color: var(--text); }
.filter-chip[aria-pressed="true"] {

/* Segmented control (DESIGN-SYSTEM.md L2.2 / L3.2) — mutually-exclusive inline
   choice, built by ui.js segmented() as a role="radiogroup" of role="radio"
   buttons (native radios are retired, so the a11y contract is rebuilt there).
   The canonical replacement for a radio group when the options must stay
   VISIBLE: short side-by-side labels, dense per-row choices, or option cards
   whose description carries a consequence (cost, destructive overwrite).
   Use .tag-picker (single) for 1-of-many from a long vocab; .checkbox for
   independent on/off. */
.segmented { display: inline-flex; }
.segmented-option {
  font: inherit; font-size: var(--text-md); color: var(--text-muted);
  background: var(--bg); border: 1px solid var(--border); border-radius: 0;
  padding: var(--space-2) var(--space-3); cursor: pointer; margin: 0;
}
.segmented-option:hover { color: var(--text); border-color: var(--text-muted); }
.segmented-option[aria-checked="true"] {
  position: relative; z-index: 1; color: var(--text); background: var(--accent-bg);
  border-color: var(--accent); font-weight: var(--weight-semibold);
}
/* Compact: joined buttons — collapse the shared border, raise the active one. */
.segmented-compact .segmented-option + .segmented-option { margin-left: -1px; }
/* Cards: stacked options, each showing label + description. */
.segmented-cards { display: flex; flex-direction: column; gap: var(--space-2); align-items: stretch; }
.segmented-cards .segmented-option {
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1);
  text-align: left; padding: var(--space-3);
}
.segmented-option-label { font-size: var(--text-base); font-weight: var(--weight-semibold); }
.segmented-option-desc { font-size: var(--text-md); font-weight: var(--weight-regular); color: var(--text-muted); line-height: 1.5; }

  color: var(--text);
  border-color: var(--text-muted);
  font-weight: 600;
}
.filter-tag-area {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.filter-tag-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
/* Custom-field filters (Milestone 1Q Phase 6) — a stacked list of labelled
   controls inside the Sources filter panel's "Custom fields" row. */
.filter-custom-fields { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
.filter-custom-field { display: flex; flex-direction: column; gap: 3px; }
.filter-custom-field label { font-size: var(--text-sm); color: var(--text-muted); }
/* In-use / All scope toggle row inside the tag-filter popover (shared by the
   Sources workspace + References page). */
.tag-picker-scope {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border);
}
.tag-picker-scope-label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.filter-tag-mode {
  display: inline-flex;
  border: 1px solid var(--border);
  align-self: flex-start;
}
.tag-mode-btn {
  background: transparent;
  border: none;
  color: var(--text-muted);
  padding: 3px 10px;
  font-size: var(--text-sm);
  font-family: inherit;
  cursor: pointer;
}
.tag-mode-btn:hover { color: var(--text); background: var(--surface-hover); }
.tag-mode-btn.active {
  background: var(--text);
  color: var(--bg);
}
.tag-mode-btn + .tag-mode-btn { border-left: 1px solid var(--border); }
.filter-toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-md);
  cursor: pointer;
}
.filter-toggle-label input[type="checkbox"] { margin: 0; }

/* Active filters chip row (always rendered above the list when any active) */
.active-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px 14px;
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.active-filters.hidden { display: none; }
/* Active-filter pills + the match-mode indicator now use chip() / chip({removable})
   (Pass 5 filter-chip consolidation, 2026-05-29); the bespoke .active-filter-chip*
   block was retired. .active-filter-clear (the Clear-all button) stays. */
.active-filter-clear {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: var(--text-sm);
  padding: 2px 8px;
  cursor: pointer;
  margin-left: 4px;
}
.active-filter-clear:hover { color: var(--text); border-color: var(--text-muted); }

/* Group headers in the source list */
/* Collapsible grouped sections (2b). The header is a real <button> so it's
   keyboard-operable; clicking it collapses the group's rows with a smooth
   grid-rows animation. Collapsed state is remembered per episode + grouping. */
.source-group { display: flex; flex-direction: column; }
.source-group-header {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 8px 14px 6px;
  background: var(--bg);
  border: 0;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 1;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: background 120ms ease;
}
.source-group-header:hover { background: var(--surface-hover); }
.source-group-header:hover .source-group-label { color: var(--text); }
.source-group-header:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.source-group-chevron {
  display: inline-flex;
  width: 10px;
  color: var(--text-muted);
  font-size: var(--text-xs);
  line-height: 1;
  user-select: none;
}
.source-group-chevron::before {
  content: '▾';
  display: inline-block;
  transition: transform 160ms ease;
}
.source-group.collapsed .source-group-chevron::before { transform: rotate(-90deg); }
.source-group-label {
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color 120ms ease;
}
.source-group-count {
  margin-left: auto;
  font-size: var(--text-xs);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.source-group-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 180ms ease;
}
.source-group.collapsed .source-group-body { grid-template-rows: 0fr; }
.source-group-items {
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
@media (prefers-reduced-motion: reduce) {
  .source-group-body { transition: none; }
  .source-group-chevron::before { transition: none; }
}

/* Source rows — Chrome-extension parity. Title row (title + type badge + expand
   caret) over a detail block revealed on expand. Collapsed = dense scanning. */
.source-row-titlerow { display: flex; align-items: baseline; gap: 6px; }
/* Scope badge sits inline in the title row (not absolute) here. */
.source-row-titlerow .source-scope-badge {
  position: static; top: auto; right: auto; bottom: auto; flex-shrink: 0;
}
.source-row.collapsed .source-row-detail { display: none; }
.source-row.collapsed .source-row-title { -webkit-line-clamp: 1; }
/* Tighter vertical rhythm for collapsed rows (dense scanning). */
.source-row.collapsed { padding-top: 7px; padding-bottom: 7px; }
.source-row-expand {
  flex-shrink: 0;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  font-size: var(--text-md);
  line-height: 1;
  padding: 2px 4px;
}
.source-row-expand:hover { color: var(--text); }
.source-type-badge {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 1px 6px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
}
/* Processing pill (2026-07-08): a freshly-uploaded PDF still being read (clean
   text + map + rotation + description). Clears when extraction completes. */
.source-processing-pill {
  flex-shrink: 0;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 6px;
  border: 1px solid var(--chip-info-border);
  background: var(--chip-info-bg);
  color: var(--info-text);
  white-space: nowrap;
  animation: processing-pulse 1.6s ease-in-out infinite;
}
@keyframes processing-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }
.source-type-badge.type-web { background: var(--chip-info-bg); color: var(--info-text); border-color: var(--chip-info-border); }
.source-type-badge.type-pdf { background: var(--chip-warning-bg); color: var(--text); border-color: var(--chip-warning-border); }
.source-type-badge.type-book { background: var(--chip-success-bg); color: var(--success-text); border-color: var(--chip-success-border); }
.source-type-badge.type-manual { background: var(--chip-danger-bg); color: var(--text); border-color: var(--chip-danger-border); }
.source-row-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.source-row-tag {
  font-size: var(--text-xs);
  padding: 1px 7px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
}
.source-row-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 8px;
  font-size: var(--text-xs);
  color: var(--text-muted);
}
.source-row-savedby { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Remove × lives in the expanded footer now — static, right-aligned, quiet. */
.source-row-footer .source-row-remove {
  position: static;
  top: auto; right: auto;
  opacity: 1;
  flex-shrink: 0;
}

/* Archived source rows — muted to indicate they're soft-deleted */
.source-row.archived {
  opacity: 0.55;
}
.source-row.archived .source-row-title::before {
  content: '🗄 ';
  font-size: var(--text-sm);
}

/* Edit modal — long form needs vertical room */
.form-grid .form-row > input + input,
.form-grid .form-row > select + input {
  margin-top: 4px;
}

/* Tag picker — popover list body (DESIGN-SYSTEM.md L2.2 / L5.2 S8). Rendered
   inside a .popover by ui.js tagPicker(): the popover supplies the surface,
   this is the header / search / scrollable-list layout. Modeled on the Bite
   Stack dropdown picker. Replaced the 1D 3-region inline pattern (retired
   2026-05-29, Pass 5 S8) — the edit-source modal now uses tagPicker(). */
.tag-picker { display: flex; flex-direction: column; max-height: 340px; overflow: hidden; }
.tag-picker-header {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  padding: 8px; border-bottom: 1px solid var(--border);
}
.tag-picker-new {
  font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); cursor: pointer; background: none;
  border: 1px dashed var(--border); padding: 3px 8px; transition: color 0.15s, border-color 0.15s;
}
.tag-picker-new:hover { color: var(--text); border-color: var(--text-muted); }
.tag-picker-new-input {
  flex: 1; min-width: 0; box-sizing: border-box; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 0; padding: 4px 8px; font-size: var(--text-md);
}
.tag-picker-new-input:focus { border-color: var(--text-muted); outline: none; }
.tag-picker-done {
  font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); cursor: pointer; background: none; border: none;
  padding: 3px 8px; transition: color 0.15s;
}
.tag-picker-done:hover { color: var(--text); }
.tag-picker-search { padding: 8px; border-bottom: 1px solid var(--border); }
.tag-picker-search input {
  width: 100%; box-sizing: border-box; background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: 0; padding: 5px 8px; font-size: var(--text-md);
}
.tag-picker-search input:focus { border-color: var(--text-muted); outline: none; }
.tag-picker-search input::placeholder { color: var(--text-muted); opacity: 0.5; }
.tag-picker-list { overflow-y: auto; flex: 1; }
.tag-picker-group {
  font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-muted); padding: 6px 12px 2px; opacity: 0.6;
}
.tag-picker-item {
  padding: 5px 12px; cursor: pointer; font-size: var(--text-sm); color: var(--text);
  transition: background 0.1s; border-bottom: 1px solid var(--surface-hover);
}
.tag-picker-item:hover { background: var(--accent-bg); }
.tag-picker-item.active { background: var(--accent-bg); color: var(--text-muted); }
.tag-picker-item.active::after { content: ' ✓'; opacity: 0.6; }

/* Tag input — free-text chip editor (DESIGN-SYSTEM.md L2.2 / L5.2 S9). Bordered
   box of chip() atoms + an inline field, built by ui.js tagInput(). The ×
   (.tag-remove) ships with chip(). */
.tag-input {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 6px 8px; border: 1px solid var(--border); background: var(--bg);
  min-height: 40px; cursor: text;
}
.tag-input:focus-within { border-color: var(--text); }
.tag-input-field {
  flex: 1; min-width: 140px; border: none; background: transparent;
  padding: 4px 2px; font-size: var(--text-lg); width: auto; color: var(--text);
}
.tag-empty { color: var(--text-muted); font-size: var(--text-base); padding: 4px 2px; flex: 1; }

/* Category control in the edit modal — grouped wrapper with dropdown +
   clearly-labeled "+ Create new" input. Hide the dropdown half if the
   project has no categories yet so the create path is the only option. */
.edit-category-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.edit-category-select { width: 100%; }
.edit-category-or {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: center;
  color: var(--text-muted);
}
.edit-category-create-label {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.edit-category-create-label-text {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text);
}
.edit-category-new-input {
  width: 100%;
}

/* 1K — Quick Capture modal (shared across Inbox page, references page,
   episodes-list home). */
.qc-backdrop {
  position: fixed; inset: 0;
  background: var(--scrim-black);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.qc-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 18px;
  width: min(480px, 92vw);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.qc-tabs { display: flex; gap: 6px; }
.qc-tab {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 6px 12px;
  border-radius: 0;
  cursor: pointer;
  font-size: var(--text-md);
}
.qc-tab.active {
  background: var(--text);
  color: var(--bg);
  border-color: var(--text);
  font-weight: 600;
}
.qc-body { display: flex; flex-direction: column; gap: 8px; }
/* .qc-field is the same field shape as a wrapping <label>, for fields whose
   control is a button (a .tag-picker trigger): a <label> forwards its click to
   the button and would double-toggle the popover open-then-shut. */
.qc-body label,
.qc-body .qc-field {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--text-md); color: var(--text-muted);
}
.qc-body input[type="text"],
.qc-body input[type="url"] {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 6px 8px;
  font-size: var(--text-base);
}
.qc-body input[type="file"] { color: var(--text); font-size: var(--text-md); }
.qc-actions { display: flex; justify-content: flex-end; gap: 8px; }
.qc-error { color: var(--danger-text); font-size: var(--text-md); }

/* ── Public citation landing page (Milestone 1G) ───────────────────── */
.cite-public-main { padding-top: 32px; padding-bottom: 64px; }
.cite-public-loading,
.cite-public-error {
  text-align: center;
  color: var(--text-muted);
  padding: 64px 16px;
  font-size: var(--text-lg);
}
.cite-public-error { color: var(--danger-text); }
.cite-public-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 28px 32px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);  /* ds-allow: one-off shadow */
}
.cite-public-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-bottom: 10px;
}
.cite-public-title {
  margin: 0 0 18px 0;
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1.3;
  color: var(--text);
}
.cite-public-cta {
  display: inline-block;
}
.cite-public-ctas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}
.cite-public-section { margin-top: 22px; }
.cite-public-section h2 {
  font-size: var(--text-base);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 0 0 8px 0;
  font-weight: 600;
}
.cite-public-summary {
  font-size: var(--text-lg);
  line-height: 1.55;
  color: var(--text);
  margin: 0;
}
.cite-public-highlight { /* container styling — passage gets the color */ }
.cite-public-context {
  font-size: var(--text-base);
  color: var(--text-muted);
  font-style: italic;
  margin: 4px 0;
  line-height: 1.5;
}
.cite-public-passage {
  border-left: 4px solid var(--border);
  background: var(--accent-bg);
  margin: 10px 0;
  padding: 12px 16px;
  font-size: var(--text-body);
  line-height: 1.55;
  color: var(--text);
  border-radius: 0;
}
/* When a highlight color is set, lift the swatch into the left border so
   readers see the producer's color cue without losing legibility. */
.cite-public-passage.hl-color-yellow { border-left-color: var(--hl-solid); background: var(--hl-bg); }
.cite-public-passage.hl-color-green  { border-left-color: var(--hl-solid); background: var(--hl-bg); }
.cite-public-passage.hl-color-blue   { border-left-color: var(--hl-solid); background: var(--hl-bg); }
.cite-public-passage.hl-color-pink   { border-left-color: var(--hl-solid); background: var(--hl-bg); }
.cite-public-passage.hl-color-orange { border-left-color: var(--hl-solid); background: var(--hl-bg); }
.cite-public-passage-meta { margin-top: 4px; }
.cite-public-footer { margin-top: 28px; }
.cite-public-footer .meta {
  font-size: var(--text-md);
  color: var(--text-muted);
  line-height: 1.5;
}
@media (max-width: 600px) {
  .cite-public-card { padding: 20px 18px; }
  .cite-public-title { font-size: var(--text-h2); }
}

/* Shared field-definition editor (Brand/field-editor.js) — the inline,
   collapsible edit form that replaces the old admin field modal. Compact
   density by default (spec FIELDS-AND-SECTIONS.md §4). */
.field-editor {
  border: 1px solid var(--border);
  background: var(--surface-hover);
  padding: 10px 12px;
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.field-editor .form-row { margin: 0; }
/* Type picker trigger (Brand/field-editor.js) — the button that replaced the
   native type dropdown (DESIGN-SYSTEM.md L2.2). Matches the .form-row field box
   so the row is unchanged; the ▾ stands in for the native arrow. */
.field-editor-type-trigger {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  color: var(--text);
  font-size: var(--text-lg);
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  transition: border-color 0.15s;
}
.field-editor-type-trigger:hover { border-color: var(--text-muted); }
.field-editor-type-trigger:focus { border-color: var(--text); outline: none; }
.field-editor-type-trigger::after { content: '\25BE'; opacity: 0.6; }
.field-editor-options { display: flex; flex-direction: column; gap: 4px; }
.field-editor-option { display: flex; align-items: center; gap: 4px; }
.field-editor-option-name { flex: 1; min-width: 0; }
.field-editor-add { margin-top: 2px; }
.field-editor-add-input { width: 100%; }
.field-editor-flags { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.field-editor-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: var(--text-base);
}
.field-editor-toggle-hint { color: var(--text-muted); font-size: var(--text-sm); }
.field-editor-error { color: var(--danger); font-size: var(--text-md); }
.field-editor-footer { display: flex; align-items: center; gap: 8px; margin-top: 2px; }

/* Shared sub-part tag-assignment widget (Brand/field-tag-assign.js) — a labeled,
   controlled tag group (e.g. Brands on a source). Visually distinct from
   free-form tags + source-filing categories via the bold label + the accent
   left border (spec FIELDS-AND-SECTIONS.md §4 tag-interop guard). */
.field-tag-assign {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 2px 0 2px 8px; border-left: 2px solid var(--text-muted);
}
.field-tag-assign-label { font-size: var(--text-md); color: var(--text-muted); font-weight: 600; }
.field-tag-assign-label::after { content: ':'; }
.field-tag-assign-chips { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.field-tag-assign-empty { font-size: var(--text-md); color: var(--text-muted); font-style: italic; }
.field-tag-assign .chip-stale { opacity: 0.65; border-style: dashed; }
/* In the source inspector, project fields (Brands) match the Tags control — an
   uppercase label on its own line ABOVE the chips + picker (not the shared
   widget's inline "Brands:" chip-row + accent border). Scoped to .info-panel so
   the shared widget keeps its spec appearance everywhere else. */
.info-panel .field-tag-assign { padding: 0; border-left: 0; margin-bottom: 16px; }
.info-panel .field-tag-assign-label {
  flex: 0 0 100%;
  font-size: var(--text-sm); font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-muted);
}
.info-panel .field-tag-assign-label::after { content: none; }


/* Tool logo in the slim header (2026-07-20). Replaces the Story // Stack
   wordmark + text label with the tool's own logo, and it is NOT a link: the
   rail's home icon is the way back, so the header logo has no job as one
   (BRANDING §6). Sized to the 22px the wordmark occupied so the header's
   vertical rhythm is unchanged. The artwork is predominantly white with two
   navy accent paths — designed for this navy strip. */
.app-header .brand .brand-logo-tool {
  display: flex;
  align-items: center;
}
.app-header .brand .brand-logo-tool img {
  height: 22px;
  width: auto;
  display: block;
}
