/* My Easy Science — Design System v2 (assets/style.css)
   ONE shared stylesheet for the whole site. Every page links this file
   and nothing else for shared styles. A page may keep a small <style>
   block ONLY for rules that exist on that page alone, prefixed with the
   page name, under 40 lines.
   Rules of the system: spacing ONLY var(--s1)..var(--s7); type ONLY
   12/13/14/16/20/24/32/36 px; radius ONLY 6/10/999 px; shadows ONLY
   the card and popover shadows; buttons EXACTLY four kinds (Primary,
   Secondary, Tertiary, Icon), at most one Primary per section; no
   !important except reduced-motion and print at the end; no boxes
   inside boxes. Theme: <html data-theme="light"|"dark">, :root is light. */
/* ===== 1. Tokens ===== */
:root {
  --bg: #f5f7fb;
  --surface: #ffffff;
  --surface-2: #f0f4fa;
  --ink: #0f1b2d;
  --ink-2: #3b4a60;
  --muted: #5d6b80;
  --line: #dfe6ef;
  --line-strong: #c5d0de;
  --primary: #2a5a8a;
  --primary-hover: #234d76;
  --primary-soft: #e7eff8;
  --on-primary: #ffffff; /* text on a --primary background; dark ink in dark mode, where --primary is light */
  --accent: #e67e22;
  /* focus ring, selection outline, one small highlight */
  --ok: #2e7d32;
  --warn: #b26a00;
  --err: #c62828;
  --ok-soft: rgba(46,125,50,.08);
  --warn-soft: rgba(178,106,0,.08);
  --err-soft: rgba(198,40,40,.08);
  --info-soft: rgba(42,90,138,.08);
  /* Group colours: a dot + 3px bar beside the group title ONLY. */
  --group-pk: #2a5a8a;
  --group-pd: #e67e22;
  --group-dose: #2e7d32;
  --group-patient: #6a4fa3;
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --radius-control: 6px;
  --radius-card: 10px;
  --radius-chip: 999px;
  --shadow-card: 0 1px 2px rgba(15,27,45,.06);
  --shadow-popover: 0 8px 24px rgba(15,27,45,.16);
  --dur-fast: 120ms;
  --dur-med: 150ms;
  --dur-slow: 200ms;
  --ease-out: ease-out;
}
[data-theme="dark"] {
  --bg: #0c1624;
  --surface: #13233a;
  --surface-2: #182c46;
  --ink: #e8eff9;
  --ink-2: #b7c6dc;
  --muted: #8da2bf;
  --line: #25405f;
  --line-strong: #36547a;
  --primary: #6aa6e0;
  --primary-hover: #86b6e8;
  --primary-soft: #1b3049;
  --on-primary: #0c1624;
  --accent: #f0923d;
  --ok: #66bb6a;
  --warn: #f0a030;
  --err: #ef6b6b;
  --ok-soft: rgba(102,187,106,.08);
  --warn-soft: rgba(240,160,48,.08);
  --err-soft: rgba(239,107,107,.08);
  --info-soft: rgba(106,166,224,.08);
  --group-pk: #6aa6e0;
  --group-pd: #f0923d;
  --group-dose: #66bb6a;
  --group-patient: #a58fd0;
  --shadow-card: 0 1px 2px rgba(0,0,0,.30);
  --shadow-popover: 0 8px 24px rgba(0,0,0,.45);
}

/* ===== 2. Base and reset ===== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
}
h1, h2, h3, h4, h5, h6, p, ul, ol, dl, figure, blockquote { margin-top: 0; margin-bottom: 0; }
ul, ol { padding-left: var(--s5); }
img, svg, canvas { max-width: 100%; display: block; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
input, select, textarea { font: inherit; color: inherit; }
::selection { background: var(--primary-soft); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* focus ring on EVERY interactive element */
.skip-link {
  position: absolute;
  left: var(--s4);
  top: -100px;
  z-index: 100;
  background: var(--surface);
  color: var(--primary);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  padding: var(--s2) var(--s3);
  font-size: 14px;
  font-weight: 600;
}
.skip-link:focus { top: var(--s2); }

/* ===== 3. Typography — ONLY 12/13/14/16/20/24/32/36 px; weights 400/500/600/700; headings 600 ===== */
h1, .h1 {
  font-size: 24px;
  line-height: 1.15;
  font-weight: 600;
  text-wrap: balance;
}
.home-title { font-size: 32px; line-height: 1.15; font-weight: 600; text-wrap: balance; } /* home page title only */
h2, .h2 {
  font-size: 20px;
  line-height: 1.3;
  font-weight: 600;
  text-wrap: balance;
}
h3, .h3 { font-size: 16px; line-height: 1.3; font-weight: 600; }
h4, .h4 { font-size: 14px; line-height: 1.3; font-weight: 600; }
.lede {
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 70ch;
}
.reading { font-size: 16px; line-height: 1.5; max-width: 70ch; }
/* reading text never wider than 70ch */
.reading p + p { margin-top: var(--s3); }
.caption { font-size: 12px; line-height: 1.5; color: var(--muted); }
.label {
  font-size: 13px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--ink-2);
}
.helper { font-size: 12px; line-height: 1.5; color: var(--muted); }
.numeric, .result-value, .data-table td, .axis-label { font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.nowrap { white-space: nowrap; }

/* ===== 4. Layout helpers — sections 32px apart, cards 16-24px apart, fields 12px apart ===== */
.page {
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
  padding: var(--s4) var(--s4) var(--s7);
}
.page > * + * { margin-top: var(--s6); }
.stack { display: flex; flex-direction: column; gap: var(--s4); }
.row { display: flex; align-items: center; gap: var(--s3); }
.row-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
}
.workbench {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: var(--s5);
  align-items: start;
}
/* Grid blowout: a grid item's automatic minimum is its content's
   min-content, so a wide descendant stretches the 1fr track past the
   viewport on a phone (pk-quick 548px, molecular-weight 496px,
   renal 447px, lipinski 406px at a 390px viewport). min-width: 0 lets
   both columns shrink to the viewport; the inner scrollers (.tabs,
   .segmented, .table-wrap) handle their own wide content. */
.tool-body .workbench > * { min-width: 0; }
/* inputs left, results right — Chunk 4 sets the inputs column to 380px
   (the Chunk 1 draft said 360px); the phone collapse is in section 23 */
/* ===== 5. Cards and titled groups — a card holds titled groups separated by spacing + a 1px hairline, never nested bordered boxes ===== */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: var(--s4);
}
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding-bottom: var(--s3);
  margin-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}
.card-header h2, .card-header h3 { font-size: 16px; }
.card-header .card-actions {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-left: auto;
}
.card-title { font-size: 16px; font-weight: 600; line-height: 1.3; }
.group { padding-top: var(--s4); margin-top: var(--s4); border-top: 1px solid var(--line); }
.group:first-child { padding-top: 0; margin-top: 0; border-top: 0; }
.group-title {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s3);
}
.group-title .group-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--group-color, var(--primary));
  flex: none;
}
.group-title .group-bar {
  width: 3px;
  height: 14px;
  border-radius: 999px;
  background: var(--group-color, var(--primary));
  flex: none;
}
.group--pk { --group-color: var(--group-pk); }
.group--pd { --group-color: var(--group-pd); }
.group--dose { --group-color: var(--group-dose); }
.group--patient { --group-color: var(--group-patient); }

/* ===== 6. Buttons — EXACTLY FOUR kinds. Primary = the single main action, at most one per section ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  height: 36px;
  padding-left: 12px;
  padding-right: 12px;
  border-radius: var(--radius-control);
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"], .btn-icon:disabled, .btn-icon[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}
.btn-primary { background: var(--primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-secondary { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.btn-tertiary { color: var(--primary); padding-left: var(--s2); padding-right: var(--s2); }
.btn-tertiary:hover { background: var(--primary-soft); }
.btn-danger { background: var(--surface); border-color: var(--line-strong); color: var(--err); }
/* destructive = Secondary shape, red text; confirm only when data would be lost */
.btn-danger:hover { border-color: var(--err); }
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: var(--radius-control);
  border: 1px solid transparent;
  color: var(--ink-2);
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.btn-icon:hover { background: var(--surface-2); color: var(--ink); }
.btn-icon:active { transform: translateY(1px); }
.btn-icon[aria-pressed="true"], .btn-icon.is-active { background: var(--primary-soft); color: var(--primary); }
.btn-icon svg { width: 20px; height: 20px; flex: none; }
.btn-block { width: 100%; }
/* full-width Primary at the bottom of an Inputs card */
/* ===== 7. Forms — controls 36px / 14px / 10px padding; labels 13px 600 --ink-2 above, 4px gap ===== */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  margin-bottom: var(--s3);
}
/* Chunk 9 (test 8): show/hide now uses the hidden property, not inline
   styles — but the flex display above beats the browser's own [hidden]
   rule, so the attribute needs this explicit win. Without it the
   inhibitor fields (enzyme kinetics) and the pKa2 field (titration) show
   on load when they must start hidden. */
