/* ============================================================
   App layout & components
   ============================================================ */

#root, .app {
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  background: var(--canvas-bg);
}

/* Phase 3 rail redesign — rails are floating glass-2 insets above the canvas.
   The grid no longer reserves columns for them; the canvas runs full width.
   Canvas-internal overlays (legend, pipeline strip, canvas-controls) are
   inset via the --rail-*-clear vars so they don't sit under the rails.
   See RAIL_REDESIGN.md §2–§3. */
:root {
  --rail-left-w: 264px;
  --rail-right-w: 280px;
  --rail-inset: 22px;     /* viewport edge → rail edge */
  --rail-clear-gap: 16px; /* extra breathing room between overlay and rail */
  --rail-left-clear: calc(var(--rail-inset) + var(--rail-left-w) + var(--rail-clear-gap));
  --rail-right-clear: calc(var(--rail-inset) + var(--rail-right-w) + var(--rail-clear-gap));
}

.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 56px minmax(0, 1fr) 44px;
  grid-template-areas:
    "topbar"
    "canvas"
    "footer";
  padding: 10px;
  gap: 10px;
  position: relative;
}

/* ── Mobile nav bar — only visible on mobile ──────────────────
   Three icon buttons that open fullscreen overlay sheets containing
   the desktop FilterBar / Legend / LeftRail content, re-laid for
   vertical mobile layout. Hidden by default (desktop). */
.mobile-nav { display: none; }
.mobile-sheet-backdrop { display: none; }

/* ── Mobile (<768px) — full feature parity with desktop ───────
   Investors viewing on phone need every control desktop has.
   Pattern: bottom nav bar with 3 icons (Filter / Legend / API)
   triggering fullscreen-bottom sheets. Right-rail inspector is
   its own bottom sheet (independent). */
