/* Ohmwork web taster — styles.
   Author: Steve Austen, The PCGP.  v0.198.0
   © 2026 Steve Austen, The PCGP. All rights reserved.
   ------------------------------------------------------------------
   The identity is the application's own, shared with the homepage:
   warm paper, dark ink, wire green, one lit-LED red. Deliberately
   single-theme — the product's canvas is paper in every OS theme —
   so every colour is explicit and the page holds together on any
   browser and background.

   Mobile-first: base styles are the phone (lesson panel stacked under
   the canvas, palette as a scrolling strip); a min-width query makes
   the desktop's three-part workshop layout (palette rail, canvas,
   lesson panel) once there is room for it. */

:root {
    --paper: #fafaf7;
    --ink: #202020;
    --ink-soft: #52524e;
    --wire: #2e5e2e;
    --led: #d43a1f;
    --accent: #1e88e5;
    --accent-ink: #1565c0; /* the accent as small text: AA on paper */
    --rule: #dddad2;
    --pass: #2e6b2e;   /* AA against paper */
    --fail: #b02416;   /* AA against paper */
    --panel: #ffffff;
}

* {
    box-sizing: border-box;
}

/* The hidden attribute always wins (v0.189.4). The browser's own
   [hidden] rule is only `display: none` at UA strength, so any
   author display — .player's flex, say — quietly resurrects the
   element: the "hidden" player has in truth been squeezed flat under
   the picker since day one, painting its toolbar over the footer.
   Important, so no future display rule can reopen the hole. */
[hidden] {
    display: none !important;
}

/* Present for assistive technology, invisible on screen — the
   standard clip pattern (v0.188.5). */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

html {
    height: 100%;
}

body {
    margin: 0;
    /* The phone layout is a normally SCROLLING page (v0.189.5): the
       canvas block first, the lesson flowing below it. Only the
       desktop media query pins the body to the viewport for the
       app-like bounded layout — pinning it here squeezed the palette
       to a sliver and crushed the lesson panel flat on phones. */
    min-height: 100%;
}

body {
    background: var(--paper);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    line-height: 1.55;
    display: flex;
    flex-direction: column;
}

/* --- Header ---------------------------------------------------------- */

/* The site header is css/site-header.css, the theme's file copied in
   by the build (v0.196.0). Two things are the taster's own business:
   the player is a tool, not a page, so there the header stays in flow
   (its sticky step nav would otherwise sit beneath it) and anchors
   inside it need no room left for a sticky bar. */
body.in-player .site-header {
    position: static;
    box-shadow: none;
}

body.in-player [id] {
    scroll-margin-top: 0;
}

/* --- The lesson picker ----------------------------------------------- */

.picker {
    width: 100%;
    max-width: 64rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
}

/* The opening block (v0.194.0): eyebrow, the page's real H1 in the
   display voice, the pitch, and how a lesson works in three lines. */
.picker-hero {
    max-width: 44rem;
    margin: 0.5rem 0 0.5rem;
}

.eyebrow {
    display: inline-block;
    margin: 0 0 0.9rem;
    padding: 0.32rem 0.9rem;
    border: 1.5px solid var(--copper);
    border-radius: 999px;
    color: var(--copper-ink);
    background: var(--paper);
    font-family: var(--mono);
    font-size: 0.68rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.picker-hero h1 {
    margin: 0;
    font-family: var(--serif);
    font-size: clamp(2rem, 5.5vw, 3.2rem);
    font-weight: 500;
    font-variation-settings: "opsz" 144;
    letter-spacing: -0.01em;
    line-height: 1.1;
    text-wrap: balance;
}

.picker-hero .lede {
    margin: 0.9rem 0 0;
    font-size: 1.1rem;
    color: var(--ink-soft);
}

.how {
    list-style: none;
    margin: 1.4rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.6rem;
    font-size: 0.95rem;
}

.how li {
    display: flex;
    gap: 0.7rem;
    align-items: baseline;
    color: var(--ink-soft);
}

.how strong {
    color: var(--ink);
}

.how-number {
    flex: 0 0 auto;
    font-family: var(--mono);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--copper-ink);
    letter-spacing: 0.08em;
}

