/* styles.css — Chemulator (Atomic Emission Spectra + Acid-Base Titration)
 * Lavender + Willow. design-system.css is linked first and owns every colour,
 * type, shape, shadow and motion token; this file only maps components onto them.
 *
 * Deliberate exceptions, defined as named tokens below and never recoloured to
 * lavender/willow because the colour IS the information:
 *   - emission-line / wavelength colours (computed in chemistry.js from the wavelength)
 *   - flame / gas-tube glow, incandescent bulb, EM-spectrum band colours
 *   - indicator colour changes (INDICATORS in titration.html) and the pH-curve series
 * Roles: lavender = interactive/primary, willow = positive/correct.
 * ONE saturated chrome element per view: Run (titration); the power switch when on (emission).
 */

/* =============================================================
   app tokens (physical / data colours + a few role aliases)
   ============================================================= */
:root {
  /* the spectrometer "dark room": near-black in BOTH themes, so spectral
     colours keep their meaning and their contrast */
  --stage:        #0e0a18;
  --stage-deep:   #07050d;
  --stage-line:   rgba(255, 255, 255, .42);
  --stage-fill:   rgba(255, 255, 255, .05);
  --stage-ink:    var(--lav-50);     /* 16:1 on --stage */
  --stage-muted:  var(--lav-200);    /* 10:1 on --stage */
  --stage-hardware: #8c849f;
  --stage-lens-fill: rgba(199, 173, 255, .16);
  --stage-lens-line: rgba(199, 173, 255, .6);
  --stage-screen: #f5f2fb;
  --stage-focus:  var(--lav-200);
  --stage-chip:      var(--lav-50);
  --stage-chip-ink:  var(--lav-700);   /* 10.6:1 */
  --stage-chip-on:   #ffffff;
  --stage-chip-on-ink: #1c1725;      /* dark in BOTH themes: the chip is white, and --ink turns light in dark mode */

  /* physical: incandescent source */
  --glow-white-halo: #fff3d0;
  --glow-white-core: #fffaf0;
  --glow-white-ray:  #fff6de;
  --bulb-on: #fffef2;
  --bulb-off: #3a3a30;
  --filament-on: #d9a441;
  --filament-off: #555555;

  /* atom diagram */
  --electron: #ffffff;
  --proton: #c0392b;
  --proton-ink: #ffffff;
  --photon-glow: rgba(46, 27, 82, .22);

  /* EM spectrum bar */
  --em-visible-gradient: linear-gradient(90deg, #6d4bb0, #4f63c4, #2f9e6f, #d99a2b, #d13b52);
  --band-label-bg: rgba(5, 5, 5, .62);
  --band-label-ink: #ffffff;

  /* source tiles */
  --tile-hover: var(--lav-100);

  /* titration: pH-curve series, calc-point markers, glassware */
  --series-curve: #0e5f7d;
  --series-eqline: rgba(184, 114, 31, .9);
  --m-init: #67e1ff; --m-half: #c9b8ff; --m-eq: #ffd36b; --m-three: #c9d1cc; --m-vmax: #ff9fb6; --m-now: var(--primary);
  --chart-axis: var(--muted);
  --chart-cur: var(--primary);
  --chart-band: rgba(145, 109, 213, .18);
  --chart-band-text: var(--primary-soft-ink);
  --chart-hover: var(--faint);
  --chart-tipbg: var(--ink);
  --chart-tiptx: var(--bg);
  --chart-beyond: rgba(46, 27, 82, .07);
  --glass: var(--ink-2);
  --water: #cfe6f7;
  --water-drop: #9ccaf0;
  --clamp: var(--line-strong);

  color-scheme: light;
}

[data-theme="dark"] {
  --tile-hover: #3d3157;
  --photon-glow: rgba(235, 224, 255, .35);
  --series-curve: #67e1ff;
  --series-eqline: rgba(240, 194, 116, .9);
  --m-init: #2bb8d9; --m-half: #8e78e0; --m-eq: #e8b23d; --m-three: #5f7284; --m-vmax: #e0708f; --m-now: var(--primary);
  --chart-band: rgba(172, 139, 238, .24);
  --chart-beyond: rgba(235, 224, 255, .07);
  --water: #2d6288;
  --water-drop: #5db0e6;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --tile-hover: #3d3157;
    --photon-glow: rgba(235, 224, 255, .35);
    --series-curve: #67e1ff;
    --series-eqline: rgba(240, 194, 116, .9);
    --m-init: #2bb8d9; --m-half: #8e78e0; --m-eq: #e8b23d; --m-three: #5f7284; --m-vmax: #e0708f; --m-now: var(--primary);
    --chart-band: rgba(172, 139, 238, .24);
    --chart-beyond: rgba(235, 224, 255, .07);
    --water: #2d6288;
    --water-drop: #5db0e6;
    color-scheme: dark;
  }
}

/* =============================================================
   base
   ============================================================= */


sub, sup { line-height: 0; }


/* ---------------- page frame, navigation, header ---------------- */
.page {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--sp-5) var(--sp-4) var(--sp-7);
}

.top-links { padding-right: 60px; }   /* keep the fixed theme toggle clear of the links */

.page-header { margin-bottom: var(--sp-5); }


h1 { margin: var(--sp-1) 0 var(--sp-3); }
h2 { margin: 0 0 var(--sp-2); }

.subtitle {
  font: var(--t-body);
  color: var(--muted);
  max-width: var(--measure);
  margin: 0;
}

/* ---------------- panels ---------------- */
.card { margin-bottom: var(--sp-5); }
.card-note {
  color: var(--muted);
  margin: 0 0 var(--sp-4);
  max-width: var(--measure);
}

/* ---------------- buttons ---------------- */
/* secondary: ghost pill */
.em-toggle-btn {
  font: var(--t-small);
  font-weight: var(--w-semi);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 10px 20px;
  min-height: 44px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--primary-soft-ink);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.em-toggle-btn:hover { background: var(--bg-tint); }
.em-toggle-btn:active { transform: translateY(1px); }

/* open state of "compare to the full EM spectrum" */
.em-toggle-btn.active {
  background: var(--primary-soft);
  border-color: var(--primary);
  color: var(--primary-soft-ink);
}

/* ---------------- source tiles ---------------- */
/* Base layout is static and fully readable (touch, narrow phones, reduced motion):
   front and back faces both visible, no flip. Flip mode needs real hover, a
   motion-OK user and >= 561px. */