.field[hidden] { display: none; }
.field:last-child { margin-bottom: 0; }
.field label, .field-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  line-height: 1.3;
}
.field .helper { font-size: 12px; color: var(--muted); line-height: 1.5; }
.field-error {
  display: flex;
  align-items: flex-start;
  gap: var(--s1);
  font-size: 12px;
  color: var(--err);
  line-height: 1.5;
}
/* A .field-error with hidden must stay hidden: display:flex above
   overrides the UA [hidden] rule, so a stale error would show
   on every load (periodic table "No element found"). */
.field-error[hidden] { display: none; }
/* error text WITH an icon, never colour alone */
.field-error svg {
  width: 14px;
  height: 14px;
  flex: none;
  margin-top: 4px;
}
.field.has-error .input, .field.has-error select, .field.has-error textarea { border-color: var(--err); }
.input, select.input, textarea.input {
  width: 100%;
  height: 36px;
  padding-left: 12px;
  padding-right: 12px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  font-size: 14px;
  line-height: 1.3;
  color: var(--ink);
}
textarea.input {
  height: auto;
  min-height: 96px;
  padding-top: var(--s2);
  padding-bottom: var(--s2);
  resize: vertical;
}
.input:hover, select.input:hover, textarea.input:hover { border-color: var(--primary); }
.input:focus, select.input:focus, textarea.input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--primary);
}
.input:disabled, select.input:disabled, textarea.input:disabled { opacity: .5; cursor: not-allowed; }
.input::placeholder { color: var(--muted); }
.input-wrap { position: relative; display: flex; align-items: center; }
.input-wrap .input { padding-right: 48px; }
.input-unit {
  position: absolute;
  right: 10px;
  font-size: 13px;
  color: var(--muted);
  pointer-events: none;
}
/* unit inside the input, right, muted */
.input-large { height: 48px; font-size: 16px; }
/* large formula field with live preview */
input[type="number"].input::-webkit-outer-spin-button, input[type="number"].input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* thin stepper only on hover/focus */
input[type="number"].input:hover::-webkit-inner-spin-button, input[type="number"].input:focus::-webkit-inner-spin-button {
  -webkit-appearance: auto;
}
input[type="number"].input { -moz-appearance: textfield; appearance: textfield; }
.check, .radio {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  line-height: 1.3;
  cursor: pointer;
  min-height: 44px; /* Chunk 8: a checkbox/radio row is a full touch target */
}
.check input, .radio input {
  width: 20px;
  height: 20px;
  flex: none;
  margin: 0;
  accent-color: var(--primary);
  cursor: pointer;
}
.check input:disabled, .radio input:disabled { opacity: .5; cursor: not-allowed; }
.switch {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  line-height: 1.3;
  cursor: pointer;
}
.switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.switch-track {
  width: 40px;
  height: 24px;
  flex: none;
  border-radius: 999px;
  background: var(--line-strong);
  position: relative;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-card);
  transition: transform var(--dur-fast) var(--ease-out);
}
.switch input:checked + .switch-track { background: var(--primary); }
.switch input:checked + .switch-track::after { transform: translateX(16px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch input:disabled + .switch-track { opacity: .5; }
.range-wrap { display: flex; align-items: center; gap: var(--s3); }
input[type="range"].range {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: var(--line);
  outline-offset: 2px;
}
input[type="range"].range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--primary);
  border: 2px solid var(--surface);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
input[type="range"].range::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--primary);
  border: 2px solid var(--surface);
  box-shadow: var(--shadow-card);
  cursor: pointer;
}
input[type="range"].range:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
input[type="range"].range:disabled { opacity: .5; cursor: not-allowed; }
.range-value {
  min-width: 64px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-left: var(--s2);
  padding-right: var(--s2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* number box beside a slider */
/* ===== 8. Segmented control — track --surface-2, active option is a white pill with a soft shadow ===== */
.segmented {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-chip);
  max-width: 100%;
  overflow-x: auto;
}
.segmented button {
  flex: 1 0 auto;
  height: 32px;
  padding-left: var(--s3);
  padding-right: var(--s3);
  border-radius: var(--radius-chip);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-2);
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.segmented button:hover { color: var(--ink); }
.segmented button[aria-checked="true"], .segmented button.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
.segmented button:disabled { opacity: .5; cursor: not-allowed; }

/* ===== 9. Tabs — underline style, 40px, active underline --primary, arrow-key nav, role="tablist" ===== */
.tabs {
  display: flex;
  gap: var(--s1);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
}
.tabs [role="tab"] {
  height: 40px;
  padding-left: var(--s3);
  padding-right: var(--s3);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-2);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.tabs [role="tab"]:hover { color: var(--ink); }
.tabs [role="tab"][aria-selected="true"] { color: var(--primary); border-bottom-color: var(--primary); }
.tabs [role="tab"]:disabled { opacity: .5; cursor: not-allowed; }
.tab-panel { padding-top: var(--s4); }

/* ===== 10. Accordion — chevron rotates (not +/-), 150ms height change, off for reduced motion ===== */
.accordion { border-top: 1px solid var(--line); }
.accordion-item { border-bottom: 1px solid var(--line); }
.accordion-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  width: 100%;
  min-height: 40px;
  padding-top: var(--s2);
  padding-bottom: var(--s2);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  text-align: left;
  color: var(--ink);
}
.accordion-header:hover { color: var(--primary); }
.accordion-header .accordion-chevron {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--muted);
  transition: transform var(--dur-med) var(--ease-out);
}
.accordion-item[data-open="true"] .accordion-chevron { transform: rotate(180deg); }
.accordion-panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-med) var(--ease-out); }
.accordion-item[data-open="true"] .accordion-panel { grid-template-rows: 1fr; }
.accordion-panel-inner { overflow: hidden; }
.accordion-panel-body { padding-bottom: var(--s4); }

/* ===== 11. Menu and popover — opens under its button, closes on Escape/outside click, arrow-key nav, 10px radius (card radius; the scale has no 8px), popover shadow ===== */
.menu-wrap { position: relative; display: inline-flex; }
.menu {
  position: absolute;
  top: calc(100% + var(--s1));
  left: 0;
  z-index: 50;
  min-width: 200px;
  padding: var(--s1);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-popover);
}
.menu[data-align="right"] { left: auto; right: 0; }
.menu[hidden] { display: none; }
.menu-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  width: 100%;
  min-height: 36px;
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-control);
  font-size: 14px;
  line-height: 1.3;
  text-align: left;
  color: var(--ink);
}
.menu-item:hover, .menu-item[data-highlighted="true"] { background: var(--surface-2); }
.menu-item svg {
  width: 20px;
  height: 20px;
  flex: none;
  color: var(--muted);
}
.menu-item .menu-kbd { margin-left: auto; font-size: 12px; color: var(--muted); }
.menu-separator { height: 1px; background: var(--line); margin: var(--s1) 0; }
.menu-label {
  padding: var(--s2) var(--s3) var(--s1);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.popover {
  position: absolute;
  z-index: 50;
  padding: var(--s3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-popover);
}
.popover[hidden] { display: none; }

/* ===== 12. Chips and tags ===== */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  height: 24px;
  padding-left: var(--s2);
  padding-right: var(--s2);
  border-radius: var(--radius-chip);
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-2);
  white-space: nowrap;
}
.chip svg { width: 14px; height: 14px; }
.chip--primary { background: var(--primary-soft); border-color: transparent; color: var(--primary); }
.chip--ok { background: var(--ok-soft); border-color: transparent; color: var(--ok); }
.chip--warn { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.chip--err { background: var(--err-soft); border-color: transparent; color: var(--err); }
button.chip { cursor: pointer; }
button.chip:hover { border-color: var(--line-strong); }
button.chip[aria-pressed="true"] { background: var(--primary); border-color: transparent; color: var(--on-primary); }

/* ===== 13. Tooltips — appear after 400ms, also on keyboard focus ===== */
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + var(--s2));
  transform: translateX(-50%) translateY(4px);
  z-index: 60;
  padding: var(--s1) var(--s2);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--radius-control);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out) 400ms, transform var(--dur-fast) var(--ease-out) 400ms;
}
[data-tooltip]:hover::after, [data-tooltip]:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ===== 14. Toast — bottom left. Success replaces the status line; errors stay inline ===== */
.toast-stack {
  position: fixed;
  left: var(--s4);
  bottom: var(--s4);
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  max-width: min(360px, calc(100vw - var(--s6)));
}
.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-popover);
  font-size: 14px;
  line-height: 1.3;
}
.toast svg { width: 20px; height: 20px; flex: none; }
.toast--ok svg { color: var(--ok); }
.toast--warn svg { color: var(--warn); }
.toast--err svg { color: var(--err); }

/* ===== 15. Modal and bottom sheet (phones) ===== */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(15,27,45,.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s4);
}
.modal-backdrop[hidden] { display: none; }
.modal {
  width: 100%;
  max-width: 560px;
  max-height: calc(100dvh - var(--s7));
  overflow: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-popover);
  padding: var(--s4);
}
.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s3);
}
.modal-header h2 { font-size: 20px; }
.sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 80;
  max-height: 85dvh;
  overflow: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  box-shadow: var(--shadow-popover);
  padding: var(--s4);
  padding-bottom: max(var(--s4), env(safe-area-inset-bottom));
}
.sheet[hidden] { display: none; }
.sheet-handle {
  width: 40px;
  height: 4px;
  margin: 0 auto var(--s3);
  border-radius: 999px;
  background: var(--line-strong);
}

