/* ────────────────────────────────────────────────────────────────
   Factory Lab — a sandbox tab off /quizzes, same mechanic as
   or-games.onrender.com/factory (sliders → live resource use, live
   profit, reveal the true optimum) rebuilt in this site's own
   brutal skin. Loaded together with editorial.css, same as the
   lecture quizzes.
   ──────────────────────────────────────────────────────────────── */
:root{ --qz-good:#2e7d4f; --qz-good-ink:#fafafa; --qz-bad:#ad3a2c; --qz-bad-ink:#fafafa; }

.wrap{ max-width:840px; margin:0 auto; padding:6.5rem 1.5rem 5rem; }
.page-header{ margin-bottom:1.1rem; }
/* Collapsed once inside an actual mode (initLab toggles this) — the mode's
   own eyebrow+heading already re-establishes context, so repeating the
   full title+description above it on every single screen was the single
   biggest thing standing between a laptop-height viewport and no scroll. */
/* inside a mode the screen has its own eyebrow and heading: the page
   header ("Factory Lab") goes away entirely */
.page-header.lab-compact{ display:none; }
.page-header.lab-compact .head-sub, .page-header.lab-compact .attrib{ display:none; }
.eyebrow{ font-size:.68rem; letter-spacing:.24em; margin-bottom:1rem; }
h1{ font-size:clamp(1.9rem,6vw,2.7rem); line-height:1.08; margin-bottom:1rem; }
.head-sub{ font-size:.95rem; line-height:1.7; max-width:600px; }
.attrib{ display:block; margin-top:.6rem; font-size:.78rem; line-height:1.6; }

#lab-root{ margin-top:2.2rem; }

/* ── mode picker ──────────────────────────────────────────────── */
.lab-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:.8rem; }
.lab-tile{ border:1px solid var(--b-line2); padding:1.1rem 1rem; text-align:left;
  background:none; cursor:pointer; font-family:inherit; }
.lab-tile-num{ font-size:.68rem; letter-spacing:.14em; font-weight:700; margin-bottom:.4rem; }
.lab-tile-desc{ font-size:.82rem; }
.lab-tile-custom{ border-left:3px solid var(--b-acc); }
.lab-tile-custom .lab-tile-num{ color:var(--b-acc) !important; }

/* the top screen: self-wrapping tiles, not a hardcoded column count that
   goes stale every time a mode is added or removed. */
.lab-mode-grid{ grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); }
.lab-mode-grid .lab-tile{ padding:1.6rem 1.4rem; }
.lab-mode-grid .lab-tile-num{ font-size:.8rem; margin-bottom:.6rem; }
.lab-mode-grid .lab-tile-desc{ font-size:.88rem; line-height:1.5; }
@media(max-width:480px){ .lab-mode-grid{ grid-template-columns:1fr; } }

/* ── play screen ──────────────────────────────────────────────── */
.lab-playhead{ margin-bottom:1.4rem; }
.lab-eyebrow{ font-size:.68rem; letter-spacing:.14em; color:var(--b-faint) !important; }
.lab-sub{ font-size:1.3rem; font-weight:700; text-transform:uppercase; margin-top:.3rem; }
@media(max-width:480px){ .lab-sub{ font-size:1.05rem; padding-right:3.4rem; } }

.lab-layout{ display:grid; grid-template-columns:1fr 1fr; gap:2rem; align-items:start; }
/* grid items default to min-width:auto (their content's min-content size),
   which can force the whole grid — and the page — wider than the viewport
   if anything inside can't wrap. Prose belongs in this column now
   (Tutorial's legend), so this is no longer just a hypothetical. */
.lab-layout > *{ min-width:0; }
/* Default: side-by-side on anything but a narrow phone — fine for
   Levels/Custom, whose sliders/editor and small diagram don't need much
   room. @media(max-width:760px) below still stacks this on a phone. */
@media(max-width:760px){ .lab-layout{ grid-template-columns:1fr; } }
/* Simplex and Tutorial opt out of the above (lab-layout-wide, set once
   when each is built, not toggled) — an 8-column tableau, and in
   Tutorial's case a calculation grid where every cell is a label plus
   its own input, needs real room. Full width at every viewport, not just
   below the phone breakpoint; the diagram just moves below instead of
   beside the table. A layout that widened only during a pivot and
   narrowed right after read as jumping around, so this is static instead
   of state-dependent — the page is simply taller here, full stop. */
.lab-layout.lab-layout-wide{ grid-template-columns:1fr; }