.sig-card {
  --sig-scale: 1.12;
  --sig-dur: var(--dur-slow);
  position: relative;
  z-index: 0;
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-width: 0;
  padding: var(--sp-3) var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background-color: var(--primary-soft);
  color: var(--primary-soft-ink);
  font: inherit;
  text-align: center;
  cursor: pointer;
  box-shadow: var(--shadow-1);
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur-slow) var(--ease);
}
.sig-front,
.sig-back {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
}
.sig-front { gap: 3px; font-weight: var(--w-semi); }
.sig-back { gap: 7px; }

.tile-symbol {
  font: var(--t-display);
  font-size: 2.1rem;
  line-height: 1;
  letter-spacing: 0;
}
.tile-name {
  font: var(--t-small);
  font-weight: var(--w-semi);
  line-height: 1.2;
}
.tile-spectrum {
  position: relative;
  display: block;
  width: 100%;
  height: 22px;
  border-radius: 6px;
  background: var(--stage-deep);
  overflow: hidden;
  flex: none;
}
.tile-spectrum i {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 3px;
  margin-left: -1.5px;
}
.tile-spectrum-rainbow {
  position: absolute;
  inset: 3px;
  border-radius: 3px;
}
.tile-lines {
  font: var(--t-mono);
  font-size: 0.75rem;
  white-space: pre-line;
}

.sig-card:hover { background-color: var(--tile-hover); border-color: var(--line-strong); box-shadow: var(--shadow-2); }
.sig-card:focus-visible {
  z-index: 5;
  background-color: var(--tile-hover);
  box-shadow: var(--focus-ring), var(--shadow-2);
}
.sig-card.active {
  z-index: 2;
  background-color: var(--tile-hover);
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary), var(--shadow-2);
}
.sig-card.active:focus-visible { box-shadow: 0 0 0 2px var(--primary), var(--focus-ring), var(--shadow-2); }
@media (prefers-reduced-motion: no-preference) {
  .sig-card:active { transform: scale(.97); transition-duration: var(--dur-fast); }
}

/* flip mode */
@media (hover: hover) and (min-width: 561px) and (prefers-reduced-motion: no-preference) {
  .sig-card {
    aspect-ratio: 3 / 4;
    display: grid;
    grid-template-rows: 1fr 0fr;
    gap: 0;
    padding: 0;
    overflow: hidden;
    transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease),
                box-shadow var(--dur) var(--ease), grid-template-rows var(--sig-dur) var(--ease),
                transform var(--sig-dur) var(--ease), z-index 0s linear var(--sig-dur);
  }
  .sig-front,
  .sig-back {
    min-height: 0;
    overflow: hidden;
    padding-inline: var(--sp-2);
    border-radius: var(--r-md);
    transition: opacity var(--sig-dur) var(--ease), transform var(--sig-dur) var(--ease), padding var(--sig-dur) var(--ease);
  }
  .sig-front { opacity: 1; }
  .sig-back { opacity: 0; padding-block: 0; transform: rotate(90deg) scale(-1); }
  .sig-card:hover,
  .sig-card:focus-visible {
    grid-template-rows: 0fr 1fr;
    transform: scale(var(--sig-scale));
    z-index: 5;
    transition-delay: 0s, 0s, 0s, 0s, 0s, 0s;
  }
  .sig-card:hover .sig-front,
  .sig-card:focus-visible .sig-front { opacity: 0; }
  .sig-card:hover .sig-back,
  .sig-card:focus-visible .sig-back { opacity: 1; padding-block: var(--sp-2); transform: rotate(0deg) scale(1); }
}

.source-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-2) var(--sp-5);
  margin: 0 0 var(--sp-1);
}
.source-chip { position: relative; }

/* ---------------- power switch ---------------- */
.power-row { margin-bottom: var(--sp-2); }

.light-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  cursor: pointer;
  user-select: none;
  min-height: 44px;
}
.light-switch input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.light-switch-track {
  position: relative;
  display: inline-block;
  width: 58px;
  height: 32px;
  border-radius: var(--r-pill);
  background: var(--card-2);
  border: 2px solid var(--muted);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  flex: none;
}
.light-switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--muted);
  transition: transform var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
/* on = positive: willow */
.light-switch input:checked + .light-switch-track {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.light-switch input:checked + .light-switch-track .light-switch-knob {
  transform: translateX(26px);
  background: var(--accent);
}
.light-switch input:focus-visible + .light-switch-track {
  outline: 2px solid var(--primary);
  outline-offset: 3px;
  box-shadow: var(--focus-ring);
}
.light-switch-label {
  font: var(--t-body-strong);
  color: var(--ink);
  min-width: 80px;
}

/* ---------------- headline ---------------- */
.headline {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin: var(--sp-4) 0 var(--sp-2);
}
.headline-symbol {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 64px;
  height: 64px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-md);
  background: var(--primary-soft);
  color: var(--primary-soft-ink);
  font: var(--t-display);
  line-height: 1;
}
.headline-name { font: var(--t-h2); color: var(--ink-2); }
.headline-description {
  color: var(--muted);
  max-width: var(--measure);
  margin: 0;
}

/* ---------------- apparatus ---------------- */
.apparatus-wrap {
  position: relative;
  display: grid;
  border-radius: var(--r-md);
  /* a ring (not a border) so the JS height maths for the zoom transition stays exact */
  box-shadow: 0 0 0 1px var(--line-strong), var(--shadow-2);
  overflow: hidden;
  background: var(--stage);
}
.stage-svg {
  grid-area: 1 / 1;
  display: block;
  width: 100%;
  height: 100%;
}
.result-svg {
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-slow) var(--ease);
}
.result-svg.visible { opacity: 1; pointer-events: auto; }

.stage-hint { color: var(--muted); margin: var(--sp-4) 0 0; }