.picker-list {
    list-style: none;
    margin: 0 0 1.5rem;
    padding: 0;
    display: grid;
    gap: 0.9rem;
}

.picker-card {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    width: 100%;
    height: 100%;
    text-align: left;
    padding: 0.9rem 1rem 1rem;
    background: var(--panel);
    border: 1.5px solid var(--rule);
    border-radius: 10px;
    cursor: pointer;
    font: inherit;
    color: inherit;
}

.picker-card:hover,
.picker-card:focus-visible {
    border-color: var(--wire);
}

.picker-card:focus-visible {
    outline: 2px solid var(--copper);
    outline-offset: 2px;
}

/* The card's ticket (v0.194.0): number, course, and "start here". */
.picker-ticket {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

.picker-number {
    color: var(--copper-ink);
    font-weight: 500;
}

.picker-start {
    color: var(--copper-ink);
    border: 1px solid var(--copper);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}

/* The card's shop window (v0.188.6): the lesson's starting circuit,
   drawn small on its own patch of paper. */
.picker-thumb {
    display: block;
    height: 110px;
    padding: 0.4rem;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 6px;
}

.picker-thumb svg {
    width: 100%;
    height: 100%;
    display: block;
}

.picker-title {
    font-family: var(--serif);
    font-weight: 500;
    font-size: 1.25rem;
    font-variation-settings: "opsz" 48;
    line-height: 1.25;
}

.picker-done {
    color: var(--pass);
}

.picker-summary {
    color: var(--ink-soft);
    font-size: 0.92rem;
}

.picker-meta {
    color: var(--ink-soft);
    font-size: 0.8rem;
}

.picker .aside {
    color: var(--ink);
    font-size: 0.98rem;
    max-width: 44rem;
}

.picker .aside p {
    margin: 0;
}

.aside-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1.4rem;
    margin-top: 1rem !important;
}

/* The homepage's buttons, for the way onward. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.75rem 1.4rem;
    font-weight: 700;
    font-size: 1rem;
    line-height: 1.2;
    text-decoration: none;
    border-radius: 8px;
    transition: background 0.15s ease, transform 0.15s ease,
                box-shadow 0.15s ease;
}

.btn-run {
    background: var(--wire);
    color: #ffffff;
    border: 1.5px solid var(--wire);
    box-shadow: 0 2px 0 rgba(32, 32, 32, 0.25);
}

.btn-run:hover,
.btn-run:focus-visible {
    background: #234a23;
    color: #ffffff;
    transform: translateY(-1px);
    box-shadow: 0 3px 0 rgba(32, 32, 32, 0.25);
}

.btn-run:active {
    transform: translateY(1px);
    box-shadow: none;
}

.btn-quiet {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--ink);
    font-weight: 600;
    text-decoration: none;
    padding: 0.5rem 0.25rem;
    border-bottom: 2px solid var(--rule);
}

.btn-quiet:hover,
.btn-quiet:focus-visible {
    color: var(--wire);
    border-bottom-color: var(--wire);
}

/* The Arduino showcase (v0.192.0): the capture on its own patch of
   paper, picker-card styling so it belongs to the page. */
.arduino-demo {
    margin: 1.5rem 0;
    padding: 1rem 1.1rem;
    background: var(--panel);
    border: 1.5px solid var(--rule);
    border-radius: 8px;
}

.arduino-demo h2 {
    margin: 0 0 0.6rem;
    font-size: 1.05rem;
}

.arduino-demo video {
    display: block;
    width: 100%;
    border: 1px solid var(--rule);
    border-radius: 6px;
    background: var(--paper);
}

.arduino-demo p {
    color: var(--ink-soft);
    font-size: 0.9rem;
    margin: 0.6rem 0 0;
}

/* --- The player layout ----------------------------------------------- */