/* ===== 16. Stat grid — label 12px muted over value 20px 600, two or three columns ===== */
.stat-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s4); }
.stat-grid--2 { grid-template-columns: repeat(2, 1fr); }
.stat { min-width: 0; }
.stat-label { font-size: 12px; color: var(--muted); line-height: 1.5; }
.stat-value {
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}
.stat-unit { font-size: 13px; font-weight: 400; color: var(--muted); }

/* ===== 17. Result hero — label, main number 36px 700 tabular, unit 16px muted, one line of meaning 14px ===== */
.result-hero { padding: var(--s4); }
.result-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  line-height: 1.3;
}
.result-value {
  font-size: 36px;
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  margin-top: var(--s1);
}
.result-value .result-unit { font-size: 16px; font-weight: 400; color: var(--muted); }
.result-meaning {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
  margin-top: var(--s2);
}

/* ===== 18. Data table — 13px, 36px rows, sticky header, numbers right-aligned, no zebra, thin dividers, horizontal scroll in its own box, copy + CSV in the card header ===== */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  line-height: 1.3;
}
.data-table th, .data-table td {
  padding-left: var(--s3);
  padding-right: var(--s3);
  height: 36px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.data-table thead th {
  position: sticky;
  top: 0;
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  z-index: 1;
}
.data-table tbody tr:last-child th, .data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr:hover { background: var(--surface-2); }
.data-table td.num, .data-table th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ===== 19. Notice — info/warning/error with icon and soft tinted background. The safety sentence uses the info notice, one line, 13px ===== */
.notice {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-radius: var(--radius-card);
  font-size: 13px;
  line-height: 1.5;
}
.notice svg {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 1px;
}
.notice--info { background: var(--info-soft); color: var(--ink); }
.notice--info svg { color: var(--primary); }
.notice--warn { background: var(--warn-soft); color: var(--ink); }
.notice--warn svg { color: var(--warn); }
.notice--err { background: var(--err-soft); color: var(--ink); }
.notice--err svg { color: var(--err); }
.notice--ok { background: var(--ok-soft); color: var(--ink); }
.notice--ok svg { color: var(--ok); }
.safety-note { font-size: 13px; line-height: 1.5; }

/* ===== 20. Empty state ===== */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--s2);
  padding: var(--s7) var(--s4);
  color: var(--muted);
}
.empty-state svg { width: 36px; height: 36px; color: var(--line-strong); }
.empty-state .empty-title { font-size: 16px; font-weight: 600; color: var(--ink); }
.empty-state p { font-size: 14px; max-width: 70ch; }

/* ===== 21. Graph and canvas — plot clamp(320px,52vh,560px) desktop, 280-340px phones; no forced 4:3/16:10; axis 12px muted, axis titles 13px with units, grid lines --line, no box around the plot, 8px extra padding; legend inline top right; curve 2.5px round joins; markers 5px; bands 12% opacity + label; hover/touch crosshair + value tooltip; header holds title + segmented + Table/Export/Full screen icon buttons; nothing loose under the plot ===== */
.graph-card { padding: 0; overflow: hidden; }
.graph-card .graph-header {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-wrap: wrap;
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
}
.graph-card .graph-header h2, .graph-card .graph-header h3 { font-size: 16px; margin-right: auto; }
.graph-card .graph-header .graph-tools {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-left: auto;
}
.plot {
  position: relative;
  height: clamp(320px, 52vh, 560px);
  padding: var(--s2);
  background: var(--surface);
}
.plot-surface { width: 100%; height: 100%; }
.plot-surface svg, .plot-surface canvas { width: 100%; height: 100%; }
.axis-label { font-size: 12px; fill: var(--muted); }
.axis-title { font-size: 13px; fill: var(--ink-2); }
.plot-grid-line { stroke: var(--line); stroke-width: 1; }
.plot-curve {
  fill: none;
  stroke-width: 2.5px;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.plot-marker { r: 5px; }
.plot-band { opacity: .12; }
.plot-band-label { font-size: 12px; fill: var(--muted); }
.plot-legend {
  position: absolute;
  top: var(--s3);
  right: var(--s4);
  display: flex;
  gap: var(--s3);
  font-size: 12px;
  color: var(--ink-2);
  background: var(--surface);
  padding: var(--s1) var(--s2);
  border-radius: var(--radius-chip);
  border: 1px solid var(--line);
}
.plot-legend .legend-swatch {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 999px;
  margin-right: var(--s1);
  vertical-align: -1px;
}
.plot-crosshair {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--line-strong);
  pointer-events: none;
}
.plot-tooltip {
  position: absolute;
  z-index: 5;
  padding: var(--s1) var(--s2);
  background: var(--ink);
  color: var(--bg);
  border-radius: var(--radius-control);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* ===== 22. Shell primitives — Chunk 2 owns the app shell; these are only the shared basics it is built from ===== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 70;
  height: 52px;
  display: flex;
  align-items: center;
  gap: var(--s4);
  padding-left: var(--s4);
  padding-right: var(--s4);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.site-header .brand {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.site-header .brand:hover { text-decoration: none; }
.site-header .brand-mark {
  width: 24px;
  height: 24px;
  flex: none;
  color: var(--primary);
  border-radius: 6px;
}
.site-header nav {
  display: flex;
  align-items: center;
  gap: var(--s1);
  margin-left: auto;
}
.site-header nav a {
  padding: var(--s2) var(--s3);
  border-radius: var(--radius-control);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
}
.site-header nav a:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.site-footer {
  border-top: 1px solid var(--line);
  padding: var(--s5) var(--s4);
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
}
.site-footer .footer-inner {
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s5);
}
.site-footer h3 { font-size: 14px; margin-bottom: var(--s2); }
.site-footer a { display: block; padding-top: 4px; padding-bottom: 4px; }
.breadcrumb {
  font-size: 13px;
  color: var(--muted);
  line-height: 1.3;
  margin-bottom: var(--s2);
}
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--primary); }
.title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
}
.title-row .title-text { min-width: 0; }
.title-row .title-actions {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex: none;
}