/* ---------------- wavelength buttons (inside the SVG screen: dark in both themes) ---------------- */
.wavelength-btn {
  display: block;
  width: calc(100% - 6px);
  height: calc(100% - 6px);
  margin: 3px;
  padding: 0;
  border: none;
  border-radius: var(--r-sm);
  background: var(--stage-chip);
  color: var(--stage-chip-ink);
  font: var(--w-semi) 14px/1 var(--font-mono);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.wavelength-btn:hover { background: var(--lav-100); }
.wavelength-btn.active {
  background: var(--stage-chip-on);
  color: var(--stage-chip-on-ink);
  box-shadow: inset 0 0 0 3px var(--lav-400);
}
.wavelength-btn:focus-visible {
  outline: 3px solid var(--stage-focus);
  outline-offset: -3px;
  box-shadow: none;
}
.wavelength-btn--static {
  background: #2d2540;
  color: var(--stage-ink);
  box-shadow: inset 0 0 0 1px var(--stage-line);
  cursor: default;
}
.wavelength-btn--static:hover { background: #2d2540; color: var(--stage-ink); }

.line-table-empty { color: var(--muted); margin: var(--sp-3) 0 0; }
.disclaimer { font: var(--t-small); color: var(--muted); margin: var(--sp-3) 0 0; }

/* ---------------- result controls: EM spectrum comparison ---------------- */
.result-controls { margin-top: var(--sp-4); }

.em-reveal-wrap {
  position: relative;
  display: none;
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.em-reveal-wrap.phase-visible { display: block; }
.em-reveal-wrap.phase-visible.animate-in { animation: riseFromBehind var(--dur-slow) var(--ease) backwards; }
@keyframes riseFromBehind {
  0% { opacity: 0; transform: translateY(24px) scale(.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.em-bar-wrap { border-radius: var(--r-sm); box-shadow: var(--shadow-1); }
.em-bar {
  position: relative;
  height: 44px;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--stage-deep);
}
.em-band {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.em-band-label {
  font: var(--t-label);
  letter-spacing: .02em;
  color: var(--band-label-ink);
  white-space: nowrap;
  padding: 1px 7px;
  border-radius: var(--r-pill);
  background: var(--band-label-bg);
}
.em-line-strip {
  position: relative;
  width: 100%;
  height: 36px;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--stage-deep);
  border: 1px solid var(--line-strong);
}
.em-marker { position: absolute; top: 0; bottom: 0; width: 3px; transform: translateX(-1.5px); }
.em-marker-band { position: absolute; top: 0; bottom: 0; opacity: .9; }
/* hydrogen: the other series sit faint behind; a series nothing is showing is an empty outline */
.em-marker--faint { width: 2px; opacity: .42; transform: translateX(-1px); }
.em-marker--hollow {
  width: 5px;
  box-sizing: border-box;
  background: transparent;
  border: 1.5px solid var(--stage-muted);
  border-radius: 2px;
  transform: translateX(-2.5px);
}
.em-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 2px var(--sp-4);
  margin-top: var(--sp-2);
  font: var(--t-label);
  color: var(--muted);
}
.em-legend[hidden] { display: none; }
.em-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.em-legend-item.is-current { color: var(--ink); font-weight: var(--w-semi); }
.em-dot {
  width: 10px;
  height: 10px;
  flex: none;
  box-sizing: border-box;
  border-radius: 50%;
  border: 1.5px solid var(--muted);
  background: transparent;
}
.em-dot--visible { border-color: transparent; background: var(--em-visible-gradient); }

.em-strip-label { font: var(--t-small); font-weight: var(--w-semi); color: var(--muted); margin: 0 0 var(--sp-2); }
#em-line-strip-label { margin-top: var(--sp-4); }
.em-axis-labels {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 10px;
  margin-top: 6px;
  font: var(--t-label);
  color: var(--muted);
}

/* ---------------- transition panel ---------------- */
.transition-panel[hidden] { display: none; }
.transition-panel {
  margin-top: var(--sp-4);
  padding: var(--sp-4);
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.transition-panel.appear { animation: cardAppear var(--dur-slow) var(--ease) backwards; }
@keyframes cardAppear {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
.transition-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-3);
}
.transition-panel-title { font: var(--t-quantity); color: var(--ink-2); margin: 0; }

/* segmented control */
.view-mode-toggle {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--card);
  overflow: hidden;
}
.view-mode-btn {
  font: var(--t-small);
  font-weight: var(--w-semi);
  padding: 8px 14px;
  min-height: 40px;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.view-mode-btn + .view-mode-btn { border-left: 1px solid var(--line); }
.view-mode-btn:hover { color: var(--ink); background: var(--bg-tint); }
.view-mode-btn.active { background: var(--primary-soft); color: var(--primary-soft-ink); }
.view-mode-btn:focus-visible { outline-offset: -3px; }

.transition-svg { display: block; width: 100%; height: auto; }
.transition-svg[hidden] { display: none; }
.transition-caption { color: var(--muted); margin: var(--sp-3) 0 0; max-width: 62ch; }

/* diagram ink: follows the theme (spectral colours of electrons/photons never do) */
.svg-note, .svg-ev { fill: var(--muted); }
.svg-n { fill: var(--ink); }
.lvl-line { stroke: var(--line-strong); }
.lvl-line--landing, .atom-orbit--landing { stroke: var(--primary); }
.atom-orbit { fill: none; stroke: var(--line-strong); transition: stroke var(--dur) var(--ease); }

.electron-vibrate {
  animation: electronVibrate 450ms ease-in-out;
  transform-box: fill-box;
  transform-origin: center;
}
@keyframes electronVibrate {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}
.photon-squiggle { filter: drop-shadow(0 0 3px var(--photon-glow)); }
/* UV / IR photons have no colour to the eye: a dashed grey wave, no glow */
.photon-squiggle--invisible { filter: none; }
.photon-tag { letter-spacing: .08em; }
.lvl-line--limit { stroke: var(--faint); }

/* the magnifier that makes Lyman's tiny landing orbit readable */
.lens-glass { fill: var(--card); }
.lens-rim { fill: none; stroke: var(--primary); stroke-width: 2; }
.lens-link { fill: none; stroke: var(--primary); stroke-width: 1.2; stroke-dasharray: 4 4; opacity: .6; }
.lens-zoom { fill: var(--primary-soft-ink); font-weight: var(--w-semi); }

/* ---------------- footer ---------------- */
.page-footer {
  text-align: center;
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}
.page-footer p { margin: 0 auto; color: var(--muted); font: var(--t-small); }

/* ---------------- narrow screens ---------------- */
@media (max-width: 600px) {
  .page { padding: var(--sp-4) var(--sp-4) var(--sp-7); }
  .card { padding: var(--sp-4); }
  .source-picker { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: var(--sp-3) var(--sp-2); padding: var(--sp-2) var(--sp-1) var(--sp-4); }
  /* the SVG screen is ~1/3 scale here, so lift the label text to stay readable */
  .wavelength-btn { font-size: 20px; }
  /* the bar is too narrow for in-band names here; the axis row below names every band */
  .em-band-label { display: none; }
  .headline-symbol { min-width: 56px; height: 56px; font-size: 1.7rem; }
}

/* =============================================================
   EMISSION PAGE  (body.emission) — sidebar + three persistent cards
   Desktop (>= 960px): left "Light source" panel is 100dvh and static;
   the right column is the only scroller. Below 960px: one column and
   the Light source panel becomes a compact sticky bar.
   ============================================================= */
body.emission .page {
  max-width: none;
  margin: 0;
  padding: 0 0 var(--sp-6);
}
body.emission .card { margin: 0; }

/* ---- Light source panel (shared) ---- */
.emission .source-panel { padding: var(--sp-4); }
.emission .source-panel h2 { font: var(--t-h2); margin: 0; }
.emission .source-picker {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
  padding: var(--sp-1);
  margin: 0;
}
.emission .source-chip-white { grid-column: 1 / -1; }
.emission .power-row { margin: 0; }
.emission .headline { margin: 0; gap: var(--sp-3); }
.emission .headline-symbol { min-width: 48px; height: 48px; padding: 0 var(--sp-3); font-size: 1.5rem; }
.emission .headline-name { font: var(--t-h3); }
.emission .headline-description { margin: 0; max-width: none; }

/* compact tiles: always static (no 3:4 flip); line wavelengths are in each tile's title */
body.emission .sig-card {
  aspect-ratio: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: clamp(4px, 1vh, 10px) var(--sp-1);
  overflow: hidden;
}
body.emission .sig-card:hover,
body.emission .sig-card:focus-visible { transform: none; grid-template-rows: none; }
body.emission .sig-front,
body.emission .sig-back,
body.emission .sig-card:hover .sig-front,
body.emission .sig-card:hover .sig-back,
body.emission .sig-card:focus-visible .sig-front,
body.emission .sig-card:focus-visible .sig-back {
  opacity: 1;
  transform: none;
  padding: 0;
  overflow: visible;
}
body.emission .sig-back { gap: 0; }
body.emission .tile-symbol { font-size: 1.5rem; }
body.emission .tile-name { font-size: var(--fs-small); }
body.emission .tile-lines { display: none; }
body.emission .tile-spectrum { height: 12px; border-radius: 4px; }
body.emission .tile-spectrum i { width: 2px; margin-left: -1px; }
body.emission .tile-spectrum-rainbow { inset: 2px; }

/* ---- header (top of the right column) ---- */
.emission .workspace-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-5);
  padding-right: 56px;                /* clear of the fixed theme toggle */
}
.emission .top-links { margin: 0; padding: 0; order: 2; gap: 0 var(--sp-4); }
.emission .home-link { padding: 0; font-size: var(--fs-small); }
.emission .page-header { display: flex; align-items: center; gap: var(--sp-3); margin: 0; min-width: 0; order: 1; }
.emission .brand-mark { margin: 0; }
.emission .brand-mark img { height: 36px; }
.emission h1 { font: var(--t-h1); margin: 0; }
.emission .subtitle { font: var(--t-small); max-width: 70ch; }

/* ---- cards in the workspace ----
   Stacked (phones, short tablets): setup, spectrum, transition one under the other.
   "Fit" mode (>= 960px wide, or a tall tablet >= 700px x 900px): nothing scrolls; the board is a
   grid: Experimental setup over Transition diagram in the wide column, the Line spectrum as one
   tall narrow column beside both. */
.emission .board { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.emission .panel { position: relative; display: flex; flex-direction: column; padding: var(--sp-4); min-width: 0; }
.emission .panel h2 { font: var(--t-h2); margin: 0 0 var(--sp-2); flex: none; }
.emission .panel-body { position: relative; flex: 1 1 auto; min-height: 0; }
.emission .panel-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 1 1 auto;
  min-height: 72px;
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  max-width: none;
  color: var(--muted);
  background: var(--card-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
}
.emission .panel-empty[hidden] { display: none; }
.emission .panel[hidden] { display: none; }
.emission .stage-hint { margin: var(--sp-2) 0 0; flex: none; }
.emission .stage-hint:empty { display: none; }

.emission .apparatus-wrap { height: 100%; }
.emission .stage-svg { min-height: 0; }
.emission .panel--setup .panel-body { min-height: 0; }
.emission .panel--setup .apparatus-wrap,
.emission .panel--setup .stage-svg { height: auto; }
.emission .card-note { margin: 0 0 var(--sp-2); font: var(--t-small); max-width: none; }

/* Line spectrum: the strip is a dark stage that fills the column; the SVG is drawn to its exact
   pixel size (app.js), wavelength running top (short) to bottom (long). */
.emission .spectrum-body { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; gap: var(--sp-2); }
.emission .spectrum-body[hidden] { display: none; }
.emission .result-wrap { flex: none; height: min(440px, 62vh); min-height: 0; }
.emission .result-wrap .stage-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.emission .result-controls { margin: 0; flex: none; }
.emission .em-toggle-btn {
  width: 100%;
  justify-content: center;
  text-align: center;
  line-height: 1.25;
  padding: 6px var(--sp-3);
  border-radius: var(--r-md);
}

.emission .transition-panel {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}
.emission .transition-panel[hidden] { display: none; }
.emission .transition-panel-header { margin-bottom: var(--sp-1); flex: none; display: block; }
.emission .transition-panel-title { font-size: var(--fs-small); }
.emission .transition-stage { position: relative; flex: 1 1 auto; min-width: 0; height: clamp(260px, 56vw, 340px); }
.emission .transition-stage .transition-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.emission .transition-stage .transition-svg[hidden] { display: none; }
.emission .transition-caption { margin: var(--sp-2) 0 0; flex: none; max-width: none; font-size: var(--fs-small); }
.wavelength-btn { font-size: 13px; white-space: nowrap; }

/* ---- hydrogen series control + the viewer tray (Experimental setup card) ---- */
.emission .setup-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-1) var(--sp-4);
  margin: 0 0 var(--sp-2);
  flex: none;
}
.emission .setup-head h2 { margin: 0; }
.emission .series-toggle[hidden] { display: none; }
.emission .series-toggle { max-width: 100%; gap: 2px; padding: 2px; }
.emission .series-toggle > button {
  font: var(--t-small);
  font-weight: var(--w-semi);
  min-height: 32px;
  padding: 2px 10px;
  white-space: nowrap;
}

/* the tray is the bottom row of the dark stage: the plates come up out of it */
.emission #apparatus-wrap { grid-template-rows: minmax(0, 1fr) auto; }
.emission .viewer-tray {
  grid-area: 2 / 1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
  padding: var(--sp-2) var(--sp-3) var(--sp-3);
}
.emission .viewer-tray[hidden] { display: none; }
.emission .tray-hint {
  flex: 1 1 150px;
  min-width: 0;
  margin: 0;
  font: var(--t-small);
  color: var(--stage-ink);
}
.emission .tray-hint:empty { display: none; }
.emission .tray-slots { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-left: auto; }

.tray-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 36px;
  padding: 2px var(--sp-4) 2px var(--sp-3);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--stage-chip);
  color: var(--stage-chip-ink);
  font: var(--t-small);
  font-weight: var(--w-semi);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tray-btn:hover { background: var(--lav-100); }
