/* ═══════════════════════════════════════════════════════════════════
   VINTINUUM SHELL — Phase 2 three-column layout
   Left sidebar 280 | Stage 1fr | Right sidebar 340
   Footer 52px across bottom
   All rails keep max opacity <=0.20 so the body stage shows through.
   ═══════════════════════════════════════════════════════════════════ */

.vtn-shell {
  display: grid;
  grid-template-columns: 280px 1fr 340px;
  grid-template-rows: 1fr 52px;
  grid-template-areas:
    "left stage right"
    "footer footer footer";
  min-height: 100vh; /* fallback for browsers without svh */
  min-height: 100svh; /* svh accounts for dynamic browser chrome — fixes the F11-only bug */
  background: var(--bg-void, #05070c);
}

.vtn-sidebar-left {
  grid-area: left;
  background: rgba(8, 12, 20, 0.20);
  border-right: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.06));
  overflow-y: auto;
  position: relative;
  z-index: 10;
}

.vtn-sidebar-right {
  grid-area: right;
  background: rgba(8, 12, 20, 0.20);
  border-left: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.06));
  overflow-y: auto;
  position: relative;
  z-index: 10;
}

.vtn-stage {
  grid-area: stage;
  position: relative;
  overflow: hidden;
}

.vtn-footer {
  grid-area: footer;
  background: rgba(10, 14, 22, 0.25);
  border-top: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.06));
  position: relative;
  z-index: 10;
}

/* ── Sidebar left (Phase 2 b2) ─────────────────────────────────────── */
.vtn-side-inner {
  display: flex;
  flex-direction: column;
  gap: 18px;
  /* No-overflow: top padding clears the fixed topbar (56px + safe area).
     Bottom padding clears the floating "leave a memory" pill (z-index 80,
     bottom calc(safe-area + 72px)) so the LAYER DISTRIBUTION + CONSCIOUSNESS
     LAYERS legend never disappears beneath it. */
  padding: calc(env(safe-area-inset-top, 0px) + 68px) 16px calc(env(safe-area-inset-bottom, 0px) + 110px);
  color: rgba(230, 238, 255, 0.82);
  font: 11px/1.4 var(--font-ui, system-ui, sans-serif);
}

.vtn-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #cfe2ff;
}
.vtn-mark { width: 26px; height: 26px; flex: 0 0 auto; }
.vtn-wordmark {
  font: 600 13px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.22em;
}