/* ===== 23. Responsive — coarse pointers: controls grow to 44px / 16px text (also stops iOS zoom on focus) ===== */
@media (pointer: coarse) {
  .btn, .input, select.input, .btn-icon, .segmented button { height: 44px; font-size: 16px; }
  .btn-icon { width: 44px; }
  .tabs [role="tab"] { height: 44px; }
  .data-table th, .data-table td { height: 44px; }
}
@media (max-width: 1023px) {
  .workbench { grid-template-columns: 1fr; }
  .site-footer .footer-inner { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
  .page { padding-left: var(--s4); padding-right: var(--s4); }
  .plot { height: clamp(280px, 52vh, 340px); }
  .title-row { flex-direction: column; }
  .title-row .title-actions { width: 100%; }
  .breadcrumb { display: none; }
  .site-header nav a:not(.nav-keep) { display: none; }
}

/* ===== 24. Reduced motion and print — the ONLY !important in this file ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .accordion-panel { transition: none !important; }
}
@media print {
  .site-header nav, .toast-stack, .modal-backdrop, .sheet, [data-tooltip]::after { display: none !important; }
  body { background: #fff !important; color: #000 !important; }
  .card, .table-wrap { box-shadow: none !important; border-color: #999 !important; }
}

/* ===== 25. App shell — Chunk 2 =====
   Header search and command palette, mobile nav, theme menu, home page
   (hero, search, card grid) and the wide page. Only Chunk 1 tokens,
   only the 12/13/14/16/20/24/32/36 font sizes, only the s1–s7 spacing
   scale, only the 6/10/999 radii. No inline <style> on any page. */
.icon { width: 24px; height: 24px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.visually-hidden { position: absolute; left: 0; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Header: search button and theme menu */
.header-search .search-kbd { font-size: 12px; color: var(--muted); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: var(--s1) var(--s2); }
.header-search svg { width: 20px; height: 20px; flex: none; }
.theme-menu .menu-item svg { width: 20px; height: 20px; }
.theme-menu .menu-check { margin-left: auto; font-size: 14px; color: var(--primary); }
/* Chunk 9 (test 8): the theme toggle shows its icons and menu ticks by
   class, never by an inline style. The light icon carries .is-on in the
   static markup; app.js moves the class when the choice changes. */
#themeBtn [data-theme-icon] { display: none; }
#themeBtn [data-theme-icon].is-on { display: inline-block; }
.theme-menu .menu-check { visibility: hidden; }
.theme-menu .menu-check.is-on { visibility: visible; }
.nav-toggle { display: none; }

/* Mobile nav: the nav is a drop-down panel, one group at a time.
   The nav switches to the menu button below 1024px because seven links
   plus brand, search and theme do not fit on a tablet. The search button
   keeps its label on tablets and becomes icon-only below 767px, the
   design system's own mobile breakpoint (section 23 hides nav links
   below 767px; the rule below overrides it only while the nav is open).
   The breadcrumb stays in the DOM on phones but is hidden by
   section 23 to save space. */
@media (max-width: 767px) {
  .header-search .search-label, .header-search .search-kbd { display: none; }
  .header-search { width: 36px; padding-left: 0; padding-right: 0; }
}
@media (max-width: 1023px) {
  .nav-toggle { display: inline-flex; }
  .site-header nav { display: none; position: absolute; top: 100%; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: var(--s1); padding: var(--s3) var(--s4); background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: var(--shadow-popover); }
  .site-header nav.open { display: flex; }
  .site-header nav.open a { display: flex; }
  .nav-group-btn { display: flex; align-items: center; justify-content: space-between; width: 100%; min-height: 44px; padding: var(--s2) var(--s3); border-radius: var(--radius-control); font-size: 14px; font-weight: 600; color: var(--ink); }
  .nav-group-btn:hover { background: var(--surface-2); }
  .nav-group-btn svg { width: 20px; height: 20px; color: var(--muted); transition: transform var(--dur-fast) var(--ease-out); }
  .nav-group.open .nav-group-btn svg { transform: rotate(180deg); }
  .nav-group-links { display: none; flex-direction: column; padding-left: var(--s4); }
  .nav-group.open .nav-group-links { display: flex; }
}
@media (min-width: 1024px) {
  .nav-group-btn { display: none; }
  .nav-group-links { display: contents; }
}

/* Phones: header icon buttons are 44px */
@media (pointer: coarse) {
  .site-header .btn-icon { width: 44px; height: 44px; }
  .site-header .btn-icon svg { width: 24px; height: 24px; }
  .site-header .header-search { height: 44px; }
}

/* Command palette */
.cmdk { position: fixed; inset: 0; z-index: 100; display: none; padding: var(--s7) var(--s4) var(--s4); background: rgba(15, 27, 45, .45); }
.cmdk.open { display: block; }
.cmdk-box { max-width: 560px; margin: 0 auto; overflow: hidden; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-popover); }
.cmdk-box:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.cmdk-input-row { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); border-bottom: 1px solid var(--line); }
.cmdk-input-row svg { width: 20px; height: 20px; color: var(--muted); }
.cmdk-input-row input { flex: 1; border: none; background: transparent; font-size: 16px; color: var(--ink); }
.cmdk-input-row input:focus { outline: none; }
.cmdk-input-row kbd { font-size: 12px; color: var(--muted); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: var(--s1) var(--s2); }
.cmdk-list { list-style: none; margin: 0; padding: var(--s2); max-height: 320px; overflow-y: auto; }
.cmdk-item { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) var(--s3); border-radius: var(--radius-control); cursor: pointer; }
.cmdk-item[aria-selected="true"] { background: var(--primary-soft); }
.cmdk-item .icon { width: 20px; height: 20px; color: var(--muted); }
.cmdk-name { font-size: 14px; font-weight: 600; white-space: nowrap; }
.cmdk-sub { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--muted); }
.cmdk-key { font-size: 12px; color: var(--muted); border: 1px solid var(--line); border-radius: var(--radius-btn); padding: var(--s1) var(--s2); }
.cmdk-empty { padding: var(--s4); font-size: 14px; color: var(--muted); }
.cmdk-foot { display: flex; flex-wrap: wrap; gap: var(--s4); padding: var(--s2) var(--s4); border-top: 1px solid var(--line); font-size: 12px; color: var(--muted); }

/* Home page */
.home-hero { padding: var(--s6) 0 var(--s4); }
.home-hero .lede { margin-top: var(--s2); }
.home-search { display: flex; align-items: center; gap: var(--s3); height: 44px; margin-top: var(--s4); padding: 0 var(--s3); background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-control); }
.home-search:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }
.home-search svg { width: 20px; height: 20px; color: var(--muted); }
.home-search input { flex: 1; border: none; background: transparent; font-size: 16px; color: var(--ink); }
.home-search input:focus { outline: none; }
.home-count { margin-top: var(--s2); font-size: 14px; color: var(--muted); }
.home-section { margin-top: var(--s6); }
.home-section h2 { font-size: 20px; }
.home-section .home-section-sub { margin-top: var(--s1); font-size: 14px; color: var(--muted); }
.home-grid { display: grid; gap: var(--s4); margin-top: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 600px) { .home-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .home-grid { grid-template-columns: 1fr 1fr 1fr; } }
.home-card { display: flex; flex-direction: column; gap: var(--s2); color: var(--ink); text-decoration: none; }
.home-card:hover { text-decoration: none; }
.home-icon { display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; background: var(--primary-soft); border-radius: var(--radius-card); color: var(--primary); }
.home-num { font-size: 12px; font-weight: 600; color: var(--muted); }
.home-card h3 { font-size: 20px; }
.home-card p { flex: 1; font-size: 14px; color: var(--muted); }
.home-tags { display: flex; flex-wrap: wrap; gap: var(--s2); }

/* Wide page (figure canvas) and footer version line */
.page--wide { max-width: none; }
.footer-version { font-size: 12px; color: var(--muted); }
/* ===== 26. Home page — Chunk 3 =====
   Home redesign: labelled search with a button, Learn now tiles,
   search results list view, For learning line. Only Chunk 1 tokens,
   only the 12/13/14/16/20/24/32/36 font sizes, only the s1–s7 spacing
   scale, only the 6/10/999 radii. The search row's top margin moved
   from .home-search (section 25) to the form wrapper below, so the
   label and the row sit together. */
.home-search-form { margin-top: var(--s4); }
.home-search-label { display: block; margin-bottom: var(--s1); font-size: 13px; font-weight: 600; color: var(--ink-2); }
.home-search { margin-top: 0; }
.home-search .btn { flex: none; }
.home-search input { min-width: 0; }

/* Learn now tiles: same card grid as the tool cards, with a time line */
.learn-time { font-size: 13px; font-weight: 600; color: var(--primary); }

/* Search results list view: shown only while a query is active */
.search-group { margin-top: var(--s4); }
.search-group h3 { font-size: 16px; }
.search-group-count { font-size: 13px; font-weight: 400; color: var(--muted); }
.search-result { display: flex; align-items: flex-start; gap: var(--s3); padding: var(--s3) 0; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none; }
.search-result:first-of-type { border-top: none; }
.search-result:hover .search-result-name { text-decoration: underline; }
.search-result-text { display: flex; flex-direction: column; gap: var(--s1); min-width: 0; }
.search-result-name { font-size: 16px; font-weight: 600; }
.search-result-summary { font-size: 14px; color: var(--muted); }
.search-more { margin-top: var(--s3); }

/* For learning line, after the cards */
.home-learning { margin-top: var(--s6); font-size: 14px; color: var(--muted); text-align: center; }

/* ===== 27. Workbench — Chunk 4 =====
   The tool workbench: inputs card left (380px), results stack right.
   Every rule here is scoped under .tool-body .workbench so it beats the
   legacy .tool-body rules (tool-base.css, loaded after this file) where
   the two disagree — legacy .btn is 44px/16px with a --lg-primary
   background, legacy .field input is 44px/16px, legacy .card is 24px
   padding on desktop, legacy h3 is 18px, legacy p carries a 16px bottom
   margin. Inside the workbench the Chunk 1 values win; outside it the
   legacy tools are untouched. Kept legacy helpers (.btn-row, .status,
   .export-bar, .table-wrap) are layout only and stay as they are. */
.tool-body .workbench .card {
  background: var(--surface);
  border-color: var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: var(--s4);
  margin-bottom: 0;
}
.tool-body .workbench .card.graph-card { padding: 0; }
.tool-body .workbench .card-header h2 { font-size: 16px; margin: 0; }
/* Groups inside the stack: the stack gap replaces the group's top margin,
   the hairline + top padding stay, so groups read the same as elsewhere. */