.tray-btn[aria-pressed="true"] {
  background: var(--stage-chip-on);
  color: var(--stage-chip-on-ink);
  box-shadow: inset 0 0 0 3px var(--lav-400);
}
.tray-btn:focus-visible { outline: 3px solid var(--stage-focus); outline-offset: 2px; box-shadow: none; }
.plate-icon { width: 14px; height: 23px; flex: none; fill: currentColor; stroke: none; }
.plate-icon-slab { stroke: currentColor; stroke-width: 1.3; }
/* the plate has left its slot: only the outline of it is left in the tray */
.tray-btn.is-out .plate-icon-slab { fill: none !important; stroke-dasharray: 2 2; }

/* the way to add the plate, inside the dark Line spectrum strip */
.add-viewer-btn {
  position: relative;
  display: block;
  width: calc(100% - 12px);
  height: calc(100% - 12px);
  margin: 6px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--stage-chip);
  color: var(--stage-chip-ink);
  font: var(--w-semi) 14px/1.2 var(--font-body);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease);
}
.add-viewer-btn:hover { background: var(--lav-100); }
.add-viewer-btn:focus-visible { outline: 3px solid var(--stage-focus); outline-offset: 2px; box-shadow: none; }
.add-viewer-btn::after {
  content: "";
  position: absolute;
  inset: -4px;
  border: 2px solid var(--glow, var(--lav-200));
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
  animation: ctaRing 2.4s var(--ease) infinite;
}
@keyframes ctaRing {
  0% { opacity: .9; transform: scale(.96); }
  70%, 100% { opacity: 0; transform: scale(1.1); }
}