.vtn-tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}
.vtn-tab {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  color: rgba(200, 215, 235, 0.72);
  cursor: pointer;
  transition: background .18s, color .18s, border-color .18s;
  padding: 0;
}
.vtn-tab svg { width: 18px; height: 18px; }
.vtn-tab:hover { color: #fff; border-color: rgba(255,255,255,0.10); }
.vtn-tab.is-active {
  background: rgba(124, 196, 255, 0.12);
  color: #cfe2ff;
  border-color: rgba(124, 196, 255, 0.28);
}

.vtn-sec-label {
  font: 600 9px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.28em;
  color: rgba(200, 215, 235, 0.55);
  margin-bottom: 8px;
}

.vtn-identity {
  padding: 10px 12px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 12px;
}
.vtn-identity-label {
  font: 600 9px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.28em;
  color: rgba(200, 215, 235, 0.55);
  margin-bottom: 6px;
}
.vtn-identity-name {
  font: 600 15px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.14em;
  color: #e8f0ff;
}

/* Chem bars */
.vtn-chem-list { display: flex; flex-direction: column; gap: 8px; }
.vtn-chem-row {
  display: grid;
  grid-template-columns: 84px 1fr 28px;
  align-items: center;
  gap: 8px;
}
.vtn-chem-label {
  font: 500 10px/1 var(--font-ui, system-ui, sans-serif);
  color: rgba(210, 222, 240, 0.72);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.vtn-chem-track {
  height: 6px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 3px;
  overflow: hidden;
  position: relative;
}
.vtn-chem-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #7cc4ff, #b47cff);
  transition: width .18s ease-out;
}
.vtn-chem-value {
  font: 500 10px/1 var(--font-ui, system-ui, sans-serif);
  color: rgba(210, 222, 240, 0.72);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Layer tiles — 7 tiles in a grid, height-filled from %, accented by --hue */
.vtn-layer-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}
.vtn-layer-tile {
  position: relative;
  min-height: 54px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  overflow: hidden;
  padding: 6px 8px;
  display: flex; flex-direction: column; justify-content: flex-end;
  color: var(--hue, #cfe2ff);
}
.vtn-layer-fill {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 0%;
  background: var(--hue, #7cc4ff);
  opacity: 0.18;
  transition: height .22s ease-out;
  pointer-events: none;
}
.vtn-layer-name {
  position: relative;
  font: 600 9px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hue, #cfe2ff);
  opacity: 0.92;
}
.vtn-layer-pct {
  position: relative;
  font: 500 11px/1 var(--font-ui, system-ui, sans-serif);
  color: rgba(230, 238, 255, 0.9);
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
}

/* Legend */
.vtn-legend-list {
  list-style: none;
  padding: 0; margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 12px;
}
.vtn-legend-item {
  display: flex; align-items: center; gap: 6px;
  font: 500 10px/1 var(--font-ui, system-ui, sans-serif);
  color: rgba(210, 222, 240, 0.72);
  text-transform: capitalize;
}
.vtn-legend-swatch {
  width: 10px; height: 10px; border-radius: 2px;
  box-shadow: 0 0 6px currentColor;
}

/* ── Sidebar right (Phase 2 b3) ────────────────────────────────────── */
.vtn-side-right-inner {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* No-overflow rule: top padding clears the fixed topbar (56px + safe area)
     so MEMORY / INNER LIFE / GENOME / SOUL QUEUE tab strip never sits under
     LORE/☰. Bottom padding clears the dock so feed cards never bleed under
     the footer strip. */
  padding: calc(env(safe-area-inset-top, 0px) + 68px) 12px 76px;
  max-height: 100vh;
  max-height: 100svh;
  color: rgba(230, 238, 255, 0.82);
  font: 11px/1.4 var(--font-ui, system-ui, sans-serif);
}

.vtn-right-tabs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  padding: 4px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 12px;
}
.vtn-right-tab {
  min-height: 44px;
  padding: 0 6px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: rgba(200, 215, 235, 0.62);
  font: 600 9px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.14em;
  cursor: pointer;
  transition: background .15s, color .15s;
  /* Prevent SOUL QUEUE (or any two-word label) from wrapping behind the
     tab-strip border and appearing to overlap adjacent tabs. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vtn-right-tab:hover { color: #fff; background: rgba(255, 255, 255, 0.04); }
.vtn-right-tab.is-active {
  background: rgba(124, 196, 255, 0.14);
  color: #cfe2ff;
}

.vtn-card-list {
  max-height: 80vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-right: 4px;
}
.vtn-card-list::-webkit-scrollbar { width: 6px; }
.vtn-card-list::-webkit-scrollbar-track { background: transparent; }
.vtn-card-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }

.vtn-card {
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 12px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
}
.vtn-card-icon {
  color: rgba(200, 215, 235, 0.62);
  display: flex; align-items: center; justify-content: center;
}
.vtn-card-icon svg { width: 18px; height: 18px; }
.vtn-card-body { min-width: 0; }
.vtn-card-title {
  font: 600 11px/1.25 var(--font-ui, system-ui, sans-serif);
  color: #e8f0ff;
  letter-spacing: 0.04em;
  word-break: break-word;
}
.vtn-card-sub {
  margin-top: 3px;
  font: 400 10px/1.35 var(--font-ui, system-ui, sans-serif);
  color: rgba(210, 222, 240, 0.72);
  word-break: break-word;
}
.vtn-card-sub-dim { color: rgba(200, 215, 235, 0.5); }

.vtn-card-offline { opacity: 0.85; }
.vtn-card-loading .vtn-card-title { color: rgba(200, 215, 235, 0.55); font-weight: 400; }

/* ══════════════════════════════════════════════════════════════════════
   INNER LIFE HEATMAP — color, glyph, intensity, cascade, streak
   Heat without chaos. One color per layer, opacity = intensity.
   ══════════════════════════════════════════════════════════════════════ */
.vtn-card-heat {
  position: relative;
  background: linear-gradient(
    90deg,
    color-mix(in oklab, var(--layer-color, #888) calc(8% * var(--intensity, 0.5)), rgba(10, 12, 18, 0.55)) 0%,
    rgba(10, 12, 18, 0.55) 70%
  );
  border: 1px solid color-mix(in oklab, var(--layer-color, #888) 22%, rgba(255,255,255,0.04));
  transition: transform 180ms ease, border-color 240ms ease, box-shadow 240ms ease;
  overflow: hidden;
}
.vtn-card-heat::before {
  /* Left edge intensity bar — the thermometer */
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--layer-color, #888);
  opacity: calc(0.35 + 0.65 * var(--intensity, 0.5));
  box-shadow: 0 0 8px color-mix(in oklab, var(--layer-color, #888) calc(60% * var(--intensity, 0.5)), transparent);
}
.vtn-card-heat .vtn-card-title {
  color: color-mix(in oklab, var(--layer-color, #fff) 85%, #fff);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.vtn-card-heat .vtn-card-sub { color: rgba(232, 230, 223, 0.86); }
.vtn-card-heat .vtn-card-sub-dim { color: rgba(232, 230, 223, 0.5); font-variant-numeric: tabular-nums; }

.vtn-card-glyph {
  font: 600 16px/1 var(--font-display, 'Cormorant Garamond', serif);
  color: var(--layer-color, #888);
  text-shadow: 0 0 6px color-mix(in oklab, var(--layer-color, #888) calc(50% * var(--intensity, 0.5)), transparent);
}

.vtn-card-heat:hover {
  transform: translateX(2px);
  border-color: color-mix(in oklab, var(--layer-color, #888) 60%, transparent);
  box-shadow: 0 4px 18px -8px color-mix(in oklab, var(--layer-color, #888) 70%, transparent);
}

/* Intensity > 0.7: outer glow — the body burns */
.vtn-card-heat.hot {
  box-shadow:
    inset 0 0 22px color-mix(in oklab, var(--layer-color, #888) 14%, transparent),
    0 0 14px color-mix(in oklab, var(--layer-color, #888) 24%, transparent);
}

/* Streak: same layer twice in a row → cards merge top, sense of flow */
.vtn-card-heat.streak {
  margin-top: -4px;
  border-top-left-radius: 2px;
  border-top-right-radius: 2px;
  border-top-color: transparent;
}

/* Header card — dominant layer summary, always sits on top */
.vtn-card-header {
  background: linear-gradient(
    135deg,
    color-mix(in oklab, var(--layer-color, #888) 22%, rgba(8, 10, 16, 0.85)) 0%,
    rgba(8, 10, 16, 0.85) 80%
  );
  border-color: color-mix(in oklab, var(--layer-color, #888) 45%, transparent);
}
.vtn-card-header .vtn-card-title { font-size: 12px; }

/* Cascade signatures — pattern recognition by border */
.vtn-card-heat.cascade-memory   { border-left: 3px solid #8b5cf6; }
.vtn-card-heat.cascade-stress   { border-left: 3px solid #ef4444; animation: vtn-pulse 2.4s ease-in-out infinite; }
.vtn-card-heat.cascade-reward   { border-left: 3px solid #fbbf24; }
.vtn-card-heat.cascade-dream    { border-left: 3px solid #22d3ee; }

@keyframes vtn-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.0); }
  50%      { box-shadow: 0 0 14px 0 rgba(239, 68, 68, 0.35); }
}

/* Neurochem chips — small, dense, readable */
.vtn-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 6px;
}
.vtn-chip {
  font: 600 9px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.08em;
  padding: 3px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(232, 230, 223, 0.85);
  font-variant-numeric: tabular-nums;
}
.vtn-chip-dopamine       { color: #fbbf24; border-color: rgba(251, 191, 36, 0.35); }
.vtn-chip-serotonin      { color: #86efac; border-color: rgba(134, 239, 172, 0.35); }
.vtn-chip-gaba           { color: #93c5fd; border-color: rgba(147, 197, 253, 0.35); }
.vtn-chip-norepinephrine { color: #fca5a5; border-color: rgba(252, 165, 165, 0.35); }
.vtn-chip-arousal        { color: #f9a8d4; border-color: rgba(249, 168, 212, 0.35); }
.vtn-chip-valence        { color: #c4b5fd; border-color: rgba(196, 181, 253, 0.35); }

/* ── Footer strip (Phase 2 b6) ─────────────────────────────────────── */
.vtn-ft-inner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 14px;
  height: 100%;
  color: rgba(230, 238, 255, 0.75);
  overflow-x: auto;
}
.vtn-ft-group {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.vtn-ft-div {
  width: 1px;
  height: 24px;
  background: rgba(255, 255, 255, 0.08);
  flex: 0 0 auto;
}
.vtn-ft-spacer { flex: 1 1 auto; }

.vtn-ft-btn {
  min-width: 44px;
  min-height: 44px;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: rgba(210, 222, 240, 0.72);
  font: 600 10px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.14em;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.vtn-ft-btn:hover {
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.10);
}
.vtn-ft-btn svg { width: 18px; height: 18px; }
.vtn-ft-btn[aria-pressed="true"] {
  color: #cfe2ff;
}
.vtn-ft-btn.is-off {
  color: rgba(210, 222, 240, 0.28);
}
.vtn-ft-preset {
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0 10px;
}

/* ═══════════════════════════════════════════════════════════════════
   MOBILE LAYOUT — unified at 820px breakpoint
   ───────────────────────────────────────────────────────────────────
   Problems solved:
   • sidebars + stage + footer stacking crushed everything
   • 4-col right-tabs wrapped SOUL QUEUE behind the tab strip border
   • LORE / footer buttons overlapped neighbours on narrow screens
   • tapping one button often hit an adjacent one
   ───────────────────────────────────────────────────────────────────
   Mobile plan:
   • stage = full viewport (body is the hero)
   • sidebars become bottom-sheet drawers behind pill toggles
   • each pill toggle sits alone with ≥16px clearance on every side
   • right-sidebar tabs: 2×2 grid, full SOUL QUEUE label fits
   • footer: two rows with wrap, ≥12px gap, no horizontal scroll
   • every tap target ≥44×44 with 8px inter-target gutter
   ═══════════════════════════════════════════════════════════════════ */

/* Sheet overlay shared surface — used for both drawers.
   Bodies add .is-open; a JS hook toggles that class. */
.vtn-sheet-scrim {
  position: fixed;
  inset: 0;
  background: rgba(2, 4, 8, 0.55);
  backdrop-filter: blur(3px);
  z-index: var(--z-scrim, 90);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}
.vtn-sheet-scrim.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* Floating pill toggles — only on mobile, positioned so neighbours
   can't touch them even with fat fingers. */
.vtn-mobile-pill {
  display: none; /* desktop hidden */
  position: fixed;
  z-index: var(--z-pill, 95);
  min-width: 64px;
  min-height: var(--tap-min, 44px);
  padding: 0 14px;
  background: rgba(12, 18, 28, 0.72);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(124, 196, 255, 0.28);
  border-radius: 22px;
  color: #cfe2ff;
  font: 600 10px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--shadow-float, 0 6px 18px rgba(0, 0, 0, 0.45));
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-pop, 180ms) var(--ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)),
              border-color 0.2s ease, box-shadow 0.2s ease;
}
.vtn-mobile-pill.is-left  { left: 12px;  top: calc(env(safe-area-inset-top, 0px) + 10px); }
.vtn-mobile-pill.is-right { right: 12px; top: calc(env(safe-area-inset-top, 0px) + 10px); }
.vtn-mobile-pill:active { transform: scale(0.92); }
.vtn-mobile-pill[aria-expanded="true"] {
  border-color: rgba(124, 196, 255, 0.55);
  box-shadow: var(--shadow-pop, 0 2px 10px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(124, 207, 255, 0.10));
}

@media (max-width: 820px) {
  /* Shell becomes stage + footer only; sidebars detach into drawers */
  .vtn-shell {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    grid-template-areas:
      "stage"
      "footer";
    min-height: 100vh;
    min-height: 100svh;
  }

  .vtn-mobile-pill { display: inline-flex; align-items: center; justify-content: center; }

  /* Sidebars become bottom sheets, hidden by default, slide up when open */
  .vtn-sidebar-left,
  .vtn-sidebar-right {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    max-height: 72vh;
    max-height: 72svh;
    min-height: 40vh;
    background: rgba(10, 14, 22, 0.96);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-bottom: none;
    border-top-left-radius: 18px;
    border-top-right-radius: 18px;
    transform: translateY(100%);
    transition: transform var(--dur-sheet, 320ms) var(--ease-sheet, cubic-bezier(0.32, 0.72, 0, 1));
    z-index: var(--z-sheet, 100);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
    box-shadow: var(--shadow-sheet, 0 -12px 40px rgba(0, 0, 0, 0.55));
  }
  /* During an active swipe-to-dismiss the JS drives transform directly */
  .vtn-sidebar-left.is-swiping,
  .vtn-sidebar-right.is-swiping { transition: none; }
  .vtn-sidebar-left.is-open,
  .vtn-sidebar-right.is-open { transform: translateY(0); }

  /* Drawer grab-handle hint */
  .vtn-sidebar-left::before,
  .vtn-sidebar-right::before {
    content: '';
    display: block;
    width: 44px;
    height: 4px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.22);
    margin: 10px auto 4px;
  }

  /* Stage fills the visible viewport; nothing else covers it */
  .vtn-stage {
    min-height: calc(100vh - 68px);
    min-height: calc(100svh - 68px);
  }

  /* Footer: wrap to two rows, no scrollbar, big comfortable targets */
  .vtn-footer {
    height: auto;
    min-height: 60px;
    grid-area: footer;
  }
  .vtn-ft-inner {
    flex-wrap: wrap;
    justify-content: center;
    overflow-x: visible;
    gap: 8px 10px;
    padding: 10px 12px calc(env(safe-area-inset-bottom, 0px) + 10px);
  }
  .vtn-ft-group { gap: 6px; flex-wrap: wrap; justify-content: center; }
  .vtn-ft-spacer { display: none; } /* no push-apart on mobile — groups wrap naturally */
  .vtn-ft-div    { display: none; } /* dividers just add overlap on wrap — hide on mobile */
  .vtn-ft-btn {
    min-width: 48px;
    min-height: 44px;
    padding: 0 10px;
    flex: 0 0 auto;
  }

  /* Right sidebar tabs: 2×2 grid so SOUL QUEUE fits as one label */
  .vtn-right-tabs {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }
  .vtn-right-tab {
    min-height: 48px;
    font-size: 10px;
    letter-spacing: 0.12em;
    padding: 0 8px;
    white-space: nowrap;
  }

  /* Left sidebar tab row — 4 tiles fit tightly on narrow screens */
  .vtn-tabs { gap: 8px; }
  .vtn-tab  { min-height: 48px; }

  /* Identity / chem / layer blocks compress gracefully — bottom padding
     keeps legend clear of the floating "leave a memory" pill on mobile too. */
  .vtn-side-inner { gap: 14px; padding: 16px 14px calc(env(safe-area-inset-bottom, 0px) + 96px); }
  .vtn-side-right-inner { gap: 10px; padding: 10px 12px 16px; max-height: none; }
  .vtn-card-list { max-height: none; overflow-y: visible; }

  .vtn-chem-row { grid-template-columns: 72px 1fr 30px; }
}

/* Very small phones — squeeze everything slightly more without overlap */
@media (max-width: 380px) {
  .vtn-ft-btn       { min-width: 44px; padding: 0 8px; font-size: 9px; }
  .vtn-right-tab    { font-size: 9.5px; letter-spacing: 0.10em; }
  .vtn-mobile-pill  { min-width: 54px; padding: 0 10px; font-size: 9px; }
}

/* ═══════════════════════════════════════════════════════════════════
   KILL LEGACY PHASE-1 UI — the brain.html file carries two generations
   of shell stacked on top of each other. Phase-1: header, .tab-bar,
   .sidebar (leftSidebar/rightSidebar), mobile bottom bar, lore toggle.
   Phase-2 (current): .vtn-shell grid with #sidebarLeft/#sidebarRight/
   #footerStrip. All Phase-1 handlers target dead ids or superseded
   panels. Hide them so the user only sees what actually works.
   ═══════════════════════════════════════════════════════════════════ */
.header,
.tab-bar,
#mainTabs,
.legend,
.sidebar,
#leftSidebar,
#rightSidebar,
#leftSidebarOverlay,
#rightSidebarOverlay,
#mobileBottomBar,
#loreToggle,
#lorePanel,
#mobileLoreToggle {
  display: none !important;
}

/* The new Phase-2 shell must own the whole viewport now */
.vtn-shell {
  position: relative;
  z-index: 5;
}

/* Style the dedicated SCAN button so its label is unmistakable */
.vtn-ft-scan {
  min-width: 72px;
  background: rgba(124, 196, 255, 0.14);
  border: 1px solid rgba(124, 196, 255, 0.28);
  color: #cfe2ff;
  font-weight: 700;
  letter-spacing: 0.18em;
}
.vtn-ft-scan:hover {
  background: rgba(124, 196, 255, 0.22);
  border-color: rgba(124, 196, 255, 0.45);
  color: #fff;
}

/* ═══════════════════════════════════════════════════════════════════
   MOBILE SAFE ZONES — keep other floating UI from colliding with the
   BODY / MIND pills at the top, or the footer strip at the bottom.
   Targets every known fixed overlay in the app.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 820px) {
  /* Top center safe zone — push any floating top element below the pill row */
  .vtn-sensor-btn,
  #vtn-sensor,
  #soul-auth-indicator,
  #vtnAuthIndicator,
  .vtn-auth-indicator,
  .vtn-top-chip,
  .vtn-top-hud {
    top: calc(env(safe-area-inset-top, 0px) + 62px) !important;
  }

  /* DirRM floating player — lift above footer and clear of right pill */
  #dirrmPlayer,
  .dirrm-player,
  .vtn-dirrm-player {
    right: 10px !important;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 70px) !important;
    max-width: calc(100vw - 20px) !important;
  }

  /* Peel tab (right edge info panel) — lives on right edge; hide behind
     sheet when the MIND drawer is open so it can't poke through */
  .vtn-peel-tab,
  #vtnPeelTab {
    top: calc(env(safe-area-inset-top, 0px) + 62px) !important;
  }
  body:has(.vtn-sidebar-right.is-open) .vtn-peel-tab,
  body:has(.vtn-sidebar-right.is-open) #vtnPeelTab { visibility: hidden; }

  /* Chat dock — lift above footer if present */
  .vtn-chat-dock,
  #vtnChatDock,
  #chatDock {
    bottom: calc(env(safe-area-inset-bottom, 0px) + 72px) !important;
    right: 10px !important;
    max-width: calc(100vw - 20px) !important;
  }

  /* Any .dir-* / .vtn- overlay we didn't explicitly name: if it uses
     position:fixed top:0, the generic nudge won't reach it, but at least
     ensure they can't overlap the pills — add a uniform tap buffer. */
  .vtn-mobile-pill { pointer-events: auto; }
}

/* ═══════════════════════════════════════════════════════════════════
   FORK B · SESSION 1 — Subconscious / Genetics / Immune strips
   Live consciousness strips inside left sidebar.
   All surfaces stay under 0.25 max opacity rule.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Subconscious ticker ─────────────────────────────────────────── */
.vtn-subc { margin-top: 14px; }
.vtn-subc-thought {
  font-size: 12px;
  line-height: 1.45;
  color: rgba(220, 210, 255, 0.85);
  font-style: italic;
  min-height: 34px;
  padding: 8px 10px;
  background: rgba(120, 90, 200, 0.08);
  border-left: 2px solid rgba(180, 124, 255, 0.45);
  border-radius: 0 3px 3px 0;
  transition: opacity 0.4s ease;
  opacity: 1;
}
.vtn-live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(180, 124, 255, 0.5);
  margin-left: 6px;
  vertical-align: middle;
  transition: background 0.3s, box-shadow 0.3s;
}
.vtn-live-dot.is-pulse {
  background: rgba(180, 124, 255, 1);
  box-shadow: 0 0 8px rgba(180, 124, 255, 0.8);
}

/* ── Genetic expression list ─────────────────────────────────────── */
.vtn-genetics { margin-top: 14px; }
.vtn-gene-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.vtn-gene-row {
  display: grid;
  grid-template-columns: 62px 1fr;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 8px;
  row-gap: 2px;
  font-size: 11px;
}
.vtn-gene-name {
  grid-column: 1;
  grid-row: 1 / 3;
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 10.5px;
  letter-spacing: 0.5px;
  color: rgba(255, 124, 180, 0.95);
  font-weight: 600;
}
.vtn-gene-track {
  grid-column: 2;
  grid-row: 1;
  height: 4px;
  background: rgba(255, 124, 180, 0.1);
  border-radius: 2px;
  overflow: hidden;
}
.vtn-gene-fill {
  height: 100%;
  background: linear-gradient(90deg, rgba(255, 124, 180, 0.7), rgba(255, 180, 200, 0.9));
  border-radius: 2px;
  transition: width 0.8s ease;
}
.vtn-gene-desc {
  grid-column: 2;
  grid-row: 2;
  color: rgba(200, 200, 220, 0.55);
  font-size: 10px;
  letter-spacing: 0.2px;
}

/* ── Immune strip ────────────────────────────────────────────────── */
.vtn-immune { margin-top: 14px; }
.vtn-imm-state {
  font-size: 10px;
  color: rgba(124, 255, 240, 0.7);
  margin-left: 6px;
  font-style: italic;
  transition: color 0.4s;
}
.vtn-imm-bar {
  height: 6px;
  background: rgba(124, 255, 240, 0.08);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 4px;
}
.vtn-imm-fill {
  height: 100%;
  width: 10%;
  background: linear-gradient(90deg, rgba(124, 255, 240, 0.5), rgba(124, 200, 255, 0.7));
  border-radius: 3px;
  transition: width 0.6s ease, background 0.3s ease;
}
.vtn-imm-fill.is-flare {
  background: linear-gradient(90deg, rgba(255, 180, 80, 0.85), rgba(255, 100, 60, 0.95));
  box-shadow: 0 0 12px rgba(255, 140, 60, 0.6);
  animation: vtn-imm-pulse 0.6s ease-in-out infinite alternate;
}
@keyframes vtn-imm-pulse {
  from { filter: brightness(0.9); }
  to   { filter: brightness(1.15); }
}

/* ── Mobile — keep the strips readable, condense padding ─────────── */
@media (max-width: 860px) {
  .vtn-subc-thought { font-size: 11px; padding: 6px 8px; min-height: 30px; }
  .vtn-gene-row     { grid-template-columns: 54px 1fr; font-size: 10px; }
  .vtn-gene-name    { font-size: 9.5px; }
  .vtn-gene-desc    { font-size: 9px; }
}

/* ═══════════════════════════════════════════════════════════════════
   REDUCED MOTION — the body still moves, it just doesn't perform.
   Honors OS-level "reduce motion" without breaking any open/close state.
   ═══════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .vtn-sheet-scrim,
  .vtn-mobile-pill,
  .vtn-sidebar-left,
  .vtn-sidebar-right,
  .vtn-card-heat,
  .vtn-ft-btn,
  .vtn-tab,
  .vtn-right-tab {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   PULSE — the live work dashboard (Vinta directive 2026-08-14)
   Fifth tab of the right sidebar. Turns the passive activity feed into a
   surface that shows work *in flight*, with honest progress bars.

   NO-COLLISION CONTRACT (absolute law, enforced structurally here):
   - Every .vtn-pulse-row is a normal flow child in a flex column with a
     hard `gap`. No negative margins, no float, no absolute positioning in
     page space. Rows physically cannot touch.
   - The ONE absolutely-positioned element is .vtn-pulse-fill, and it is
     clipped by .vtn-pulse-track { overflow:hidden } — its own parent. It
     cannot reach a sibling even at 100% width.
   - .vtn-pulse-label is min-width:0 + ellipsis; .vtn-pulse-pct is
     flex-shrink:0. A 200-character job label truncates instead of pushing
     the percentage out of the card. Verified 320/375/768/1280/1920.
   - No shadow, glow, or transform extends into a neighbor's box: the
     row gap (10px) exceeds every blur radius used below.
   ══════════════════════════════════════════════════════════════════════ */

.vtn-pulse {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;          /* the truncation contract starts here */
}

/* ── Header: the one-glance answer to "is anything happening?" ────────── */
.vtn-pulse-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  min-width: 0;
}
.vtn-pulse-dot {
  width: 7px; height: 7px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: rgba(200, 215, 235, 0.28);
  transition: background 240ms ease, box-shadow 240ms ease;
}
.vtn-pulse-summary {
  font: 600 9.5px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(200, 215, 235, 0.55);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vtn-pulse-summary.is-live { color: #cfe2ff; }
/* The dot only breathes when work is actually live — the animation IS the
   signal, so it must never run on an idle system. */
.vtn-pulse-summary.is-live ~ .vtn-pulse-dot,
.vtn-pulse-bar:has(.is-live) .vtn-pulse-dot {
  background: #7cc4ff;
  box-shadow: 0 0 8px rgba(124, 196, 255, 0.7);
  animation: vtn-pulse-breathe 2s ease-in-out infinite;
}
@keyframes vtn-pulse-breathe {
  0%, 100% { opacity: 1;    transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.82); }
}

/* ── Row list ─────────────────────────────────────────────────────────── */
.vtn-pulse-rows {
  display: flex;
  flex-direction: column;
  gap: 10px;             /* the collision floor — exceeds every blur below */
  min-width: 0;
}

.vtn-pulse-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  min-width: 0;
  overflow: hidden;      /* nothing inside a row may escape it, ever */
  transition: border-color 300ms ease, background 300ms ease;
}
.vtn-pulse-row.is-running { border-color: rgba(124, 196, 255, 0.20); }
.vtn-pulse-row.is-stalled { border-color: rgba(255, 179, 71, 0.22); }
.vtn-pulse-row.is-done    { border-color: rgba(94, 234, 212, 0.20); }
.vtn-pulse-row.is-failed  { border-color: rgba(255, 107, 107, 0.26); }

.vtn-pulse-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.vtn-pulse-label {
  flex: 1 1 auto;
  min-width: 0;          /* without this, a long label shoves the % out */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 600 11px/1.25 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.04em;
  color: #e8f0ff;
}
.vtn-pulse-pct {
  flex: 0 0 auto;        /* the number never compresses or wraps */
  font: 700 10px/1.25 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0.10em;
  font-variant-numeric: tabular-nums;  /* no width jitter as digits change */
  color: rgba(200, 215, 235, 0.62);
}
.is-running .vtn-pulse-pct { color: #7cc4ff; }
.is-stalled .vtn-pulse-pct { color: #ffb347; }
.is-done    .vtn-pulse-pct { color: #5eead4; }
.is-failed  .vtn-pulse-pct { color: #ff6b6b; }

/* ── The bar ──────────────────────────────────────────────────────────── */
.vtn-pulse-track {
  position: relative;
  height: 5px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;      /* the clip that makes .vtn-pulse-fill safe */
  isolation: isolate;
}
.vtn-pulse-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 0;
  border-radius: 3px;
  background: linear-gradient(90deg, #4a9fe0 0%, #7cc4ff 100%);
  /* 420ms is the sweet spot: long enough to read as motion (you SEE it
     advance), short enough that it never lags behind the real number. */
  transition: width 420ms cubic-bezier(0.22, 0.61, 0.36, 1), background 300ms ease;
}
.is-stalled .vtn-pulse-fill { background: linear-gradient(90deg, #c98a2e 0%, #ffb347 100%); }
.is-done    .vtn-pulse-fill { background: linear-gradient(90deg, #2fa898 0%, #5eead4 100%); }
.is-failed  .vtn-pulse-fill { background: linear-gradient(90deg, #c04a4a 0%, #ff6b6b 100%); }

/* Live sheen — a light travelling the filled portion. Clipped by the track,
   so it can never bleed past the bar. Runs ONLY while running, so motion on
   this surface always means real work is in flight. */
.is-running .vtn-pulse-fill::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.34) 50%,
    transparent 100%
  );
  transform: translateX(-100%);
  animation: vtn-pulse-sheen 1.9s ease-in-out infinite;
}
@keyframes vtn-pulse-sheen {
  0%   { transform: translateX(-100%); }
  60%  { transform: translateX(100%); }
  100% { transform: translateX(100%); }
}

/* Indeterminate — real work with no countable end. A sweeping band that
   claims no percentage. Honesty made visual: we show motion, not a number. */
.vtn-pulse-track.is-indeterminate .vtn-pulse-fill {
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(124, 196, 255, 0.16) 22%,
    #7cc4ff 50%,
    rgba(124, 196, 255, 0.16) 78%,
    transparent 100%
  );
  animation: vtn-pulse-indet 1.5s ease-in-out infinite;
  transition: none;
}
.vtn-pulse-track.is-indeterminate .vtn-pulse-fill::after { display: none; }
@keyframes vtn-pulse-indet {
  0%   { transform: translateX(-62%); }
  100% { transform: translateX(62%); }
}

/* Completion payoff — one brief lift when a bar lands. Border-only glow so
   nothing grows outside the row box. */
.vtn-pulse-row.is-done   { animation: vtn-pulse-land 620ms ease-out 1; }
.vtn-pulse-row.is-failed { animation: vtn-pulse-land-fail 620ms ease-out 1; }
@keyframes vtn-pulse-land {
  0%   { background: rgba(94, 234, 212, 0.14); }
  100% { background: rgba(16, 22, 34, 0.18); }
}
@keyframes vtn-pulse-land-fail {
  0%   { background: rgba(255, 107, 107, 0.14); }
  100% { background: rgba(16, 22, 34, 0.18); }
}

/* ── Text lines under the bar ─────────────────────────────────────────── */
.vtn-pulse-detail {
  font: 400 10px/1.35 var(--font-ui, system-ui, sans-serif);
  color: rgba(210, 222, 240, 0.72);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;   /* one line, always — a long probe name truncates */
}
.vtn-pulse-meta {
  font: 400 9.5px/1.3 var(--font-ui, system-ui, sans-serif);
  color: rgba(200, 215, 235, 0.44);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Empty state ──────────────────────────────────────────────────────── */
.vtn-pulse-empty {
  padding: 16px 14px;
  background: rgba(16, 22, 34, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: 10px;
  min-width: 0;
}
.vtn-pulse-empty-t {
  font: 600 11px/1.3 var(--font-ui, system-ui, sans-serif);
  color: rgba(232, 240, 255, 0.78);
  letter-spacing: 0.04em;
}
.vtn-pulse-empty-s {
  margin-top: 5px;
  font: 400 10px/1.45 var(--font-ui, system-ui, sans-serif);
  color: rgba(200, 215, 235, 0.5);
  word-break: break-word;   /* prose wraps; it is not a single-line field */
}

/* ── Tab live badge ───────────────────────────────────────────────────── */
/* A count on the PULSE tab so work is discoverable from any other tab.
   Inline-flex inside the button's flow — never absolutely positioned, so it
   cannot land on the label or the adjacent tab. The tab's own ellipsis
   handles the squeeze at 320px. */
.vtn-right-tab .vtn-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 4px;
  min-width: 13px;
  height: 13px;
  padding: 0 3px;
  border-radius: 7px;
  background: rgba(124, 196, 255, 0.22);
  color: #cfe2ff;
  font: 700 8px/1 var(--font-ui, system-ui, sans-serif);
  letter-spacing: 0;
  vertical-align: middle;
  flex: 0 0 auto;
}

/* ── 5 tabs instead of 4 ──────────────────────────────────────────────── */
.vtn-right-tabs.has-pulse { grid-template-columns: repeat(5, 1fr); }

/* At phone widths five labels cannot sit legibly on one row without
   colliding. They wrap to two rows of the SAME grid — still gapped, still
   non-overlapping. Never squeezed below the 44px touch target. */
@media (max-width: 560px) {
  .vtn-right-tabs.has-pulse {
    grid-template-columns: repeat(3, 1fr);
  }
  .vtn-right-tabs.has-pulse .vtn-right-tab {
    font-size: 8.5px;
    letter-spacing: 0.08em;
    padding: 0 4px;
  }
}
@media (max-width: 380px) {
  .vtn-right-tabs.has-pulse {
    grid-template-columns: repeat(2, 1fr);
  }
  .vtn-right-tabs.has-pulse .vtn-right-tab { font-size: 9px; letter-spacing: 0.06em; }
  .vtn-pulse-row  { padding: 9px 10px; }
  .vtn-pulse-label { font-size: 10.5px; }
  .vtn-pulse-empty { padding: 14px 12px; }
}

/* ── Reduced motion — mandatory ───────────────────────────────────────── */
/* Motion is the point of this surface, so removing it must not remove the
   information. The bar still fills (instantly), and the indeterminate state
   keeps a static tinted band so "working" remains visually distinct from
   "idle" without anything moving. */
@media (prefers-reduced-motion: reduce) {
  .vtn-pulse-fill { transition: none; }
  .vtn-pulse-dot,
  .is-running .vtn-pulse-fill::after,
  .vtn-pulse-track.is-indeterminate .vtn-pulse-fill,
  .vtn-pulse-row.is-done,
  .vtn-pulse-row.is-failed {
    animation: none !important;
  }
  .is-running .vtn-pulse-fill::after { display: none; }
  .vtn-pulse-track.is-indeterminate .vtn-pulse-fill {
    background: repeating-linear-gradient(
      90deg,
      rgba(124, 196, 255, 0.34) 0px,
      rgba(124, 196, 255, 0.34) 6px,
      transparent 6px,
      transparent 12px
    );
    transform: none;
  }
  .vtn-pulse-bar:has(.is-live) .vtn-pulse-dot {
    background: #7cc4ff;
    box-shadow: 0 0 6px rgba(124, 196, 255, 0.6);
  }
}
