/* ═══════════════════════════════════════════════════════════════
   styles.css — Project-specific overrides for miasma.
   Shared patterns (glass, tool-btn, layout tokens) in /shared-base.css.
   All colors via CSS vars injected by colors.js — no hardcoded values.
   Compartment colors: --epi-s / -e / -i / -r / -d / -v / -m / -z
                       plus -wash (0.18α) and -tint (0.10α) variants.
   ═══════════════════════════════════════════════════════════════ */

/* ───── Keyframes ───── */
@keyframes pulse-dot {
  0%, 100% { opacity: 0.4; transform: scale(1); }
  50%      { opacity: 1; transform: scale(1.6); }
}


/* ───── Base — full-viewport app shell ───── */
html {
  font-size: clamp(14px, 1.5vw, 16px);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ───── Speed button — widen for fractional speeds (0.25x, 0.5x) so the
   four-character label doesn't clip the fixed 34px tool-btn box. Shared
   .tool-btn pins width:34px; we override with width:auto + a side-pad. ───── */
#speed-btn {
  width: auto;
  padding: 0 0.45rem;
}

body {
  display: flex;
  flex-direction: column;
}


/* ═══════════════════════════════════════
   MAIN LAYOUT — full-viewport canvas behind HUD sidebar/toolbar.
   ═══════════════════════════════════════ */
main {
  flex: 1;
  min-height: 0;
  position: relative;
  z-index: 1;
}


/* ═══════════════════════════════════════
   CANVAS CONTAINER
   ═══════════════════════════════════════ */
#sim-container {
  position: absolute;
  inset: 0;
  background: var(--bg-canvas);
  cursor: crosshair;
  touch-action: none;
  overflow: hidden;
  transition: background 0.3s var(--ease-out);
}

#sim-container.pan-mode { cursor: grab; }
#sim-container.panning  { cursor: grabbing; }

#sim-canvas {
  display: block;
  width: 100%;
  height: 100%;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: crisp-edges;
  touch-action: none;
}


/* ═══════════════════════════════════════
   THEME TOGGLE ICONS
   ═══════════════════════════════════════ */
#theme-btn .icon-auto,
#theme-btn .icon-sun,
#theme-btn .icon-moon { display: none; }

#theme-btn[data-theme="auto"]  .icon-auto { display: block; }
#theme-btn[data-theme="light"] .icon-sun  { display: block; }
#theme-btn[data-theme="dark"]  .icon-moon { display: block; }


/* ═══════════════════════════════════════
   COMPARTMENT LEGEND — colored dots + label rows
   Generic .legend-dot pulls a per-class --dot-color.
   ═══════════════════════════════════════ */
.legend-grid {
  display: flex;
  flex-direction: column;
  gap: 0.12rem;
}

.legend-sub {
  font-family: var(--font-sans);
  font-size: clamp(0.46rem, 0.7vw, 0.52rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  margin-top: 0.25rem;
  opacity: 0.6;
}

.legend-sub:first-child { margin-top: 0; }

.legend-item {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: clamp(0.58rem, 0.88vw, 0.66rem);
  color: var(--text-secondary);
}

.legend-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--dot-color);
}

.legend-dot.epi-s-dot { --dot-color: var(--epi-s); }
.legend-dot.epi-e-dot { --dot-color: var(--epi-e); }
.legend-dot.epi-i-dot { --dot-color: var(--epi-i); }
.legend-dot.epi-r-dot { --dot-color: var(--epi-r); }
.legend-dot.epi-d-dot { --dot-color: var(--epi-d); }
.legend-dot.epi-v-dot { --dot-color: var(--epi-v); }
.legend-dot.epi-m-dot { --dot-color: var(--epi-m); }
.legend-dot.epi-z-dot { --dot-color: var(--epi-z); }


/* ═══════════════════════════════════════
   COMPARTMENT STAT READOUTS
   Reuses .stat-value / .stat-label from shared-base.css.
   Per-compartment color via --stat-color.
   ═══════════════════════════════════════ */