/* ---- the EM comparison dialog (native <dialog>; never scrolls: it is sized to its content) ---- */
dialog.pop {
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-3);
  width: min(92vw, 720px);
  max-width: none;
  max-height: 96dvh;
  overflow: visible;   /* the magnifier may reach beyond the card; nothing inside ever scrolls */
}
dialog.pop[open] { display: flex; flex-direction: column; animation: riseFromBehind var(--dur-slow) var(--ease) backwards; }
dialog.pop::backdrop { background: var(--overlay); }
.pop-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5) var(--sp-5); }
.pop-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.pop-title { font: var(--t-h2); letter-spacing: var(--tr-heading); color: var(--ink-2); margin: 0; }
.pop-close { width: var(--control-h); padding: 0; flex: none; }
.em-dialog .em-reveal-wrap { display: block; margin: 0; }

/* ---- wide screens: the cards beside the strip ---- */

/* ---- TABLET / MOBILE (stacked): the sticky source bar on top ---- */
@media (max-width: 959px) {
  .emission .source-panel {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-2) 72px var(--sp-2) var(--sp-3);
    border-width: 0 0 1px;
    border-radius: 0;
    box-shadow: var(--shadow-2);
  }
  .emission .source-panel h2,
  .emission .headline-description {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .emission .power-row { order: 1; }
  .emission .headline { order: 2; margin-left: auto; }
  .emission .source-picker {
    order: 3;
    flex: 1 1 100%;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: var(--sp-1);
    padding: 0;
  }
  .emission .source-chip-white { grid-column: auto; }
  .emission .tile-name { display: none; }
  .emission .headline-symbol { display: none; }
  .emission .transition-panel-header .view-mode-toggle { position: relative; margin: var(--sp-1) 0 var(--sp-2); }
  body.emission .sig-card { min-height: 44px; justify-content: center; padding: 4px 2px; }
  body.emission .tile-symbol { font-size: 1.25rem; }
  .emission .light-switch { min-height: 40px; }

  .emission .workspace { display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-3); }
  .emission .workspace-head { padding-right: 0; }
  .emission .transition-panel-header .view-mode-toggle { position: relative; }
}
@media (max-width: 959px) and (max-height: 700px) {
  .emission .subtitle { display: none; }
}

/* ---- FIT MODE: wide screens, and tall tablets in portrait. Nothing in here scrolls. ---- */
@media (min-width: 960px), (min-width: 700px) and (min-height: 900px) {
  .emission {
    --spec-w: clamp(206px, 17vw, 236px);
    --board-gap: clamp(8px, 1.4vh, 14px);
  }
  html:has(body.emission) { height: 100%; }
  body.emission { height: 100dvh; overflow: hidden; }
  body.emission .page { height: 100dvh; padding: 0; }

  .emission .workspace {
    height: 100%;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: var(--board-gap);
    padding: clamp(10px, 1.6vh, 20px) var(--sp-4);
  }
  .emission .workspace-head { flex: none; padding-right: 56px; }
  .emission .page-footer { flex: none; margin-top: 0; padding-top: 0; border-top: 0; }
  .emission .page-footer p { font-size: var(--fs-label); }
  .emission .card-note { display: none; }

  .emission .board {
    flex: 1 1 0;
    min-height: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--spec-w);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "setup spectrum" "transition spectrum";
    gap: var(--board-gap);
  }
  .emission .board.board--solo { grid-template-rows: minmax(0, 1fr); grid-template-areas: "setup spectrum"; }
  .emission .panel { min-height: 0; padding: var(--sp-3) var(--sp-4); }
  .emission .panel--setup { grid-area: setup; }
  .emission .panel--spectrum { grid-area: spectrum; padding: var(--sp-3); }
  .emission .panel--transition { grid-area: transition; }
  .emission .panel h2 { margin-bottom: var(--sp-1); }

  /* setup: content-sized beside the transition card; the whole column when it is alone */
  .emission .board--solo .panel--setup .panel-body { flex: 1 1 auto; }
  .emission .board--solo .panel--setup .apparatus-wrap { position: absolute; inset: 0; height: auto; }
  .emission .board--solo .panel--setup .stage-svg { height: 100%; }

  /* spectrum: the strip takes all the height that is left */
  .emission .result-wrap { flex: 1 1 auto; height: auto; }

  /* transition: diagram + text side by side */
  .emission .transition-panel .transition-stage { height: auto; flex: 1 1 auto; }
  .emission .transition-panel-header .view-mode-toggle { position: absolute; top: var(--sp-2); right: var(--sp-3); margin: 0; }
  body.emission .view-mode-toggle .view-mode-btn { min-height: 32px; padding: 4px 14px; font-size: var(--fs-small); }
  .emission .transition-panel-header { margin: 6px 0 0; }

  .emission .top-links { flex-direction: column; align-items: flex-end; gap: 0; }
  .emission .subtitle { max-width: 90ch; }
}
@media (min-width: 960px) {
  body.emission .page {
    display: grid;
    grid-template-columns: clamp(280px, 24vw, 340px) minmax(0, 1fr);
  }
  /* static, full-height, not scrollable */
  .emission .source-panel {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100dvh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    gap: clamp(8px, 1.8vh, 18px);
    padding: clamp(12px, 2.4vh, 24px) var(--sp-4);
    border-width: 0 1px 0 0;
    border-radius: 0;
  }
  .emission .source-panel .headline-description { font: var(--t-body); line-height: 1.45; }
  .emission .workspace { padding-left: var(--sp-4); padding-right: var(--sp-4); }

  .emission .transition-panel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) clamp(170px, 40%, 250px);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "stage head" "stage cap";
    column-gap: var(--sp-4);
  }
  .emission .transition-panel-header { grid-area: head; }
  .emission .transition-stage { grid-area: stage; }
  .emission .transition-caption { grid-area: cap; align-self: start; margin-top: var(--sp-1); font-size: 0.8125rem; line-height: 1.45; }
  .emission .transition-panel-title { font-size: var(--fs-small); font-weight: var(--w-semi); color: var(--ink); line-height: 1.4; }
}
/* narrow laptops: a tighter series control and caption so the cards keep their height */
@media (min-width: 960px) and (max-width: 1180px) {
  .emission .series-toggle > button { font-size: 0.75rem; padding: 2px 7px; min-height: 30px; }
  .emission .transition-caption { font-size: 0.75rem; line-height: 1.4; }
  .emission .transition-panel-title { font-size: 0.8125rem; }
}
@media (min-width: 960px) and (min-height: 800px) { .emission .page-footer { display: block; } }
@media (min-width: 960px) and (max-height: 799px) { .emission .page-footer { display: none; } }
/* short windows: drop the long intro lines */
@media (min-width: 960px) and (max-height: 960px) {
  .emission .subtitle { display: none; }
}
/* last resort: below ~560px of height the page cannot be made to fit, so the workspace scrolls */
@media (min-width: 960px) and (max-height: 559px) {
  .emission .source-panel { overflow-y: auto; }
  .emission .workspace { overflow-y: auto; }
  .emission .board { flex: none; min-height: 420px; }
}
/* tall tablet, portrait: the source bar sits on top (not sticky: nothing scrolls), the board fills the rest */
@media (min-width: 700px) and (max-width: 959px) and (min-height: 900px) {
  body.emission .page { display: flex; flex-direction: column; }
  .emission .source-panel { flex: none; position: relative; }
  .emission .workspace { flex: 1 1 0; }
  .emission .top-links { flex-direction: row; align-items: center; gap: 0 var(--sp-4); }
  .emission .transition-panel { display: flex; flex-direction: column; }
  .emission .transition-caption { font-size: var(--fs-small); }
}


