/* =============================================================
   Chemulate Polarity: screen shell (package 2).
   Layout and components on top of the design-system.css tokens.
   Rules: no overflow:auto|scroll anywhere; tokens only (no hard-coded colours).
   Sizes: 1280x720, 1366x768 and 1024x640 = two columns;
          820x1180 (portrait) = one column, stage on top.
   ============================================================= */

/* the page is one fixed screen: nothing scrolls */
html, body { height: 100%; overflow: hidden; }
body {
  display: flex; flex-direction: column;
  height: 100vh; height: 100dvh;
}

/* ---------- app bar ---------- */
.app-bar {
  position: relative; z-index: 40; flex: none;
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  padding: var(--sp-2) var(--sp-4);
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.app-bar .top-links { margin: 0; padding: 0; gap: 0; flex: none; }
.app-bar .home-link { font: var(--t-small); font-weight: var(--w-semi); padding: 6px 0; white-space: nowrap; }
.app-bar__brand {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  width: auto; margin: 0; flex: none; line-height: 1;
}
.app-bar__brand img { height: 30px; width: auto; }
.app-bar__title {
  font: var(--w-display) 1.0625rem/1.2 var(--font-display);
  letter-spacing: var(--tr-heading); color: var(--title); white-space: nowrap;
}
.app-bar__tools {
  margin-left: auto; display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2); min-width: 0;
}
.app-bar__btn { min-height: var(--control-h); padding: 6px 14px; font: var(--t-small); font-weight: var(--w-semi); }
/* the theme toggle lives in the bar (the design system pins it to the corner) */
.app-bar .theme-toggle { position: static; flex: none; width: var(--control-h); height: var(--control-h); font-size: 1.05rem; box-shadow: none; }

/* ---------- main: two columns (stage left, tray right) ---------- */
.app-main {
  flex: 1 1 0; min-height: 0; min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(300px, 28vw, 380px);
  grid-template-rows: minmax(0, 1fr);
  gap: var(--sp-4);
  padding: var(--sp-4);
}

.stage-col {
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column; gap: var(--sp-3);
}

/* the scene card fills the stage; the svg letterboxes inside it */
.sim {
  position: relative;
  flex: 1 1 0; min-height: 0; min-width: 0;
  display: grid; grid-template-rows: minmax(0, 1fr);
  padding: var(--sp-3);
}
#stage { display: block; width: 100%; height: 100%; min-width: 0; min-height: 0; touch-action: none; user-select: none; -webkit-user-select: none; }
#stage:focus { outline: none; }
#stage:focus-visible { outline: 2px solid var(--primary); outline-offset: 4px; border-radius: var(--r-sm); }