.stat-row[data-compartment="S"]     { --stat-color: var(--epi-s); }
.stat-row[data-compartment="E"]     { --stat-color: var(--epi-e); }
.stat-row[data-compartment="I"]     { --stat-color: var(--epi-i); }
.stat-row[data-compartment="R"]     { --stat-color: var(--epi-r); }
.stat-row[data-compartment="D"]     { --stat-color: var(--epi-d); }
.stat-row[data-compartment="V"]     { --stat-color: var(--epi-v); }
.stat-row[data-compartment="M"]     { --stat-color: var(--epi-m); }
.stat-row[data-compartment="Z"]     { --stat-color: var(--epi-z); }
.stat-row[data-compartment="empty"] { --stat-color: var(--text-secondary, #808696); }

/* Dark theme: --epi-d collapses to canvas background so D cells render as
   "holes" — but the same color on text disappears against the panel. Swap
   in --text for the D row's label/value so the row stays readable; we lose
   the per-compartment hue for D in dark mode, which is unavoidable when the
   hue IS the background. */
:root[data-theme="dark"] .stat-row[data-compartment="D"] { --stat-color: var(--text); }

.stat-row[data-compartment] .stat-value,
.stat-row[data-compartment] .stat-label { color: var(--stat-color); }

/* Sub-rows (Latent under E, Carrier under R, Infectious-corpse under D)
   inherit --stat-color from their parent compartment via [data-compartment]
   above. Override .stat-sub's muted defaults so the label/value stay on the
   parent's hue — slight alpha softening keeps the visual hierarchy without
   washing the color out. */
.stat-sub[data-compartment] .stat-label,
.stat-sub[data-compartment] .stat-value { color: var(--stat-color); opacity: 0.85; }

/* Dim zero-count rows so non-zero entries stand out */
.stat-row[data-zero="true"] { opacity: 0.4; }

/* Population total + observed Re + status (hospital/quarantine) + Phase 5 mean age/health readout rows are role-tagged */
.stat-row[data-role="population"] .stat-value,
.stat-row[data-role="reff"] .stat-value,
.stat-row[data-role="hospital"] .stat-value,
.stat-row[data-role="quarantine"] .stat-value,
.stat-row[data-role="mean-age"] .stat-value,
.stat-row[data-role="mean-health"] .stat-value,
.stat-row[data-role="animal-total"] .stat-value,
.stat-row[data-role="animal-mean-age"] .stat-value {
  font-variant-numeric: tabular-nums;
}

/* Phase-17: animal-reservoir census group. The animal S/I/R/D rows reuse the
   --epi-* hues via [data-compartment] above (matching the animal-dot
   overlay). A small uppercase heading separates the group from the human
   compartments above it — spacing + heading, no container border (per the
   command-center design language: surfaces differ by spacing, not lines). */
.stat-animal-group {
  margin-top: 0.65rem;
}

.stat-subhead {
  font: 600 var(--font-sm) / 1.4 var(--font-mono, monospace);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary, #808696);
  margin-bottom: 0.25rem;
}


/* ═══════════════════════════════════════
   STRAIN REGISTRY PANEL — prevalence bars
   ═══════════════════════════════════════ */
.strain-list {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.strain-row {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.35rem;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.2s var(--ease-out);
}

.strain-row:hover { background: var(--bg-hover); }

.strain-row.active { background: var(--accent-subtle); }

.strain-swatch {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--strain-color, var(--epi-i));
}

.strain-name {
  font-family: var(--font-mono);
  font-size: var(--font-sm);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.strain-prev {
  font-family: var(--font-mono);
  font-size: var(--font-sm);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.strain-bar {
  grid-column: 1 / -1;
  height: 3px;
  background: var(--strain-bar-bg);
  border-radius: var(--radius);
  overflow: hidden;
}

.strain-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--strain-color, var(--epi-i));
  transition: width 0.3s var(--ease-out);
}

/* Phase D: force-directed strain forest at the top of the strain panel.
   Replaces the Phase 8 ancestor-chain canvas (`.lineage-tree-canvas`) which
   was removed in Phase C. Muted track-coloured background matches the time-
   series chart aesthetic; fixed CSS height (the canvas backing buffer is
   sized by resizeCanvasDPR). cursor: pointer because the canvas is
   click-targetable — each node selects the corresponding strain. */
.strain-forest-canvas {
  display: block;
  width: 100%;
  height: 200px;
  margin-bottom: 0.5rem;
  background: var(--ts-track);
  border-radius: var(--radius);
  cursor: pointer;
}


/* ═══════════════════════════════════════
   PULSE DOT — active outbreak indicator
   ═══════════════════════════════════════ */
.pulse-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--epi-i);
  animation: pulse-dot 2.5s var(--ease-in-out) infinite;
  flex-shrink: 0;
  vertical-align: middle;
  margin-right: 0.35rem;
}


/* ═══════════════════════════════════════
   TIME SERIES PANEL — Compartments-tab chart
   ═══════════════════════════════════════ */
/* Phase-17: the stacked compartment chart docks at the top of the sidebar's
   Compartments tab (it was a floating canvas-corner HUD through Phase 15-16).
   Plain block, full panel width, fixed 16:9 chart area; the human compartment
   census stacks below it. The --bg-base fill matches the chart's "empty"
   band so unfilled headroom above the stack reads as depopulated land. */