/* =============================================================
   TITRATION  (body.tit) — a dashboard that fits the window exactly: nothing scrolls.
   Normal view : header / [ titration | curve ] / calculation bar (compact)
   Calculation : header / [ curve | calculation ]   (body.calcview; the titration view is display:none)
   ============================================================= */
html:has(.tit) { height: 100%; overflow: hidden; }
.tit {
  height: 100%;
  overflow: hidden;
  --control-h: clamp(32px, 4.8vh, 40px);   /* laptop-sized controls; the page has to fit */
  --gap: clamp(8px, 1.4vh, 12px);
}
.tit .page {
  max-width: none;
  margin: 0;
  height: 100vh; height: 100dvh;
  min-height: 0;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: var(--gap);
  padding: clamp(8px, 1.4vh, 14px) var(--sp-4);
  overflow: hidden;
}
.tit .card { margin: 0; padding: 0; border-radius: var(--r-lg); min-width: 0; }
.tit .theme-toggle { top: var(--sp-2); right: var(--sp-3); }

/* ---------- header ---------- */
.tit .top {
  padding: clamp(6px, 1vh, 10px) var(--sp-4);
  margin-right: 44px;      /* reserves the corner for the fixed theme toggle */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px var(--sp-5);
  align-items: center;
}
.tit .brand { min-width: 0; display: flex; align-items: center; gap: var(--sp-3); }
.tit .brand-mark { margin: 0; flex: none; display: flex; }
.tit .brand-mark img { height: 34px; width: auto; }
.tit .brand-text { min-width: 0; }
.tit .eyebrow { display: block; line-height: 1.2; }
.tit .brand h1 { font: var(--t-h1); font-size: clamp(1.125rem, .9rem + .8vw, 1.5rem); letter-spacing: var(--tr-heading); margin: 0; color: var(--lav-700); white-space: nowrap; }
[data-theme="dark"] .tit .brand h1 { color: var(--ink); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .tit .brand h1 { color: var(--ink); } }
.tit .top-links { flex-direction: column; flex-wrap: nowrap; padding: 0; margin: 0 0 0 var(--sp-2); gap: 0; }
.tit .home-link { padding: 0; font: var(--t-small); font-weight: var(--w-semi); white-space: nowrap; }