.lab-sliders{ display:flex; flex-direction:column; gap:1rem; margin-bottom:1.4rem; }
.lab-prow{ border:1px solid var(--b-line2); padding:.8rem .9rem; }
.lab-pname{ font-weight:700; font-size:.9rem; margin-bottom:.2rem; }
.lab-slider-row{ display:flex; align-items:center; gap:.7rem; }
.lab-slider-row input[type=range]{ flex:1; }
.lab-slider-val{ font-size:.85rem; font-weight:700; width:2.6rem; text-align:right; flex-shrink:0; }

.lab-section-label{ font-size:.68rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--b-faint) !important; margin-bottom:.6rem; }

.lab-btnrow{ display:flex; flex-wrap:wrap; gap:.6rem; margin-bottom:.7rem; }
.lab-btnrow .btn{ font-size:.72rem; padding:.5rem .9rem; letter-spacing:.06em; cursor:pointer; }

.lab-reveal-line{ line-height:1.6; }

/* same marker idiom as the Wyndor bonus question, plus a hollow ring for
   the revealed optimum (Custom mode's trial point vs. the true optimum). */
.lab-diagram{ border:1px solid var(--b-line2); padding:.9rem; }
.lab-diagram svg{ display:block; width:100%; height:auto; max-width:340px; margin:0 auto; }

/* Branch & Bound's search tree — a real diagram instead of a text log. */
.lab-bb-tree svg{ display:block; width:100%; height:auto; max-width:380px; margin:0 auto; }

/* Transportation's route network — sources left, stores right. */
.lab-transport-net svg{ display:block; width:100%; height:auto; max-width:340px; margin:0 auto .6rem; }
.lab-marker{ fill:var(--qz-good); stroke:var(--b-bg); stroke-width:2px; }
.lab-marker.bad{ fill:var(--qz-bad); }
.lab-opt-marker{ fill:none; stroke:var(--b-acc); stroke-width:2.5px; }

/* ── custom builder ───────────────────────────────────────────── */
.lab-obj-row{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap;
  font-size:.9rem; font-weight:700; margin-bottom:1.2rem; }
.lab-coef{ width:3.4rem; border:2px solid var(--b-ink); background:none; color:inherit !important;
  font-family:inherit; font-size:.85rem; padding:.3rem .4rem; text-align:center; }
.lab-cons-list{ display:flex; flex-direction:column; gap:.5rem; margin-bottom:.8rem; }
.lab-cons-row{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; font-size:.85rem; }
.lab-rel{ font:inherit; font-size:.9rem; padding:.28rem .2rem; border:2px solid var(--b-ink); background:var(--b-bg); color:var(--b-ink) !important; cursor:pointer; }
/* with the ≤/≥/= picker the row got one control wider and the ✕ wrapped
   onto its own line: one row, slightly narrower fields */
.lab-cons-row{ flex-wrap:nowrap; gap:.4rem; }
.lab-cons-row .lab-coef{ width:3rem; padding:.3rem .25rem; min-width:0; }
.lab-cons-row > span{ white-space:nowrap; }
/* ties a constraint row back to its dashed line in the diagram */
.lab-cons-swatch{ width:.85rem; height:.85rem; flex-shrink:0; border:1px solid var(--b-line2); }
.lab-cons-del{ background:none; border:1px solid var(--b-line2); color:var(--b-faint) !important;
  width:1.8rem; height:1.8rem; cursor:pointer; font-family:inherit; margin-left:auto; }
.lab-cons-del:hover{ border-color:var(--qz-bad) !important; color:var(--qz-bad) !important; }
.lab-add-btn{ font-size:.72rem; padding:.45rem .8rem; letter-spacing:.06em; cursor:pointer;
  margin-bottom:1.2rem; }
.lab-custom-result{ border:1px solid var(--qz-good); padding:.65rem .85rem; font-size:.85rem;
  margin-bottom:.7rem; }
.lab-custom-result.bad{ border-color:var(--qz-bad); }
.lab-custom-result .lab-reveal-line{ color:var(--qz-good) !important; }
.lab-custom-result.bad .lab-reveal-line{ color:var(--qz-bad) !important; }

/* ── tutorial ─────────────────────────────────────────────────── */
/* the "where am I" strip — three pills, the current stage lit up in
   accent. This one element is what makes the whole screen actually read
   as step-by-step; everything else here is reference or feedback. */
