/* =========================================================================
   body-map.css — the interactive anatomical exercise selector's design layer.
   ALL colour is driven from custom properties + a mode class on .bm; no hue is
   hardcoded outside these tokens. Painted in OUR palette (off-black base, lime
   Normal accent / red Advanced accent) — never the source asset's colours.

   Three distinct colour USES, deliberately kept un-confusable:
     · resting muscle   — dark grey above the base (--muscle-rest)
     · frequency heat    — MUTED ramp toward the mode accent (background read)
     · selection         — FULL accent + outline + pulse (foreground intent)
   ========================================================================= */

.bm {
  /* figure tokens — greys sit ABOVE the #0b0b0d base so the body reads out */
  --muscle-rest:   #26262b;   /* untrained muscle fill */
  --muscle-stroke: #3a3a44;   /* subtle separation between muscles */
  --bm-silhouette: #17171b;   /* inert / decorative parts: barely above base */

  /* heat + selection hues resolve from the active MODE (set just below) */
  --bm-heat:    var(--accent);
  --bm-sel:     var(--accent);
  --bm-sel-ink: var(--accent-ink);

  display: block;
}
/* Mode recolours the WHOLE figure by swapping these two tokens — toggling the
   class is the only thing that changes the heatmap + selection hue. */
.bm.mode-normal   { --bm-heat: var(--accent);          --bm-sel: var(--accent);          --bm-sel-ink: var(--accent-ink); }
.bm.mode-advanced { --bm-heat: var(--accent-advanced); --bm-sel: var(--accent-advanced); --bm-sel-ink: var(--accent-advanced-ink); }

/* ---- toolbar: front/back + figure toggles (accessible segmented controls) ---- */
.bm-toolbar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2);
  margin-bottom: var(--s-3);
}
.bm-seg {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
}
.bm-seg-opt {
  min-height: 34px;
  padding: 0 14px;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--ink-faint);
  font-size: var(--t--1);
  font-weight: 650;
  letter-spacing: 0.06em;
}
.bm-seg-opt:hover { color: var(--ink-dim); }
.bm-seg-opt.is-on { background: var(--bm-heat); color: var(--bm-sel-ink); }
.bm-seg-opt.is-on:hover { color: var(--bm-sel-ink); }

/* ---- stage: fixed-height box so front↔back/gender swaps never shift layout ---- */
.bm-stage {
  height: min(54vh, 440px);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity var(--bm-swap) var(--bm-ease), transform var(--bm-swap) var(--bm-ease);
  will-change: opacity, transform;
}
.bm-stage.bm-out { opacity: 0; transform: scale(0.985); }
.bm-stage.bm-in  { opacity: 0; transform: scale(1.015); }

.bm-svg {
  height: 100%;
  width: 100%;
  display: block;
  overflow: visible;
}

/* DUAL VIEW — the display-only logging companion: front + back side by side,
   compact, so a whole-body choice lights up at once. Each figure meets inside
   its half (preserveAspectRatio), so they stay narrow on a phone. */
.bm-dual .bm-stage { gap: var(--s-4); }
.bm-dual .bm-svg { flex: 0 0 auto; height: 100%; width: auto; } /* each sizes to its viewBox aspect */

/* ---- the figure itself ---- */
.bm-decor {
  fill: var(--bm-silhouette);
  stroke: none;
}
.bm-muscle {
  fill: var(--muscle-rest);
  stroke: var(--muscle-stroke);
  stroke-width: 2;
  /* CALM, slow fades (see --bm-* tokens) — the figure settles, never snaps. */
  transition: fill var(--bm-fade) var(--bm-ease), stroke var(--bm-fade) var(--bm-ease),
              stroke-width 160ms var(--bm-ease);
}
.bm.is-interactive .bm-muscle { cursor: pointer; }
.bm.is-interactive .bm-muscle:hover { stroke: var(--ink-dim); }
.bm.is-static .bm-muscle { cursor: default; pointer-events: none; } /* OUTPUT, not a control */