@media (max-width: 767px) {
  .app { padding: 6px; gap: 6px; }
  .rail-left { display: none; }

  /* Right rail — bottom sheet when something is selected.
     Shadow is theme-aware: heavier on dark canvas, softer on light. */
  .rail-right {
    display: flex !important;
    position: fixed !important;
    left: 0; right: 0; bottom: 0;
    top: auto;
    width: 100% !important;
    max-width: none !important;
    height: 78vh;
    max-height: calc(100vh - 60px); /* keep ≥60px above viewport top */
    border-radius: var(--r-3) var(--r-3) 0 0;
    border: 1px solid var(--hairline-strong);
    border-bottom: none;
    box-shadow: var(--mobile-sheet-shadow), 0 -2px 0 var(--hairline) inset;
    z-index: 80;
    transform: translateY(100%);
    transition: transform 240ms var(--ease);
  }
  .rail-right[data-active-mode="entity"],
  .rail-right[data-active-mode="endpoint"],
  .rail-right[data-active-mode="question"] {
    transform: translateY(0);
  }
  .rail-right[data-active-mode="empty"],
  .rail-right.rail-collapsed {
    transform: translateY(100%);
    pointer-events: none;
  }
  .rail-right[data-active-mode]:not([data-active-mode="empty"])::before {
    content: "";
    position: absolute;
    top: 6px; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 4px;
    border-radius: 999px;
    /* Drag handle visible in both themes — hairline-strong is too faint
       on the translucent sheet in light mode (rgba(0,0,0,0.15)). Use a
       theme-aware --drag-handle token below. */
    background: var(--drag-handle, var(--hairline-strong));
    pointer-events: none;
  }

  /* Default-hide canvas overlays — they re-render as mobile sheets via the
     [data-mobile-sheet] attribute on .app below. */
  .filter-bar, .legend { display: none !important; }

  /* When a sheet is open, suppress canvas-controls so they don't peek above the sheet. */
  .app[data-mobile-sheet="filter"] .canvas-controls,
  .app[data-mobile-sheet="legend"] .canvas-controls,
  .app[data-mobile-sheet="api"] .canvas-controls,
  .app[data-mobile-sheet="filter"] .mobile-nav,
  .app[data-mobile-sheet="legend"] .mobile-nav,
  .app[data-mobile-sheet="api"] .mobile-nav {
    display: none !important;
  }

  /* Keep zoom controls but lift to clear the mobile nav bar. */
  .canvas-controls { bottom: 60px !important; right: 10px !important; }

  /* Topbar simplification — drop the tagline divider. */
  .topbar { padding: 0 10px; gap: 6px; }
  .topbar-tagline { display: none; }
  .brand { padding-right: 6px; border-right: none; margin-right: 0; }
  .topbar-cta {
    padding: 6px 11px !important;
    font-size: 11.5px !important;
  }

  /* Footer — single tight row */
  .footer {
    padding: 0 10px !important;
    gap: 8px !important;
    overflow-x: auto;
    flex-wrap: nowrap;
  }
  .footer .footer-stat,
  .footer .footer-link { flex-shrink: 0; }
  .footer-mobile-hide { display: none !important; }

  /* ── Mobile nav bar (bottom of canvas) ─────────────────────
     Tap targets meet WCAG: each button ≥40px tall (44px target zone
     met via padding+icon). iOS safe-area-inset keeps it clear of the
     home indicator on iPhone X+ devices. */
  .mobile-nav {
    display: flex;
    position: absolute;
    bottom: max(12px, env(safe-area-inset-bottom));
    left: 10px;
    z-index: 12;
    align-items: center;
    gap: 4px;
    padding: 4px;
    border-radius: var(--r-pill);
    background: color-mix(in oklab, var(--bg-2) 85%, transparent);
    border: 1px solid var(--hairline);
    backdrop-filter: blur(12px) saturate(140%);
    -webkit-backdrop-filter: blur(12px) saturate(140%);
    box-shadow: 0 4px 16px rgba(0,0,0,0.28);
  }
  .mobile-nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 13px;
    min-height: 40px;
    border-radius: var(--r-pill);
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-2);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease);
  }
  .mobile-nav-btn:hover {
    color: var(--text-1);
    background: var(--accent-tint);
  }
  .mobile-nav-btn[aria-pressed="true"] {
    color: var(--text-on-accent);
    background: var(--accent-bright);
    border: 1px solid color-mix(in oklab, var(--accent-bright) 60%, #000);
    font-weight: 600;
    box-shadow:
      0 2px 8px var(--accent-glow),
      inset 0 1px 0 var(--glass-inset-top),
      0 0 0 2px color-mix(in oklab, var(--accent-bright) 35%, transparent);
  }

  /* ── Mobile sheet backdrop — theme-aware so light mode doesn't
     get a near-opaque dark navy overlay over its sage-cream canvas. */
  .mobile-sheet-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: color-mix(in oklab, var(--bg-0) 68%, transparent);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    z-index: 70;
    animation: mobile-backdrop-in 180ms var(--ease);
  }
  :root[data-theme="dark"] .mobile-sheet-backdrop {
    background: rgba(8, 12, 20, 0.55);
  }
  @keyframes mobile-backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* ── Mobile FilterBar — shown when [data-mobile-sheet="filter"] ── */
  .app[data-mobile-sheet="filter"] .filter-bar {
    display: flex !important;
    position: fixed !important;
    top: auto !important;
    bottom: 0;
    left: 0; right: 0;
    transform: none !important;
    flex-direction: column;
    align-items: stretch;
    width: 100%;
    max-width: none;
    border-radius: var(--r-3) var(--r-3) 0 0;
    padding: 18px 16px 24px;
    gap: 14px;
    z-index: 75;
    border: 1px solid var(--hairline-strong);
    border-bottom: none;
    box-shadow: var(--mobile-sheet-shadow);
    animation: mobile-sheet-in 220ms var(--ease);
  }
  .app[data-mobile-sheet="filter"] .filter-bar-title {
    /* Real h2 element, lifted from sr-only on mobile */
    position: static;
    width: auto;
    height: auto;
    margin: 4px 0 4px;
    padding: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
    font-family: var(--font-display);
    font-size: 14px;
    font-weight: 600;
    color: var(--text-1);
    letter-spacing: -0.01em;
  }
  /* Pipeline + confidence + count + reset all stack vertically on mobile */
  .app[data-mobile-sheet="filter"] .filter-pipeline {
    flex-wrap: wrap;
    gap: 6px;
  }
  .app[data-mobile-sheet="filter"] .filter-pipeline-stage {
    flex: 1 1 calc(50% - 6px);
    min-width: 0;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .app[data-mobile-sheet="filter"] .filter-divider {
    width: auto;
    height: 1px;
    margin: 0;
  }
  .app[data-mobile-sheet="filter"] .confidence-filter {
    width: 100%;
  }
  .app[data-mobile-sheet="filter"] .confidence-slider {
    flex: 1;
    width: auto !important;
  }
  /* Larger thumb on mobile so it meets touch-target guidance and stays
     visible on the light-bg slider track. */
  .app[data-mobile-sheet="filter"] .confidence-slider::-webkit-slider-thumb {
    width: 20px !important;
    height: 20px !important;
    border-width: 2px !important;
  }
  .app[data-mobile-sheet="filter"] .confidence-slider::-moz-range-thumb {
    width: 20px !important;
    height: 20px !important;
    border-width: 2px !important;
  }

  /* ── Mobile Legend — shown when [data-mobile-sheet="legend"] ── */
  .app[data-mobile-sheet="legend"] .legend {
    display: block !important;
    position: fixed !important;
    top: auto !important;
    bottom: 0;
    left: 0; right: 0;
    transform: none !important;
    width: 100%;
    max-width: none;
    border-radius: var(--r-3) var(--r-3) 0 0;
    padding: 18px 16px 24px;
    z-index: 75;
    border: 1px solid var(--hairline-strong);
    border-bottom: none;
    box-shadow: var(--mobile-sheet-shadow);
    max-height: 80vh;
    overflow-y: auto;
    animation: mobile-sheet-in 220ms var(--ease);
  }

  /* ── Mobile API browser (left rail) — shown when [data-mobile-sheet="api"] ── */
  .app[data-mobile-sheet="api"] .rail-left {
    display: flex !important;
    position: fixed !important;
    top: auto !important;
    bottom: 0;
    left: 0; right: 0;
    width: 100% !important;
    max-width: none !important;
    height: 80vh;
    border-radius: var(--r-3) var(--r-3) 0 0;
    z-index: 75;
    border: 1px solid var(--hairline-strong);
    border-bottom: none;
    box-shadow: var(--mobile-sheet-shadow);
    overflow-y: auto;
    animation: mobile-sheet-in 220ms var(--ease);
  }
  /* Drag-handle on mobile sheets — uses theme-aware --drag-handle so
     it stays visible on translucent surfaces in both light and dark. */
  .app[data-mobile-sheet="filter"] .filter-bar::after,
  .app[data-mobile-sheet="legend"] .legend::after,
  .app[data-mobile-sheet="api"] .rail-left::after {
    content: "";
    position: absolute;
    top: 6px; left: 50%;
    transform: translateX(-50%);
    width: 36px; height: 4px;
    border-radius: 999px;
    background: var(--drag-handle, var(--hairline-strong));
    pointer-events: none;
  }
  @keyframes mobile-sheet-in {
    from { transform: translateY(100%); opacity: 0.6; }
    to   { transform: translateY(0); opacity: 1; }
  }
}

/* ── Narrow phones (<360px) — pipeline stages stack 1-per-row in
   the filter sheet so labels like "BD & IP" never truncate. */
@media (max-width: 359px) {
  .app[data-mobile-sheet="filter"] .filter-pipeline {
    flex-direction: column;
    align-items: stretch;
  }
  .app[data-mobile-sheet="filter"] .filter-pipeline-stage {
    flex: 1 1 100%;
    width: 100%;
  }
}

/* ── Tablet (768–1079px) — desktop layout, hide left rail only.
   Right rail still shows as a side panel (we have room). */
@media (min-width: 768px) and (max-width: 1079px) {
  .rail-left { display: none; }
}

/* ── Topbar ───────────────────────────────────────────────── */
.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  border-radius: var(--r-3);
  position: relative;
  z-index: 30;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-right: 12px;
  border-right: 1px solid var(--hairline);
  margin-right: 4px;
  height: 32px;
}
.brand-mark {
  width: 26px; height: 26px;
  border-radius: 8px;
  background:
    radial-gradient(circle at 30% 30%, var(--accent-bright), transparent 60%),
    linear-gradient(135deg, var(--accent), var(--accent-dim));
  position: relative;
  box-shadow:
    inset 0 1px 0 0 oklch(100% 0 0 / 0.4),
    0 0 12px var(--accent-glow);
}
.brand-mark::after {
  content: "";
  position: absolute; inset: 4px;
  border-radius: 5px;
  background: linear-gradient(180deg, oklch(100% 0 0 / 0.18), transparent 60%);
}
.brand-name {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-1);
}
.brand-name .accent { color: var(--accent); font-weight: 500; }