.lab-tut-steps{ display:flex; gap:.5rem; flex-wrap:wrap; margin-bottom:1rem; }
.lab-tut-step{ border:1px solid var(--b-line2); padding:.4rem .8rem; font-size:.66rem;
  font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--b-faint) !important; }
.lab-tut-step.active{ border-color:var(--b-acc); color:var(--b-acc) !important; }

/* model + notation grouped into one visually secondary "reference" row,
   side by side now that Tutorial is full width — kept deliberately
   quieter (muted border, smaller text) than the lesson/status pair below
   it, so the eye lands on "what's active" first, "what this all means"
   second. */
.lab-tut-ref-row{ display:flex; gap:1rem; flex-wrap:wrap; margin-bottom:.7rem; }
.lab-tut-ref-row > *{ flex:1 1 280px; margin-bottom:0 !important; }
.lab-tut-model{ border:1px solid var(--b-line2); padding:.6rem .8rem .7rem; }
.lab-tut-model-line{ font-size:.88rem; font-weight:700; margin-bottom:.3rem; }
.lab-tut-cons-line{ display:flex; align-items:center; gap:.55rem; font-weight:400; font-size:.82rem; }
/* A small diagram (flTutorialLegend), scoped to just the algebra;
   .lab-tableau-caption (below) is what explains the columns themselves,
   directly on the real table. */
.lab-tut-legend{ border:1px solid var(--b-line2); padding:.6rem .8rem .7rem; }
.lab-tut-legend svg{ display:block; width:100%; height:auto; max-width:260px; margin:0 auto; }

/* lesson (the rule) and status (what your click did) touch directly —
   one connected "what's going on" panel instead of two separate boxes
   competing for attention; -1px collapses the doubled border where they
   meet into a single line. */
.lab-tut-guide{ margin-bottom:.7rem; }
.lab-tut-guide .lab-lesson{ margin-bottom:0; }
.lab-tut-guide .lab-custom-result{ margin-bottom:0; margin-top:-1px; }
.lab-lesson{ border:1px solid var(--b-acc); padding:.65rem .85rem; font-size:.85rem; line-height:1.5;
  margin-bottom:.7rem; }
.lab-lesson .lab-reveal-line{ color:var(--b-acc) !important; }

/* Branch & Bound's node log — an accepted incumbent stands out; pruned
   nodes fade (opacity is set inline, per entry, alongside this). */
.lab-tree-good{ color:var(--qz-good) !important; font-weight:700; }

/* Generic "not shown right now" toggle — Simplex's own step-guidance
   elements (steps strip, legend, lesson) start hidden and only appear
   once the "explain every step" checkbox is switched on. */
.lab-hidden{ display:none !important; }

/* Simplex's opt-in tutorial toggle — a plain checkbox + label, not styled
   as a button, so it reads as a mode switch rather than an action. */
.lab-tut-toggle-row{ display:flex; align-items:center; gap:.5rem; font-size:.82rem;
  margin-bottom:.9rem; cursor:pointer; }
.lab-tut-toggle-input{ width:1rem; height:1rem; cursor:pointer; }

/* Fallback for the "Reading the tableau" legend when the student has
   deleted every constraint — flTutorialLegend needs at least one to draw. */
.lab-tut-note{ font-size:.8rem; color:var(--b-faint) !important; padding:.4rem 0; }

/* ── simplex tableau ──────────────────────────────────────────── */
.lab-tableau-wrap{ overflow-x:auto; margin-bottom:.7rem; }
.lab-tableau{ border-collapse:collapse; width:100%; font-size:.74rem; font-variant-numeric:tabular-nums; }
.lab-tableau th, .lab-tableau td{ border:1px solid var(--b-line2); padding:.3rem .4rem;
  text-align:right; white-space:nowrap; }
.lab-tableau th:first-child, .lab-tableau td:first-child{ text-align:left; }
.lab-tableau thead th{ color:var(--b-faint) !important; font-weight:700; font-size:.64rem;
  letter-spacing:.06em; text-transform:uppercase; }
.lab-tableau-basis{ font-weight:700; }
.lab-tableau-z{ border-top:2px solid var(--b-ink); }
/* Eq. (0) on top, as in the lecture's tableau */
.lab-tableau-z-top{ border-top:0; border-bottom:2px solid var(--b-ink); }
.lab-tableau-eq{ color:var(--b-faint) !important; font-weight:400; }
.lab-ratio-cell{ white-space:nowrap; }
.lab-tableau-z td{ font-weight:700; }
.lab-ratio-cell{ color:var(--b-faint) !important; }
/* With 6+ variable columns the table has to scroll horizontally — but
   Basis (which row is which) and RHS (the actual value, the whole point
   of reading the table) can't be the columns that scroll out of view.
   Pinned on every row, header and caption row included (flPin in JS). */