/* ---------- scene (package 3): every colour is a token, so light and dark both work ---------- */
.pol-view-reset {
  position: absolute; top: var(--sp-3); right: var(--sp-3); z-index: 2;
  min-height: var(--control-h); padding: 4px 14px;
  font: var(--t-small); font-weight: var(--w-semi);
}
.pol-ghost { fill: none; stroke: var(--faint); stroke-width: 1.5; stroke-dasharray: 5 5; }
.pol-rope { fill: none; stroke: var(--ink-2); stroke-linecap: round; }
/* a rigid stick (weaker-than-centre atom): straight and stiff, drawn in the muted tone */
.pol-stick { fill: none; stroke: var(--muted); stroke-linecap: round; }
.pol-bead { fill: var(--primary); stroke: var(--card); stroke-width: 2; }
/* scene labels: the size comes from the stage (--pol-fs-*, set by measureText in app.js), never below 11px on screen */
.pol-bead-symbol { fill: var(--primary-ink); font-family: var(--font-body); font-weight: var(--w-display); font-size: var(--pol-fs-bead, 16px); text-anchor: middle; }
.pol-ph-ring { fill: none; stroke: var(--primary); stroke-width: 1.6; stroke-dasharray: 4 3; }
.pol-arrow-head { fill: var(--primary); }
.pol-arrow { stroke: var(--primary); stroke-width: 3; stroke-linecap: round; }
.pol-frost-limb { fill: none; stroke: var(--ink-2); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.pol-frost-body { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 1.4; }
.pol-frost-head { fill: var(--card); stroke: var(--ink-2); stroke-width: 1.4; }
.pol-frost-hair { fill: var(--primary-soft); stroke: var(--primary); stroke-width: 1.2; stroke-linejoin: round; }
.pol-frost-hand { fill: var(--card); stroke: var(--ink-2); stroke-width: 1.2; }
.pol-frost-eye { fill: var(--ink); }
.pol-frost-smile { fill: none; stroke: var(--ink); stroke-width: 1.3; stroke-linecap: round; }
.pol-frost-badge { fill: var(--accent); }
.pol-frost-symbol { fill: var(--accent-ink); font-family: var(--font-body); font-weight: var(--w-display); font-size: var(--pol-fs-frost, 13px); text-anchor: middle; }
/* a placeholder atom (#A to #G): a dashed ring round its badge */
.pol-frost-ring { fill: none; stroke: var(--accent); stroke-width: 1.4; stroke-dasharray: 3 2; }

/* Run and the verdict chip sit at the foot of the stage */
.stage-foot {
  flex: none;
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  min-height: var(--control-h);
}
.run-btn { min-width: 120px; }
.status {
  flex: 1 1 180px; min-width: 0; margin: 0; max-width: none;
  font: var(--t-small); color: var(--muted);
}

/* ---------- tray (builder, package 1): the mode selector, two bodies, one palette ---------- */
.tray {
  min-width: 0; min-height: 0;
  container: tray / inline-size;
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-4);
  overflow: hidden;
}
.tray-mode > button { min-height: var(--control-h); padding: 6px 10px; font: var(--t-small); font-weight: var(--w-semi); }
.tray-body { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; min-height: 0; }
.tray-note, .tray-current { margin: 0; font: var(--t-small); color: var(--muted); }
.tray-current strong { color: var(--ink-2); font-weight: var(--w-semi); }
.tray-pick { align-self: flex-start; }
.select { width: 100%; }
.shape-row { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.shape-row .select { flex: 1 1 auto; min-width: 0; }
.shape-row .btn { flex: none; min-height: var(--control-h); padding: 6px 14px; font: var(--t-small); font-weight: var(--w-semi); }

/* The build area: a square. Slots sit at fixed fractions of --r (SLOT_POS in app.js), so they never overlap. */
.build {
  --box: 190px;
  --r: calc(var(--box) * 0.38);
  --slot: 34px;
  position: relative; flex: none;
  width: var(--box); height: var(--box); max-width: 100%;
  margin: 0 auto;
  border: 1px dashed var(--line-strong); border-radius: var(--r-md);
  background: var(--bg-tint);
}
.drop {
  position: absolute;
  left: calc(50% + var(--r) * var(--x, 0));
  top: calc(50% + var(--r) * var(--y, 0));
  transform: translate(-50%, -50%);
  box-sizing: border-box;
  width: var(--slot); height: var(--slot); margin: 0; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%; border: 1.5px dashed var(--line-strong);
  background: var(--card); color: var(--muted);
  font: var(--w-display) 13px/1 var(--font-body);
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab;
  transition: transform var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.drop--centre { --slot: 40px; border-style: solid; border-color: var(--line-strong); }
.drop.is-filled { background: var(--primary-soft); border: 1.5px solid var(--primary); color: var(--ink-2); }
.drop.is-filled[data-kind="ph"] { border-style: dashed; color: var(--primary-soft-ink); }
.drop.is-target { outline: 2px dashed var(--primary); outline-offset: 3px; }
.drop.is-over { background: var(--primary-soft); transform: translate(-50%, -50%) scale(1.1); outline-style: solid; }
.drop.is-lifted { opacity: .4; }

/* The palette: 20 elements and 7 placeholders in 7 columns (four rows). */
.palette { --tile: 38px; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.tile {
  box-sizing: border-box;
  min-width: 0; height: var(--tile); margin: 0; padding: 0;
  display: grid; place-items: center;
  font: var(--w-display) 14px/1 var(--font-body); color: var(--ink-2);
  background: var(--card); border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab;
  transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.tile:hover { border-color: var(--primary); }
.tile--ph { border-style: dashed; border-color: var(--primary); color: var(--primary-soft-ink); background: var(--bg-tint); }
.tile:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.tile-gap { display: block; min-width: 0; }

/* Letter values: one row per letter on the molecule (letter, value, slider). */
.values { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.values-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: 28px; }
.values-title { font: var(--t-small); font-weight: var(--w-semi); color: var(--ink-2); }
.values-head .btn { min-height: 28px; padding: 2px 10px; font: var(--t-small); font-weight: var(--w-semi); }
.values-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px var(--sp-3); }
.value-row { display: grid; grid-template-columns: 26px 32px minmax(0, 1fr); align-items: center; gap: 6px; min-height: 26px; min-width: 0; }
.value-letter { font: var(--w-display) 14px/1 var(--font-body); color: var(--ink-2); white-space: nowrap; }
.value-out { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ink-2); }
.value-range { width: 100%; min-width: 0; margin: 0; accent-color: var(--primary); }
.values-empty { margin: 0; font: var(--t-small); font-size: 13px; color: var(--muted); }

/* the ghost that follows a drag (the shell's pointer engine, dnd.js) */
.drag-ghost {
  position: fixed; left: 0; top: 0; z-index: 90;
  box-sizing: border-box; margin: 0;
  display: grid; place-items: center;
  pointer-events: none;
  border-radius: var(--r-sm); border: 2px solid var(--primary);
  background: var(--card); color: var(--ink-2);
  box-shadow: var(--shadow-2);
  font: var(--w-display) 14px/1 var(--font-body);
  transition: opacity var(--dur-fast) var(--ease);
}
.drag-ghost[data-kind="ph"] { border-style: dashed; background: var(--primary-soft); color: var(--primary-soft-ink); }
.drag-ghost.is-leaving { opacity: 0; }
body.is-dragging { cursor: grabbing; user-select: none; -webkit-user-select: none; }

/* Geometry on a wide tray (portrait tablet): the shape and build area on the left, the palette on the right. */
@container tray (min-width: 560px) {
  .builder {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    grid-template-areas: "shape palette" "build palette" "values palette";
    align-items: start; gap: var(--sp-2) var(--sp-4);
  }
  .shape-row { grid-area: shape; }
  .build { grid-area: build; --box: 170px; }
  .values { grid-area: values; }
  .palette { grid-area: palette; --tile: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .drop, .tile, .drag-ghost { transition: none; }
}

/* ---------- popups (native dialog) ---------- */
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: 96vh; max-height: 96dvh;
  overflow: hidden;
}
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; }
/* fit-to-size: the body shrinks to the dialog; anything that cannot fit is paged, never scrolled */
.pop-content {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}

@keyframes riseFromBehind {
  0% { opacity: 0; transform: translateY(24px) scale(.98); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ---------- portrait tablet (820x1180): one column, stage on top ---------- */
@media (orientation: portrait), (max-width: 899px) {
  .app-main { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 55fr) minmax(0, 45fr); }
}

/* ---------- short laptop screens (1024x640 and 1280x720 or under 700px tall) ---------- */
@media (max-height: 700px) {
  .select { min-height: 40px; }
  .btn { min-height: var(--control-h); }
  .tray { padding: var(--sp-3); gap: var(--sp-2); }
  .app-main { padding: var(--sp-3); gap: var(--sp-3); }
  .sim { padding: var(--sp-2); }
}

/* The builder, compact: up to seven letters (the octahedral worst case) fit a tray at 1024x640 and 1280x720. */
@media (max-height: 800px) {
  .tray-mode > button { min-height: 34px; }
  .builder { gap: 6px; }
  .shape-row .btn { min-height: 36px; }
  .values-head { min-height: 24px; }
  .values-head .btn { min-height: 24px; padding: 0 10px; }
  .value-row { min-height: 24px; }
  .build { --box: 150px; --slot: 30px; }
  .drop--centre { --slot: 34px; }
  .palette { --tile: 32px; gap: 3px; }
  .values-list { gap: 2px var(--sp-2); }
}

@media (prefers-reduced-motion: reduce) {
  dialog.pop[open] { animation: none; }
}

/* ---------- package 4: scene corner (Challenge toggle and the session score) ---------- */
.pol-corner {
  position: absolute; top: var(--sp-3); left: var(--sp-3); z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2);
  max-width: calc(100% - 180px);   /* keep clear of the Reset view button */
}
.pol-corner-btn { min-height: var(--control-h); padding: 6px 14px; font: var(--t-small); font-weight: var(--w-semi); }
.pol-corner .btn[aria-pressed="true"] { background: var(--primary); color: var(--primary-ink); border-color: transparent; }
.pol-score { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }

/* ---------- view modes: the switch and the Ball and stick layer toggles (top right, under Reset view) ---------- */
.pol-corner-r {
  position: absolute; top: calc(var(--sp-3) + var(--control-h) + var(--sp-2)); right: var(--sp-3); z-index: 2;
  display: flex; flex-direction: column; align-items: flex-end; gap: var(--sp-2);
}
.pol-corner-r .seg > button { min-height: calc(var(--control-h) - 8px); padding: 6px 12px; font: var(--t-small); font-weight: var(--w-semi); }
.pol-layers { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.pol-layers[hidden] { display: none; }
.pol-layers { gap: 4px; }
.pol-layers .pol-corner-btn { min-height: 28px; padding: 2px 12px; }   /* four toggles fit where three did */
.pol-corner-r .pol-corner-btn[hidden] { display: none; }
.pol-corner-r .btn[aria-pressed="true"] { background: var(--primary); color: var(--primary-ink); border-color: transparent; }
.pol-score .ds-chip { font: var(--t-small); font-weight: var(--w-semi); padding: 8px 14px; }

/* ---------- package 4: Challenge row (in the stage foot, beside Run) ---------- */
.challenge { flex: 0 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.challenge-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); min-width: 0; }
.ch-choice { min-width: 112px; padding: 8px 16px; font: var(--t-body-strong); }
.ch-choice[aria-pressed="true"],
.ch-dir[aria-pressed="true"] { background: var(--primary); color: var(--primary-ink); border-color: transparent; }
.ch-dir { width: var(--control-h); min-width: var(--control-h); height: var(--control-h); padding: 0; }
.ch-arrow { width: 22px; height: 22px; vertical-align: middle; }

/* ---------- package 4: popup contents (fit without scrolling at 1024x640) ---------- */
.pop-content { gap: var(--sp-3); }
.pop-content p, .pop-content li {
  font-family: var(--font-body); font-size: 15px; font-weight: var(--w-normal);
  line-height: 1.5; color: var(--ink); max-width: none; margin: 0;
}
.pop-content strong { color: var(--ink-2); font-weight: var(--w-semi); }
.pop-content .pop-caption, .pop-content .pop-net { font-weight: var(--w-semi); color: var(--ink-2); }
.pop-content .pop-note, .pop-content .pop-credit { color: var(--muted); font-size: 14px; }

/* Molecules: 2 x 5 grid of presets, Back / Next under it */
.mol-grid { flex: 0 0 auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
.mol-btn {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  min-height: 60px; padding: 8px 14px;
  text-align: left; color: var(--ink);
  background: var(--card); border: 1px solid var(--line-strong); border-radius: var(--r-md);
}
.mol-btn:hover { background: var(--bg-tint); border-color: var(--primary); }
.mol-btn[aria-current="true"] { background: var(--primary-soft); border-color: var(--primary); }
.mol-formula { font: var(--t-body-strong); font-size: 17px; line-height: 1.2; color: var(--ink-2); }
.mol-formula sub, .mol-formula sup { font-size: .72em; line-height: 0; }
.mol-formula sub { vertical-align: -.25em; }
.mol-formula sup { vertical-align: .6em; }
.mol-name { font: var(--t-small); font-size: 14px; line-height: 1.3; color: var(--muted); }
.mol-nav { flex: none; display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.mol-page { font: var(--t-small); font-size: 14px; color: var(--muted); }

/* Under the hood: the per-atom table */
.hood-table { width: 100%; border-collapse: collapse; }
.hood-table th {
  text-align: left; vertical-align: bottom; padding: 4px 6px; line-height: 1.25;
  font: var(--t-small); font-size: 13px; font-weight: var(--w-semi); color: var(--muted);
  border-bottom: 1px solid var(--line-strong);
}
.hood-table td {
  padding: 4px 6px; line-height: 1.3; color: var(--ink);
  font: var(--t-small); font-size: 14px; border-bottom: 1px solid var(--line);
}
.hood-table .num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hood-table .atom-sym { font-weight: var(--w-semi); color: var(--ink-2); }
.hood-table tfoot td { font-weight: var(--w-semi); color: var(--ink-2); border-bottom: 0; }

/* About: four short points */
.about-list { margin: 0; padding-left: 1.25em; display: flex; flex-direction: column; gap: 6px; }

@media (max-height: 700px) {
  .pop-body { padding: var(--sp-3) var(--sp-4) var(--sp-4); gap: var(--sp-2); }
  .pop-content { gap: var(--sp-2); }
}

/* ---------- package 7: spring ropes, walk and run cycles, sweat, and the reduced-motion guard ---------- */
/* Sweat drops: one token, set for light and dark (the drops are the only blue in the scene). */
:root { --pol-sweat: #4fa8dc; }
:root:not([data-theme="light"]) { --pol-sweat: #4fa8dc; }
:root[data-theme="dark"] { --pol-sweat: #9bd7f5; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --pol-sweat: #9bd7f5; } }
.pol-drop { fill: var(--pol-sweat); }

/* Walk (1.0 s cycle, legs +/-22 deg, arms +/-15 deg, bob 3 px) and run (0.55 s, legs +/-40, arms +/-50, bob 6 px).
   One keyframe set spans the whole cycle; the two legs (and the free arm) are half a cycle apart. */
.pol-frost.is-walk, .pol-frost.is-run { --cycle: 1s; --leg: 22deg; --arm: 15deg; --bob: 3px; }
.pol-frost.is-run { --cycle: 0.55s; --leg: 40deg; --arm: 50deg; --bob: 6px; }
.pol-frost.is-walk .leg-swing, .pol-frost.is-run .leg-swing {
  transform-origin: 0 0; animation: pol-leg var(--cycle) ease-in-out infinite;
}
.pol-frost.is-walk .arm-swing, .pol-frost.is-run .arm-swing {
  transform-origin: 0 0; animation: pol-arm var(--cycle) ease-in-out infinite;
}
.pol-frost.is-walk .frost-trunk, .pol-frost.is-run .frost-trunk {
  animation: pol-bob var(--cycle) ease-in-out infinite;
}
.pol-frost.is-walk .leg-b, .pol-frost.is-run .leg-b,
.pol-frost.is-walk .arm-b, .pol-frost.is-run .arm-b { animation-delay: calc(var(--cycle) * -0.5); }

@keyframes pol-leg {
  0%, 100% { transform: rotate(var(--leg)); }
  25%, 75% { transform: rotate(0deg); }
  50% { transform: rotate(calc(var(--leg) * -1)); }
}
@keyframes pol-arm {
  0%, 100% { transform: rotate(var(--arm)); }
  50% { transform: rotate(calc(var(--arm) * -1)); }
}
@keyframes pol-bob {
  0%, 50%, 100% { transform: translateY(0); }
  25%, 75% { transform: translateY(calc(var(--bob) * -1)); }
}

@media (prefers-reduced-motion: reduce) {
  .pol-frost .leg-swing, .pol-frost .arm-swing, .pol-frost .frost-trunk { animation: none !important; }
}

/* dipole arrows (net and bond): ONE path each, the shaft, the open head and the cross at the positive end. House accent. */
.pol-dipole { fill: none; stroke: var(--accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
/* the Jack Frost net arrow's label: beside the arrow, outside the floor disc (app.js: drawNetJF) */
.pol-net-label { font-family: var(--font-body); font-weight: var(--w-semi); font-size: var(--pol-fs-mark, 13px); fill: var(--ink-2); text-anchor: middle; }

/* Subscripts and superscripts in labels (app.js: subscriptDigits). HTML sub and sup stay at 80% of their line (11px or more
   at the sizes used), and the SVG caption is sized so its 75% tspans stay at 11px or more. */
sub, sup { font-size: .8em; line-height: 0; }

/* 3D reference: the floor (the molecule's symmetry plane), the shadow, the corner gizmo (app.js: drawFloor, drawShadow, drawGizmo).
   Static drawing with no pointer events, so dragging the molecule still works. No animation here. */
.pol-floor, .pol-shadow, .pol-gizmo { pointer-events: none; }
.pol-floor-disc { fill: var(--bg-tint); fill-opacity: 0.7; stroke: var(--line-strong); stroke-width: 1.5; }
.pol-grid { stroke: var(--muted); stroke-opacity: 0.35; stroke-width: 1; stroke-linecap: round; }
.pol-grid.is-far { stroke-opacity: 0.18; }
.pol-floor-axis { stroke: var(--muted); stroke-opacity: 0.6; stroke-width: 1.5; stroke-linecap: round; }
.pol-floor-axis.is-far { stroke-opacity: 0.35; }
.pol-shadow-blob { fill: var(--ink); fill-opacity: 0.28; }
.pol-shadow-bond { stroke: var(--ink); stroke-opacity: 0.28; stroke-width: 3; stroke-linecap: round; }
.pol-shadow-net { stroke: var(--ink); stroke-opacity: 0.5; stroke-width: 3.5; stroke-linecap: round; }
.pol-plumb { fill: none; stroke: var(--muted); stroke-width: 1.2; stroke-dasharray: 3 4; }
.pol-gizmo-arm { fill: none; stroke-width: 2.2; stroke-linecap: round; }
.pol-gizmo-arm.is-x, .pol-gizmo-label.is-x { stroke: var(--primary); fill: var(--primary); }
.pol-gizmo-arm.is-y, .pol-gizmo-label.is-y { stroke: var(--accent); fill: var(--accent); }
.pol-gizmo-arm.is-z, .pol-gizmo-label.is-z { stroke: var(--ink); fill: var(--ink); }
.pol-gizmo-label { font-family: var(--font-body); font-weight: var(--w-display); font-size: var(--pol-fs-axis, 12px); }

/* Symmetry cut (MIRROR-CHECK.md; app.js: drawFloor, drawCutSheet, drawCutMarks, drawCutCaption). Static drawing, no
   animation, no pointer events, house tokens only. The sheet and its lifted copy sit in the floor layer. */
.pol-cut, .pol-cut-caption { pointer-events: none; }
.pol-cut-sheet { fill: var(--primary); fill-opacity: 0.12; stroke: var(--primary); stroke-width: 1; }
.pol-cut-shade { fill: var(--accent); fill-opacity: 0.16; stroke: var(--accent); stroke-width: 1; stroke-opacity: 0.6; }
.pol-cut-pair { stroke: var(--ink-2); stroke-width: 1.6; stroke-dasharray: 4 3; stroke-linecap: round; fill: none; }
.pol-cut-unpaired { fill: none; stroke: var(--warn); stroke-width: 3; }
.pol-cut-caption { font-family: var(--font-body); font-weight: var(--w-semi); font-size: var(--pol-fs-cap, 15px); fill: var(--ink-2); }
.pol-cut-caption--sub { font-weight: var(--w-normal); fill: var(--muted); }

/* ---------- Ball and stick (view modes): colour tokens, set for light and dark like the sweat token above.
   Delta marks on the card: red and blue both reach 4.5:1 in light and dark. Ball fills are pale constants in app.js. ---------- */
:root {
  --bs-neg: #b42318;            /* delta minus (more electronegative end): 6.6 on white */
  --bs-pos: #1d4ed8;            /* delta plus: 6.7 on white */
  --bs-stick: #8a84a0;          /* neutral stick and the neutral mid stop */
  --bs-hi: #ffffff;             /* thin highlight along a stick */
  --bs-ball-edge: #5b5470;      /* sphere outline */
  --bs-cloud: #7a52c4;          /* electron cloud, a calm hue, distinct from red and blue */
  --bs-symbol: #1c1725;         /* symbols on the pale balls (the same in both themes) */
}
:root:not([data-theme="light"]) {
  --bs-neg: #b42318; --bs-pos: #1d4ed8; --bs-stick: #8a84a0; --bs-hi: #ffffff;
  --bs-ball-edge: #5b5470; --bs-cloud: #7a52c4; --bs-symbol: #1c1725;
}
:root[data-theme="dark"] {
  --bs-neg: #ff8a7a;            /* 7.4 on the dark card */
  --bs-pos: #8ab4ff;            /* 8.1 on the dark card */
  --bs-stick: #6f6890;
  --bs-hi: #ffffff;
  --bs-ball-edge: #a79fc0;
  --bs-cloud: #b79cf0;
  --bs-symbol: #1c1725;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bs-neg: #ff8a7a; --bs-pos: #8ab4ff; --bs-stick: #6f6890; --bs-hi: #ffffff;
    --bs-ball-edge: #a79fc0; --bs-cloud: #b79cf0; --bs-symbol: #1c1725;
  }
}

/* Ball and stick classes (app.js: buildBallRig, drawBallMarks, drawBallCloud, drawLegend, drawBallFrame).
   Sizes come from --pol-fs-mark (set by measureText), so every label stays at 11px or more on screen. */
/* electron cloud on: the sticks fade under the stronger cloud, so the cloud reads first */
.bs-cloud-on .bs-stick-tint, .bs-cloud-on .bs-stick { stroke-opacity: .25; }
.bs-cloud-on .bs-stick-hi { stroke-opacity: .15; }
.bs-stick { fill: none; stroke: var(--bs-stick); stroke-linecap: round; }
.bs-stick-tint { fill: none; stroke-linecap: round; }
.bs-stick-hi { fill: none; stroke: var(--bs-hi); stroke-opacity: .5; stroke-linecap: round; }
.bs-ball { stroke: var(--bs-ball-edge); stroke-width: 1.2; }
.bs-symbol { fill: var(--bs-symbol); font-family: var(--font-body); font-weight: var(--w-display); text-anchor: middle; }
.bs-symbol--centre { font-size: var(--pol-fs-bead, 16px); }
.bs-symbol--term { font-size: var(--pol-fs-frost, 13px); }
.bs-mark { font-family: var(--font-body); font-weight: var(--w-display); font-size: var(--pol-fs-mark, 13px); text-anchor: middle; }
.bs-mark--neg { fill: var(--bs-neg); }
.bs-mark--pos { fill: var(--bs-pos); }
.bs-label { font-family: var(--font-body); font-weight: var(--w-semi); font-size: var(--pol-fs-mark, 13px); fill: var(--ink-2); text-anchor: middle; }
.bs-note { font-family: var(--font-body); font-weight: var(--w-normal); font-size: var(--pol-fs-mark, 13px); fill: var(--muted); text-anchor: middle; }
.bs-legend-text { font-family: var(--font-body); font-weight: var(--w-display); font-size: var(--pol-fs-mark, 13px); fill: var(--ink-2); }
.bs-legend-bar { stroke: var(--line-strong); stroke-width: 1; }
.bs-stop--neg { stop-color: var(--bs-neg); }
.bs-stop--pos { stop-color: var(--bs-pos); }
.bs-stop--neutral { stop-color: var(--bs-stick); }
.bs-stop--cloud { stop-color: var(--bs-cloud); }