.tit .ctrls { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tit .ctrl-row { display: flex; flex-wrap: wrap; gap: 4px var(--sp-5); align-items: center; }
.tit .grp { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.tit .ctl { display: flex; align-items: center; gap: 6px; font: var(--t-small); }
.tit .ctl label { font: var(--t-small); font-weight: var(--w-semi); white-space: nowrap; color: var(--ink-2); }
.tit .ctl select,
.tit .ctl input[type=number] {
  font: var(--t-small);
  padding: 3px 8px;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.tit .ctl select option,
.tit .ctl select optgroup { background: var(--card); color: var(--ink); }
.tit .ctl select:focus-visible,
.tit .ctl input[type=number]:focus-visible { outline: none; border-color: var(--primary); box-shadow: var(--focus-ring); }
.tit .ctl input[type=number] { width: 68px; }
.tit .ctl input[type=range],
.tit .vol-slider { accent-color: var(--primary); }
.tit .ctl input[type=range] { width: 76px; }
.tit .info { display: flex; flex-wrap: wrap; gap: 0 var(--sp-5); font: var(--t-small); line-height: 1.4; color: var(--muted); }
.tit .info b { color: var(--ink); font-weight: var(--w-semi); }
.tit .warn {
  grid-column: 1 / -1;
  background: var(--warn-soft);
  color: var(--warn-ink);
  border-left: 3px solid var(--warn);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  padding: 3px var(--sp-3);
  font: var(--t-small);
  display: none;
}

/* ---------- stage: three cards, two arrangements ---------- */
.tit .stage {
  min-height: 0;
  display: grid;
  gap: var(--gap);
  grid-template-columns: clamp(236px, 20vw, 290px) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas: "sim curve" "calc calc";
}
.tit .sim { grid-area: sim; padding: 6px; min-height: 0; }
.tit .chartcard { grid-area: curve; }
.tit .calccard { grid-area: calc; }
.tit.calcview .stage {
  grid-template-columns: minmax(280px, 33%) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  grid-template-areas: "curve calc";
}
.tit.calcview .sim { display: none; }
@media (max-width: 959px) {
  .tit.calcview .stage {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 40%) minmax(0, 1fr);
    grid-template-areas: "curve" "calc";
  }
}

/* the browser morphs the cards between the two arrangements (reduced motion: instant, no transition is started) */
.tit #simCard { view-transition-name: sim-card; }
.tit #curveCard { view-transition-name: curve-card; }
.tit #calcCard { view-transition-name: calc-card; }
::view-transition-group(*) { animation-duration: var(--dur-slow); animation-timing-function: var(--ease); }
::view-transition-old(root), ::view-transition-new(root) { animation: none; }

.tit .sim svg { width: 100%; height: 100%; display: block; }
.tit .sim .glass { stroke: var(--glass); }
.tit .sim .tk { fill: var(--glass); stroke: none; }
.tit .sim .liq { fill: var(--water); }
.tit .sim .clamp { fill: var(--clamp); }
.tit .sim .handle {
  fill: var(--muted);
  transform-box: fill-box; transform-origin: 0 50%;
  transition: transform var(--dur) var(--ease);
}
.tit .sim .handle.open { transform: rotate(90deg); }   /* tap turned in line with the flow */
.tit .sim .meniscus { fill: var(--card); }             /* cuts the concave top out of the burette liquid */
.tit .sim .surface { fill: var(--card); fill-opacity: .3; stroke: var(--glass); stroke-width: .8; }
.tit .sim .ripple { fill: none; stroke: var(--glass); stroke-width: 1; }
.tit .sim #flaskLiquid { transition: fill var(--dur) var(--ease-move); }
.tit .sim .drop { fill: var(--water-drop); stroke: var(--glass); stroke-width: .6; }
.tit .sim .lbl-ink { fill: var(--ink); }
.tit .sim .lbl-muted { fill: var(--muted); }

/* ---------- curve card ---------- */
.tit .clabel {
  margin: 0; flex: none;
  font: var(--t-label); letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.tit .chartcard { padding: 8px 12px; display: flex; flex-direction: column; gap: 6px; min-width: 0; min-height: 0; }
.tit .curve-head { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; flex: none; }
/* the reaction, large: the same style as the see-saw card of Chemical Equilibrium */
.tit .eqband {
  flex: 1 1 auto; min-width: 0; margin: 0; padding: 2px var(--sp-3); max-width: 100%;
  font: var(--w-display) clamp(1.0625rem, .82rem + .75vw, 1.5rem)/1.25 var(--font-display);
  letter-spacing: var(--tr-heading); text-align: center; color: var(--title);
  background: var(--primary-soft); border-radius: var(--r-md); overflow-wrap: anywhere;
}
.tit .eqband .eq-main { display: block; }
.tit .eqband .eq-alt {
  display: block; margin-top: 1px; font: var(--t-small); font-weight: var(--w-normal); letter-spacing: 0;
  color: var(--ink-2); line-height: 1.3;
}
.tit.calcview .cv-eq { display: none; }
.tit:not(.calcview) .calc-eq { display: none; }
.tit.calcview .curve-head .eqband { display: none; }
.tit .plot { position: relative; flex: 1 1 0; min-height: 0; }
.tit #chart { position: absolute; inset: 0; width: 100%; height: 100%; cursor: crosshair; }
.tit .strip { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.tit .vol-slider { flex: 1; min-width: 140px; }
.tit.calcview .vol-slider { flex-basis: 100%; }
.tit .ro { font: var(--t-small); color: var(--muted); white-space: nowrap; }
.tit .ro strong { color: var(--ink); font: var(--t-quantity); font-size: var(--fs-small); }
.tit .btngrp { display: flex; flex-wrap: wrap; gap: 6px; }
.tit input[type=range]:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; box-shadow: none; }

/* buttons: ghost pills; Run is the one saturated element */
.tit .page button:not(.theme-toggle) {
  font: var(--t-small);
  font-weight: var(--w-semi);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 3px 12px;
  min-height: var(--control-h);
  border-radius: var(--r-pill);
  cursor: pointer;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--primary-soft-ink);
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.tit .page button:not(.theme-toggle):hover:not(:disabled) { background: var(--bg-tint); }
.tit .page button:not(.theme-toggle):active:not(:disabled) { transform: translateY(1px); }
.tit .page button:disabled { opacity: .5; cursor: not-allowed; }
.tit .page button.primary {
  background: var(--primary);
  border-color: transparent;
  color: var(--primary-ink);
  box-shadow: var(--shadow-1);
}
.tit .page button.primary:hover:not(:disabled) { background: var(--primary-hover); }

/* ---------- calculation card ---------- */
.tit .calccard { padding: 6px 12px; background: var(--card-2); display: flex; flex-direction: column; gap: var(--sp-2); min-height: 0; overflow: hidden; }
.tit:not(.calcview) .calccard { cursor: pointer; }
.tit .calc-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; flex: none; }
.tit .calc-head .clabel { order: 1; }
.tit .pills { order: 3; display: flex; flex-wrap: wrap; gap: 4px 8px; }
.tit #showCalc { order: 2; }
.tit .indgrp { order: 4; flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 2px var(--sp-4); min-width: 0; }
.tit .indgrp .ctl select { max-width: 250px; }
.tit .indgrp .note { flex: 1 1 260px; min-width: 0; font: var(--t-small); line-height: 1.4; color: var(--muted); }
.tit .indgrp .note b { color: var(--ink); font-weight: var(--w-semi); }
/* pills: soft pill + a leading edge in the point's own marker colour */
.tit .page .sig.chip {
  background: var(--primary-soft);
  color: var(--primary-soft-ink);
  border-color: var(--line-strong);
  border-left: 6px solid var(--mk, var(--m-init));
  padding-left: 10px;
}
.tit .page .chip[data-key="init"] { --mk: var(--m-init); }
.tit .page .chip[data-key="half"] { --mk: var(--m-half); }
.tit .page .chip[data-key="eq"]   { --mk: var(--m-eq); }
.tit .page .chip[data-key="vmax"] { --mk: var(--m-vmax); }
.tit .page .chip[data-key="now"]  { --mk: var(--m-now); font-variant-numeric: tabular-nums; }
.tit .page .sig.chip:hover:not(:disabled) { background: var(--tile-hover); }
.tit .page .sig.chip.active,
.tit .page #showCalc[aria-expanded="true"] {
  background: var(--tile-hover);
  border-color: var(--primary);
  color: var(--primary-soft-ink);
  box-shadow: 0 0 0 1px var(--primary);
}
.tit .page .sig.chip.active { border-left-color: var(--mk, var(--m-init)); }

.tit .calc-body { display: none; }
.tit.calcview .calc-body { display: flex; flex-direction: column; gap: var(--sp-2); flex: 1 1 0; min-height: 0; position: relative; }
.tit.calcview .calccard { padding: 10px 14px; }
.tit.calcview .calc-head { gap: 8px 10px; }
.tit.calcview .calc-head .clabel { flex: 1 1 auto; }
.tit.calcview #showCalc { order: 2; }
.tit.calcview .calc-eq { order: 3; flex: 1 1 100%; }
.tit.calcview .pills { order: 4; flex: 1 1 100%; }
.tit.calcview .indgrp { display: none; }

.tit .chead {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px var(--sp-4);
  border-left: 6px solid var(--m-init);
  padding-left: 10px;
}
.tit .chead h3 { margin: 0; font: var(--t-h2); font-size: 1.125rem; color: var(--ink-2); }
.tit .chead span { color: var(--muted); font: var(--t-small); }
.tit .chead .res { margin-left: auto; font: var(--t-quantity); font-size: 1.0625rem; color: var(--ink); }
.tit .chead .res small { font: var(--t-small); color: var(--muted); }
.tit .wpage { flex: 1 1 0; min-height: 0; overflow: hidden; }
.tit .wcols { display: grid; gap: 12px; align-items: start; }
.tit .wcol { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.tit .pager { flex: none; display: flex; align-items: center; justify-content: center; gap: var(--sp-4); }
.tit .pgnum { font: var(--t-small); color: var(--muted); min-width: 7em; text-align: center; }
.tit .wmeasure { position: absolute; left: 0; top: 0; visibility: hidden; pointer-events: none; display: flex; flex-direction: column; gap: 12px; }

.tit .wstep {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-1);
  padding: var(--sp-2) var(--sp-3);
  min-width: 0;
}
.tit .wstep h4 { margin: 0 0 4px; font: var(--t-h3); font-size: max(11px, calc(1rem * var(--wk, 1))); color: var(--ink-2); display: flex; align-items: center; gap: var(--sp-2); }
.tit .wstep h4 span {
  background: var(--primary-soft);
  color: var(--primary-soft-ink);
  width: 24px;
  height: 24px;
  border-radius: var(--r-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: var(--t-label);
  letter-spacing: 0;
  flex: none;
}
/* the last step of every working is the pH result: willow = the answer */
.tit .wstep:last-child h4 span { background: var(--accent-soft); color: var(--accent-soft-ink); }
.tit .wstep p { margin: 3px 0; font: var(--t-body); font-size: max(11px, calc(clamp(.8125rem, .62rem + .45vw, .9375rem) * var(--wk, 1))); line-height: 1.4; max-width: none; overflow-wrap: anywhere; }
.tit .eqn { font-weight: var(--w-semi); }
.tit .warnflat { color: var(--warn-ink); background: var(--warn-soft); border-radius: var(--r-sm); padding: 2px 8px; }
.tit table.ice {
  border-collapse: separate;
  border-spacing: 0;
  margin: 4px 0;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
  font-variant-numeric: tabular-nums;
}
.tit table.ice th,
.tit table.ice td {
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 2px 6px;
  text-align: center;
  font: var(--t-small);
  font-size: max(11px, calc(.8125rem * var(--wk, 1)));
  line-height: 1.35;
  color: var(--ink);
}
.tit table.ice td { white-space: nowrap; }
.tit table.ice tr > :last-child { border-right: 0; }
.tit table.ice tbody tr:last-child > * { border-bottom: 0; }
.tit table.ice thead th { background: var(--primary-soft); color: var(--primary-soft-ink); font-weight: var(--w-semi); }
.tit table.ice .unit { display: block; font-weight: var(--w-normal); font-size: max(11px, calc(var(--fs-label) * var(--wk, 1))); color: var(--muted); }
.tit table.ice tbody th { text-align: left; background: var(--card-2); white-space: nowrap; font-weight: var(--w-semi); }
.tit .final {
  font-weight: var(--w-semi);
  background: var(--accent-soft);
  color: var(--ink);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  padding: 3px var(--sp-3);
}

/* narrower laptops and tablets: a tighter header, smaller pills */
@media (max-width: 1100px) {
  .tit .eyebrow { display: none; }
  .tit .brand { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--sp-3); align-items: center; }
  .tit .brand-mark { grid-row: 1 / 3; }
  .tit .brand-text { display: contents; }
  .tit .brand h1 { grid-column: 2; grid-row: 1; }
  .tit .top-links { grid-column: 2; grid-row: 2; flex-direction: row; gap: 0 var(--sp-3); margin: 0; }
  .tit .ctl input[type=range] { width: 60px; }
  .tit .ctl input[type=number] { width: 62px; }
  .tit .page .sig.chip { font-size: .8125rem; padding: 2px 8px 2px 9px; }
  .tit .pills { gap: 4px 6px; }
}
@media (max-width: 900px) {
  .tit .top { grid-template-columns: minmax(0, 1fr); }
}
@media (max-height: 760px) {
  .tit.calcview [data-add] { display: none; }
}
@media (max-height: 680px) {
  .tit.calcview .chead > span:not(.res) { display: none; }
}

/* phones are not a target: let the page flow rather than squeeze */
@media (max-width: 700px) {
  html:has(.tit), .tit { overflow: auto; height: auto; }
  .tit .page { height: auto; min-height: 100dvh; overflow: visible; display: flex; flex-direction: column; }
  .tit .top { grid-template-columns: minmax(0, 1fr); margin-right: 44px; }
  .tit .stage, .tit.calcview .stage { display: flex; flex-direction: column; }
  .tit .sim { height: 380px; }
  .tit .plot { height: 300px; flex: none; }
  .tit .wpage { overflow: visible; }
}

/* ---------------- reduced motion ---------------- */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .em-reveal-wrap.phase-visible.animate-in,
  .transition-panel.appear,
  dialog.pop[open],
  .add-viewer-btn::after,
  .electron-vibrate { animation: none !important; }
  .theme-toggle:hover,
  .tit .page button:active { transform: none !important; }
}

/* ---------------- EM comparison loupe ---------------- */
.em-loupe {
  position: absolute;
  z-index: 5;
  width: 260px;
  height: 176px;
  overflow: hidden;
  pointer-events: none;
  background: var(--stage-deep);
  border: 2px solid var(--primary);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-3);
}
.em-loupe-inner { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.em-loupe-guide { position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--primary); opacity: .55; }
.em-loupe-read {
  position: absolute; right: 6px; bottom: 6px; padding: 1px 7px;
  font: var(--w-semi) 12px/1.4 var(--font-mono, monospace);
  color: #fff; background: rgba(8, 6, 16, .72); border-radius: var(--r-pill);
}
.em-loupe .em-band-label { display: none; }
