/* =============================================================
   seesaw.css  -  Chemulate Equilibrium, the Le Chatelier see-saw.
   Appearance only. Every colour is a token from design-system.css /
   eq-tokens.css (no hex). seesaw.js builds the SVG in the host's own
   pixel units, so the text below is real CSS pixels at any host size.

   Reading the picture
     beam level            Q = K   (not "equal amounts")
     reactant side down    Q < K   -> the reaction runs forward
     product side down     Q > K   -> the reaction runs in reverse
   Balloon radius is a monotonic function of snapshot.species[].rel;
   the amount is always printed in the balloon, so size is never the
   only cue. Series identity = colour + outline dash + marker shape.

   Saturation budget: balloons, blocks and the heat entity sit at the
   soft steps. The ONE saturated element is the thing just disturbed
   (.is-hot ring + .saw-tag pill), and the heat entity while it holds
   surplus heat. Only individual transform properties (rotate, scale,
   translate) are animated, from seesaw.js.
   ============================================================= */

.saw {
  position: relative; display: flex; flex-direction: column;
  width: 100%; height: 100%; min-width: 0; min-height: 0;
  overflow: hidden;
}
.saw-svg {
  display: block; flex: 1 1 0; width: 100%; height: 0; min-height: 0;
  overflow: hidden;
}

/* every animated part: transform-origin is set inline in px (the viewBox is the host's pixel box) */
.saw-beam, .saw-counter, .saw-balloon, .saw-val, .saw-heat, .saw-ring, .saw-token {
  transform-box: view-box;
}

/* ---------- visible state text under the beam ----------
   Fixed height (two lines) so a change of wording can never resize the SVG above it. */
.saw-state {
  flex: none; display: flex; align-items: center; justify-content: center;
  height: calc(2 * 1.3em + 8px); margin: 0; padding: 2px var(--sp-2);
  font: var(--t-small); line-height: 1.3; color: var(--ink); text-align: center; overflow: hidden;
}
.saw-state-in {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; text-wrap: balance; min-width: 0;
}
.saw[data-size="s"] .saw-state { font-size: 0.8125rem; }
.saw-state-main { font-weight: var(--w-semi); }
.saw-qk { font-family: var(--font-mono); font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; }
.saw-note { display: none; flex: none; margin: 0; padding: 0 var(--sp-2) var(--sp-1); height: calc(2 * 1.35em + 6px); overflow: hidden;
  font: var(--t-small); line-height: 1.35; color: var(--muted); text-align: center; text-wrap: balance; }
.saw[data-note="1"] .saw-note, .saw[data-note="2"] .saw-note { display: block; }

/* ---------- svg text ---------- */
.saw-svg text { font-family: var(--font-body); fill: var(--ink); }
.saw-num { font-family: var(--font-mono) !important; font-variant-numeric: tabular-nums; font-weight: var(--w-medium); }
.saw-unit { fill: var(--muted) !important; }
.saw-val text { paint-order: stroke; stroke: var(--card); stroke-width: 3px; stroke-linejoin: round; }
.saw-head { fill: var(--muted) !important; font-weight: var(--w-semi); letter-spacing: var(--tr-label); }
.saw-lab text { font-weight: var(--w-semi); }
.saw-sub { fill: var(--ink-2) !important; }

/* ---------- fixed parts ---------- */
.saw-level { stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 3 5; fill: none; }
.saw-post { fill: var(--line-strong); stroke: none; }
.saw-pivot { fill: var(--ink-2); stroke: var(--card); stroke-width: 2; }
.saw-plank { fill: var(--card-2); stroke: var(--line-strong); stroke-width: 1.5; }

/* ---------- series identity ---------- */
.saw-s0 { --c: var(--eq-a); }
.saw-s1 { --c: var(--eq-b); }
.saw-s2 { --c: var(--eq-c); }
.saw-s3 { --c: var(--eq-d); }
.saw-mark { fill: var(--c); stroke: none; }

/* ---------- balloons ---------- */
.saw-balloon {
  fill: var(--card-2);
  fill: color-mix(in srgb, var(--c) var(--eq-tint-balloon), var(--card));
  stroke: var(--c); stroke-width: 2; vector-effect: non-scaling-stroke;
  transition: stroke-width var(--dur) var(--ease);
}
.saw-s1 .saw-balloon { stroke-dasharray: 6 4; }
.saw-s2 .saw-balloon { stroke-dasharray: 2 3; }
.saw-s3 .saw-balloon { stroke-dasharray: 8 3 2 3; }
.saw-knot { fill: var(--c); stroke: none; }
.saw-balloon.is-hot { stroke: var(--primary); stroke-width: 4; stroke-dasharray: none; }

/* ---------- pure solid / liquid blocks (not in Q): static ---------- */
.saw-block {
  fill: var(--card-2);
  fill: color-mix(in srgb, var(--eq-solid) var(--eq-tint-solid), var(--card));
  stroke: var(--eq-solid-ink); stroke-width: 1.5; vector-effect: non-scaling-stroke;
}
.saw-block.is-hot { stroke: var(--primary); stroke-width: 4; }
.saw-block-txt { fill: var(--eq-solid-ink) !important; }

/* ---------- heat entity (never part of Q) ---------- */
.saw-blob {
  --heat-mix: 16%;
  fill: var(--warn-soft);
  fill: color-mix(in srgb, var(--eq-heat) var(--heat-mix), var(--card));
  stroke: var(--eq-heat-ink); stroke-width: 2; vector-effect: non-scaling-stroke;
  transition: fill var(--dur) var(--ease);
}
.saw-heat.is-deficit .saw-blob { stroke-dasharray: 5 4; }
.saw-heat.is-hot .saw-blob { stroke-width: 4; }
.saw-flame { fill: none; stroke: var(--ink); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.saw-flame * { vector-effect: non-scaling-stroke; }
.saw-ghost .saw-blob { fill: none; stroke-dasharray: 3 4; }
.saw-ghost .saw-flame { stroke: var(--eq-heat-ink); }

/* ---------- inert gas: a ring on its own shelf, never on a pan ---------- */
.saw-ring-c { fill: none; stroke: var(--eq-inert); stroke-width: 3; vector-effect: non-scaling-stroke; }
.saw-ring.is-hot .saw-ring-c { stroke: var(--primary); stroke-width: 5; }
.saw-shelf { stroke: var(--eq-inert); stroke-width: 2; stroke-linecap: round; }

/* ---------- tokens flying pan to pan ---------- */
.saw-token {
  fill: var(--card-2);
  fill: color-mix(in srgb, var(--c, var(--ink-2)) var(--eq-tint-token), var(--card));
  stroke: var(--c, var(--ink-2)); stroke-width: 1.5;
}
.saw-token--heat { fill: var(--warn-soft); stroke: var(--eq-heat-ink); stroke-dasharray: 2 2; }

/* ---------- pulse label: the one saturated element ---------- */
.saw-tag-bg { fill: var(--primary); }
.saw-svg text.saw-tag-txt { fill: var(--primary-ink); font-weight: var(--w-semi); }
.saw-tag--soft .saw-tag-bg { fill: var(--warn-soft); stroke: var(--warn-ink); stroke-width: 1.5; }
.saw-svg .saw-tag--soft text.saw-tag-txt { fill: var(--warn-ink); }