#timeseries-panel {
  width: 100%;
  aspect-ratio: 16 / 9;
  margin-bottom: 0.75rem;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-base);
}

/* Surface and map-view controls live in Settings. */
.settings-map-controls {
  display: flex;
  flex-direction: column;
}

.settings-mode-group {
  width: 100%;
  justify-content: stretch;
}

.settings-mode-group .mode-btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0.25rem 0.25rem;
  font-size: var(--font-sm);
}

/* Phase-15: Advanced Parameters section — shoals-style inline collapsible.
   The toggle button spans the panel width; the section underneath holds the
   slider rows and animates in/out via .hidden (display:none). */
.advanced-wrap {
  margin-top: 0.5rem;
}

.advanced-toggle-btn {
  width: 100%;
  font-size: var(--font-base);
  padding: 0.5rem 0.75rem;
  font-weight: 600;
}

.advanced-toggle-btn.active {
  color: var(--text-on-accent);
  background: var(--accent);
}

.advanced-section {
  margin-top: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.advanced-section.hidden { display: none; }

#timeseries-canvas {
  display: block;
  width: 100%;
  height: 100%;
}


/* (Removed) Brush size indicator — the DOM circle hovering above the canvas
   was replaced by a render-pass overlay that tints the actual cells under
   the brush footprint. See renderPaintOverlay() in src/render.js. */


/* ═══════════════════════════════════════
   PAINT MODE — Interventions tab UI
   3×2 grid of buttons (sidebar is narrow; bindModeGroup's single-row
   sliding indicator doesn't tolerate wrapping). Per-mode active accent
   recolors the active button background to its intervention target.
   ═══════════════════════════════════════ */
.paint-mode-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2px;
  padding: 3px;
  margin: 0.25rem 0 0.5rem;
  background: var(--bg-hover);
  border-radius: var(--radius);
}

.paint-mode-btn {
  background: transparent;
  border: none;
  padding: 0.45rem 0.4rem;
  font-family: var(--font-sans);
  font-size: var(--font-sm);
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: var(--radius);
  line-height: 1;
  transition: background 0.2s var(--ease-out), color 0.2s var(--ease-out);
}

.paint-mode-btn:hover  { color: var(--text); }
.paint-mode-btn.active { color: var(--text-on-accent); background: var(--accent); }

/* Per-mode accent on the active button — recolor the background fill to the
   intervention's semantic compartment color. */
.paint-mode-btn#mode-seed.active       { background: var(--epi-i); color: var(--text-on-accent); }
.paint-mode-btn#mode-vaccinate.active  { background: var(--epi-v); color: var(--text-on-accent); }
.paint-mode-btn#mode-quarantine.active { background: var(--epi-e); color: var(--text-on-accent); }
.paint-mode-btn#mode-sanitize.active   { background: var(--epi-r); color: var(--text-on-accent); }
.paint-mode-btn#mode-cull.active       { background: var(--epi-d); color: var(--text-on-accent); }

/* Brush-size mode group: same inline-mode-toggles container as the animal-
   display row, but with explicit active styling because the three buttons
   carry single-character labels and need a clear visual selection cue.
   bindModeGroup isn't called here (paint.js handles clicks directly so the
   controller stays the source of truth), so we paint the active button's
   background inline via this rule instead of via the sliding indicator. */
#brush-size-group {
  flex: 0 0 auto;
  min-width: 160px;
}
#brush-size-group .mode-btn {
  padding: 0.25rem 0.7rem;
  min-width: 38px;
  border-radius: var(--radius);
  font-variant-numeric: tabular-nums;
}
#brush-size-group .mode-btn.active {
  background: var(--accent);
  color: var(--text-on-accent);
}


/* ═══════════════════════════════════════
   PRESETS — preset chooser at top of Settings tab
   Dropdown + Apply button on one row, description hint below.
   ═══════════════════════════════════════ */
.preset-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}

.preset-select {
  flex: 1 1 auto;
  min-width: 0;
}

.preset-apply-btn {
  flex: 0 0 auto;
  padding: 0.45rem 0.9rem;
  font-weight: 600;
}

.preset-apply-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.preset-desc {
  margin-top: 0.25rem;
}


/* ═══════════════════════════════════════
   STATS — scale-bounce animation on value change
   ═══════════════════════════════════════ */
.stat-value.bump { transform: scale(1.25); }


/* ═══════════════════════════════════════
   RESPONSIVE — Tablet (≤ 900px)
   Sidebar collapses to bottom-sheet (handled by .sim-panel
   in shared-base.css); time-series shrinks above it.
   ═══════════════════════════════════════ */