/* IA mode switcher — pill segmented, the spine of the hybrid */
.mode-switch {
  display: inline-flex;
  align-items: center;
  padding: 3px;
  height: 32px;
  border-radius: var(--r-pill);
  background: oklch(0% 0 0 / 0.18);
  border: 1px solid var(--hairline);
  position: relative;
}
:root[data-theme="light"] .mode-switch { background: oklch(0% 0 0 / 0.04); }

.mode-switch button {
  position: relative;
  padding: 0 14px;
  height: 26px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-2);
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: 6px;
  transition: color var(--duration-fast) var(--ease);
  z-index: 1;
}
.mode-switch button:hover { color: var(--text-1); }
.mode-switch button[aria-selected="true"] { color: var(--text-1); }
.mode-switch .indicator {
  position: absolute;
  top: 3px; bottom: 3px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
  border: 1px solid var(--hairline-strong);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.25), inset 0 1px 0 var(--hairline-specular);
  transition: transform var(--duration) var(--ease), width var(--duration) var(--ease);
  z-index: 0;
}

/* Search */
.search {
  flex: 1;
  max-width: 480px;
  margin: 0 auto;
  height: 32px;
  display: flex; align-items: center;
  padding: 0 10px 0 10px;
  border-radius: var(--r-2);
  background: oklch(0% 0 0 / 0.18);
  border: 1px solid var(--hairline);
  gap: 8px;
  color: var(--text-2);
  transition: border var(--duration-fast) var(--ease), background var(--duration-fast) var(--ease);
}
:root[data-theme="light"] .search { background: oklch(0% 0 0 / 0.04); }
.search:focus-within {
  border-color: var(--accent);
  background: var(--accent-tint);
}
.search input {
  flex: 1;
  background: none; border: 0; outline: none;
  font-size: 12.5px;
  color: var(--text-1);
}
.search input::placeholder { color: var(--text-3); }

.topbar-right {
  display: flex; align-items: center; gap: 6px;
  margin-left: auto;
}

/* Generic icon button — used header & footer for consistency */
.icon-btn {
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-2);
  color: var(--text-2);
  transition: background var(--duration-fast) var(--ease), color var(--duration-fast) var(--ease);
}
.icon-btn:hover { background: var(--bg-3); color: var(--text-1); }
.icon-btn[aria-pressed="true"] {
  color: var(--accent);
  background: var(--accent-tint);
}

.btn {
  height: 32px;
  padding: 0 14px;
  border-radius: var(--r-2);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-1);
  background: var(--bg-2);
  border: 1px solid var(--hairline-strong);
  display: inline-flex; align-items: center; gap: 6px;
  transition: all var(--duration-fast) var(--ease);
}
.btn:hover { background: var(--bg-3); border-color: var(--text-4); }
.btn-primary {
  background: var(--accent);
  color: oklch(15% 0.01 240);
  border-color: var(--accent-bright);
  box-shadow: 0 0 0 1px var(--accent-bright) inset, 0 1px 0 0 oklch(100% 0 0 / 0.3) inset, 0 0 16px var(--accent-glow);
}
.btn-primary:hover { background: var(--accent-bright); }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--bg-3); color: var(--text-1); }

/* ── Filter bar (Dynamic Island style) ────────────────────── */
.filter-bar {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translate(-50%, 0);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border-radius: var(--r-pill);
  z-index: 10;
  transition: all var(--duration) var(--ease);
}
/* Filter bar title — visually hidden on desktop (the bar is its own
   landmark via aria-label), revealed inside the mobile sheet. */
.filter-bar-title {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Theme toggle — visible click feedback ──────────────────
   Icon swap on click rotates the new icon in. Subtle accent
   ring on press confirms the click landed even if the user's
   eye is elsewhere on the page during the repaint. */
.theme-toggle {
  position: relative;
}
.theme-toggle:active {
  background: var(--accent-tint);
  transform: scale(0.94);
}
.theme-toggle svg {
  transition: transform 280ms var(--ease), opacity 200ms var(--ease);
}
.theme-toggle[data-theme="dark"] svg { animation: theme-icon-in 320ms var(--ease); }
.theme-toggle[data-theme="light"] svg { animation: theme-icon-in 320ms var(--ease); }
@keyframes theme-icon-in {
  from { transform: rotate(-30deg) scale(0.7); opacity: 0; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .theme-toggle svg { animation: none !important; transition: none !important; }
  .theme-toggle:active { transform: none; }
}

.filter-chip {
  display: inline-flex; align-items: center; gap: 6px;
  height: 30px;
  padding: 0 12px;
  border-radius: var(--r-pill);
  font-size: 12px;
  color: var(--text-2);
  background: transparent;
  border: 1px solid transparent;
  transition: all var(--duration-fast) var(--ease);
  white-space: nowrap;
}
.filter-chip:hover { color: var(--text-1); background: var(--bg-3); }
.filter-chip.active {
  color: var(--text-1);
  background: var(--accent-tint);
  border-color: oklch(78% 0.13 var(--accent-h) / 0.4);
}
.filter-chip .count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-3);
  background: oklch(0% 0 0 / 0.25);
  padding: 1px 5px;
  border-radius: 4px;
}
:root[data-theme="light"] .filter-chip .count { background: oklch(0% 0 0 / 0.05); }
.filter-chip.active .count { color: var(--accent); background: oklch(78% 0.13 var(--accent-h) / 0.18); }

.filter-divider {
  width: 1px;
  height: 18px;
  background: var(--hairline);
  margin: 0 2px;
}

/* ── Pipeline stages embedded in the FilterBar ─────────────── */
.filter-pipeline {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.filter-pipeline-stage {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
  background: transparent;
  border: 1px solid transparent;
  transition: all var(--duration-fast) var(--ease);
  white-space: nowrap;
  cursor: pointer;
  position: relative;
}
.filter-pipeline-stage::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--phase-color, var(--accent));
  flex-shrink: 0;
  opacity: 0.85;
}
.filter-pipeline-stage:hover {
  color: var(--text-1);
  background: color-mix(in oklab, var(--phase-color, var(--accent)) 8%, transparent);
}
/* Stronger active state — solid tint background, color-matched border,
   bold label so the selection reads at-a-glance, not at-a-second-glance. */
.filter-pipeline-stage[data-active="true"] {
  color: var(--text-1);
  font-weight: 600;
  background: color-mix(in oklab, var(--phase-color, var(--accent)) 22%, transparent);
  border-color: color-mix(in oklab, var(--phase-color, var(--accent)) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--phase-color, var(--accent)) 30%, transparent),
              0 0 16px color-mix(in oklab, var(--phase-color, var(--accent)) 22%, transparent);
}
.filter-pipeline-stage[data-active="true"]::before {
  opacity: 1;
  box-shadow: 0 0 8px var(--phase-color, var(--accent));
}