.player {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

.workbench {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* The canvas block: toolbar, palette strip, drawing area. */

.canvas-area {
    display: flex;
    flex-direction: column;
    min-height: 55vh;
}

.toolbar {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--rule);
}

/* The rows above and below the canvas hold their height whatever the
   squeeze (v0.189.5) — a palette clipped to a sliver of button-tops
   is what a phone got before. */
.toolbar,
.palette,
.canvas-hint,
.run-note {
    flex-shrink: 0;
}

.toolbar .spacer {
    flex: 1;
}

button {
    font: inherit;
}

.tool-button,
.palette-button,
.reveal-button {
    padding: 0.4rem 0.9rem;
    border: 1.5px solid var(--ink);
    border-radius: 6px;
    background: var(--panel);
    color: var(--ink);
    cursor: pointer;
}

.tool-button:hover,
.palette-button:hover,
.reveal-button:hover {
    background: #f0f0ea;
}

.tool-button:focus-visible,
.palette-button:focus-visible,
.reveal-button:focus-visible,
.danger:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* Undo/redo sit greyed until there is something to step through
   (v0.188.3) — present but quiet, as toolbar history always is. */
.tool-button:disabled {
    opacity: 0.45;
    cursor: default;
}

.tool-button:disabled:hover {
    background: var(--panel);
}

/* Run is the moment the product comes alive, and dresses for it
   (v0.188.6): the one big button in the row of verbs. */
.tool-button.primary {
    background: var(--wire);
    border-color: var(--wire);
    color: #ffffff;
    font-weight: 700;
    padding: 0.45rem 1.3rem;
    font-size: 1rem;
}

.tool-button.primary:hover {
    background: #234a23;
}

.danger {
    padding: 0.35rem 0.8rem;
    border: 1.5px solid var(--fail);
    border-radius: 6px;
    background: var(--panel);
    color: var(--fail);
    cursor: pointer;
}

.palette {
    display: flex;
    gap: 0.4rem;
    padding: 0.5rem 0.75rem;
    overflow-x: auto;
    border-bottom: 1px solid var(--rule);
}

/* Palette buttons are a shelf of parts (v0.188.6): the real symbol
   above its name, drawn by the canvas's own painters. */
.palette-button {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
    min-width: 64px;
    padding: 0.35rem 0.6rem 0.3rem;
    white-space: nowrap;
    font-size: 0.72rem;
}

.palette-button svg {
    width: 52px;
    height: 30px;
    display: block;
    pointer-events: none;
}

/* Ink strokes would vanish on the armed blue: the symbol goes white
   with the caption. CSS wins over SVG presentation attributes, so
   this overrides the painters' inline stroke and colour. */
.palette-button.armed svg g {
    stroke: #ffffff;
    color: #ffffff;
}

/* The armed palette button stays visibly pressed until its part is
   placed on the canvas (v0.187.6) — the desktop shows the same mode
   with a checked toolbar action and the crosshair cursor. A darker
   blue than the canvas accent, for AA contrast under white text. */
.palette-button.armed,
.palette-button.armed:hover {
    background: #1565c0;
    border-color: #1565c0;
    color: #ffffff;
    font-weight: 700;
}

/* The hint above the canvas — one quiet line, with the full gestures
   behind the toggle (v0.188.6). Still written on the page, per the
   house law; just not all at once. */
.canvas-hint {
    margin: 0;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    color: var(--ink-soft);
    border-bottom: 1px solid var(--rule);
}

.hint-line {
    margin: 0;
}

.hint-toggle {
    border: none;
    background: none;
    padding: 0;
    font: inherit;
    color: var(--accent-ink);
    text-decoration: underline;
    cursor: pointer;
}

.hint-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

#hint-details p {
    margin: 0.35rem 0 0;
}

.canvas-frame {
    flex: 1;
    min-height: 45vh;
    position: relative;
}

/* Floating canvas controls (v0.188.6): history and view in a soft
   rounded cluster over the canvas — the modern canvas-app furniture —
   leaving the toolbar above to the verbs. */
.canvas-controls {
    position: absolute;
    right: 0.6rem;
    bottom: 0.6rem;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.25rem;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(32, 32, 32, 0.14);
}