@media (max-width: 900px) {
  main {
    position: fixed;
    inset: 0;
    height: 100%;
  }

  #sim-container {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  #dashboard { z-index: 95; }
}


/* ═══════════════════════════════════════
   RESPONSIVE — Phone (≤ 600px)
   ═══════════════════════════════════════ */
@media (max-width: 600px) {
  #top-bar { gap: 0.4rem; }
}


/* ═══════════════════════════════════════
   ACCESSIBILITY — coarse pointer touch targets
   ═══════════════════════════════════════ */
@media (pointer: coarse) {
  .tab-btn { padding: 0.65rem 0.4rem 0.55rem; }
  .strain-row { padding: 0.4rem 0.5rem; }
}


/* ═══════════════════════════════════════
   REDUCED MOTION
   ═══════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .pulse-dot { animation: none; opacity: 0.7; }
  .strain-bar-fill { transition: none; }
}


/* ═══════════════════════════════════════
   TOGGLES PANEL — Phase 3 compartment + flag toggles
   Lives inside #tab-settings alongside the param sliders.
   Reuses .settings-dd-row / .settings-dd-label / .checkbox-label
   from shared-base.css; only the section headers + tiny layout
   tweaks are sim-specific.
   ═══════════════════════════════════════ */
.toggles-section-header {
  font-family: var(--font-mono);
  font-size: var(--font-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  margin-top: 0.75rem;
  margin-bottom: 0.35rem;
}

.toggles-section-header:first-child { margin-top: 0; }

/* Row label can hold a swatch + text inline. Align baseline so the swatch
   sits centered with the text. (Legacy — kept for back-compat with any
   pre-restyle markup.) */
.toggles-row-label {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* The right-hand wrapper holds only the checkbox toggle — let it shrink to
   the control width rather than stretching. (Legacy — superseded by
   .toggle-row + .tog-wrap below.) */
.toggles-checkbox-wrap {
  flex: 0 0 auto;
  justify-content: flex-end;
}

/* ───── Phase-14 restyle: geon-style colored toggles + shoals-style
   colored label text. The row binds a per-key `tog-{key}` class that
   sets a single `--tog-color` CSS custom property; the .tog switch in
   shared-base.css picks it up for the on-state gradient, and the label
   text on the row inherits the same color. ───── */
.toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.toggle-row .toggle-label {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--tog-color, var(--text));
  /* Slightly darker base; the colored letter prefix (V — Vaccinated, ...)
     reads as the affordance. Match the geon-on-blue feel. */
  font-weight: 500;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: opacity 0.2s var(--ease-out);
}

.toggle-row .tog-wrap {
  flex: 0 0 auto;
}

/* Per-compartment color bindings. The base `.tog` rules in shared-base.css
   read `--tog-color`; we just point it at the appropriate --epi-* var.
   Flag-row toggles inherit their parent-compartment color (L→E, C→R, F→D)
   so the visual register matches the rendered overlay. */
.tog-s, .toggle-row.tog-s { --tog-color: var(--epi-s); }
.tog-e, .toggle-row.tog-e { --tog-color: var(--epi-e); }
.tog-i, .toggle-row.tog-i { --tog-color: var(--epi-i); }
.tog-r, .toggle-row.tog-r { --tog-color: var(--epi-r); }
.tog-d, .toggle-row.tog-d { --tog-color: var(--epi-d); }
.tog-v, .toggle-row.tog-v { --tog-color: var(--epi-v); }
.tog-m, .toggle-row.tog-m { --tog-color: var(--epi-m); }
.tog-z, .toggle-row.tog-z { --tog-color: var(--epi-z); }

/* Disabled rows (via `bindDeps` enable-mode → adds `.ctrl-disabled`) get
   muted across both label and switch. Existing shared rules already fade
   .ctrl-disabled — repeat for the label text under our color binding. */
.toggle-row.ctrl-disabled .toggle-label,
.toggle-row.ctrl-disabled .tog { opacity: 0.4; pointer-events: none; }

/* Animal-display row uses the inline mode-group layout — sits the buttons
   on the right of the label and gives them the same tinted feel as the
   topology / view-mode toggles. */
.animal-display-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.inline-mode-toggles {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
  gap: 0;
  padding: 2px;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bg-panel-solid) 60%, transparent);
}

.inline-mode-toggles .mode-btn {
  font-size: var(--font-sm);
  padding: 0.2rem 0.55rem;
}

.inline-mode-toggles .mode-btn.active {
  background: var(--accent);
  color: var(--text-on-accent);
}
