@import url('./tokens.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: 15px;
  line-height: 1.5;
  min-height: 100vh;
}

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: 1.75rem; }
h2 { font-size: 1.35rem; }
h3 { font-size: 1.1rem; }

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-sources-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;
}

.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: 11px;
  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: 11px;
  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: rgba(232, 232, 230, 0.06);
  border-color: var(--navy-text);
  color: var(--navy-text);
}

.user-menu {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  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: 12px;
}
.hero-nav-left a {
  color: var(--navy-muted);
  font-size: 11px;
  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: 12px;
  color: var(--navy-muted);
}

.hero-controls a {
  color: var(--navy-muted);
  font-size: 11px;
  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: 11px;
  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: 11px;
  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: 0.9rem;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 16px;
  font-size: 12px;
  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: #fff;
  border-color: var(--danger);
}
.btn-danger:hover { opacity: 0.85; }

.btn-sm {
  padding: 6px 12px;
  font-size: 10px;
  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: 1.05rem;
  color: var(--text);
}

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

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

.chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 0;
  font-size: 10px;
  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: rgba(74, 122, 82, 0.10); color: var(--success); border-color: rgba(74, 122, 82, 0.35); }
.chip-warning { background: rgba(176, 138, 46, 0.10); color: var(--warning); border-color: rgba(176, 138, 46, 0.35); }
.chip-danger { background: rgba(196, 90, 60, 0.10); color: var(--danger); border-color: rgba(196, 90, 60, 0.35); }
.chip-info { background: rgba(74, 106, 138, 0.10); color: var(--info); border-color: rgba(74, 106, 138, 0.35); }
/* 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: 12px;
  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;
}
.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: 28px; 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: 10px;
  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: 16px;
  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: 11px;
  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: 14px;
  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;
}

.form-row .hint {
  font-size: 0.78rem;
  color: var(--text-dim);
}

.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: 1.2rem;
}

.sign-in-card .subtitle {
  text-align: center;
  color: var(--text-muted);
  font-size: 12px;
  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: 11px;
  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: 13px;
  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: rgba(196, 90, 60, 0.10);
  color: var(--danger);
  border: 1px solid rgba(196, 90, 60, 0.35);
  padding: 9px 12px;
  border-radius: 0;
  font-size: 13px;
  margin-bottom: 12px;
}

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

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

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(26, 26, 24, 0.45);
  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: -4px 0 20px rgba(44, 40, 37, 0.06); transform: translateX(100%); }
.side-panel.dock-right.open { transform: translateX(0); }
.side-panel.dock-left { left: 0; border-right: 1px solid var(--border); box-shadow: 4px 0 20px rgba(44, 40, 37, 0.06); 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; }
.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: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
}

.modal-body { padding: 24px; }

.modal-error {
  margin: 0 24px 14px;
  background: rgba(196, 90, 60, 0.10);
  color: var(--danger);
  border: 1px solid rgba(196, 90, 60, 0.35);
  padding: 9px 12px;
  border-radius: 0;
  font-size: 13px;
}

.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: 13px;
  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: 16px;
  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: 11px;
  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: 15px;
  letter-spacing: 0.02em;
}
.season-header .meta {
  color: var(--text-muted);
  font-size: 0.85rem;
}

.season-caret {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  color: var(--text-muted);
  font-size: 0.8rem;
  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: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.project-toggle .meta {
  color: var(--text-muted);
  font-size: 13px;
}
.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: 0.85rem;
}

.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: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  background: var(--bg);
}

/* L2.5 density modifier — compact rows for high-density tables. */
table.list.table-compact td { padding: 6px 10px; }

/* L2.5 sortable column header — chevron after the label; idle muted, active
   full-strength; click cycles asc → desc → none (driven by data-direction). */
.th-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.th-sortable::after {
  content: '↕';
  margin-left: 6px;
  font-size: 9px;
  color: var(--text-muted);
}
.th-sortable[data-direction="asc"]::after { content: '↑'; color: var(--text); }
.th-sortable[data-direction="desc"]::after { content: '↓'; color: var(--text); }

/* ---------- 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); }
.hidden { display: none !important; }
.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: 12px;
  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: 10px;
  font-weight: 700;
  text-transform: uppercase;
  overflow: hidden;
}
.user-menu-trigger .avatar img {
  width: 100%; height: 100%; object-fit: cover;
}

.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: 0 8px 24px rgba(11, 26, 50, 0.15);
}
.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: 12px; 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: 11px;
  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: 10px; }
.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: 11px; 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: 12px;
  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; }
}

/* Cross-subdomain auth handoff interstitial — shown briefly while
   mintHandoffToken runs and the page redirects. Sentence-case copy,
   sharp corners, navy text on cream surface (BRANDING §6/§8). */