.canvas-controls .tool-button {
    border: none;
    background: transparent;
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    font-size: 0.9rem;
}

.canvas-controls .tool-button:hover {
    background: #f0f0ea;
}

/* The undo/redo arrows, drawn at a proper weight (v0.189.7). */
.canvas-controls .tool-button svg {
    display: block;
    width: 19px;
    height: 19px;
    color: var(--ink);
}

.canvas-controls .tool-button:disabled:hover {
    background: transparent;
}

/* The bridge to the lesson (v0.189.8): floats bottom-left of the
   canvas, opposite the controls cluster — the one place a phone
   thumb can always reach the text from. Desktop hides it. */
.jump-button {
    position: absolute;
    left: 0.6rem;
    bottom: 0.6rem;
    z-index: 1;
    padding: 0.35rem 0.85rem;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(32, 32, 32, 0.14);
    font-size: 0.85rem;
    color: var(--ink);
    cursor: pointer;
}

.jump-button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* The selection's verbs float top-left over the canvas (v0.189.6),
   opposite the wiring ✕ — dressed as the controls cluster is, with
   Delete in the warning red the Delete button has always worn. */
.selection-actions {
    position: absolute;
    top: 0.5rem;
    left: 0.5rem;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.25rem;
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(32, 32, 32, 0.14);
}

.selection-actions .tool-button {
    border: none;
    background: transparent;
    padding: 0.3rem 0.55rem;
    border-radius: 6px;
    font-size: 0.9rem;
}

.selection-actions .tool-button:hover {
    background: #f0f0ea;
}

#delete-selected {
    color: var(--fail);
}

/* The voltage view's toggle sits pressed while it is on (v0.189.0),
   in the same pale blue as the reveal chips. */
.canvas-controls .tool-button.active {
    background: #eef4fb;
    color: #1565c0;
    font-weight: 700;
}

.controls-divider {
    width: 1px;
    align-self: stretch;
    background: var(--rule);
    margin: 0 0.15rem;
}

/* The cancel-wire button floats over the canvas while a wire is
   being routed — the touch cancel (keyboards also have Escape). */
.wire-cancel {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 1;
    padding: 0.35rem 0.8rem;
    border: 1.5px solid var(--fail);
    border-radius: 6px;
    background: var(--panel);
    color: var(--fail);
    cursor: pointer;
    font-size: 0.85rem;
}

.wire-cancel:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

#canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: var(--paper);
    touch-action: none; /* the canvas handles its own gestures */
    /* A breath of depth (v0.189.0): the drawing area reads as the
       bench surface the panels sit above. */
    box-shadow: inset 0 1px 4px rgba(32, 32, 32, 0.06),
                inset 0 0 18px rgba(32, 32, 32, 0.04);
}

/* The canvas is focusable (v0.187.6): a keyboard user Tabs to it and
   presses Enter to land an armed palette part. Make that focus as
   visible as every button's. */
#canvas:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

/* Pins are focusable too — Tab walks them, Enter wires, L lifts a
   leg — but an SVG circle gets no reliable default focus ring from
   any browser, so the keyboard's position on the canvas was
   invisible (v0.191.1, found chasing Steve's "can you even focus a
   pin?"). A bold accent stroke is the ring; CSS stroke outranks the
   presentation attributes, so it shows on lifted pins' red rings
   too. */
#canvas circle[data-pin-component]:focus-visible {
    stroke: var(--accent);
    stroke-width: 2.5;
    outline: none;
}

.run-note {
    /* Tall enough for one REAL line of its text (v0.190.3): at
       1.4rem the note's appearance grew the row by a few pixels,
       resizing the canvas-frame — and when the old code toggled
       the note every frame, the whole drawing visibly shook. The
       reservation must cover font-size × line-height + padding. */
    min-height: 1.7rem;
    line-height: 1.4;
    padding: 0.15rem 0.75rem;
    color: var(--fail);
    font-size: 0.85rem;
}

/* --- The lesson panel ------------------------------------------------- */