/* Confidence threshold slider */
.confidence-filter {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px;
}
.confidence-slider {
  -webkit-appearance: none;
  appearance: none;
  height: 4px;
  background: var(--glass-border-strong);
  border-radius: 999px;
  outline: none;
}
/* Slider thumb — explicit theme-aware border so it reads on the
   slider track in both modes (was too pale in light mode where
   --bg-1 is near-white). */
.confidence-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--accent-bright);
  border: 2px solid var(--text-on-accent);
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--accent-bright), 0 0 8px var(--accent-glow);
}
.confidence-slider::-moz-range-thumb {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--accent-bright);
  border: 2px solid var(--text-on-accent);
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--accent-bright), 0 0 8px var(--accent-glow);
}
.confidence-value {
  font-size: 10.5px;
  color: var(--text-2);
  min-width: 28px;
  text-align: right;
}

/* Evidence segmented control — REPLACES the broken slider */
.evidence-segment {
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding: 2px;
  border-radius: var(--r-pill);
  background: oklch(0% 0 0 / 0.22);
  border: 1px solid var(--hairline);
  position: relative;
  gap: 0;
}
:root[data-theme="light"] .evidence-segment { background: oklch(0% 0 0 / 0.05); }
.evidence-segment-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-3);
  padding: 0 8px 0 4px;
  border-right: 1px solid var(--hairline);
  margin-right: 2px;
  height: 100%;
  display: inline-flex; align-items: center;
}
.evidence-segment button {
  position: relative;
  height: 24px;
  padding: 0 10px;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-3);
  border-radius: var(--r-pill);
  display: inline-flex; align-items: center; gap: 5px;
  transition: color var(--duration-fast) var(--ease);
  z-index: 1;
}
.evidence-segment button .dot {
  width: 6px; height: 6px; border-radius: 50%;
}
.evidence-segment button[aria-pressed="true"] {
  color: var(--text-1);
  background: var(--bg-3);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3), inset 0 1px 0 var(--hairline-specular);
}

/* ── Rails — Phase 3 floating insets (RAIL_REDESIGN.md) ──── */
.rail {
  position: absolute;
  top: calc(56px + 10px + 12px);
  bottom: calc(44px + 10px + 12px);
  display: flex;
  flex-direction: column;
  border-radius: 14px;
  overflow: hidden;
  min-height: 0;
  border: 1px solid var(--hairline-strong);
  box-shadow:
    0 8px 24px oklch(0% 0 0 / 0.18),
    0 2px 6px oklch(0% 0 0 / 0.10),
    inset 0 1px 0 var(--hairline-specular);
  z-index: 13;
  transition: width var(--duration) var(--ease);
}
:root[data-theme="light"] .rail {
  box-shadow:
    0 8px 24px oklch(0% 0 0 / 0.10),
    0 2px 6px oklch(0% 0 0 / 0.05),
    inset 0 1px 0 var(--hairline-specular);
}
.rail-left  { left: 22px; width: 264px; }
.rail-right { right: 22px; width: 280px; }

.rail-collapsed {
  width: 44px !important;
  display: flex; flex-direction: column; align-items: center;
  padding: 10px 0;
  gap: 6px;
}
.rail-collapsed .icon-btn { width: 32px; height: 32px; }
.rail-collapsed .vlabel {
  writing-mode: vertical-rl;
  text-orientation: mixed;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-3);
  margin-top: 6px;
}

/* Rail responsive cliff (RAIL_REDESIGN.md §2.4 + mobile sheet).
   - ≥1280px: both rails visible at full width.
   - 768–1279px: left rail hidden, right rail visible as side panel.
   - <768px: left rail hidden, right rail becomes a bottom sheet (see
     the mobile rules higher up). */
@media (max-width: 1279px) {
  .rail-left { display: none; }
}

.rail-tabs {
  display: flex;
  padding: 8px 8px 0;
  gap: 2px;
  border-bottom: 1px solid var(--hairline);
}
.rail-tab {
  flex: 1;
  height: 30px;
  padding: 0 10px;
  border-radius: var(--r-2) var(--r-2) 0 0;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-3);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  position: relative;
  transition: color var(--duration-fast) var(--ease);
}
.rail-tab:hover { color: var(--text-2); }
.rail-tab[aria-selected="true"] { color: var(--text-1); }
.rail-tab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px; bottom: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}
.rail-tab .badge {
  font-family: var(--font-mono); font-size: 9px;
  padding: 1px 4px;
  border-radius: 3px;
  background: var(--bg-3);
  color: var(--text-3);
}

.rail-header {
  padding: 14px 16px 8px;
  border-bottom: 1px solid var(--hairline);
}
.rail-header h2 {
  margin: 0;
  font-size: var(--t-h2);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-1);
}
.rail-header .sub {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--text-3);
  line-height: 1.5;
}

.rail-section {
  padding: 12px 16px;
  border-bottom: 1px solid var(--hairline);
}
.rail-section:last-child { border-bottom: 0; }
.rail-section-title {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  margin: 0 0 10px;
  display: flex; align-items: center; gap: 8px;
}
.rail-section-title .count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-4);
  letter-spacing: 0;
  text-transform: none;
}

.rail-body {
  flex: 1;
  min-height: 0;
}

/* ── Question card (left rail) ────────────────────────────── */
.q-card {
  width: 100%;
  text-align: left;
  display: block;
  padding: 10px 12px;
  border-radius: var(--r-2);
  margin-bottom: 6px;
  border: 1px solid transparent;
  background: transparent;
  transition: all var(--duration-fast) var(--ease);
  position: relative;
}
.q-card:hover {
  background: var(--bg-2);
  border-color: var(--hairline);
}
.q-card[data-active="true"] {
  background: var(--accent-tint);
  border-color: oklch(78% 0.13 var(--accent-h) / 0.45);
}
.q-card[data-active="true"]::before {
  content: "";
  position: absolute;
  left: -1px; top: 12px; bottom: 12px;
  width: 2px;
  background: var(--accent);
  border-radius: 0 2px 2px 0;
}
.q-card-q {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-1);
  line-height: 1.45;
  letter-spacing: -0.005em;
  margin: 0 0 6px;
}
.q-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  align-items: center;
}
.q-tag {
  font-family: var(--font-mono);
  font-size: 9.5px;
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--bg-2);
  color: var(--text-3);
  border: 1px solid var(--hairline);
  text-transform: lowercase;
}
.q-card[data-active="true"] .q-tag {
  background: oklch(78% 0.13 var(--accent-h) / 0.18);
  color: var(--accent);
  border-color: oklch(78% 0.13 var(--accent-h) / 0.3);
}