.handoff-overlay {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-weight: 500;
  font-size: 18px;
  letter-spacing: 0.01em;
  z-index: 1000;
}
.handoff-overlay.open { display: flex; }

/* ---------- 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-sources-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-sources-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-sources-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-sources-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: 13px;
  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: 12px;
  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 .sources-scope-row,
.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: #ffffff;
}
.page-thumb-canvas-wrap canvas {
  max-width: 100%;
  height: auto;
  display: block;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}
.page-thumb-label { font-size: 11px; 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: 16px;
  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: 13px;
  font-family: inherit;
}
.url-add-box input[type="url"]:focus { border-color: var(--text-muted); }
.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: 13px;
  font-family: inherit;
}
.sources-search input[type="search"]:focus { border-color: var(--text-muted); }
.tag-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.tag-chip {
  background: var(--accent-bg);
  color: var(--text-muted);
  font-size: 11px;
  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);
}
.tag-chips-empty {
  font-size: 11px;
  color: var(--text-muted);
  font-style: italic;
}

/* 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: 16px;
  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; }
.source-row-title {
  color: var(--text);
  font-weight: 600;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 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: 9.5px;
  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;
  vertical-align: 1px;
}

.source-row-meta { font-size: 11px; margin-top: 2px; color: var(--text-muted); padding-right: 74px; }
/* Source-scope cascade toggle row (Phase 2). Always-visible primary control
   above the sources list. */