.lesson-panel {
    border-top: 2px solid var(--rule);
    background: var(--panel);
    display: flex;
    flex-direction: column;
    /* Unconstrained here: on a phone the panel flows at natural
       height and the PAGE scrolls. The desktop media query bounds it
       and clips (v0.189.3's fix, moved there in v0.189.5) so a long
       results list scrolls within rather than over the footer. */
}

.lesson-panel-header,
.step-nav {
    flex-shrink: 0;
}

.lesson-panel-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.9rem;
    border-bottom: 1px solid var(--rule);
    flex-wrap: wrap;
}

.lesson-panel-header .lesson-title {
    font-family: var(--serif);
    font-weight: 500;
    font-size: 1.15rem;
    font-variation-settings: "opsz" 48;
    line-height: 1.25;
    margin: 0;
    flex: 1;
}

.step-nav {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.9rem;
    border-bottom: 1px solid var(--rule);
    font-family: var(--mono);
    font-size: 0.78rem;
    color: var(--ink-soft);
}

.step-nav button {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

.step-nav button {
    padding: 0.25rem 0.7rem;
    border: 1.5px solid var(--ink);
    border-radius: 6px;
    background: var(--panel);
    cursor: pointer;
}

.step-nav button:disabled {
    opacity: 0.4;
    cursor: default;
}

/* The lesson text, set like a well-made book on the paper it sits on
   (v0.189.0): a modest scale, room to breathe, quiet furniture. */
.lesson-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 1rem 1.1rem 1.2rem;
    font-size: 0.95rem;
    line-height: 1.62;
}

.lesson-body h2,
.lesson-body h3 {
    margin: 0 0 0.5em;
    font-size: 1.15rem;
    line-height: 1.3;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--rule);
}

.lesson-body h4, .lesson-body h5, .lesson-body h6 {
    margin: 1.2em 0 0.4em;
    font-size: 1rem;
}

.lesson-body p {
    margin: 0.65em 0;
}

.lesson-body pre {
    background: #f0f0ea;
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.6rem 0.8rem;
    overflow-x: auto;
    font-size: 0.85rem;
    line-height: 1.5;
}

/* A code block can scroll sideways, so it is focusable (v0.194.0);
   the ring says so. */
.lesson-body pre:focus-visible {
    outline: 2px solid var(--copper);
    outline-offset: 2px;
}

.lesson-body code {
    font-family: var(--mono);
    font-size: 0.88em;
    background: #f0f0ea;
    border-radius: 4px;
    padding: 0.08em 0.35em;
}

.lesson-body pre code {
    background: none;
    border-radius: 0;
    padding: 0;
    font-size: inherit;
}

/* Wiring tables and their kin (v0.189.1), set like the rest of the
   book: ruled lightly, headed on the panel grey. */
.lesson-body table {
    border-collapse: collapse;
    margin: 0.8em 0;
    font-size: 0.9rem;
}

.lesson-body th,
.lesson-body td {
    border: 1px solid var(--rule);
    padding: 0.35rem 0.65rem;
    text-align: left;
    vertical-align: top;
}

.lesson-body th {
    background: #f0f0ea;
    font-weight: 700;
}

/* The two fault signatures, and anything else the prose sets apart:
   a quoted law on its own quiet ground (v0.189.0). */
.lesson-body blockquote {
    margin: 0.8em 0;
    padding: 0.5rem 0.9rem;
    border-left: 3px solid var(--wire);
    background: #f2f6f2;
    border-radius: 0 6px 6px 0;
}

.lesson-body blockquote p {
    margin: 0;
}

/* Reveal buttons as quiet chips rather than full buttons — an offer,
   not a control (v0.189.0). */
.reveal-button {
    display: inline-block;
    margin: 0.5rem 0.4rem 0.5rem 0;
    padding: 0.3rem 0.85rem;
    font-size: 0.85rem;
    background: #eef4fb;
    border: none;
    border-radius: 999px;
    color: #1565c0; /* the armed blue — AA on this pale ground */
}

.reveal-button:hover {
    background: #dfeaf8;
}