.q-persona {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-weight: 600;
  color: var(--text-4);
  margin-bottom: 4px;
}

/* ── Schema legend (canvas-corner) ────────────────────────── */
.legend {
  position: absolute;
  bottom: 16px;
  left: 16px;
  z-index: 3;
  padding: 12px 14px;
  border-radius: var(--r-3);
  min-width: 180px;
  max-width: 200px;
}
.legend h3 {
  margin: 0 0 8px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  display: flex; align-items: center; justify-content: space-between;
}
.legend-toggle {
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 4px;
  color: var(--text-3);
}
.legend-toggle:hover { color: var(--text-1); background: var(--bg-3); }
.legend-group { margin-bottom: 10px; }
.legend-group:last-child { margin-bottom: 0; }
.legend-group-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-4);
  margin-bottom: 6px;
}
.legend-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 11.5px;
  color: var(--text-2);
  padding: 3px 0;
  line-height: 1.3;
}
.legend-swatch {
  width: 12px; height: 12px;
  border-radius: 3px;
  flex-shrink: 0;
  border: 1px solid var(--hairline-strong);
}
.legend-swatch.dot { border-radius: 50%; }
.legend-edge {
  width: 22px; height: 2px;
  flex-shrink: 0;
  border-radius: 2px;
}
.legend-edge.dashed { height: 0; border-top: 2px dashed var(--edge-inferred); }
.legend-edge.dotted { height: 0; border-top: 2px dotted var(--edge-predicted); }

/* ── Pipeline strip (top of canvas) ───────────────────────── */
.pipeline {
  position: absolute;
  top: 64px;
  left: 16px;
  right: 16px;
  z-index: 6;
  padding: 10px 12px;
  border-radius: var(--r-3);
  display: flex;
  align-items: center;
  gap: 8px;
}
.pipeline-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  font-weight: 600;
  padding-right: 10px;
  border-right: 1px solid var(--hairline);
}
.pipeline-track {
  flex: 1;
  display: flex;
  gap: 4px;
}
.pipeline-stage {
  flex: 1;
  display: flex; flex-direction: column; gap: 4px;
  padding: 6px 10px;
  border-radius: var(--r-2);
  background: oklch(0% 0 0 / 0.2);
  border: 1px solid var(--hairline);
  transition: all var(--duration) var(--ease);
  position: relative;
  min-width: 0;
  cursor: pointer;
}
:root[data-theme="light"] .pipeline-stage { background: oklch(0% 0 0 / 0.04); }
.pipeline-stage:hover { background: var(--bg-2); }
.pipeline-stage[data-active="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent), 0 0 16px var(--accent-glow);
}
.pipeline-stage-name {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-1);
  letter-spacing: -0.005em;
  display: flex; align-items: center; gap: 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pipeline-stage-name::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--phase-color, var(--accent));
  box-shadow: 0 0 8px var(--phase-color, var(--accent));
  flex-shrink: 0;
}
.pipeline-stage-count {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-3);
}
.pipeline-stage-count strong { color: var(--text-1); font-weight: 500; }

/* ── Inspector (right rail) ───────────────────────────────── */
.inspector-tabs {
  display: flex;
  margin: 12px 12px 0;
  padding: 3px;
  border-radius: var(--r-2);
  background: oklch(0% 0 0 / 0.2);
  border: 1px solid var(--hairline);
  gap: 0;
}
:root[data-theme="light"] .inspector-tabs { background: oklch(0% 0 0 / 0.04); }
.inspector-tab {
  flex: 1;
  height: 26px;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-3);
  border-radius: var(--r-1);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: all var(--duration-fast) var(--ease);
}
.inspector-tab[aria-selected="true"] {
  color: var(--text-1);
  background: var(--bg-3);
  box-shadow: 0 1px 2px oklch(0% 0 0 / 0.3), inset 0 1px 0 var(--hairline-specular);
}

.entity-hero {
  padding: 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.entity-kind {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--entity-color, var(--accent));
  width: max-content;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  background: oklch(78% 0.13 var(--accent-h) / 0.12);
  border: 1px solid oklch(78% 0.13 var(--accent-h) / 0.3);
}
.entity-name {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text-1);
  margin: 0;
}
.entity-id {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-3);
}
.entity-desc {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.5;
  margin: 6px 0 0;
}

.kv-list {
  display: grid;
  grid-template-columns: 110px 1fr;
  row-gap: 6px;
  column-gap: 12px;
  font-size: 12px;
}
.kv-list dt {
  color: var(--text-3);
  font-weight: 500;
}
.kv-list dd {
  color: var(--text-1);
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  word-break: break-word;
}

.connections-list { display: flex; flex-direction: column; gap: 4px; }
.connection-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px;
  border-radius: var(--r-1);
  font-size: 11.5px;
  color: var(--text-2);
  background: transparent;
  width: 100%;
  text-align: left;
  transition: background var(--duration-fast) var(--ease);
}
.connection-row:hover { background: var(--bg-2); color: var(--text-1); }
.connection-row .arrow { color: var(--text-4); font-family: var(--font-mono); font-size: 10px; }
.connection-row .ent-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.connection-row .target-name { flex: 1; }
.connection-row .count {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-3);
}

/* API tab */
.api-method {
  display: inline-flex; align-items: center;
  height: 18px;
  padding: 0 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  border-radius: 3px;
  letter-spacing: 0.04em;
}
.api-method.get { background: oklch(78% 0.13 200 / 0.18); color: var(--ent-target); }
.api-method.post { background: oklch(80% 0.14 145 / 0.18); color: var(--ent-asset); }
.api-method.delete { background: oklch(70% 0.18 25 / 0.18); color: var(--danger); }

.api-endpoint {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-1);
  letter-spacing: -0.005em;
}
.api-endpoint .var { color: var(--accent); }

/* ── Legend interactive rows — hover vs active distinction ───
   Hover gets a neutral tint so the row visibly feels reachable;
   active styling is left to the inline style (so it only fires
   for entity-row selection, not the always-on edge tier toggles
   whose only signal is the dimmed inactive state). */