.tool-body .workbench .stack > .group { margin-top: 0; }
.tool-body .workbench h3.group-title {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 var(--s3);
}
.tool-body .workbench .graph-header h2 { margin: 0; }
/* Buttons: Chunk 1 sizes and colours, not the legacy 44px primary. */
.tool-body .workbench .btn {
  min-width: 0;
  min-height: 36px;
  height: 36px;
  padding: 8px 12px;
  font-size: 14px;
}
.tool-body .workbench .btn-primary { background: var(--primary); color: var(--on-primary); }
.tool-body .workbench .btn-secondary { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.tool-body .workbench .btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.tool-body .workbench .btn-tertiary { background: transparent; border-color: transparent; color: var(--primary); }
.tool-body .workbench .btn-tertiary:hover { background: var(--primary-soft); }
.tool-body .workbench .btn:hover { filter: none; }
/* Fields: Chunk 1 36px controls; the flex gap (4px) replaces the legacy
   label/helper margins. */
.tool-body .workbench .field { margin-bottom: var(--s3); }
.tool-body .workbench .field label { margin-bottom: 0; }
.tool-body .workbench .field .helper { margin-top: 0; }
.tool-body .workbench .field-error { font-size: 12px; color: var(--err); margin-top: 0; }
.tool-body .workbench input.input,
.tool-body .workbench select.input,
.tool-body .workbench textarea.input {
  height: 36px;
  min-height: 36px;
  padding: 8px 12px;
  font-size: 14px;
  border-color: var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
}
.tool-body .workbench input.input-large { height: 48px; min-height: 48px; font-size: 16px; }
.tool-body .workbench .input-wrap input.input { padding-right: 48px; }
.tool-body .workbench input.input:focus,
.tool-body .workbench select.input:focus {
  border-color: var(--primary);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tool-body .workbench input.input[aria-invalid="true"],
.tool-body .workbench select.input[aria-invalid="true"] { border-color: var(--err); }
.tool-body .workbench .input-wrap .input-unit {
  position: absolute;
  right: 10px;
  font-size: 13px;
  color: var(--muted);
  pointer-events: none;
}
/* Result hero: the legacy p margin (16px bottom) must not apply here. */
.tool-body .workbench .result-hero .result-label { margin: 0; }
.tool-body .workbench .result-hero .result-value { margin: var(--s1) 0 0; }
.tool-body .workbench .result-hero .result-meaning { margin: var(--s2) 0 0; }
.tool-body .workbench .result-hero .accordion { margin-top: var(--s4); }
/* Helpers, status, safety and export sit in the stack, so the stack gap
   is their spacing — no extra margins. */
.tool-body .workbench p.helper { margin-bottom: 0; }
.tool-body .workbench .example-row + .helper,
.tool-body .workbench .btn-row + .helper,
.tool-body .workbench .tab-panel + .helper { margin-top: var(--s2); }
.tool-body .workbench .status { margin: 0; }
.tool-body .workbench .safety-note { margin: 0; }
.tool-body .workbench .export-bar { margin-top: 0; }
/* Worked-example row: button + select side by side, wrapping. */
.tool-body .workbench .example-row { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.tool-body .workbench .example-row select { flex: 1 1 160px; min-width: 0; }
/* Calculate / Reset stack at the bottom of the Inputs card. */
.tool-body .workbench .workbench-actions { display: grid; gap: var(--s2); }
/* Formula lines in the "How was this calculated?" accordion. */
.tool-body .workbench .formula {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--s3);
  overflow-x: auto;
  margin: 8px 0;
}
/* Result notes kept from the legacy tools (renal weight line, warnings).
   Plain line is 14px: 15px is not on the type scale. */
.tool-body .workbench .warn-inline { color: var(--warn); font-size: 14px; margin: 0; }
.tool-body .workbench .plain-line { font-size: 14px; margin: 0; }
/* Short plot for the wide, short renal bar (standard plot is 320–560px). */
.tool-body .workbench .plot--short { height: clamp(220px, 34vh, 300px); }
@media (max-width: 767px) {
  .tool-body .workbench .plot--short { height: clamp(200px, 30vh, 260px); }
}
/* Coarse pointers: controls grow to 44px / 16px, as in section 23. */
@media (pointer: coarse) {
  .tool-body .workbench .btn { min-height: 44px; height: 44px; font-size: 16px; }
  .tool-body .workbench input.input,
  .tool-body .workbench select.input { height: 44px; min-height: 44px; font-size: 16px; }
}

/* ===== 28. Simulator — Chunk 5a =====
   Graph-first layout for the simulator tools (PK/PD Graph Builder,
   Multiple Dose Simulator). Desktop: a 340px sticky sidebar left
   (accordion groups, one open at a time, each with a coloured dot and
   a one-line summary of its current values; Reset and Examples in the
   footer), and the graph card, result strip and tabs card right.
   The graph card header holds the view segmented control, the scale
   switch, the Table toggle, the Display options and Export menus, the
   reference pin buttons and Full screen. Phone: graph first (about
   300px), then the strip as a horizontal row, then the sidebar groups,
   then the tabs card. Tablet (768–1023px): the sidebar is a
   collapsible panel above the graph, opened by the Controls toggle in
   the graph header. Every rule is scoped under .tool-body .simulator
   so it beats the legacy .tool-body rules in tool-base.css, which load
   after this file — same reason as the §27 workbench overrides. */
.tool-body .simulator {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  grid-template-areas:
    "side graph"
    "side strip"
    "side tabs"
    "side related";
  gap: var(--s4);
  align-items: start;
}
.tool-body .simulator > * { min-width: 0; }
.tool-body .sim-sidebar { grid-area: side; }
.tool-body .sim-graph-card { grid-area: graph; }
.tool-body .sim-strip { grid-area: strip; }
.tool-body .sim-tabs-card { grid-area: tabs; }
.tool-body .sim-related { grid-area: related; }
/* Sidebar: sticky under the 52px site header, scrolls inside itself. */
.tool-body .sim-sidebar {
  position: sticky;
  top: 68px;
  max-height: calc(100vh - 84px);
  overflow-y: auto;
}
.tool-body .sim-sidebar .card { margin-bottom: 0; }
.tool-body .sim-sidebar-footer {
  padding-top: var(--s4);
  margin-top: var(--s4);
  border-top: 1px solid var(--line);
  display: grid;
  gap: var(--s2);
}
/* Sidebar group header: coloured dot + name + chevron; the summary
   line under it is always visible, so the group's state reads without
   opening it. */
.tool-body .sim-group-header .group-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--primary);
  flex: none;
}
.tool-body .sim-group-header .group-dot--blue { background: var(--g-blue); }
.tool-body .sim-group-header .group-dot--green { background: var(--g-green); }
.tool-body .sim-group-header .group-dot--orange { background: var(--g-orange); }
.tool-body .sim-group-header .sim-group-name { flex: 1 1 auto; }
.tool-body .sim-group-summary {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.4;
  margin: 0 0 var(--s2);
  padding-left: 16px;
  overflow-wrap: break-word;
}
.tool-body .sim-group-summary:empty { display: none; }
/* Fields and buttons: Chunk 1 36px controls, not the legacy 44px. */
.tool-body .simulator .field { margin-bottom: var(--s3); }
.tool-body .simulator .field label { margin-bottom: 0; }
.tool-body .simulator .field .helper { margin-top: 0; }
.tool-body .simulator .field-error { font-size: 12px; color: var(--err); margin-top: 0; }
.tool-body .simulator input.input,
.tool-body .simulator select.input,
.tool-body .simulator textarea.input {
  height: 36px;
  min-height: 36px;
  padding: 8px 12px;
  font-size: 14px;
  border-color: var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
}
.tool-body .simulator input.input:focus,
.tool-body .simulator select.input:focus {
  border-color: var(--primary);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tool-body .simulator input.input[aria-invalid="true"],
.tool-body .simulator select.input[aria-invalid="true"] { border-color: var(--err); }
.tool-body .simulator .input-wrap input.input { padding-right: 48px; }
.tool-body .simulator .input-wrap .input-unit {
  position: absolute;
  right: 10px;
  font-size: 13px;
  color: var(--muted);
  pointer-events: none;
}
.tool-body .simulator input[type="range"].range { width: 100%; }
.tool-body .simulator .radio-line {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s3);
  margin-bottom: var(--s3);
}
.tool-body .simulator .radio-line label,
.tool-body .simulator .check-line {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  cursor: pointer;
}
.tool-body .simulator .check-line { margin-bottom: var(--s3); }
.tool-body .simulator .check-line input[type="checkbox"],
.tool-body .simulator .radio-line input[type="radio"] {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--primary);
}
.tool-body .simulator .btn {
  min-width: 0;
  min-height: 36px;
  height: 36px;
  padding: 8px 12px;
  font-size: 14px;
}
.tool-body .simulator .btn-primary { background: var(--primary); color: var(--on-primary); }
.tool-body .simulator .btn-secondary { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.tool-body .simulator .btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.tool-body .simulator .btn-tertiary { background: transparent; border-color: transparent; color: var(--primary); }
.tool-body .simulator .btn-tertiary:hover { background: var(--primary-soft); }
.tool-body .simulator .btn:hover { filter: none; }
.tool-body .simulator p.helper { margin-bottom: 0; }
.tool-body .simulator .status { margin: 0; }
.tool-body .simulator .safety-note { margin: 0; }
.tool-body .simulator .plain-line { font-size: 14px; margin: 0; }
.tool-body .simulator .warn-inline { color: var(--warn); font-size: 14px; margin: 0; }
/* Formula block (the maths panel) — same block as the workbench one. */
.tool-body .simulator .formula {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--s3);
  overflow-x: auto;
  margin: 8px 0;
  white-space: pre-wrap;
}
/* Graph card: no padding of its own; header, plot and foot stack. */
.tool-body .sim-graph-card { padding: 0; }
.tool-body .sim-graph-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
}
.tool-body .sim-graph-header .segmented { flex: 1 1 240px; min-width: 0; }
.tool-body .sim-graph-header .menu-wrap { flex: none; }
.tool-body .sim-plot { padding: var(--s3) var(--s4) 0; }
.tool-body .sim-plot .canvas-wrap,
.tool-body .sim-plot .chartbox { width: 100%; }
.tool-body .sim-graph-foot { padding: var(--s2) var(--s4) var(--s4); }
.tool-body .sim-graph-foot > * + * { margin-top: var(--s2); }
/* Chart containers: the tool JS sets the SVG size from the box width,
   so the SVG fills its container. */