.revealed {
    border-left: 3px solid var(--accent);
    padding-left: 0.8rem;
    margin: 0.6rem 0;
}

/* --- Properties, checks, completion ----------------------------------- */

/* --- The quiz page (v0.188.1) ----------------------------------------
   Takes the step text's place after the last step. Feedback carries
   its verdict in glyph and words; the colour only underlines it, and
   both colours are the AA pair already proven against the panel. */

.quiz-question {
    margin: 0.9rem 0;
}

.quiz-choice {
    display: flex;
    align-items: flex-start;
    gap: 0.45rem;
    margin: 0.3rem 0 0.3rem 0.75rem;
    cursor: pointer;
}

.quiz-choice input {
    margin-top: 0.3rem;
}

.quiz-answer-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    margin-left: 0.75rem;
}

.quiz-value {
    width: 7rem;
    padding: 0.3rem 0.45rem;
    border: 1.5px solid var(--ink);
    border-radius: 6px;
    font: inherit;
}

.quiz-choice input:focus-visible,
.quiz-value:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.quiz-feedback {
    margin: 0.4rem 0 0 0.75rem;
}

.quiz-feedback.right { color: var(--pass); }
.quiz-feedback.wrong { color: var(--fail); }
.quiz-feedback.unanswered { color: var(--ink-soft); }

.quiz-summary {
    font-weight: 700;
}

.properties {
    border-top: 1px solid var(--rule);
    padding: 0.6rem 0.9rem;
    font-size: 0.9rem;
}

.properties h3 {
    margin: 0 0 0.3rem;
    font-size: 0.95rem;
}

.properties input[type="number"] {
    width: 7rem;
    padding: 0.25rem 0.4rem;
    font: inherit;
    border: 1.5px solid var(--ink);
    border-radius: 4px;
    margin-left: 0.4rem;
}

/* Colour and range dropdowns (v0.189.1), dressed as the inputs are. */
.properties select {
    padding: 0.25rem 0.4rem;
    font: inherit;
    border: 1.5px solid var(--ink);
    border-radius: 4px;
    margin-left: 0.4rem;
    background: var(--panel);
    color: var(--ink);
}

.properties select:focus-visible,
.properties input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.prop-note {
    color: var(--ink-soft);
    font-size: 0.85rem;
}

.live-readout {
    font-family: var(--mono);
    color: var(--accent-ink);
}

/* The resistance scrubber (v0.189.0): full width under its number
   box, in the working blue. */
.value-scrub {
    display: block;
    width: 100%;
    margin: 0.4rem 0 0.1rem;
    accent-color: #1565c0;
}

.check-results {
    list-style: none;
    margin: 0;
    padding: 0.4rem 0.9rem;
    /* Its own scrollbar (v0.189.3): eight verdicts must never push
       the completion card or the page about. */
    overflow-y: auto;
    min-height: 0;
    flex-shrink: 1;
}

.check-results li {
    display: flex;
    gap: 0.5rem;
    padding: 0.25rem 0;
    font-size: 0.88rem;
    align-items: baseline;
}

.check-mark {
    font-weight: 700;
}

.check-pass { color: var(--pass); }
.check-fail { color: var(--fail); }

.completion {
    margin: 0.6rem 0.9rem 1rem;
    padding: 0.9rem 1rem;
    border: 2px solid var(--pass);
    border-radius: 8px;
    background: #f2f8f2;
    overflow-y: auto;
    min-height: 0;
    flex-shrink: 1;
}

.properties {
    flex-shrink: 0;
}

.completion h3 {
    margin: 0 0 0.4rem;
    color: var(--pass);
}

.completion .cta {
    display: inline-block;
    margin-top: 0.5rem;
    padding: 0.5rem 1rem;
    background: var(--wire);
    color: #ffffff;
    border-radius: 6px;
    text-decoration: none;
    font-weight: 700;
}

/* --- Footer ----------------------------------------------------------- */

/* The site footer is css/site-footer.css, the theme's file copied in
   by the build (v0.197.0). In the player the columns fold away and the
   title block becomes one slim line, so the workbench keeps every pixel
   it can (v0.197.2: app.js sets body.in-player; the earlier :has() rule
   went, so the fold does not depend on selector support). */