.legend-row-interactive {
  transition: background var(--duration-fast) var(--ease),
              border-color var(--duration-fast) var(--ease),
              opacity var(--duration-fast) var(--ease);
}
.legend-row-interactive:hover {
  background: color-mix(in oklab, var(--text-3) 10%, transparent);
  border: 1px solid var(--hairline);
}
.legend-row-interactive:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Lang-tabs share the same dark background as the code-block in
   both themes — they're a single visual surface, not a strip on
   top of it. The seam was most visible in light mode where the
   tabs strip was nearly white and the code-block was dark navy. */
.lang-tabs {
  display: flex;
  padding: 4px 8px 0;
  border-bottom: 1px solid rgba(255,255,255,0.06);
  background: oklch(0% 0 0 / 0.32);
  border-radius: var(--r-2) var(--r-2) 0 0;
  gap: 0;
}
:root[data-theme="light"] .lang-tabs {
  background: oklch(20% 0.01 240 / 0.95);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.lang-tab { color: rgba(226,232,240,0.55); }
.lang-tab[aria-selected="true"] { color: rgba(226,232,240,0.95) !important; }
.lang-tab {
  height: 26px;
  padding: 0 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-3);
  border-radius: var(--r-1) var(--r-1) 0 0;
  transition: color var(--duration-fast) var(--ease);
  position: relative;
}
.lang-tab[aria-selected="true"] { color: var(--text-1); }
.lang-tab[aria-selected="true"]::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px; bottom: 0;
  height: 2px;
  background: var(--accent);
  border-radius: 2px 2px 0 0;
}

.code-block {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.65;
  background: oklch(0% 0 0 / 0.32);
  border: 1px solid var(--hairline);
  border-radius: 0 0 var(--r-2) var(--r-2);
  border-top: 0;
  padding: 12px 14px;
  overflow-x: auto;
  color: var(--text-1);
  white-space: pre;
  margin: 0;
}
:root[data-theme="light"] .code-block { background: oklch(20% 0.01 240 / 0.95); color: oklch(94% 0.005 240); }
/* Syntax token colors. The code-block bg is dark in both themes, so the
   tokens are always bright pastel — pin them to fixed values rather than
   reading theme tokens (which are dark in light mode and would vanish). */
.code-block .tok-key { color: oklch(82% 0.16 190); }
.code-block .tok-str { color: oklch(82% 0.13 145); }
.code-block .tok-num { color: oklch(80% 0.13 80); }
.code-block .tok-com { color: rgba(226,232,240,0.62); font-style: italic; }
.code-block .tok-kw  { color: oklch(76% 0.16 285); }
.code-block .tok-fn  { color: oklch(82% 0.16 190); }

.recipe {
  padding: 14px 16px;
  border-bottom: 1px solid var(--hairline);
}
.recipe-q {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-1);
  line-height: 1.45;
  margin: 0 0 8px;
}
.recipe-traversal {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-3);
  margin-bottom: 10px;
  padding: 6px 8px;
  background: oklch(0% 0 0 / 0.2);
  border-radius: var(--r-1);
  border: 1px solid var(--hairline);
}
:root[data-theme="light"] .recipe-traversal { background: oklch(0% 0 0 / 0.04); }
.recipe-traversal .ent {
  color: var(--ent-color, var(--accent));
}
.recipe-traversal .arr { color: var(--text-4); }

/* ── Footer ───────────────────────────────────────────────── */
.footer {
  grid-area: footer;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 16px;
  border-radius: var(--r-3);
  font-size: 11.5px;
  color: var(--text-3);
}
.footer-stat {
  display: inline-flex; align-items: center; gap: 6px;
}
.footer-stat .label { color: var(--text-4); text-transform: uppercase; letter-spacing: 0.08em; font-size: 10px; font-weight: 600; }
.footer-stat .value {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-1);
}
.footer-stat .value.live::before {
  content: "";
  display: inline-block;
  width: 6px; height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 8px var(--success);
  animation: pulse 2s ease-in-out infinite;
  vertical-align: middle;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
.footer-divider {
  width: 1px; height: 18px;
  background: var(--hairline);
}
.footer-right { margin-left: auto; display: flex; align-items: center; gap: 6px; }
.footer-link {
  font-size: 11.5px;
  color: var(--text-3);
  padding: 4px 8px;
  border-radius: var(--r-1);
  transition: all var(--duration-fast) var(--ease);
}
.footer-link:hover { color: var(--text-1); background: var(--bg-3); }

/* ── Canvas ───────────────────────────────────────────────── */
/* Background grid recipe matches the production dashboard's
   .schema-canvas — 48px fine grid + 240px major grid + ambient
   vignettes. Applied per-theme so the explorer drops into the
   dashboard without visual seams. */
.canvas {
  grid-area: canvas;
  position: relative;
  border-radius: var(--r-3);
  overflow: hidden;
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-1);
}

:root[data-theme="dark"] .canvas {
  background:
    repeating-linear-gradient(0deg,  rgba(255,255,255,0.042) 0px, rgba(255,255,255,0.042) 1px, transparent 1px, transparent 48px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.042) 0px, rgba(255,255,255,0.042) 1px, transparent 1px, transparent 48px),
    repeating-linear-gradient(0deg,  rgba(255,255,255,0.08)  0px, rgba(255,255,255,0.08)  1px, transparent 1px, transparent 240px),
    repeating-linear-gradient(90deg, rgba(255,255,255,0.08)  0px, rgba(255,255,255,0.08)  1px, transparent 1px, transparent 240px),
    radial-gradient(ellipse at 50% 35%, rgba(0,229,191,0.18) 0%, transparent 75%),
    radial-gradient(ellipse at 20% 80%, rgba(30,58,95,0.45) 0%, transparent 65%),
    linear-gradient(155deg, rgba(255,255,255,0.075) 0%, rgba(255,255,255,0.03) 100%),
    #0b1a32 !important;
  box-shadow: inset 0 0 100px rgba(0,0,0,0.3), var(--shadow-1) !important;
}