.tool-body .simulator #chartMain,
.tool-body .simulator #chartMulti,
.tool-body .simulator #chartTable { width: 100%; }
.tool-body .simulator #chartMain svg,
.tool-body .simulator #chartMulti svg,
.tool-body .simulator #chartTable svg { display: block; width: 100%; height: 100%; }
.tool-body .simulator .chartbox svg { display: block; width: 100%; height: auto; touch-action: pan-y; border-radius: 10px; }
.tool-body .simulator .chartbox svg:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* Multi-dose levels sub-panel inside the graph card (shown by the
   Display options switch, not a section of its own). */
.tool-body .sim-multi {
  border-top: 1px solid var(--line);
  padding: var(--s4);
}
.tool-body .sim-multi > * + * { margin-top: var(--s2); }
.tool-body .sim-multi-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
}
.tool-body .sim-multi-header h3 { font-size: 14px; margin: 0; }
/* Dosing-interval slider row (Multiple Dose): the slider is the star,
   full width of the graph card, with the live peak and trough tiles
   beside it. */
.tool-body .sim-tau-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--s3);
  align-items: center;
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
}
.tool-body .sim-tau-row .range-wrap { min-width: 0; }
.tool-body .sim-tau-tile { min-width: 104px; }
.tool-body .sim-tau-tile .stat-value { font-size: 20px; }
/* Helper under the tau slider row (Multiple Dose). */
.tool-body .sim-tau-help {
  padding: var(--s2) var(--s4);
  margin: 0;
  border-bottom: 1px solid var(--line);
}
/* Result strip: 4–6 stat tiles in one row, key number first. */
.tool-body .sim-strip {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--s3);
}
.tool-body .sim-strip .stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--s3) var(--s4);
  min-width: 0;
}
.tool-body .sim-strip .stat-value { overflow-wrap: break-word; }
/* Tabs card: the tab panels sit under the tabs with a little air. */
.tool-body .sim-tabs-card .tab-panel { padding-top: var(--s4); }
.tool-body .sim-tabs-card .tab-panel > * + * { margin-top: var(--s3); }
.tool-body .sim-tabs-card h3 { font-size: 16px; margin: 0; }
/* Sidebar group headings: the button is the heading's content. */
.tool-body .sim-sidebar .accordion-item > h3 { margin: 0; font-size: inherit; }
/* Result hero inside the graph foot: no extra padding, margins reset. */
.tool-body .sim-graph-foot .result-hero { padding: 0; }
.tool-body .simulator .result-hero .result-label { margin: 0; }
.tool-body .simulator .result-hero .result-value { margin: var(--s1) 0 0; }
.tool-body .simulator .result-hero .result-meaning { margin: var(--s2) 0 0; }
/* Curve data table inside the graph card (Table toggle). */
.tool-body .sim-data {
  border-top: 1px solid var(--line);
  padding: var(--s4);
}
.tool-body .sim-data > * + * { margin-top: var(--s2); }
.tool-body .sim-data h3 { font-size: 14px; margin: 0; }
/* Form rows inside a menu (Display options). */
.tool-body .menu-section {
  padding: var(--s2) var(--s3);
  border-top: 1px solid var(--line);
}
.tool-body .menu-section .field:last-child { margin-bottom: 0; }
/* Full screen: the graph card fills the screen and scrolls. */
.tool-body .sim-graph-card:fullscreen {
  background: var(--surface);
  padding: var(--s4);
  overflow-y: auto;
  border-radius: 0;
}
/* The Controls toggle only exists on tablets (768–1023px), where the
   sidebar is a collapsible panel above the graph. Scoped under
   .simulator so it beats the legacy .tool-body .btn rule in
   tool-base.css, which loads after this file and ties at (0,2,0). */
.tool-body .simulator .sim-controls-toggle { display: none; }
@media (max-width: 1023px) {
  .tool-body .simulator {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "graph"
      "strip"
      "side"
      "tabs"
      "related";
  }
  .tool-body .sim-sidebar {
    position: static;
    max-height: none;
    overflow: visible;
  }
  /* Phone: the strip scrolls sideways, tiles keep their width. */
  .tool-body .sim-strip {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: var(--s1);
  }
  .tool-body .sim-strip .stat { flex: 0 0 132px; scroll-snap-align: start; }
  /* Phone: the tau slider spans the row, tiles sit below it. */
  .tool-body .sim-tau-row { grid-template-columns: 1fr 1fr; }
  .tool-body .sim-tau-row .range-wrap { grid-column: 1 / -1; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .tool-body .simulator {
    grid-template-areas:
      "side"
      "graph"
      "strip"
      "tabs"
      "related";
  }
  .tool-body .sim-sidebar { display: none; }
  .tool-body .simulator.sim-controls-open .sim-sidebar { display: block; }
  .tool-body .simulator .sim-controls-toggle { display: inline-flex; }
}
/* Phones (<600px): the graph is about 300px tall (Chunk 5 acceptance),
   so the plot box is square instead of 4:3. The PK/PD chart ratio in
   the tool JS matches (1.0 below 600px); the multi and table charts
   already draw at 300px on narrow screens. */
@media (max-width: 599px) {
  .tool-body .simulator .canvas-wrap { aspect-ratio: 1 / 1; }
}
/* Coarse pointers: controls grow to 44px / 16px, as in section 23. */
@media (pointer: coarse) {
  .tool-body .simulator .btn { min-height: 44px; height: 44px; font-size: 16px; }
  .tool-body .simulator input.input,
  .tool-body .simulator select.input { height: 44px; min-height: 44px; font-size: 16px; }
}

/* ===== 29. Studio — Chunk 6a =====
   Work-area-first layout for the studio tools (Draw Structure,
   Mechanism Arrows, Structures from a Name, Equation Balancer).
   Desktop: a 44px vertical tool rail left (icon buttons, tooltips,
   active = --primary-soft fill + primary icon), the work area in the
   middle (canvas/viewer height clamp(420px, 64vh, 720px), no forced
   aspect ratio; drawing canvases get a dot-grid background), and a
   280px properties panel right (titled groups, collapsible). A
   floating mini-toolbar (Undo, Redo, Clear) sits top-left of the
   canvas and an Export menu top-right; a 28px status bar sits under
   the work area (hint left, counts right). At 1440x900 the work area
   is >=60% of the visible height. Phones: work area first, then the
   rail as a horizontal toolbar, then the properties panel below.
   Every rule is scoped under .tool-body .studio so it beats the
   legacy .tool-body rules in tool-base.css, which load after this
   file — same reason as the §27/§28 overrides. */
.tool-body .studio {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 280px;
  grid-template-areas:
    "rail work props"
    "rail status props"
    "learn learn learn"
    "related related related";
  gap: var(--s4);
  align-items: start;
}
.tool-body .studio > * { min-width: 0; }
.tool-body .studio-rail { grid-area: rail; }
.tool-body .studio-work { grid-area: work; }
.tool-body .studio-props { grid-area: props; }
.tool-body .studio-status { grid-area: status; }
.tool-body .studio-learn { grid-area: learn; }
.tool-body .studio-related { grid-area: related; }
/* Variants: --top (Structures from a Name) puts one large input at
   the top and the results grid below; --panes (Equation Balancer)
   has a 320px input pane left and the result pane right. */
.tool-body .studio--top {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "input"
    "work"
    "status"
    "learn"
    "related";
}
.tool-body .studio--panes {
  grid-template-columns: 320px minmax(0, 1fr);
  grid-template-areas:
    "input work"
    "input status"
    "learn learn"
    "related related";
}
/* Variant: --top-props (Molecule Views, Ethanol Five Ways, 3D Viewer,
   Periodic Table) puts one input card at the top and the summary /
   details panel pinned beside the work area. */
.tool-body .studio--top-props {
  grid-template-columns: minmax(0, 1fr) 280px;
  grid-template-areas:
    "input input"
    "work props"
    "status props"
    "learn learn"
    "related related";
}
.tool-body .studio-input { grid-area: input; }
/* Tool rail: vertical column of 44px icon buttons. Active = the
   shared .is-active / aria-pressed look (primary-soft fill). */
.tool-body .studio-rail {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  position: sticky;
  top: 68px;
  padding: var(--s1);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
}
.tool-body .studio-rail .rail-sep {
  height: 1px;
  background: var(--line);
  margin: var(--s1) 0;
}
.tool-body .studio-rail .btn-icon {
  width: 36px;
  height: 36px;
}
.tool-body .studio-rail .btn-icon.active,
.tool-body .studio-rail .btn-icon.is-active,
.tool-body .studio-rail .btn-icon[aria-pressed="true"] {
  background: var(--primary-soft);
  color: var(--primary);
}
/* The tool JS toggles .is-active/.secondary on the draw-structure rail
   buttons and .active on the mechanism rail buttons; both read as
   the active state in the rule above. */
/* Work area: the canvas/viewer card. No padding of its own; the
   canvas wraps fill it. */
.tool-body .studio-work { padding: 0; overflow: visible; }
.tool-body .studio-canvas-wrap {
  position: relative;
  border-radius: var(--radius-card);
  overflow: hidden;
}
.tool-body .studio-canvas-wrap .canvas-wrap,
.tool-body .studio-canvas-wrap .mechanism-canvas {
  height: clamp(420px, 64vh, 720px);
  width: 100%;
}
.tool-body .studio-canvas-wrap .canvas-wrap { aspect-ratio: auto; }
/* Dot-grid background on drawing canvases. */
.tool-body .studio-canvas-wrap--dots {
  background-color: var(--surface);
  background-image: radial-gradient(circle, var(--line-strong) 1px, transparent 1px);
  background-size: 22px 22px;
}
.tool-body .studio-canvas-wrap--dots svg { background: transparent; }
.tool-body .studio-canvas-wrap svg { display: block; width: 100%; height: 100%; }
/* The mechanism canvas keeps its own touch behaviour and cursor. */
.tool-body .studio .mechanism-canvas {
  touch-action: none;
  cursor: crosshair;
}
.tool-body .studio .mechanism-canvas text { user-select: none; }
.tool-body .studio .arrow-handle { cursor: grab; touch-action: none; }
/* Draw Structure: the picked atom button shows white text on its
   element colour (the JS sets the inline background). */
.tool-body .studio .atom-btn { min-width: 48px; font-weight: 700; }
.tool-body .studio .atom-btn.active { color: #fff; }
.tool-body .studio .canvas-wrap > svg { touch-action: none; cursor: crosshair; }
/* Atom picker row in the properties panel. */
.tool-body .studio-props .atom-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
/* Floating mini-toolbar top-left of the canvas, Export menu
   top-right. Both float over the work area. */
.tool-body .studio-float {
  position: absolute;
  z-index: 3;
  display: flex;
  gap: var(--s1);
}
.tool-body .studio-float--left { top: var(--s2); left: var(--s2); }
.tool-body .studio-float--right { top: var(--s2); right: var(--s2); }
.tool-body .studio-float .btn-icon {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  box-shadow: var(--shadow-card);
}
.tool-body .studio-float .menu-wrap { position: relative; }
/* Work card header (Structures from a Name): title left, Export
   menu right. */
.tool-body .studio-work-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
}
.tool-body .studio-work-head h2 { font-size: 16px; margin: 0; }
.tool-body .studio-work-head .menu-wrap { flex: none; }
.tool-body .studio-results-wrap { padding: var(--s4); }
/* View area: the tabbed views card (Molecule Views, Ethanol Five Ways).
   Positioned so the floating Export menu can sit top-right over the
   views. */
.tool-body .studio-view-wrap {
  position: relative;
  padding: var(--s4);
  /* Chunk 9 (test 5): the work area must be at least 60% of the viewport
     height, like the canvas tools get from their clamp(420px, 64vh, 720px)
     wrap. The two tools that use this wrap (Ethanol Five Ways, Molecule
     Views) have short content, so the wrap takes the same floor. */
  min-height: clamp(420px, 64vh, 720px);
}
/* Properties tabs (3D Viewer Details | Style | Measure, Periodic
   Table Overview | Properties | Ions): the shared Chunk 1 .tabs,
   switched by app.js initTabs. */
.tool-body .studio-prop-tabs .tabs {
  padding: 0 var(--s2);
}
.tool-body .studio-prop-tabs .tabs [role="tab"] {
  padding-left: var(--s2);
  padding-right: var(--s2);
}
.tool-body .studio-prop-tabs .tab-panel {
  padding: var(--s4);
}
.tool-body .studio-prop-tabs .tab-panel > * + * { margin-top: var(--s3); }
/* Periodic Table: one toolbar row — search field (flexes), Colour by
   select, List view toggle — with the colour legend as a compact
   inline row under it. */
.tool-body .studio-input .pt-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: end;
}
.tool-body .studio-input .pt-toolbar .field { flex: 1 1 260px; margin-bottom: 0; }
.tool-body .studio-input .pt-toolbar .field .input { width: 100%; }
.tool-body .studio-input .pt-toolbar .btn { flex: none; }
.tool-body .studio-input .pt-legend-box { margin: var(--s3) 0 0; }
/* Learn section under the studio can hold more than one card (the
   3D Viewer game sits above the About card). */