.lab-col-pin-left{ position:sticky; left:0; background:var(--b-bg); z-index:2; }
.lab-col-pin-right{ position:sticky; right:0; background:var(--b-bg); z-index:2; }
/* Tutorial-only caption row, glued under the real header — this IS the
   "what does this column mean" answer, on the table itself. white-space
   MUST be overridden back to normal: the general numeric-cell rule above
   sets nowrap, and a row of un-wrappable prose cells was inflating the
   table's (and the whole grid column's) intrinsic width past the page. */
.lab-tableau-caption td{ color:var(--b-faint) !important; font-size:.6rem; font-weight:400;
  font-style:italic; border-top:none; padding-top:0; padding-bottom:.4rem; white-space:normal; }
/* Tutorial only: the coefficient at a basic variable's own row×column
   (always 1) vs. its actual value in RHS — these look identical as plain
   numbers, so make them look different instead of explaining it in words. */
.lab-tableau-self{ color:var(--b-faint) !important; font-weight:400; }
.lab-tableau-value{ color:var(--b-acc) !important; font-weight:700; }

/* ── hand-calculation step (Tutorial, opts.requireCalc) ─────────────── */
.lab-calc-formulas{ border:1px solid var(--b-acc); padding:.65rem .85rem; font-size:.82rem;
  line-height:1.5; margin-bottom:.7rem; }
.lab-calc-formulas .lab-reveal-line{ color:var(--b-acc) !important; margin-bottom:.3rem; }
.lab-calc-formulas .lab-reveal-line:last-child{ margin-bottom:0; }
.lab-calc-note{ color:var(--b-faint) !important; font-size:.76rem; line-height:1.55; margin-bottom:.55rem; }
.lab-calc-widget{ display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; font-size:.8rem;
  margin-bottom:.7rem; }
.lab-calc-label{ color:var(--b-faint) !important; }
.lab-calc-scratch{ width:9rem; border:1px solid var(--b-line2); background:none; color:inherit !important;
  font-family:inherit; font-size:.8rem; padding:.3rem .5rem; }
.lab-calc-result{ font-family:inherit; font-size:.8rem; font-weight:700; color:var(--qz-good) !important;
  background:none; border:none; padding:0; cursor:default; }
.lab-calc-result:not(:disabled){ cursor:pointer; text-decoration:underline; text-underline-offset:.2em; }
.lab-calc-result.bad{ color:var(--qz-bad) !important; }
.lab-pivot-row{ background:var(--b-line2); }
.lab-calc-cell{ vertical-align:top; padding-top:.25rem !important; }
.lab-calc-old{ font-size:.6rem; color:var(--b-faint) !important; margin-bottom:.2rem; white-space:nowrap; }
.lab-calc-input{ width:3.6rem; border:1px solid var(--b-line2); background:none; color:inherit !important;
  font-family:inherit; font-size:.75rem; padding:.2rem .3rem; text-align:right; }
.lab-calc-input.correct{ border-color:var(--qz-good) !important; }
.lab-calc-input.incorrect{ border-color:var(--qz-bad) !important; }
.lab-calc-input.lab-calc-fixed{ border-style:dashed; color:var(--b-faint) !important; }
.lab-calc-formulas .lab-calc-sub{ padding-left:1.1rem; }
/* augmented form: model ≤ → equation with its slack, then the current solution */
.lab-aug{ display:grid; grid-template-columns:auto auto 1fr; column-gap:.55rem; row-gap:.3rem;
  align-items:baseline; font-size:.86rem; font-weight:700; }
.lab-aug-row{ display:contents; }
.lab-aug-arrow{ color:var(--b-faint) !important; font-weight:400; }
.lab-aug-now{ grid-column:1 / -1; font-weight:400; border-top:1px solid var(--b-line2); margin-top:.5rem; padding-top:.5rem;
  font-size:.8rem; line-height:1.55; color:var(--b-acc) !important; }

/* column headers pick the entering variable, rows pick the leaving one —
   both are live click targets, not just a readout. */
.lab-th-click{ cursor:pointer; }
.lab-th-click:hover{ background:var(--b-line2); }
.lab-row-click{ cursor:pointer; }
.lab-row-click:hover td{ background:var(--b-line2); }
.lab-sel-col{ background:var(--b-acc) !important; color:var(--b-bg) !important; }