:root[data-theme="light"] .canvas {
  background:
    /* fine grid (48px) */
    repeating-linear-gradient(0deg,  rgba(15,23,42,0.055) 0px, rgba(15,23,42,0.055) 1px, transparent 1px, transparent 48px),
    repeating-linear-gradient(90deg, rgba(15,23,42,0.055) 0px, rgba(15,23,42,0.055) 1px, transparent 1px, transparent 48px),
    /* major grid (240px) */
    repeating-linear-gradient(0deg,  rgba(15,23,42,0.085) 0px, rgba(15,23,42,0.085) 1px, transparent 1px, transparent 240px),
    repeating-linear-gradient(90deg, rgba(15,23,42,0.085) 0px, rgba(15,23,42,0.085) 1px, transparent 1px, transparent 240px),
    /* warm corner wash (top-right) */
    radial-gradient(ellipse 70% 55% at 95% 0%, rgba(252,213,206,0.32) 0%, transparent 55%),
    /* cool corner wash (bottom-left) */
    radial-gradient(ellipse 65% 50% at 0% 100%, rgba(186,230,253,0.30) 0%, transparent 55%),
    /* center teal vignette tie-in */
    radial-gradient(ellipse 50% 45% at 50% 50%, rgba(94,224,210,0.10) 0%, transparent 60%),
    /* tinted paper base — sage-cream, NOT bleached white */
    linear-gradient(155deg, #eef3f5 0%, #e9eef4 100%) !important;
}
.schema-svg .node-group { transition: opacity 220ms var(--ease); }
.schema-svg .node-group[data-dim="true"] { opacity: 0.28; }
.schema-svg .node-group[data-active="true"] { opacity: 1; }
.schema-svg .node-disc { transition: fill-opacity 200ms var(--ease), stroke 200ms var(--ease); }
.canvas svg {
  width: 100%; height: 100%;
  display: block;
}

/* Canvas controls: zoom & fit — horizontal pill, anchored to canvas
   so it follows the graph on resize. Inline styles in app.jsx set
   the visual treatment (background blur, border, etc); this rule
   just establishes the layout direction. */
.canvas-controls {
  position: absolute;
  bottom: 14px;
  right: 14px;
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 1px;
  padding: 2px;
  border-radius: 999px;
}

/* Hover tooltip on graph node */
.graph-tooltip {
  position: absolute;
  pointer-events: none;
  padding: 8px 10px;
  border-radius: var(--r-2);
  font-size: 11.5px;
  color: var(--text-1);
  z-index: 8;
  white-space: nowrap;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease);
}
.graph-tooltip[data-show="true"] { opacity: 1; }
.graph-tooltip .tt-kind {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
  margin-bottom: 2px;
}

/* SVG node base */
.node-circle {
  filter: drop-shadow(0 2px 4px oklch(0% 0 0 / 0.4));
  cursor: pointer;
  transition: r var(--duration) var(--ease), filter var(--duration) var(--ease);
}
.node-label {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  fill: var(--text-1);
  pointer-events: none;
  letter-spacing: -0.005em;
}
.node-sub {
  font-family: var(--font-mono);
  font-size: 9.5px;
  fill: var(--text-3);
  pointer-events: none;
}
.node-group[data-dim="true"] .node-circle,
.node-group[data-dim="true"] .node-label,
.node-group[data-dim="true"] .node-sub {
  opacity: 0.18;
  transition: opacity var(--duration) var(--ease);
}
.node-group[data-active="true"] .node-circle {
  filter: drop-shadow(0 0 12px var(--node-color, var(--accent))) drop-shadow(0 2px 6px oklch(0% 0 0 / 0.5));
}
.edge {
  stroke-linecap: round;
  transition: stroke-opacity var(--duration) var(--ease), stroke-width var(--duration) var(--ease);
}
.edge[data-dim="true"] { stroke-opacity: 0.08; }
.edge[data-active="true"] {
  stroke-opacity: 1;
  stroke-width: 2.5;
  filter: drop-shadow(0 0 6px var(--edge-color, var(--accent)));
}

/* Tweaks panel host overrides */
.tweaks-panel { font-family: var(--font-sans); }

/* ── Accordion section — Phase 3 reusable shell ───────────── */
.acc-section {
  border-bottom: 1px solid var(--hairline);
}
.acc-section:last-child { border-bottom: 0; }
.acc-header {
  display: flex; align-items: center;
  height: 32px;
  padding: 0 12px;
  background: transparent;
  cursor: pointer;
  user-select: none;
  transition: background var(--duration-fast) var(--ease);
}
.acc-header:hover {
  background: color-mix(in oklab, var(--accent) 6%, transparent);
}
.acc-caret {
  width: 10px; height: 10px;
  margin-right: 8px;
  color: var(--text-3);
  transform: rotate(-90deg);
  transition: transform 180ms cubic-bezier(0.32, 0.72, 0, 1);
  flex-shrink: 0;
}
.acc-header[aria-expanded="true"] .acc-caret { transform: rotate(0deg); }
.acc-title {
  font-size: 11.5px; font-weight: 600;
  color: var(--text-2);
  letter-spacing: 0.02em;
  flex: 1;
  text-align: left;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acc-count {
  font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  color: var(--text-3);
  margin-left: 8px;
  flex-shrink: 0;
}
.acc-body {
  overflow: hidden;
  max-height: 0;
  transform: scaleY(0); transform-origin: top;
  opacity: 0;
  transition:
    max-height 200ms cubic-bezier(0.32, 0.72, 0, 1),
    transform 180ms cubic-bezier(0.32, 0.72, 0, 1),
    opacity 160ms ease;
}
.acc-section[data-open="true"] .acc-body {
  max-height: 4000px;
  transform: scaleY(1);
  opacity: 1;
}
.acc-body-inner {
  padding: 4px 12px 12px;
}
@media (prefers-reduced-motion: reduce) {
  .acc-caret, .acc-body { transition: none; }
}

/* Inspector content rows — Phase 4 step 5 */
.insp-tier-group { margin-bottom: 10px; }
.insp-tier-group:last-child { margin-bottom: 0; }
.insp-tier-header {
  display: flex; align-items: center; gap: 6px;
  font-size: 9.5px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-3);
  margin-bottom: 4px;
}
.insp-tier-dot {
  width: 6px; height: 6px; border-radius: 50%;
  flex-shrink: 0;
}
.insp-tier-dot[data-tier="direct"]    { background: var(--edge-direct); }
.insp-tier-dot[data-tier="inferred"]  { background: var(--edge-inferred); }
.insp-tier-dot[data-tier="predicted"] { background: var(--edge-predicted); }
.insp-tier-count { margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--text-4); }

.insp-row {
  display: flex; align-items: center; gap: 6px;
  height: 28px;
  padding: 0 4px;
  font-size: 11px;
  border-radius: 5px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}
.insp-row:hover { background: color-mix(in oklab, var(--accent) 8%, transparent); }
.insp-row .dir { font-family: var(--font-mono); font-size: 10px; color: var(--text-4); width: 12px; flex-shrink: 0; }
.insp-row .kind-chip {
  font-size: 10.5px; font-weight: 500;
  padding: 2px 7px; border-radius: 999px;
  flex-shrink: 0;
  border: 1px solid;
}
.insp-row .label-mono {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3);
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.insp-row .conf-num {
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
  color: var(--text-2);
  flex-shrink: 0;
}