body.in-player .site-footer {
    margin-top: 0;
}

body.in-player .site-footer-grid {
    display: none;
}

body.in-player .site-title-block > div {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.3rem 1rem;
    border-bottom: 0;
}

body.in-player .site-title-block dt::after {
    content: ":";
}

/* --- Phones: the page scrolls, and what you just touched surfaces
   first (v0.189.5). Selecting a part or pressing Check my work must
   not demand a scroll past the whole lesson text: on narrow screens
   the properties and verdicts sit directly under the canvas, the
   reading matter after them. Flex order only — the markup (and the
   desktop, which resets nothing because it never constrained order)
   stays in document order. */

@media (max-width: 899px) {
    .lesson-panel-header { order: 1; }
    .step-nav { order: 2; }
    .properties { order: 3; }
    .check-results { order: 4; }
    .completion { order: 5; }
    .lesson-body { order: 6; }

    /* The step nav rides sticky at the viewport top once the reading
       starts (v0.189.8), so Back/Next and the way up to the circuit
       are always in reach however deep the lesson goes. */
    .step-nav {
        position: sticky;
        top: 0;
        z-index: 2;
        background: var(--panel);
        flex-wrap: wrap;
    }

    #jump-to-canvas {
        margin-left: auto;
    }

    /* Scrolled-to regions land clear of the sticky nav. */
    #check-results,
    #quiz-page,
    .lesson-body {
        scroll-margin-top: 3.2rem;
    }
}

/* --- Desktop: the workshop layout ------------------------------------- */

@media (min-width: 900px) {
    /* The app-like layout: body pinned to the viewport, canvas and
       panel side by side, every region scrolling internally. The
       phone's scroll bridges have no meaning here. */
    body {
        height: 100%;
    }

    .jump-button,
    #jump-to-canvas {
        display: none;
    }

    .workbench {
        flex-direction: row;
    }

    .canvas-area {
        flex: 1;
        min-width: 0;
        min-height: 0;
    }

    .lesson-panel {
        width: 24rem;
        /* The workbench row is viewport-bounded; the panel fills it,
           clips as a backstop, and its regions scroll within
           (v0.189.3, moved here in v0.189.5). */
        min-height: 0;
        overflow: hidden;
        border-top: none;
        border-left: 2px solid var(--rule);
    }

    .canvas-frame {
        min-height: 0;
    }
}

/* =====================================================================
   The design lift (v0.193.0, matching the homepage): the picker is a
   brochure and wears the drawing-sheet language — dotted canvas grid,
   sheet frame, wire-run section tags, meter-glass accents, the serif
   display voice. The player is a TOOL: its layout mechanics are
   untouched; only its chrome (buttons, cards, readouts) is refined.
   ================================================================== */

/* The faces, self-hosted beside the page so the offline copy has
   them too (v0.194.0): Fraunces for display, IBM Plex Mono for the
   instrument voice. Both fall back to the system's own. */
@font-face {
    font-family: "Fraunces";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("../fonts/fraunces.woff2") format("woff2");
}

@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/IBMPlexMono-400.woff2") format("woff2");
}

@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("../fonts/IBMPlexMono-500.woff2") format("woff2");
}

:root {
    --copper: #b26a00;
    --copper-ink: #8a5200;  /* copper as small text: AA on paper */
    --glass: #b9dfb0;      /* the meter's backlit display */
    --glass-ink: #172714;  /* the meter's digits */
    --mono: "IBM Plex Mono", "Menlo", "Consolas", "DejaVu Sans Mono", monospace;
    --serif: "Fraunces", Georgia, "Times New Roman", serif;
}

/* The application's dotted grid behind everything, with a soft
   overhead vignette — the player's panels sit opaque on top. */
body {
    background-image:
        radial-gradient(ellipse 90% 55% at 50% 0%,
                        rgba(255, 255, 255, 0.75), transparent 70%),
        radial-gradient(var(--rule) 1.1px, transparent 1.1px);
    background-size: 100% 100%, 22px 22px;
}