.sources-scope-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.sources-scope-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
/* 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: 9px;
  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: 12px; color: var(--text-muted); min-width: 58px; }
.scope-picker-field select { flex: 1; }
/* 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: 13px;
  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: 18px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.project-mode-season { font-size: 13px; 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: 14px; }
.project-research-hint { font-size: 12px; color: var(--text-muted); }
.source-row-summary {
  font-size: 12px;
  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: 13px;
  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-sources-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: 100vw; }
  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-sources-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-sources-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-sources-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: 100vw; }
  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: 13px;
  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; }

/* 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;
}

/* Info tab — metadata definition grid. */
.info-meta-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 7px 12px;
  font-size: 13px;
  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: 11px;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
  color: var(--text-muted);
  width: 100%;
  margin-bottom: 2px;
}
.hl-toc-chip {
  font-size: 11px;
  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-group-heading {
  font-size: 11px;
  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 rgba(11, 26, 50, 0.55); }
  60%  { box-shadow: 0 0 0 10px rgba(11, 26, 50, 0.0); }
  100% { box-shadow: 0 0 0 0 rgba(11, 26, 50, 0.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);
}
/* 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: 14px; 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: 14px;
  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;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.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: 12px; }
.reader-aa-menu { display: flex; flex-direction: column; gap: 4px; padding: 8px 10px; }
.reader-aa-head {
  font-size: 10px;
  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: 14px;
  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: 12px;
  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: 12px;
  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: 12px;
  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); }
/* Stored-highlight overlay on the body — painted via the CSS Custom Highlight
   API (no DOM mutation), semi-transparent so text stays readable. */
::highlight(rs-body-yellow) { background-color: rgba(253, 224, 71, 0.40); }
::highlight(rs-body-green)  { background-color: rgba(134, 239, 172, 0.45); }
::highlight(rs-body-blue)   { background-color: rgba(147, 197, 253, 0.45); }
::highlight(rs-body-pink)   { background-color: rgba(249, 168, 212, 0.45); }
::highlight(rs-body-orange) { background-color: rgba(253, 186, 116, 0.45); }

.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);
  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: 36px;
  line-height: 1;
}
.drop-overlay-text {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.drop-overlay-hint {
  font-size: 11px;
  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: 11px;
  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: 11px;
  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: 16px;
  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-color-yellow { --hl-bg: rgba(253, 224, 71, 0.55); --hl-solid: #fde047; }
.hl-color-green  { --hl-bg: rgba(74, 222, 128, 0.45); --hl-solid: #86efac; }
.hl-color-blue   { --hl-bg: rgba(96, 165, 250, 0.40); --hl-solid: #93c5fd; }
.hl-color-pink   { --hl-bg: rgba(244, 114, 182, 0.40); --hl-solid: #f9a8d4; }
.hl-color-orange { --hl-bg: rgba(251, 146, 60, 0.45); --hl-solid: #fdba74; }

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

/* Floating selection toolbar appended to <body>. Pops up on selection in
   a PDF text layer. Five color swatches + close button. */
.hl-toolbar {
  position: absolute;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  user-select: none;
}
.hl-toolbar.hidden { display: none; }
.hl-toolbar-row { display: flex; align-items: center; gap: 4px; }
.hl-toolbar-sep { width: 1px; height: 20px; background: var(--border); margin: 0 2px; }
.hl-toolbar-swatch {
  width: 24px;
  height: 24px;
  border: 1px solid var(--border);
  background: var(--hl-solid, #fde047);
  cursor: pointer;
  padding: 0;
}
.hl-toolbar-swatch:hover { transform: scale(1.1); }
.hl-toolbar-btn {
  width: 26px;
  height: 24px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 0;
}
.hl-toolbar-btn:hover { background: var(--surface-hover); }
.hl-toolbar-cancel {
  width: 24px;
  height: 24px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.hl-toolbar-cancel:hover { color: var(--text); }

/* Expandable annotate form (note + tags + color). */
.hl-toolbar-annotate { display: flex; flex-direction: column; gap: 6px; width: 240px; }
.hl-toolbar-annotate.hidden { display: none; }
.hl-annotate-dots { display: flex; gap: 4px; }
.hl-annotate-dot {
  width: 18px; height: 18px; border: 1px solid var(--border);
  background: var(--hl-solid, #fde047); cursor: pointer; padding: 0;
}
.hl-annotate-dot.selected { outline: 2px solid var(--text); outline-offset: 1px; }
.hl-annotate-note, .hl-annotate-tags {
  width: 100%; box-sizing: border-box;
  border: 1px solid var(--border); background: var(--bg);
  font-family: inherit; font-size: 12px; padding: 6px 8px; color: var(--text);
}
.hl-annotate-note { resize: vertical; }
.hl-annotate-actions { display: flex; justify-content: flex-end; }

/* Auto-highlight toggle in the Highlights tab. */
.hl-auto-toggle {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 12px; color: var(--text); cursor: pointer; margin: 0 0 10px;
}
.hl-auto-toggle .hl-auto-hint { flex-basis: 100%; margin-left: 22px; }

/* 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: 11px; 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: 13px;
  font-weight: 500;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.ref-tile-note {
  font-size: 12px;
  background: rgba(0, 0, 0, 0.18);
  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: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0;
  font-size: 11px;
}
.ref-tile-meta { font-size: 11px; }

.ref-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  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);
}

/* ---------- References gallery modal (1J-a Chunk 4b) ---------- */
.ref-gallery-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  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: 18px;
  font-weight: 600;
}
.ref-gallery-meta { flex: 1; font-size: 13px; }
.ref-gallery-close {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: 24px;
  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: 12px;
}
.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: 12px;
  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: 14px;
}

.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: 12px;
  background: rgba(0, 0, 0, 0.18);
  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: 11px;
}
.ref-gallery-tile-cat {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(88, 194, 147, 0.12);
  color: var(--accent);
  border-radius: 0;
  font-size: 10.5px;
  font-weight: 600;
}
.ref-gallery-tile-source { font-size: 10.5px; }
.ref-gallery-tile-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.ref-gallery-tile-tag {
  display: inline-block;
  padding: 1px 7px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 0;
  font-size: 10.5px;
}
.ref-gallery-tile-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 11px;
  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; }
/* 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;
  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: rgba(0, 0, 0, 0.75);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}
.hl-color-chip.active { outline: 2px solid var(--text); }

.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);
}
/* 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: 13px;
  color: var(--text);
  line-height: 1.5;
  white-space: pre-wrap;
}
.highlight-meta {
  margin-top: 4px;
  font-size: 11px;
}
.highlight-note {
  margin-top: 6px;
  font-size: 12px;
  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; }

/* ── 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 rgba(11, 26, 50, 0.18);
  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    rgba(11, 26, 50, 0.55), 0 0 0 2px var(--navy-bg); }
  60%  { box-shadow: 0 0 0 14px rgba(11, 26, 50, 0.00), 0 0 0 2px var(--navy-bg); }
  100% { box-shadow: 0 0 0 2px var(--navy-bg), 0 4px 12px rgba(11, 26, 50, 0.18); }
}
.highlight-row.collapsed-other {
  padding-top: 6px;
  padding-bottom: 6px;
}
.highlight-row.collapsed-other .highlight-text {
  font-size: 12px;
  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: 13px;
}
.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: 12px;
  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: 12px;
  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: 12px;
  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: 12px;
  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: 16px;
}
/* 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: 16px;
  line-height: 1;
}
.pdf-zoom-label {
  min-width: 46px;
  padding: 3px 4px;
  font-size: 12px;
  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: 11px;
  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-reader-spacer { flex: 1; }
.pdf-download {
  font-size: 12px;
  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: #ffffff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  flex-shrink: 0;
}
.pdf-page-canvas {
  display: block;
  max-width: 100%;
  background: #ffffff;
}

/* 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;
  border-radius: 0;
  mix-blend-mode: multiply;
}

/* 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;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: var(--accent-bg);
  border: 1px solid var(--border);
}
.hl-merge-bar-label { font-size: 12px; color: var(--text-muted); line-height: 1.35; }
.hl-merge-bar-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* 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);
}
.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; }
.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: 12px;
  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%;
}
.pdf-text-layer span.markedContent { top: 0; height: 0; }
.pdf-text-layer ::selection {
  background: rgba(96, 165, 250, 0.4); /* soft blue selection */
}
/* 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; }
.pdf-reader-error {
  color: var(--danger);
  font-size: 13px;
  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;
  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: 12px;
  flex-shrink: 0;
  max-width: 130px;
}
.sources-toolbar-select:focus { border-color: var(--text-muted); }
.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;
}
.saved-views-head {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: 4px 14px 6px;
}
.saved-views-empty {
  padding: 8px 14px;
  font-size: 12px;
  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: 13px;
  color: var(--text);
}
.saved-view-icon { flex-shrink: 0; font-size: 13px; }
.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: 11px;
  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: 12px;
  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); }
.saved-views-foot {
  border-top: 1px solid var(--border);
  margin-top: 4px;
  padding-top: 4px;
}
.saved-views-action {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
  padding: 8px 14px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.saved-views-action:hover { background: var(--surface-hover); }
.saved-views-action-icon { font-size: 14px; }

/* 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: 13px;
}
.saved-view-radio {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 13px;
  cursor: pointer;
}
.saved-view-radio input { flex-shrink: 0; }
.saved-view-hint {
  font-size: 11px;
  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; }
.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: 10px;
  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: 12px;
  width: 100%;
}
.filter-select:focus { border-color: var(--text-muted); }
.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: 11px;
  padding: 3px 8px;
  cursor: pointer;
  user-select: none;
}
.filter-chip:hover { color: var(--text); }
.filter-chip[aria-pressed="true"] {
  color: var(--text);
  border-color: var(--text-muted);
  font-weight: 600;
}
.filter-tag-area {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.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: 11px;
  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: 12px;
  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: 11px;
  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: 9px;
  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: 11px;
  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: 10px;
  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; }
}

/* Compact-density source rows */
.source-row.compact {
  padding: 6px 14px;
}
.source-row.compact .source-row-title {
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.source-row.compact .source-row-meta { display: none; }

/* 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: 11px;
}

/* 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: 10px; 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: 12px;
}
.tag-picker-new-input:focus { border-color: var(--text-muted); outline: none; }
.tag-picker-done {
  font-size: 10px; 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: 12px;
}
.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: 9px; 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: 11px; 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: 14px; width: auto; color: var(--text);
}
.tag-empty { color: var(--text-muted); font-size: 13px; 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: 10px;
  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: 11px;
  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: rgba(0,0,0,0.55);
  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: 12px;
}
.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-body label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; 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: 13px;
}
.qc-body input[type="file"] { color: var(--text); font-size: 12px; }
.qc-actions { display: flex; justify-content: flex-end; gap: 8px; }
.qc-error { color: var(--danger-text); font-size: 12px; }

/* ── 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: 14px;
}
.cite-public-error { color: var(--danger-text); }
.cite-public-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 28px 32px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.cite-public-eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 11px;
  color: var(--text-muted);
  margin-bottom: 10px;
}
.cite-public-title {
  margin: 0 0 18px 0;
  font-size: 24px;
  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: 13px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 0 0 8px 0;
  font-weight: 600;
}
.cite-public-summary {
  font-size: 14px;
  line-height: 1.55;
  color: var(--text);
  margin: 0;
}
.cite-public-highlight { /* container styling — passage gets the color */ }
.cite-public-context {
  font-size: 13px;
  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: 15px;
  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: 12px;
  color: var(--text-muted);
  line-height: 1.5;
}
@media (max-width: 600px) {
  .cite-public-card { padding: 20px 18px; }
  .cite-public-title { font-size: 20px; }
}

