:root {
  --bg: #f4f1ea; --panel: #e9e4d8; --ink: #222; --muted: #666; --accent: #1565c0; --warn: #c62828;
  --lcd: #c7d6b0; --lcd-ink: #1e2a1a;
}
* { box-sizing: border-box; }
body { margin: 0; font: 14px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif; color: var(--ink); background: var(--bg); }
/* Nothing highlights when you click or drag around the bench and its
   controls. The text stays in the page for screen readers; only
   prose, lists and form fields remain selectable on purpose. */
body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
p, li, dd, td, th, .events, input, textarea, select, [contenteditable] { -webkit-user-select: text; user-select: text; }
svg, svg text, .key, .status, summary, label, button { -webkit-user-select: none !important; user-select: none !important; }
.top { padding: 8px 16px; border-bottom: 1px solid #d8d2c4; display: flex; flex-wrap: wrap; align-items: baseline; gap: 16px; }
.top h1 { font-size: 18px; margin: 0; }
.muted { color: var(--muted); font-weight: normal; }
.notice { margin: 0; font-size: 12px; color: var(--muted); }
.layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 12px; padding: 12px 16px; }
/* The control column sticks to the viewport and scrolls on its own, so the
   bench stays in view while long panels are read. */
.controls { position: sticky; top: 12px; align-self: start; max-height: calc(100vh - 24px); overflow-y: auto; overscroll-behavior: contain; padding-right: 2px; }
/* main.ts refines max-height from the column's real top edge (below the header). */
@media (max-width: 900px) { .layout { grid-template-columns: 1fr; } .controls { position: static; max-height: none; overflow: visible; } }
.bench svg { width: 100%; height: auto; background: #ddd6c6; border-radius: 6px; display: block; touch-action: none; -webkit-user-select: none; user-select: none; }
.bench svg:focus { outline: 2px solid var(--accent); }
.status { margin: 6px 0 0; font-size: 13px; min-height: 1.4em; }
.status.error { color: var(--warn); }
.controls details { background: var(--panel); border-radius: 6px; padding: 6px 10px; margin-bottom: 8px; }
.controls summary { cursor: pointer; font-weight: 600; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 6px 0; }
.row label { display: inline-flex; align-items: center; gap: 4px; }
input[type=range] { width: 120px; }
input[type=number] { width: 70px; }
.hint { font-size: 12px; color: var(--muted); margin: 4px 0 0; }
.events { list-style: none; padding: 0; margin: 0; max-height: 160px; overflow: auto; font-size: 12px; }
.events li { padding: 2px 0; border-bottom: 1px dotted #ccc; }
.events li.warn { color: var(--warn); }
.inspector p { margin: 4px 0; }
.selected-name { font-weight: 600; color: var(--accent); }
#tray-box .part-view[hidden] { display: none; }
.key { position: fixed; z-index: 10; background: #fffbe6; border: 1px solid #c9b86a; padding: 6px 8px; border-radius: 4px; font-size: 13px; max-width: 280px; box-shadow: 0 2px 6px rgba(0,0,0,.2); }
.key .swatches { display: flex; gap: 4px; margin-top: 4px; }
.key .swatch { width: 14px; height: 22px; border: 1px solid #555; border-radius: 2px; }
button { font: inherit; }
/* Start is the primary action: dark green with white text (contrast about
   7.9:1), and also heavier, larger and bordered so it stands apart from the
   other buttons by value and shape, not hue alone. */
#activity-start { background: #1b5e20; color: #fff; font-weight: 700; padding: 5px 14px; border: 2px solid #0b3d12; border-radius: 5px; margin-left: auto; cursor: pointer; }
#activity-start::before { content: "\25B6\00a0"; font-size: 0.8em; }
#activity-start:hover { background: #2e7d32; }
#activity-start:focus-visible { outline: 3px solid #ffb300; outline-offset: 2px; }
#activity-start:active { background: #0b3d12; }

/* SVG */
svg text { font-family: system-ui, sans-serif; fill: var(--ink); }
.label { font-size: 3.2px; font-weight: 600; }
.tiny { font-size: 2.3px; }
.warn { fill: var(--warn); font-weight: 700; }
.panel { fill: #c9c3b4; stroke: #8a8470; stroke-width: 0.4; }
.dmm-body { fill: #e8c44a; stroke: #7a6420; }
.lcd { fill: var(--lcd); stroke: #6a7a5a; stroke-width: 0.3; }
.lcd-text { font-family: ui-monospace, Menlo, monospace; font-size: 6px; fill: var(--lcd-ink); }
.lcd-text.small { font-size: 4px; }
.lcd-text.big { font-size: 8px; }
.lamp { fill: #777; }
.lamp.on { fill: #3ddc3d; }
#psu-cc.on { fill: #ff5252; }
.dial { fill: #333; stroke: #111; stroke-width: 0.4; }
.dial-pointer { stroke: #fff; stroke-width: 0.9; stroke-linecap: round; }
.dial-label { fill: #333; cursor: pointer; }
.dial-stop { cursor: pointer; outline: none; }
.dial-dot-hit { fill: transparent; }
.dial-dot { fill: #555; stroke: #222; stroke-width: 0.2; }
.dial-stop.on .dial-dot { fill: #0a5; stroke: #063; }
.dial-stop:focus .dial-dot-hit, .dial-stop:hover .dial-dot-hit { fill: rgba(21, 101, 192, 0.18); }
.dial-label.on { fill: #0a5; font-weight: 700; }
.jack-ring { stroke-width: 0.5; }
.jack-red { fill: #e53935; stroke: #7f0000; }
.jack-black { fill: #333; stroke: #000; }
.jack-hole { fill: #000; }
.jack.in-use .jack-ring { stroke: #ffd600; stroke-width: 0.8; }
.battery-body { fill: #3b3b3b; stroke: #111; stroke-width: 0.4; }
.battery-body + text, .battery .label, .battery .tiny { fill: #fff; }
.bb-body { fill: #f7f5ef; stroke: #b8b2a2; stroke-width: 0.4; }
.bb-gap { stroke: #d8d2c4; stroke-width: 1.2; }
.rail-plus { stroke: #d32f2f; stroke-width: 0.35; }
.rail-minus { stroke: #1565c0; stroke-width: 0.35; }
.rail-label, .bb-label { fill: #777; }
.hole { fill: #555; stroke: #999; stroke-width: 0.15; }
.hole.hot { fill: #ff6f00; stroke: #7f2a00; stroke-width: 0.45; }
.hole.taken { fill: #9a9a9a; }
.board-body { fill: #2a7a8f; stroke: #14505f; stroke-width: 0.4; }
.board .label { fill: #fff; font-size: 2.8px; }
.board .tiny { fill: #e0f2f1; }
.pin { fill: #111; stroke: #cfd8dc; stroke-width: 0.25; cursor: pointer; }
.pin-power { fill: #263238; stroke: #ffd600; stroke-width: 0.35; }
.pin-label { font-size: 2.2px; fill: #e0f2f1; }
.leg { stroke: #7a7a7a; stroke-width: 0.65; stroke-linecap: round; }
.resistor-body { fill: #d8c49a; stroke: #7a6a40; stroke-width: 0.2; }
.label-pill { fill: #3d2f6b; opacity: 0.9; }
.label-text { fill: #fff; }
.dead .resistor-body { fill: #4a4a4a; }
.dead-mark { fill: #ff5252; font-weight: 700; }
.led-body { stroke: #333; stroke-width: 0.2; }
.led-letter { fill: #000; font-weight: 700; }
.led-glow { filter: blur(0.8px); }
.contact { fill: #777; }
.lever { stroke: #444; stroke-width: 0.5; stroke-linecap: round; }
.pot-body { fill: #4a6fa5; stroke: #223; stroke-width: 0.2; }
.pot-knob { fill: #ddd; stroke: #333; stroke-width: 0.2; }
.pot-pointer { stroke: #333; stroke-width: 0.4; }
.part { cursor: grab; }
.part:focus { outline: none; }
.part:focus .label-pill, .part.selected .label-pill { stroke: var(--accent); stroke-width: 0.4; }
.part:focus .label-text, .part.selected .label-text { font-weight: 700; }
.part:focus .resistor-body, .part.selected .resistor-body { stroke: var(--accent); stroke-width: 0.5; }
.lead-outline { fill: none; stroke: #000; stroke-width: 1.2; stroke-linecap: round; opacity: 0.35; }
.lead-core { fill: none; stroke-width: 0.8; stroke-linecap: round; }
.lead { cursor: pointer; }
.lead:focus .lead-outline, .lead.selected .lead-outline { stroke: var(--accent); opacity: 1; }
.probe-lead { fill: none; stroke-width: 0.7; opacity: 0.8; }
.probe-body { stroke-width: 1.6; stroke-linecap: round; }
.probe-needle { stroke: #b0b4b8; stroke-width: 0.45; stroke-linecap: round; }
.probe-tip { fill: transparent; stroke: none; cursor: grab; outline: none; }
.probe-tip:focus { stroke: var(--accent); stroke-width: 0.4; stroke-dasharray: 1 0.6; }
.hole.guide { fill: #f7c58a; stroke: #e69a3c; stroke-width: 0.2; }
.hole.strip { fill: #ffab00; stroke: #ff6f00; stroke-width: 0.25; }
.ghost { opacity: 0.6; pointer-events: none; }
.ghost line { stroke: var(--accent); stroke-width: 0.6; }
.ghost circle { fill: var(--accent); }

/* activities */
.activity h2 { font-size: 15px; margin: 6px 0 2px; }
.activity .badge { display: inline-block; font-size: 11px; padding: 1px 6px; border-radius: 10px; background: #d7d0bf; margin-right: 6px; }
.activity .intro { margin: 4px 0 8px; }
.activity ol.steps { padding-left: 20px; margin: 4px 0; }
.activity ol.steps li.done { color: var(--muted); text-decoration: line-through; }
.activity ol.steps li.current { font-weight: 600; }
.activity ul.goals { list-style: none; padding: 0; margin: 4px 0; }
.activity ul.goals li { padding: 3px 0; border-bottom: 1px dotted #ccc; }
.activity ul.goals li.achieved::before { content: "✓ "; color: #2e7d32; font-weight: 700; }
.activity ul.goals li.todo::before { content: "○ "; color: var(--muted); }
.activity ul.goals li .optional { color: var(--muted); font-size: 12px; }
.activity .predict input { width: 90px; }
.activity .hint { background: #fffbe6; border: 1px solid #c9b86a; padding: 6px 8px; border-radius: 4px; margin: 6px 0; }
.activity .result { margin: 6px 0; padding: 6px 8px; border-radius: 4px; background: #e3f2fd; }
.activity .result.good { background: #e8f5e9; }
.activity .result.bad { background: #ffebee; }
.activity .complete { background: #c8e6c9; border: 1px solid #2e7d32; padding: 8px; border-radius: 4px; margin: 6px 0; font-weight: 600; }
.activity .score { color: var(--muted); font-size: 12px; }
svg .disabled { opacity: 0.35; pointer-events: none; }

.account { margin: 0; font-size: 13px; }
.account .button { display: inline-block; padding: 3px 8px; border: 1px solid #888; border-radius: 4px; background: #fff; color: var(--ink); text-decoration: none; }
.progress h3 { font-size: 13px; margin: 6px 0 2px; }
.level-row { font-size: 13px; padding: 3px 0; border-bottom: 1px dotted #ccc; }

/* Keys, notifications (bench) */
.notifications { list-style: none; padding: 0; margin: 4px 0; }
.notifications li { background: #fffbe6; border: 1px solid #c9b86a; border-radius: 4px; padding: 4px 8px; margin: 3px 0; font-size: 13px; }
.keys .key-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 3px 0; border-bottom: 1px dotted #ccc; }
.confirm { background: #e3f2fd; border: 1px solid #90caf9; border-radius: 4px; padding: 6px 8px; margin: 6px 0; }
.level-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 3px 0; }
/* Class key codes (dashboard and bench sidebar). Not .key: that class is the bench tooltip. */
.keycode { font-family: ui-monospace, Menlo, monospace; font-size: 14px; letter-spacing: 1px; white-space: nowrap; background: #fff; border: 1px solid #d8d2c4; border-radius: 4px; padding: 2px 6px; -webkit-user-select: text; user-select: text; }
.keyval { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; max-width: 100%; }
.copy-key { font-size: 12px; padding: 2px 8px; }

/* Professor page */
.prof { max-width: 1100px; margin: 0 auto; padding: 12px 16px; }
.prof section { background: var(--panel); border-radius: 6px; padding: 10px 14px; margin-bottom: 12px; }
.prof h2 { font-size: 16px; margin: 0 0 6px; }
.prof h3 { font-size: 14px; margin: 10px 0 4px; }
.prof table { border-collapse: collapse; width: 100%; font-size: 13px; }
.prof th, .prof td { text-align: left; padding: 4px 6px; border-bottom: 1px solid #d8d2c4; vertical-align: top; }
.prof form.stack { display: grid; grid-template-columns: max-content 1fr; gap: 6px 10px; align-items: center; max-width: 640px; }
.prof form.stack input, .prof form.stack textarea { width: 100%; font: inherit; }
.prof form.stack .span { grid-column: 1 / -1; }
.prof .status-pending { color: #b26a00; font-weight: 600; }
.prof .status-approved { color: #2e7d32; font-weight: 600; }
.prof .status-rejected, .prof .status-suspended { color: var(--warn); font-weight: 600; }
.prof .crumbs a { margin-right: 8px; }
.replay { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 12px; }
@media (max-width: 900px) { .replay { grid-template-columns: 1fr; } }
.replay svg { width: 100%; height: auto; background: #ddd6c6; border-radius: 6px; display: block; }
.replay .timeline { max-height: 420px; overflow: auto; font-size: 12px; list-style: none; padding: 0; margin: 4px 0; }
.replay .timeline li { padding: 2px 4px; border-bottom: 1px dotted #ccc; cursor: pointer; }
.replay .timeline li.done { color: var(--muted); }
.replay .timeline li.current { background: #fff3c4; font-weight: 600; }
.replay .timeline li.warn { color: var(--warn); }
.replay input[type=range] { width: 100%; }
.pointer-dot { fill: rgba(255, 0, 0, 0.55); stroke: #900; stroke-width: 0.3; }
.pointer-trail { fill: none; stroke: rgba(255, 0, 0, 0.35); stroke-width: 0.4; }
.badge { display: inline-block; font-size: 11px; padding: 1px 6px; border-radius: 10px; background: #d7d0bf; margin-right: 6px; }

/* Bench supply front panel. */
.lcd.standby { fill: #a9b89a; }
.lcd-tag { fill: var(--lcd-ink); opacity: 0.7; }
.knob { cursor: ns-resize; outline: none; }
.knob-body { fill: #2b2b2b; stroke: #111; stroke-width: 0.4; }
.knob-pointer { stroke: #fff; stroke-width: 0.9; stroke-linecap: round; }
.knob-tick { stroke: #555; stroke-width: 0.35; }
.knob:focus .knob-body, .knob:hover .knob-body { stroke: var(--accent); stroke-width: 0.6; }
.button { cursor: pointer; outline: none; }
.button-body { fill: #d9d4c6; stroke: #7a7462; stroke-width: 0.4; }
.button.on .button-body { fill: #bfc9b0; }
.button:focus .button-body, .button:hover .button-body { stroke: var(--accent); stroke-width: 0.6; }
.activity-buttons { margin-top: 6px; padding-top: 6px; border-top: 1px solid #d8d2c4; }
#activity-actions { display: contents; }
#next-activity { font-weight: 600; }
/* About, contact and privacy pages: plain reading text. */
.prose { max-width: 720px; margin: 0 auto; padding: 16px; line-height: 1.55; font-size: 15px; }
.prose h2 { font-size: 22px; margin: 8px 0 12px; }
.prose h3 { font-size: 16px; margin: 20px 0 6px; }
.prose p, .prose li { -webkit-user-select: text; user-select: text; }
.prose a { color: var(--accent); }
.site-footer { padding: 12px 16px; font-size: 12px; color: var(--muted); border-top: 1px solid #d8d2c4; display: flex; flex-wrap: wrap; gap: 12px; }
.site-footer a { color: var(--muted); }