.tool-body .studio-learn > * + * { margin-top: var(--s4); }
/* Data table under the mechanism filmstrip. */
.tool-body .studio-data { padding: 0 var(--s4) var(--s4); }
.tool-body .studio-data > * + * { margin-top: var(--s2); }
/* Status bar: 28px, hint left, counts right. */
.tool-body .studio-status {
  min-height: 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  font-size: 13px;
  color: var(--muted);
  padding: 0 var(--s1);
}
.tool-body .studio-status .studio-count {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.tool-body .studio-status .status { margin: 0; }
/* Properties panel: sticky under the 52px site header, scrolls
   inside itself. Titled groups (12px uppercase muted). */
.tool-body .studio-props {
  position: sticky;
  top: 68px;
  max-height: calc(100vh - 84px);
  overflow-y: auto;
  padding: 0;
}
.tool-body .studio-props .prop-group { border-bottom: 1px solid var(--line); }
.tool-body .studio-props .prop-group:last-child { border-bottom: 0; }
.tool-body .studio-props .accordion-item > h3 { margin: 0; font-size: inherit; }
.tool-body .studio-props .accordion-header {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  padding-left: var(--s4);
  padding-right: var(--s4);
}
.tool-body .studio-props .accordion-panel-body { padding: 0 var(--s4) var(--s4); }
.tool-body .studio-props .accordion-panel-body > * + * { margin-top: var(--s3); }
.tool-body .studio-props .accordion-item { border-bottom: 1px solid var(--line); }
.tool-body .studio-props .accordion-item:last-child { border-bottom: 0; }
.tool-body .studio-props .field { margin-bottom: 0; }
.tool-body .studio-props .field label { margin-bottom: 0; }
.tool-body .studio-props .field .helper { margin-top: 0; }
.tool-body .studio-props .field-error { font-size: 12px; color: var(--err); margin-top: 0; }
.tool-body .studio-props input.input,
.tool-body .studio-props select.input,
.tool-body .studio-props textarea.input {
  height: 36px;
  min-height: 36px;
  padding: 8px 12px;
  font-size: 14px;
  border-color: var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
}
.tool-body .studio-props input.input:focus,
.tool-body .studio-props select.input:focus {
  border-color: var(--primary);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tool-body .studio-props .check-line {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: 14px;
  cursor: pointer;
}
.tool-body .studio-props .check-line input[type="checkbox"] {
  width: 20px;
  height: 20px;
  flex: none;
  accent-color: var(--primary);
}
/* Fields and buttons inside the studio: Chunk 1 36px controls. */
.tool-body .studio .field { margin-bottom: var(--s3); }
.tool-body .studio .field label { margin-bottom: 0; }
.tool-body .studio .field .helper { margin-top: 0; }
.tool-body .studio .field-error { font-size: 12px; color: var(--err); margin-top: 0; }
.tool-body .studio input.input,
.tool-body .studio select.input,
.tool-body .studio textarea.input {
  height: 36px;
  min-height: 36px;
  padding: 8px 12px;
  font-size: 14px;
  border-color: var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
}
.tool-body .studio input.input:focus,
.tool-body .studio input.input:focus-visible,
.tool-body .studio select.input:focus {
  border-color: var(--primary);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.tool-body .studio .btn {
  min-width: 0;
  min-height: 36px;
  height: 36px;
  padding: 8px 12px;
  font-size: 14px;
}
.tool-body .studio .btn-primary { background: var(--primary); color: var(--on-primary); }
.tool-body .studio .btn-secondary { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.tool-body .studio .btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.tool-body .studio .btn-tertiary { background: transparent; border-color: transparent; color: var(--primary); }
.tool-body .studio .btn-tertiary:hover { background: var(--primary-soft); }
.tool-body .studio .btn:hover { filter: none; }
.tool-body .studio p.helper { margin-bottom: 0; }
.tool-body .studio .status { margin: 0; }
.tool-body .studio .safety-note { margin: 0; }
/* Bond-order segmented control: the active bond is the pill (the
   tool JS toggles .is-active on the active button). */
.tool-body .studio .ord-seg .btn { height: 32px; min-height: 32px; padding-left: var(--s3); padding-right: var(--s3); border-radius: var(--radius-chip); font-size: 13px; font-weight: 600; color: var(--ink-2); border: 0; background: transparent; }
.tool-body .studio .ord-seg .btn.is-active {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-card);
}
/* Mechanism step filmstrip: numbered chips under the canvas, the
   current step filled. */
.tool-body .studio-filmstrip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  padding: var(--s3) var(--s4);
  border-top: 1px solid var(--line);
}
.tool-body .studio-filmstrip .step-label { font-weight: 700; font-size: 14px; }
.tool-body .studio-step-chip {
  min-width: 36px;
  height: 36px;
  padding: 0 var(--s2);
  border-radius: var(--radius-chip);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.tool-body .studio-step-chip[aria-current="true"] {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
}
/* Mechanism palette swatches in the properties panel. */
.tool-body .studio-props .palette {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 8px 0;
}
.tool-body .studio-props .palette button {
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 10px;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  min-height: 40px;
}
.tool-body .studio-props .palette button.active { outline: 2px solid var(--accent); }
/* Structures from a Name: the large input row and the results grid. */
.tool-body .studio-input .input-large {
  height: 48px;
  min-height: 48px;
  font-size: 16px;
}
.tool-body .studio-input .input-row {
  display: flex;
  gap: var(--s2);
  align-items: stretch;
}
.tool-body .studio-input .input-row .input { flex: 1 1 auto; min-width: 0; }
.tool-body .studio-input .input-row .btn { height: 48px; min-height: 48px; flex: none; }
.tool-body .studio-input .chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: var(--s3);
}
.tool-body .studio-input .chips .btn { height: 32px; min-height: 32px; font-size: 13px; }
.tool-body .studio-results {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--s3);
  min-height: 320px;
}
.tool-body .studio-results .mol {
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: var(--s4);
  background: var(--surface);
  margin-top: 0;
  position: relative;
}
.tool-body .studio-results .mol h3 { margin: 0 0 4px; text-transform: capitalize; }
.tool-body .studio-results .mol svg {
  width: 100%;
  height: auto;
  background: var(--soft);
  border-radius: 10px;
}
.tool-body .studio-results .mol .hint { color: var(--muted); font-size: 13px; margin-top: 8px; }
.tool-body .studio-results:empty + .results-empty { display: block; }
.tool-body .studio .results-empty { display: none; color: var(--muted); font-size: 14px; }
/* Per-card menu (Structures from a Name): a small details dropdown
   top-right of each molecule card. */
.tool-body .studio-results .mol-menu { position: absolute; top: var(--s2); right: var(--s2); }
.tool-body .studio-results .mol-menu > summary {
  list-style: none;
  cursor: pointer;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  color: var(--ink-2);
}
.tool-body .studio-results .mol-menu > summary::-webkit-details-marker { display: none; }
.tool-body .studio-results .mol-menu > summary:hover { color: var(--ink); border-color: var(--primary); }
.tool-body .studio-results .mol-menu > summary svg { width: 20px; height: 20px; }
.tool-body .studio-results .mol-menu-items {
  position: absolute;
  right: 0;
  top: 40px;
  z-index: 5;
  min-width: 180px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-popover);
  padding: var(--s1);
}
.tool-body .studio-results .mol-menu-items button {
  display: flex;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 14px;
  border-radius: var(--radius-control);
  cursor: pointer;
}
.tool-body .studio-results .mol-menu-items button:hover { background: var(--surface-2); }
/* Equation Balancer: the two panes. Left: input + Balance + Copy +
   examples. Right: the balanced result in a large typeset line, the
   atom-check table under it, the diagram under that. */