.insp-shape {
  display: flex; flex-direction: column; gap: 3px;
  min-height: 36px;
  padding: 5px 4px;
  border-radius: 5px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease);
}
.insp-shape:hover { background: color-mix(in oklab, var(--accent) 8%, transparent); }
.insp-shape[data-selected="true"] { background: var(--accent-tint); }
.insp-shape .path-row {
  display: flex; align-items: center; gap: 4px;
  flex-wrap: wrap;
}
.insp-shape .path-arrow { color: var(--text-4); font-size: 10px; }
.insp-shape .meta-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 10px;
  color: var(--text-3);
}
.insp-shape .meta-row .conf-num { font-family: var(--font-mono); font-weight: 500; color: var(--text-2); }

.insp-family-group { margin-bottom: 10px; }
.insp-family-group:last-child { margin-bottom: 0; }
.insp-family-header {
  display: flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--text-3);
  margin-bottom: 4px;
  padding: 0 4px;
}
.insp-family-swatch {
  width: 8px; height: 8px; border-radius: 2px;
  flex-shrink: 0;
}
.insp-family-count { margin-left: auto; font-family: var(--font-mono); font-size: 10px; color: var(--text-4); }
.insp-show-all {
  width: 100%;
  font-size: 10.5px;
  color: var(--text-3);
  padding: 4px 0;
  border-top: 1px dashed var(--hairline);
  margin-top: 4px;
  text-align: left;
  padding-left: 14px;
  cursor: pointer;
  transition: color var(--duration-fast) var(--ease);
}
.insp-show-all:hover { color: var(--text-1); }

/* ── Canvas-overlay rail-clearance (Phase 3 cold-review fix) ─────
   The legend, pipeline strip, and canvas-controls live inside .canvas
   and sit on top of the SVG. The floating rails also sit over the
   canvas, so without these offsets the overlays disappear behind them.
   Offsets activate per breakpoint: clear right rail at ≥1080, both at ≥1280. */
@media (min-width: 1080px) {
  .pipeline { right: var(--rail-right-clear); }
  /* When the right rail is VISIBLE (something is selected), the zoom
     pillbox and the bottom canvas-filters island shift left so they
     don't sit behind the rail. When nothing is selected (rail slid
     off-screen) they hug the canvas edge. Animation kept smooth via
     transition on right/left so it follows the rail's slide-in. */
  .app:not([data-no-selection="true"]) .canvas-controls {
    right: var(--rail-right-clear);
  }
  .app:not([data-no-selection="true"]) .canvas-filters {
    /* Center the filter island in the visible canvas area (left of rail) */
    left: calc(50% - var(--rail-right-w) / 2);
  }
  .canvas-controls,
  .canvas-filters {
    transition: right 280ms var(--ease), left 280ms var(--ease);
  }
}
@media (min-width: 1280px) {
  .pipeline { left: var(--rail-left-clear); }
  .legend   { left: var(--rail-left-clear); }
}

/* ── Empty-state right rail — hide at desktop until something is
   selected. The empty state was visually blocking the canvas. */
@media (min-width: 1080px) {
  .rail-right[data-active-mode="empty"]:not(.rail-collapsed) {
    transform: translateX(calc(100% + var(--rail-inset, 22px)));
    pointer-events: none;
    opacity: 0;
    transition: transform 280ms var(--ease), opacity 200ms var(--ease);
  }
  .rail-right:not([data-active-mode="empty"]) {
    transform: translateX(0);
    opacity: 1;
    transition: transform 280ms var(--ease), opacity 200ms var(--ease);
  }
}

/* ── Canvas-bottom floating filters (OG_schema.html pattern) ──
   Two grouped controls — edge tier toggles (left side) and the
   confidence scrubber (right side) — in a single floating pill
   pinned to the bottom-center of the canvas. Anchored inside
   .canvas so it follows the graph on resize. */
.canvas-filters {
  position: absolute;
  bottom: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border-radius: var(--r-pill);
  background: color-mix(in oklab, var(--bg-2) 78%, transparent);
  border: 1px solid var(--hairline-strong);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  box-shadow: 0 8px 24px rgba(0,0,0,0.32),
              inset 0 1px 0 var(--glass-inset-top);
  max-width: calc(100% - 28px);
}

/* Edge tier toggle group */
.cf-toggles {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.cf-toggle-row {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 9px;
  border-radius: var(--r-pill);
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-2);
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  transition: opacity var(--duration-fast) var(--ease),
              background var(--duration-fast) var(--ease);
}
.cf-toggle-row[data-on="false"] { opacity: 0.45; }
.cf-toggle-row:hover { background: color-mix(in oklab, var(--text-3) 10%, transparent); }
.cf-toggle-row:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* iOS-style toggle switch */
.cf-toggle-switch {
  width: 26px; height: 14px;
  border-radius: 999px;
  background: var(--hairline-strong);
  position: relative;
  flex-shrink: 0;
  transition: background var(--duration-fast) var(--ease);
}
.cf-toggle-switch::after {
  content: "";
  position: absolute;
  top: 1px; left: 1px;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--text-1);
  transition: transform var(--duration-fast) var(--ease);
}
.cf-toggle-switch[data-on="true"] { background: var(--accent-bright); }
.cf-toggle-switch[data-on="true"]::after {
  transform: translateX(12px);
  background: var(--text-on-accent);
}

.cf-toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.cf-toggle-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}

.cf-divider {
  width: 1px;
  height: 22px;
  background: var(--hairline);
}

/* Confidence slider group */
.cf-confidence {
  display: inline-flex;
  flex-direction: column;
  gap: 3px;
  min-width: 200px;
}
.cf-confidence-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.cf-confidence-label {
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-3);
}
.cf-confidence-count {
  font-family: var(--font-mono);
  font-size: 9.5px;
  color: var(--text-3);
}
.cf-confidence-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.cf-slider { flex: 1; }
.cf-confidence-value {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--text-1);
  font-weight: 600;
  min-width: 30px;
  text-align: right;
}

/* On mobile, CanvasFilters re-uses the existing mobile-sheet pattern
   indirectly — defaults are good for mobile, so we just shrink it
   slightly so it doesn't overlap the mobile-nav. */
@media (max-width: 767px) {
  .canvas-filters {
    /* Hide on mobile — the same controls live inside the Filter sheet
       triggered from the mobile-nav bar. Avoids two filter surfaces
       fighting for space at narrow widths. */
    display: none;
  }
}