/* FREQUENCY HEATMAP — a MUTED ramp (mixes the mode accent INTO the resting grey,
   so it desaturates toward "background heat", never full selection colour).
   Only the Progress page (.bm-rich) shows heat; there it earns a FULLER ramp. */
.bm-muscle[data-heat="1"] { fill: color-mix(in oklab, var(--bm-heat) 14%, var(--muscle-rest)); }
.bm-muscle[data-heat="2"] { fill: color-mix(in oklab, var(--bm-heat) 27%, var(--muscle-rest)); }
.bm-muscle[data-heat="3"] { fill: color-mix(in oklab, var(--bm-heat) 41%, var(--muscle-rest)); }
.bm-muscle[data-heat="4"] { fill: color-mix(in oklab, var(--bm-heat) 56%, var(--muscle-rest)); }

.bm-rich .bm-muscle[data-heat="1"] { fill: color-mix(in oklab, var(--bm-heat) 24%, var(--muscle-rest)); }
.bm-rich .bm-muscle[data-heat="2"] { fill: color-mix(in oklab, var(--bm-heat) 44%, var(--muscle-rest)); }
.bm-rich .bm-muscle[data-heat="3"] { fill: color-mix(in oklab, var(--bm-heat) 64%, var(--muscle-rest)); }
.bm-rich .bm-muscle[data-heat="4"] { fill: color-mix(in oklab, var(--bm-heat) 84%, var(--muscle-rest)); }

/* IMPLIED — the logging confirmation glow: the muscles a chosen bucket/region
   works. Clear accent fill + outline (distinct from the muted heat read), but
   it FADES in gently via the --bm-fade transition above. */
.bm-muscle.is-implied {
  fill: color-mix(in oklab, var(--bm-sel) 72%, var(--muscle-rest));
  stroke: var(--bm-sel);
  stroke-width: 3;
}

/* SELECTION — FULL-saturation accent + a clear outline + a brief pulse. Distinct
   from heat by saturation AND outline, so the colour uses never blur. */
.bm-muscle.is-selected {
  fill: var(--bm-sel);
  stroke: var(--bm-sel);
  stroke-width: 3.5;
  animation: bm-pulse 360ms var(--bm-ease) both;
}

/* Keyboard focus — visible without colour alone (white outline stroke), and
   distinct from the accent selection stroke. */
.bm-muscle:focus { outline: none; }
.bm.is-interactive .bm-muscle:focus-visible {
  outline: none;
  stroke: var(--ink);
  stroke-width: 3.5;
}

@keyframes bm-pulse {
  0%   { filter: drop-shadow(0 0 0 transparent); }
  45%  { filter: drop-shadow(0 0 8px var(--bm-sel)); }
  100% { filter: drop-shadow(0 0 3px var(--bm-sel)); }
}

/* Calm whole-figure reveal — Progress, when the page opens / window changes. */
.bm-stage.bm-enter { animation: bm-enter var(--bm-enter) var(--bm-ease) both; }
@keyframes bm-enter {
  from { opacity: 0; transform: translateY(8px) scale(0.99); }
  to   { opacity: 1; transform: none; }
}

/* ---- caption ---- */
.bm-caption {
  text-align: center;
  color: var(--ink-faint);
  font-size: var(--t--1);
  letter-spacing: 0.02em;
  margin: var(--s-3) 0 0;
}

/* ---- reduced motion: no transitions/pulse/reveal; states still resolve ---- */
@media (prefers-reduced-motion: reduce) {
  .bm-muscle { transition: none; }
  .bm-muscle.is-selected { animation: none; filter: drop-shadow(0 0 3px var(--bm-sel)); }
  .bm-stage { transition: none; }
  .bm-stage.bm-out, .bm-stage.bm-in { opacity: 1; transform: none; }
  .bm-stage.bm-enter { animation: none; }
}

/* ---- picker wiring: the DISPLAY-ONLY figure is a compact companion ABOVE the
   exercise list. It must never crowd the list out — keep it short so the
   exercises stay the immediate, primary action on a phone. ---- */
.picker-figure { margin-bottom: var(--s-3); }
.picker-figure .bm-stage { height: min(26vh, 188px); }
.picker-content { display: block; }