.tool-body .studio-input .input-row--stack { flex-direction: column; align-items: stretch; }
.tool-body .studio-input .input-row--stack .btn { height: 36px; min-height: 36px; }
.tool-body .studio-result-line {
  padding: var(--s4);
  border-bottom: 1px solid var(--line);
}
.tool-body .studio-result-line .big {
  word-break: break-word;
  font-size: 24px;
  margin: 0;
}
.tool-body .studio-result-line .plain-line { font-size: 14px; margin: var(--s2) 0 0; }
.tool-body .studio-result-pane .data { margin: var(--s4); width: calc(100% - 2 * var(--s4)); }
.tool-body .studio-result-pane .data td.tick { color: var(--ok); font-weight: 700; }
.tool-body .studio-result-pane .data td.tick--no { color: var(--err); }
.tool-body .studio-result-pane .studio-diagram {
  padding: var(--s4);
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tool-body .studio-result-pane .studio-diagram #diagram { width: 100%; }
.tool-body .studio-result-pane #diagram svg { width: 100%; height: auto; }
.tool-body .studio-result-pane #diagram .hint { margin: 0; }
.tool-body .studio-result-pane #diagramLegend { padding: 0 var(--s4); }
.tool-body .studio-result-pane .diagram-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  padding: 0 var(--s4) var(--s4);
}
.tool-body .studio .examples .btn {
  margin: 0 8px 8px 0;
  white-space: normal;
  height: auto;
  min-height: 36px;
  text-align: left;
}
.tool-body .studio #browseList .btn {
  display: block;
  width: 100%;
  text-align: left;
  margin-top: 8px;
  font-size: 14px;
  word-break: break-word;
  white-space: normal;
  height: auto;
  min-height: 36px;
}
/* Learn section under the studio: same block as the workbench one. */
.tool-body .studio-learn .card { margin-bottom: 0; }
.tool-body .studio-learn .formula {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  padding: var(--s3);
  overflow-x: auto;
  margin: 8px 0;
  white-space: pre-wrap;
}
/* Full screen: the work card fills the screen and scrolls. */
.tool-body .studio-work:fullscreen {
  background: var(--surface);
  padding: var(--s4);
  overflow-y: auto;
  border-radius: 0;
}
/* Phones and tablets (<=1023px): one column, work area first, then
   the rail as a horizontal toolbar, then the properties panel. The
   --panes variant keeps input first (the result appears directly
   under the input, per the brief). */
@media (max-width: 1023px) {
  .tool-body .studio {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "work"
      "status"
      "rail"
      "props"
      "learn"
      "related";
  }
  .tool-body .studio--top {
    grid-template-areas:
      "input"
      "work"
      "status"
      "learn"
      "related";
  }
  .tool-body .studio--panes {
    grid-template-areas:
      "input"
      "work"
      "status"
      "learn"
      "related";
  }
  .tool-body .studio--top-props {
    grid-template-areas:
      "input"
      "work"
      "status"
      "props"
      "learn"
      "related";
  }
  .tool-body .studio-rail {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
  }
  .tool-body .studio-rail .rail-sep {
    width: 1px;
    height: 24px;
    margin: 0 var(--s1);
  }
  .tool-body .studio-props {
    position: static;
    max-height: none;
    overflow: visible;
  }
}
/* Phones (<600px): the work area is about 300px tall, so the canvas
   is shorter than the desktop clamp. */
@media (max-width: 599px) {
  .tool-body .studio-canvas-wrap .canvas-wrap,
  .tool-body .studio-canvas-wrap .mechanism-canvas { height: 300px; }
  .tool-body .studio-results { grid-template-columns: minmax(0, 1fr); min-height: 0; }
}
/* Coarse pointers: controls grow to 44px / 16px, as in section 23. */
@media (pointer: coarse) {
  .tool-body .studio .btn { min-height: 44px; height: 44px; font-size: 16px; }
  .tool-body .studio input.input,
  .tool-body .studio select.input { height: 44px; min-height: 44px; font-size: 16px; }
  .tool-body .studio-rail .btn-icon { width: 44px; height: 44px; }
  .tool-body .studio-step-chip { min-width: 44px; height: 44px; }
}

/* ================================================================
   Section 30 — App page (Chunk 7: Figure Canvas editor shell)
   The canvas page is a window-sized application, not a document:
   the site header shrinks to a compact 44 px bar, the footer is
   hidden (it stays in the DOM for the shell checks), and the page
   fills exactly 100dvh below the header with no page scroll —
   panels and the artboard area scroll internally. The editor's own
   shell (top bar, rail, flyout, board, inspector, bottom bar) lives
   in assets/css/figure-canvas.css; this section only locks the page
   around it. ================================================= */
body.is-canvas-app {
  overflow: hidden;
  height: 100dvh;
}
body.is-canvas-app .site-header {
  height: 44px;
  padding-left: var(--s3);
  padding-right: var(--s3);
}
body.is-canvas-app .site-header .brand {
  font-size: 16px;
}
body.is-canvas-app .site-header .brand-mark {
  width: 22px;
  height: 22px;
}
/* Compact header: nav links and the search label hide; search and
   theme stay reachable as icon buttons. */
body.is-canvas-app #siteNav,
body.is-canvas-app .site-header .search-label,
body.is-canvas-app .site-header .search-kbd {
  display: none;
}
body.is-canvas-app .site-header .header-search {
  min-width: 44px;
  padding: 0;
}
body.is-canvas-app .site-footer {
  display: none;
}
body.is-canvas-app .page--app {
  max-width: none;
  height: calc(100dvh - 44px);
  margin: 0;
  padding: 0;
  overflow: hidden;
}
body.is-canvas-app .page--app > * + * {
  margin-top: 0;
}

/* ===== Chunk 8: coarse pointers (touch) get 44px touch targets =====
   On phones and tablets the smallest side of every control is at least
   44px. Checkboxes and radios themselves grow to 24px; their label row
   is the 44px target. */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
  .btn-icon { min-width: 44px; min-height: 44px; }
  .segmented button { min-height: 44px; }
  .tabs button { min-height: 44px; }
  .menu-item { min-height: 44px; }
  .tool-body .simulator .check-line,
  .tool-body .studio-props .check-line,
  .tool-body .simulator .radio-line { min-height: 44px; }
  .tool-body .simulator .check-line input[type="checkbox"],
  .tool-body .simulator .radio-line input[type="radio"],
  .tool-body .studio-props .check-line input[type="checkbox"] { width: 24px; height: 24px; }
  .tool-body .switch { min-height: 44px; }
  .tool-body .studio-props .palette button { min-width: 44px; min-height: 44px; }
}