/* Wire-run section tags, as the homepage draws them. */
.section-tag {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    margin: 2.25rem 0 1.1rem;
    font-family: var(--serif);
    font-weight: 500;
    font-variation-settings: "opsz" 72;
    font-size: clamp(1.5rem, 3.4vw, 1.9rem);
    line-height: 1.15;
}

.tag-number {
    font-family: var(--mono);
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--copper-ink);
    letter-spacing: 0.08em;
}

.tag-wire {
    flex: 1;
    height: 10px;
    min-width: 2.5rem;
    background-image:
        radial-gradient(circle at calc(100% - 5px) 50%,
                        var(--wire) 4px, transparent 4.5px),
        linear-gradient(var(--wire), var(--wire));
    background-size: 100% 100%, calc(100% - 5px) 2px;
    background-position: left top, left center;
    background-repeat: no-repeat;
}

/* Lesson cards: wire-green spines and a gentle lift, the homepage
   shelf brought home. Fault-finding lessons wear the LED red spine,
   the bench-skills lessons copper, as the homepage's cards do. */
.picker-card {
    border-left: 4px solid var(--wire);
    transition: transform 0.15s ease, border-color 0.15s ease,
                box-shadow 0.15s ease;
}

.picker-card.course-faults {
    border-left-color: var(--led);
}

.picker-card.course-technique {
    border-left-color: var(--copper);
}

.picker-card:hover,
.picker-card:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 10px 30px -12px rgba(32, 32, 32, 0.25);
}

@media (min-width: 40rem) {
    .picker-list {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 64rem) {
    .picker-list {
        grid-template-columns: repeat(3, 1fr);
    }
}

.picker-thumb {
    background-image:
        radial-gradient(var(--rule) 1px, transparent 1px);
    background-size: 14px 14px;
}

.picker-meta {
    font-family: var(--mono);
    font-size: 0.72rem;
}

/* The workshop pitch, stamped with the copper spine. */
.picker .aside {
    background: var(--panel);
    border: 1.5px solid var(--rule);
    border-left: 4px solid var(--copper);
    border-radius: 10px;
    padding: 1.1rem 1.3rem 1.2rem;
}

/* Run presses like a real button, as on the homepage CTA. */
.tool-button.primary {
    box-shadow: 0 2px 0 rgba(32, 32, 32, 0.25);
    transition: background 0.15s ease, transform 0.15s ease,
                box-shadow 0.15s ease;
}

.tool-button.primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 3px 0 rgba(32, 32, 32, 0.25);
}

.tool-button.primary:active {
    transform: translateY(1px);
    box-shadow: none;
}

/* Palette parts lift off the shelf under the pointer. */
.palette-button {
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.palette-button:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(32, 32, 32, 0.08);
}

/* The meter's reading in the panel, on real meter glass. */
.live-readout[data-live="meter"] {
    display: inline-block;
    background: var(--glass);
    color: var(--glass-ink);
    border: 1.5px solid #1a1c1e;
    border-radius: 6px;
    padding: 0.35rem 0.7rem;
    box-shadow: inset 0 2px 5px rgba(23, 39, 20, 0.25);
    font-weight: 700;
}

/* The completion CTA wears the full Run green. */
.completion .cta {
    padding: 0.7rem 1.4rem;
    border-radius: 8px;
    font-weight: 700;
    box-shadow: 0 2px 0 rgba(32, 32, 32, 0.25);
    transition: background 0.15s ease, transform 0.15s ease,
                box-shadow 0.15s ease;
}

.completion .cta:hover {
    background: #234a23;
    transform: translateY(-1px);
}

/* The footer in the instrument voice. */

/* Lifts and presses stand still for reduced motion. */
@media (prefers-reduced-motion: reduce) {
    .picker-card,
    .picker-card:hover,
    .picker-card:focus-visible,
    .tool-button.primary,
    .palette-button,
    .completion .cta {
        transition: none;
        transform: none;
    }
}

