/* ============================================================================
   multimeter.css: Using a Multimeter
   Same paper-and-ink design language as the oscilloscope tool; the meter
   itself renders as a dark instrument with an amber protective boot (field
   meter) or a slim compact body (pocket meter), switched via
   .meter-shell[data-meter].
   ========================================================================= */

:root {
    --paper: #f6f3ec;
    --paper-2: #efeadf;
    --ink: #1c1a15;
    --ink-2: #4a463d;
    --ink-3: #8a8478;
    --rule: #d9d3c2;
    --accent: #c8341a;
    --accent-2: #9a2818;
    --meter-body: #3a3d42;
    --meter-face: #2e3136;
    /* The protective holster around the instrument. */
    --boot: #b5452a;
    --boot-2: #8c3018;
    /* The yellow secondary markings printed on the panel: sub-legends,
       the jack sub-labels, the pointer. These stay yellow because that is
       the convention the meters themselves use for "press SELECT to get
       this", and it has to read against a dark face. */
    --legend: #e8a91d;
    --lcd-bg: #c9d2bf;
    --lcd-ink: #1d241a;
    --yellow-btn: #f0c53a;
    --warn: #d68a1a;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: 'Inter', -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
}
/* The body is the lead wires' containing block, so its overflow-x: clip
   trims the drawing at the window edge. Anchored to the root instead, the
   SVG (sized by JS to the rightmost jack + 90 px) widened the scrollable
   area past a phone's screen. The body starts at the page origin, so the
   drawing's page coordinates are unchanged. */
body {
    position: relative;
    background-image:
        radial-gradient(circle at 20% 10%, rgba(200, 52, 26, 0.04) 0%, transparent 50%),
        radial-gradient(circle at 80% 80%, rgba(200, 52, 26, 0.03) 0%, transparent 50%);
}
.serif { font-family: 'Fraunces', Georgia, serif; }
/* Titles are one colour and upright: the <em> word is not set apart. */
.serif em { font-style: normal; font-weight: inherit; }
/* Fonts: all three are served from assets/fonts with the page, so the
   tool needs nothing from Google (or any other site) to look right. Each
   is a variable font, split by script as Google serves them: Latin,
   Latin Extended and, for Ω and µ in the labels, Greek. Licences (SIL
   OFL 1.1) are beside the files.
   Inter: body text. JetBrains Mono: labels, buttons, the meter's panel.
   Fraunces: the titles, in one colour (ink). */
@font-face {
    font-family: 'Inter';
    src: url('../assets/fonts/inter-greek-wght-normal.woff2') format('woff2');
    font-weight: 100 900; font-style: normal; font-display: swap;
    unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}
@font-face {
    font-family: 'Inter';
    src: url('../assets/fonts/inter-latin-ext-wght-normal.woff2') format('woff2');
    font-weight: 100 900; font-style: normal; font-display: swap;
    unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'Inter';
    src: url('../assets/fonts/inter-latin-wght-normal.woff2') format('woff2');
    font-weight: 100 900; font-style: normal; font-display: swap;
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('../assets/fonts/jetbrains-mono-greek-wght-normal.woff2') format('woff2');
    font-weight: 100 800; font-style: normal; font-display: swap;
    unicode-range: U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('../assets/fonts/jetbrains-mono-latin-ext-wght-normal.woff2') format('woff2');
    font-weight: 100 800; font-style: normal; font-display: swap;
    unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('../assets/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2');
    font-weight: 100 800; font-style: normal; font-display: swap;
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Fraunces';
    src: url('../assets/fonts/fraunces-latin-ext-opsz-normal.woff2') format('woff2');
    font-weight: 100 900; font-style: normal; font-display: swap;
    unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'Fraunces';
    src: url('../assets/fonts/fraunces-latin-ext-opsz-italic.woff2') format('woff2');
    font-weight: 100 900; font-style: italic; font-display: swap;
    unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'Fraunces';
    src: url('../assets/fonts/fraunces-latin-opsz-normal.woff2') format('woff2');
    font-weight: 100 900; font-style: normal; font-display: swap;
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Fraunces';
    src: url('../assets/fonts/fraunces-latin-opsz-italic.woff2') format('woff2');
    font-weight: 100 900; font-style: italic; font-display: swap;
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* The dial's outer legends are absolutely positioned, so they add their
   own width to the page's scrollable area. clip (not hidden) trims that
   sideways overflow without turning this into a scroll container. */
.wrap {
    max-width: 1330px; margin: 0 auto; padding: 16px 16px 40px;
    overflow-x: clip; overflow-y: visible;
}

/* ===== Masthead (same as the scope tool) ===== */
.masthead {
    position: relative; z-index: 40;
    display: flex; justify-content: space-between; align-items: flex-end;
    border-bottom: 1px solid var(--rule);
    padding-bottom: 10px; margin-bottom: 16px; flex-wrap: wrap; gap: 8px;
}
.masthead h1 {
    font-family: 'Fraunces', Georgia, serif; font-weight: 500;
    font-size: clamp(22px, 4vw, 40px); margin: 0;
    letter-spacing: -0.02em; line-height: 1.1;
}
.masthead h1 em { font-style: normal; font-weight: inherit; }
.masthead-tools {
    display: flex; align-items: center; justify-content: flex-end;
    gap: 12px; flex-wrap: wrap;
}
/* The mute switch, at the far right of the masthead. The icon carries
   the state; no label beside it. */
.sound-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--ink-3); background: transparent; border: none;
    padding: 4px 6px; cursor: pointer; order: 99; margin-left: auto;
    transition: color 0.15s;
}
.sound-toggle:hover { color: var(--accent); }
.sound-icon { height: 28px; width: auto; flex: none; display: block; }
.sound-toggle .sound-off-cross { display: none; }
.sound-toggle.muted .sound-on-waves { display: none; }
.sound-toggle.muted .sound-off-cross { display: inline; }
.sound-toggle.muted { color: var(--ink-3); }
/* Muted, but the meter is making a sound right now: the icon pulses red. */
.sound-toggle.muted.muted-alert {
    color: #c8341a;
    animation: muted-alert-pulse 0.8s ease-in-out infinite;
}
@keyframes muted-alert-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
    .sound-toggle.muted.muted-alert { animation: none; }
}

/* ===== Layout ===== */
/* The meter on the left, the bench it is connected to on the right, both
   fixed width and the pair centered on the page. Below 760px there is no
   room for two columns, so the bench drops under the meter and keeps the
   same reading order. */
/* The bench and the meter, side by side and centered on the page as ONE
   thing: the probes are standing on the bench and reaching into the
   instrument beside them, so it is the pair that wants to be on the
   center line, not either half of it. The bench keeps a fixed width so
   the probes have a known amount of room whatever the window does. */
.main-stack {
    display: grid;
    grid-template-columns: 236px minmax(272px, 420px) 400px;
    grid-template-rows: auto 1fr;
    grid-template-areas: "head draw meter"
                         "foot draw meter";
    justify-content: center;
    column-gap: 20px; row-gap: 10px;
    align-items: start;
    width: 100%;
}
.meter-shell { grid-area: meter; }
.bench-space { grid-area: bench; }

/* The bench. On a wide screen its pieces go straight into the page grid:
   the two control cards in their own column on the left, and #bench-draw,
   the ground the part and probes are drawn on, beside them. On a phone it
   is one ordinary column (see the 740 px rules). */
.bench-space { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.bench-draw { display: none; }
@media (min-width: 741px) {
    .bench-space { display: contents; }
    .bench-head { grid-area: head; }
    .bench-foot { grid-area: foot; }
    .bench-draw { display: block; grid-area: draw; align-self: stretch; min-height: 1px; }
    .src-knobs, .src-waves { grid-area: draw; }
    /* The cards sit over the drawing's cables, which run off to the left. */
    .bench-head, .bench-foot { position: relative; z-index: 40; width: 236px; }
}
/* Too narrow for three columns: the two cards go side by side above the
   bench and the meter. */
@media (min-width: 741px) and (max-width: 999px) {
    .main-stack {
        grid-template-columns: minmax(272px, 1fr) 400px;
        grid-template-rows: auto auto 1fr;
        grid-template-areas: "head meter"
                             "foot meter"
                             "draw meter";
    }
    /* Cards take the full left column; the drawing sits below them. */
    .bench-head, .bench-foot { width: auto; max-width: 420px; }
}
.src-knobs.floating {
    position: absolute; z-index: 40;
    transform: translateX(-50%);
}
.src-knobs { display: flex; gap: 6px; justify-content: center; }
/* The generator's SINE / SQUARE buttons, sitting in its name row. */
.src-waves { display: flex; gap: 4px; justify-content: center; }
.src-waves[hidden] { display: none; }
.src-waves.floating {
    position: absolute; z-index: 41;
    transform: translate(-100%, -50%);
}
.src-wave {
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 26px; padding: 0;
    border: 1px solid rgba(255,255,255,0.22); border-radius: 4px;
    background: rgba(255,255,255,0.06); color: rgba(236,240,244,0.70);
    cursor: pointer;
}
.src-wave svg { width: 24px; height: 16px; }
.src-wave:hover { background: rgba(255,255,255,0.14); }
.src-wave.active {
    background: #7fd4ff; border-color: #7fd4ff; color: #10202c;
}
/* A dial that does nothing in this mode: still there, grayed out. */
/* Grayed out and taking no input; the cell itself still catches a press,
   so it can open a popup saying why. */
.knob-cell.disabled { opacity: 0.35; cursor: not-allowed; }
.knob-cell.disabled > * { pointer-events: none; }

.src-knobs[hidden] { display: none; }

/* Meter utilities live in the masthead, clear of the lead cables leaving
   the instrument. They stay full-size targets without reading like a second
   footer under the meter. */
.meter-actions {
    display: flex; justify-content: center; gap: 8px;
    margin: 0; flex-wrap: wrap;
}
.meter-actions .btn,
.meter-actions .btn.big {
    width: auto; min-width: 0; flex: 0 1 auto;
    padding: 8px 11px; font-size: 10.5px;
}

/* The way into the guidance. A quiet button most of the time; when the
   meter is wired in a way that is going to cost a fuse it stops being
   quiet, because that is the one thing you should not have to open a
   panel to find out. */
.help-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; }
.help-btn-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 17px; height: 17px; border-radius: 50%; flex: none;
    border: 1.5px solid currentColor;
    font-size: 11px; font-weight: 700; line-height: 1;
}
.help-btn.warn {
    border-color: var(--accent);
    color: var(--accent);
    background: rgba(200, 52, 26, 0.06);
    animation: help-pulse 1.6s ease-in-out infinite;
}
.help-btn.warn .help-btn-mark {
    background: var(--accent); color: #fff; border-color: transparent;
}
@keyframes help-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(200, 52, 26, 0.34); }
    50%      { box-shadow: 0 0 0 5px rgba(200, 52, 26, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .help-btn.warn { animation: none; }
}

/* Below this there is no room for a bench beside the meter, so it goes
   under it and the probes are not drawn at all. */
@media (max-width: 740px) {
    .main-stack {
        grid-template-columns: min(400px, 100%);
        grid-template-rows: none;
        grid-template-areas: "bench" "meter";
        justify-content: center;
    }
    .masthead { align-items: flex-start; }
    .masthead-tools { width: 100%; justify-content: space-between; }
    /* On a phone the buttons wrap; the mute switch stays top right,
       level with the title, rather than dropping onto a line of its own. */
    .sound-toggle { position: absolute; top: 0; right: 0; }
    .masthead h1 { padding-right: 44px; }
}

/* ===== The bench panel ===== */
.bench {
    display: flex; flex-direction: column; gap: 10px;
}

/* ===== THE METER ===== */
.meter-shell {
    display: flex; flex-direction: column; align-items: center;
    position: relative; gap: 8px;
    /* Room under the boot for the test leads to lie unplugged. */
    margin-bottom: 170px;
}
/* Tabs above the meter, click to switch Field / Compact / Logging. */
.meter-tabs {
    --bar-h: 44px;
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    width: 380px; max-width: 100%;
    height: var(--bar-h); min-height: var(--bar-h);
    gap: 0;
    border: 1px solid var(--rule);
    border-radius: 6px;
    overflow: hidden;
    background: var(--paper-2);
    box-sizing: border-box;
}
.meter-tab {
    appearance: none; border: none; background: transparent;
    padding: 0 6px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 11px; font-weight: 600; color: var(--ink-2);
    cursor: pointer; line-height: 1.15;
    border-right: 1px solid var(--rule);
    transition: background 0.12s, color 0.12s;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
}
.meter-tab:last-child { border-right: none; }
.meter-tab small {
    display: block; font-size: 9px; font-weight: 600;
    color: var(--ink-3); letter-spacing: 0.08em; margin-top: 1px;
    white-space: nowrap;
}
.meter-tab:hover:not(.active) { background: rgba(28, 26, 21, 0.04); color: var(--ink); }
.meter-tab.active {
    background: var(--ink); color: var(--paper);
}
.meter-tab.active small { color: #cfccc2; }
.meter-tab:focus-visible {
    outline: 2px solid var(--accent); outline-offset: -2px; z-index: 1;
}
/* Both meters share one FIXED width, same footprint, different skin. */
.meter-boot {
    background: linear-gradient(160deg, var(--boot), var(--boot-2));
    border-radius: 24px;
    padding: 11px;
    box-shadow: 0 10px 28px rgba(30, 25, 10, 0.28), inset 0 2px 0 rgba(255,255,255,0.25);
    width: 380px;
    max-width: 100%;
}
/* Field-meter skin: a blue impact holster around the graphite instrument. */
.meter-shell[data-meter="field"] .meter-boot {
    background: linear-gradient(155deg, #4389b5 0%, #286b98 48%, #174866 100%);
    border: 1px solid #123c57;
    box-shadow: 0 10px 28px rgba(20, 48, 67, 0.30),
                inset 0 2px 0 rgba(255,255,255,0.24);
}
.meter-face {
    background: linear-gradient(175deg, var(--meter-body), var(--meter-face));
    border-radius: 16px;
    padding: 13px 18px 14px;
    box-shadow: inset 0 2px 6px rgba(0,0,0,0.45);
}
/* Pocket skin: dark body, thinner boot, no field-yellow, same width. */
.meter-shell[data-meter="pocket"] .meter-boot {
    background: linear-gradient(160deg, #4a4e55, #35383e);
    padding: 10px;
    border-radius: 20px;
}
.meter-shell[data-meter="pocket"] .meter-face { padding: 12px 14px 16px; }

.meter-brand {
    display: flex; justify-content: space-between; align-items: baseline;
    margin-bottom: 8px;
}
.meter-model {
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    font-size: 15px; color: #e8e4da; letter-spacing: 0.06em;
    text-transform: uppercase;
}
.meter-tagline {
    font-family: 'JetBrains Mono', monospace; font-size: 11px; font-weight: 600;
    color: var(--legend); letter-spacing: 0.14em;
}

/* ===== LCD ===== */
.lcd {
    background: var(--lcd-bg);
    border: 3px solid #17191c;
    border-radius: 8px;
    padding: 8px 12px 10px;
    box-shadow: inset 0 2px 8px rgba(0,0,0,0.25);
    transition: background 0.2s;
    /* Fixed min height so OFF (blank digits) cannot collapse the face. */
    min-height: 108px;
}
/* Backlight on: a warm, pale LED white-green, the way a lit LCD actually
   looks, rather than a cyan wash. */
.lcd.backlit {
    background: #e2edc9;
    box-shadow: inset 0 2px 8px rgba(0,0,0,0.14), 0 0 16px rgba(214, 238, 170, 0.45);
}
.gfx { transition: background 0.2s, box-shadow 0.2s; }
.gfx.backlit {
    --gfx-bg: #eef3dc;
    box-shadow: inset 0 2px 8px rgba(0,0,0,0.12), 0 0 16px rgba(214, 238, 170, 0.45);
}
/* Hide content but keep layout size when the dial is OFF. */
.lcd.lcd-off .lcd-main, .lcd.lcd-off .lcd-annun, .lcd.lcd-off .lcd-bar,
.lcd.lcd-off .lcd-range { visibility: hidden; }
.lcd-annun {
    display: flex; justify-content: space-between; align-items: flex-start;
    gap: 8px;
    font-family: 'JetBrains Mono', monospace; font-size: 11px; font-weight: 600;
    color: var(--lcd-ink); min-height: 28px;
}
.lcd-annun-left {
    display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
    min-width: 0; flex: 1; padding-top: 2px;
}
/* Fixed segment stacks (AC over DC, Hz over %), permanent like a real LCD. */
.lcd-annun-right {
    display: flex; gap: 8px; align-items: flex-start; flex: none;
}
.an-stack {
    display: flex; flex-direction: column; align-items: center;
    gap: 1px; line-height: 1.15;
}
.lcd-annun .an { opacity: 0.08; transition: opacity 0.1s; }
.lcd-annun .an.on { opacity: 1; }
.lcd-annun .an-slot {
    display: block; text-align: center; letter-spacing: 0.04em;
    min-width: 1.6em; /* reserved width so neighbors never shift */
}
.lcd-annun .an-minmax {
    display: inline-block; min-width: 2.6em; /* MAX / MIN / AVG */
}
/* The hazard bolt is an LCD segment like every other annunciator: the same
   ink as the digits, dark when energized and a ghost when it is not. It is
   the SHAPE that carries the warning, not a color the glass cannot make. */
.lcd-annun .an-svg-bolt { height: 15px; vertical-align: -3px; }
/* The same bolt set into running text (the Quick Reference), so
   the symbol a student reads about is the symbol on the screen. */
.qr-bolt {
    display: inline-block; line-height: 0; vertical-align: -1px;
    padding: 0 1px;
}
.qr-bolt svg { height: 1em; width: auto; }
.lcd-main {
    display: flex; align-items: baseline; justify-content: flex-end; gap: 8px;
    min-height: 56px;
}
.lcd-neg {
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    font-size: 40px; color: var(--lcd-ink); visibility: hidden;
}
.lcd-digits {
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    font-size: 46px; letter-spacing: 0.04em; color: var(--lcd-ink);
    font-variant-numeric: tabular-nums;
    transform: skewX(-4deg);   /* seven-segment lean */
}
.lcd-unit {
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    font-size: 20px; color: var(--lcd-ink); min-width: 42px;
}
/* Continuity visual: semi-transparent waves expand from the meter body
   while the beeper sounds (works muted / for deaf/hard-of-hearing students). */
.beep-waves {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 4;
    overflow: visible;
    opacity: 0;
    transition: opacity 0.12s;
}
.meter-shell.beeping .beep-waves { opacity: 1; }
.beep-ring {
    position: absolute;
    left: 50%;
    top: 52%;
    width: 92%;
    height: 88%;
    border: 2px solid rgba(200, 52, 26, 0.38);
    border-radius: 32px;
    box-shadow: 0 0 12px rgba(200, 52, 26, 0.12);
    transform: translate(-50%, -50%) scale(0.92);
    opacity: 0;
    animation: none;
}
.meter-shell.beeping .beep-ring {
    animation: beep-wave 1.35s ease-out infinite;
}
.meter-shell.beeping .beep-ring:nth-child(2) { animation-delay: 0.45s; }
.meter-shell.beeping .beep-ring:nth-child(3) { animation-delay: 0.9s; }
@keyframes beep-wave {
    0%   { transform: translate(-50%, -50%) scale(0.92); opacity: 0.42; }
    70%  { opacity: 0.12; }
    100% { transform: translate(-50%, -50%) scale(1.28); opacity: 0; }
}
/* 33-segment bargraph (field meter) */
/* Range scale above the bargraph, 0 at the left, the active range's full
   scale at the right, exactly like the range annunciation on the real
   field meter. Populated by renderRange(); field meter only. */
.lcd-range {
    display: flex; justify-content: space-between; align-items: baseline;
    font-family: 'JetBrains Mono', monospace; font-size: 11px; font-weight: 600;
    color: var(--lcd-ink); opacity: 0.8; margin-top: 6px; line-height: 1;
    min-height: 11px;
}
.lcd-bar { display: flex; gap: 2px; margin-top: 3px; height: 8px; }
.lcd-bar i {
    flex: 1; background: rgba(29, 36, 26, 0.12); border-radius: 1px;
}
.lcd-bar i.lit { background: var(--lcd-ink); }

/* ===== GRAPHICAL SCREEN (logging meter) =====
   A dot-matrix panel rather than fixed LCD segments: anything can be drawn
   anywhere, which is why this meter can show a second reading, a menu, and
   a trend plot on the same glass. Everything inside is monospaced and
   pixel-small on purpose: reading a crowded screen is part of the skill. */
.gfx {
    --gfx-bg: #dfe3dc;
    --gfx-ink: #14181a;
    background: var(--gfx-bg);
    border: 2px solid #0e1012;
    border-radius: 3px;
    padding: 0 0 4px;
    box-shadow: inset 0 2px 10px rgba(0,0,0,0.22);
    font-family: 'JetBrains Mono', monospace;
    color: var(--gfx-ink);
    /* The real screen is nearly square and dominates the panel. */
    min-height: 238px;
    display: flex; flex-direction: column;
}
.gfx[hidden] { display: none; }
.gfx.gfx-off > * { visibility: hidden; }

/* Readability: every piece of text on the glass is at least 9 px and in
   full-strength ink. A real LCD has no half-tone text, and small grey
   letters on a grey-green screen are what made the session rows (Peak Max,
   Average, Minimum and their times) hard to read. */
/* The status strip runs inverted across the top of the glass, the way
   the real one does: battery and clock at the left, date at the right. */
.gfx-status {
    display: flex; align-items: center; gap: 7px;
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.02em;
    background: var(--gfx-ink); color: var(--gfx-bg);
    padding: 2px 6px; min-height: 15px;
}
.gfx-batt {
    display: inline-flex; gap: 1px; align-items: center; flex: none;
    border: 1px solid var(--gfx-bg); border-radius: 1px; padding: 1px;
}
.gfx-batt i {
    width: 3px; height: 6px; background: var(--gfx-bg);
}
.gfx-batt i.empty { background: transparent; }
.gfx-mini { flex: 1; min-width: 0; text-align: center; white-space: nowrap; overflow: hidden; }
/* Past the input's continuous rating the warning blinks, like the real one. */
.gfx-mini.warn {
    font-weight: 700; color: #ffd7cf;
    animation: gfx-warn 0.9s steps(1, end) infinite;
}
@keyframes gfx-warn { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
    .gfx-mini.warn { animation: none; }
}
.gfx-clock, .gfx-date { flex: none; }

.gfx-page { position: relative; flex: 1; display: flex; flex-direction: column; padding: 0 7px; }
.gfx-readout { display: flex; flex-direction: column; flex: 1; position: relative; }
/* With a screen open the readout shrinks to a single line, mode chips on
   the left, the live value on the right, and the screen opens under it. */
.gfx-readout.compact {
    flex: none; flex-direction: row; align-items: baseline; gap: 8px;
    border-bottom: 1px solid var(--gfx-ink);
    padding: 2px 0 3px; margin-bottom: 2px;
}
.gfx-readout.compact .gfx-mods { flex: 1; }
.gfx-readout.compact .gfx-primary { flex: none; }
.gfx-readout.compact .gfx-secondary,
.gfx-readout.compact .gfx-session,
.gfx-readout.compact .gfx-cont,
.gfx-readout.compact .gfx-rangeline,
.gfx-readout.compact .gfx-scale,
.gfx-readout.compact .gfx-bar { display: none; }
.gfx-readout.compact .gfx-primary { min-height: 0; margin: 0; }
.gfx-readout.compact .gfx-digits { font-size: 24px; }
.gfx-readout.compact .gfx-unit { font-size: 12px; min-width: 0; }
.gfx-readout.compact .gfx-neg { font-size: 19px; }
.gfx-readout.compact .gfx-mods { min-height: 0; margin: 0; flex-wrap: nowrap; }

.gfx-mods {
    display: flex; gap: 5px; flex-wrap: wrap; min-height: 13px; margin-top: 2px;
}
.gfx-chip {
    font-size: 10px; font-weight: 700; letter-spacing: 0.06em;
    background: var(--gfx-ink); color: var(--gfx-bg);
    padding: 1px 4px; border-radius: 2px; line-height: 1.3;
}
/* The hazard chip on the dot-matrix screen: an inverted block like the
   other chips, carrying the bolt as a drawn glyph. A monochrome LCD has no
   red to reach for. */
.gfx-chip.bolt { padding: 1px 5px; display: inline-flex; align-items: center; }
.gfx-chip.bolt .an-svg-bolt { height: 10px; width: auto; }

.gfx-primary {
    display: flex; align-items: baseline; justify-content: flex-end; gap: 6px;
    min-height: 44px; margin-top: 1px;
}
/* A message where the digits would be, the Input Alert. A dot-matrix
   screen has one way to shout: it inverts the block and flashes it, so
   that is what this does rather than fading anything. */
.gfx-msg {
    position: absolute; left: 0; right: 0; top: 18px;
    text-align: center; font-size: 13px; font-weight: 700;
    letter-spacing: 0.02em; line-height: 1.4;
    border: 1.5px solid var(--gfx-ink); border-radius: 2px;
    padding: 8px 6px; z-index: 2;
    animation: gfx-msg-invert 1.1s steps(1, end) infinite;
}
.gfx-msg[hidden] { display: none; }
@keyframes gfx-msg-invert {
    0%   { background: var(--gfx-bg); color: var(--gfx-ink); }
    50%  { background: var(--gfx-ink); color: var(--gfx-bg); }
    100% { background: var(--gfx-bg); color: var(--gfx-ink); }
}
.gfx-neg { font-size: 30px; font-weight: 700; visibility: hidden; }
.gfx-digits {
    font-size: 38px; font-weight: 700; letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
}
.gfx-unit { font-size: 17px; font-weight: 700; min-width: 34px; }
.gfx-secondary {
    text-align: right; font-size: 11.5px; font-weight: 700;
    min-height: 15px; line-height: 15px;
    white-space: nowrap; overflow: hidden;
}
/* Record session summary, three values, each with the elapsed time it
   was captured, and the session start stamp underneath. */
.gfx-session { font-size: 11px; font-weight: 700; margin-top: 1px; }
.gfx-session[hidden] { display: none; }
/* The same rows on a saved record's page, at the same size. */
.gfx-panel .gfx-srow, .gfx-panel .gfx-sstart { font-size: 11px; font-weight: 700; }
.gfx-srow {
    display: flex; align-items: baseline; gap: 6px; line-height: 1.35;
}
.gfx-srow > span:first-child { flex: none; min-width: 78px; }
.gfx-srow b { flex: 1; text-align: right; font-variant-numeric: tabular-nums; }
.gfx-stime { flex: none; font-weight: 600; font-variant-numeric: tabular-nums; }
.gfx-sstart {
    margin-top: 2px; padding-top: 2px; font-weight: 600;
    border-top: 1px dotted rgba(21, 26, 22, 0.45);
}
/* Continuity's graphic indicator, a solid bar for a short, a broken one
   for an open, because the digits are far too slow to show a flicker. */
.gfx-cont { display: flex; align-items: center; gap: 7px; margin-top: 3px; }
.gfx-cont[hidden] { display: none; }
.gfx-cont-bar {
    flex: 1; height: 7px; border: 1.5px solid var(--gfx-ink); border-radius: 2px;
    background: repeating-linear-gradient(90deg,
        var(--gfx-ink) 0 10px, transparent 10px 20px);
}
.gfx-cont.shorted .gfx-cont-bar { background: var(--gfx-ink); }
.gfx-cont-txt { flex: none; font-size: 10.5px; font-weight: 700; letter-spacing: 0.06em; }
/* "Auto Range" sits above the scale, right-aligned, as on the real screen. */
.gfx-rangeline {
    text-align: right; font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.02em; min-height: 13px; line-height: 13px;
}
/* The scale labels sit on a track exactly as wide as the bar below them,
   with the unit parked in the gutter to its right, so the 0 on the scale
   lands on the middle segment of the bar. */
.gfx-scale {
    display: flex; align-items: baseline;
    font-size: 9px; font-weight: 700; line-height: 1; margin-bottom: 1px;
    min-height: 10px;
}
.gfx-scale-track { position: relative; flex: 1; height: 10px; }
.gfx-scale-track span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
/* The end labels tuck inside the track so they cannot collide with the
   unit in the gutter, the way the numbers do on the real scale. */
.gfx-scale-track span:first-child { transform: none; }
.gfx-scale-track span:last-child { transform: translateX(-100%); }
.gfx-scale .gfx-scale-unit {
    flex: none; width: 28px; padding-left: 4px; text-align: right;
    font-weight: 700; white-space: nowrap;
}
.gfx-bar { display: flex; gap: 1px; height: 11px; padding-right: 26px; }
.gfx-bar i {
    flex: 1; background: rgba(20, 24, 26, 0.16);
}
.gfx-bar i.tick { background: rgba(20, 24, 26, 0.4); }
.gfx-bar i.lit { background: var(--gfx-ink); }

/* Menu / memory / trend overlay, drawn over the readout, same glass. */
/* Screens open BELOW the reading, not over it, so the value stays
   visible while you pick what to do with it. */
.gfx-panel {
    flex: 1; min-height: 0;
    display: flex; flex-direction: column; gap: 2px;
    padding-top: 2px;
}
.gfx-panel[hidden] { display: none; }
.gfx-panel-head, .gfx-trend-head {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em;
    border-bottom: 1px solid rgba(21, 26, 22, 0.45);
    padding-bottom: 2px; display: flex; gap: 6px; align-items: baseline;
}
.gfx-trend-head b { letter-spacing: 0.06em; }
.gfx-trend-time { margin-left: auto; font-variant-numeric: tabular-nums; }
/* Menu items sit in two columns, as on the real screen; the cursor pad
   moves the selector square between them. */
/* minmax(0, ...) so an over-long label ellipsizes inside its column
   rather than widening the column past the screen. */
.gfx-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 8px; }
.gfx-list { list-style: none; margin: 2px 0 0; padding: 0; font-size: 10.5px; }
.gfx-list li {
    display: flex; gap: 4px; align-items: baseline;
    padding: 1px 2px; border-radius: 2px; line-height: 1.4;
}
.gfx-list li.sel { background: var(--gfx-ink); color: var(--gfx-bg); }
.gfx-list.plain li { padding-left: 2px; }
.gfx-sel { flex: none; width: 8px; font-size: 8px; line-height: 1; }
.gfx-li-label {
    font-weight: 700; flex: 0 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gfx-li-detail { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; white-space: nowrap; text-align: right; }/* A single saved record, opened from memory. */
.gfx-rec-name {
    display: flex; justify-content: space-between; align-items: baseline;
    font-size: 11px; font-weight: 700; margin-top: 2px;
}
.gfx-rec-name span { font-weight: 600; font-size: 10px; }
.gfx-rec-big {
    font-size: 26px; font-weight: 700; text-align: right; line-height: 1.2;
    font-variant-numeric: tabular-nums;
}
.gfx-rec-sub { font-size: 10.5px; font-weight: 700; margin-bottom: 2px; }
.gfx-cursor { stroke: var(--gfx-ink); stroke-width: 1; stroke-dasharray: 2 2; vector-effect: non-scaling-stroke; }
.gfx-trend-empty { font-size: 11px; font-weight: 600; padding: 8px 2px; }
.gfx-trend-plot { position: relative; flex: 1; min-height: 62px; margin-top: 2px; }
.gfx-trend-plot svg { width: 100%; height: 100%; display: block; }
.gfx-band { fill: rgba(21, 26, 22, 0.22); stroke: none; }
.gfx-evtick { fill: none; stroke: var(--gfx-ink); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
.gfx-line { fill: none; stroke: var(--gfx-ink); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.gfx-axis {
    position: absolute; right: 1px; font-size: 9.5px; font-weight: 700;
    background: var(--gfx-bg); padding: 0 1px;
}
.gfx-axis-hi { top: 0; }
.gfx-axis-lo { bottom: 0; }
.gfx-trend-stats {
    display: flex; gap: 8px; font-size: 10px; font-weight: 700;
    border-top: 1px solid rgba(21, 26, 22, 0.45); padding-top: 2px;
}
.gfx-trend-stats b { font-variant-numeric: tabular-nums; }

/* Softkey labels along the bottom of the glass, each one sitting directly
   above the button that does it. */
.gfx-softlabels {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px;
    margin: 4px 7px 0; padding-top: 4px;
    border-top: 1.5px solid var(--gfx-ink);
}
.gfx-sklabel {
    text-align: center; font-size: 11px; font-weight: 700;
    letter-spacing: 0.02em; line-height: 16px;
    min-height: 18px; border: 1px solid var(--gfx-ink); border-radius: 2px;
    white-space: nowrap; overflow: hidden;
}
.gfx-sklabel:empty { border-color: transparent; }
.gfx-sklabel.on { background: var(--gfx-ink); color: var(--gfx-bg); }

/* The four physical softkeys. */
.softkeys {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 3px;
    margin-top: 6px;
}
.softkeys[hidden] { display: none; }
.skey {
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
    background: #52565e; color: #e8e4da;
    border: 1px solid #23252a; border-bottom-width: 3px;
    border-radius: 6px; padding: 6px 2px; cursor: pointer;
    transition: all 0.08s;
}
.skey:active { transform: translateY(1px); border-bottom-width: 2px; }
.skey.active { background: #7f858f; color: #16181b; box-shadow: inset 0 1px 3px rgba(0,0,0,0.3); }
/* A softkey with nothing assigned to it carries the class `dead`, but no
   styling: on the real meter these are the same four physical buttons
   whatever is on the screen, so they keep their normal look and press
   animation. The blank label on the screen above them is the only cue,
   and pressing one simply does nothing. */

/* Four-way cursor pad, the keys that move the menu selector. */
.cursor-pad {
    position: relative; width: 92px; height: 92px;
    margin: 8px auto 0;
}
.cursor-pad[hidden] { display: none; }
.cursor-pad .cbtn {
    position: absolute;
    font-family: 'JetBrains Mono', monospace; font-size: 11px; line-height: 1;
    background: #52565e; color: #e8e4da;
    border: 1px solid #23252a; border-bottom-width: 3px;
    border-radius: 7px; cursor: pointer; padding: 0;
    transition: all 0.08s;
}
.cbtn:active { transform: translateY(1px); border-bottom-width: 2px; }
.cbtn:hover { background: #626771; }
.cursor-pad .cbtn.up, .cursor-pad .cbtn.down { left: 30px; width: 32px; height: 28px; }
.cursor-pad .cbtn.left, .cursor-pad .cbtn.right { top: 32px; width: 28px; height: 28px; }
.cursor-pad .cbtn.up { top: 0; }
.cursor-pad .cbtn.down { bottom: 0; }
.cursor-pad .cbtn.left { left: 0; }
.cursor-pad .cbtn.right { right: 0; }
.cursor-pad .cbtn-hub {
    position: absolute; pointer-events: none;
    left: 33px; top: 33px; width: 26px; height: 26px;
    border-radius: 50%; background: #3a3d42;
    box-shadow: inset 0 1px 3px rgba(0,0,0,0.5);
}

/* Contrast: the same glass, more or less bite in the pixels. */
.gfx[data-contrast="1"] { --gfx-ink: #4b524c; }
.gfx[data-contrast="2"] { --gfx-ink: #303733; }
.gfx[data-contrast="4"] { --gfx-ink: #0b0f0c; }
.gfx[data-contrast="5"] { --gfx-ink: #000; }

/* ===== Logging-meter skin =====
   A big graphite bench instrument in a yellow holster: dark title bar,
   a tall screen that dominates the panel, blue-gray keys, and a heavy
   knob with a light paddle. */
.meter-shell[data-meter="logging"] .meter-boot {
    background: linear-gradient(162deg, #c5512f, #a83c20 55%, #8a2f16);
    padding: 12px 11px 13px;
    border-radius: 18px;
}
.meter-shell[data-meter="logging"] .meter-face {
    background: linear-gradient(178deg, #4c5058, #3a3e45 40%, #33373d);
    border-radius: 7px;
    padding: 0 0 11px;
}
/* Title bar: dark strip across the top, model number picked out in yellow. */
.meter-shell[data-meter="logging"] .meter-brand {
    background: linear-gradient(180deg, #23262b, #191c20);
    margin: 0 0 9px;
    padding: 5px 11px 6px;
    border-radius: 6px 6px 0 0;
    align-items: baseline;
    box-shadow: inset 0 -1px 0 rgba(0,0,0,0.5);
}
.meter-shell[data-meter="logging"] .meter-model {
    font-size: 12.5px; letter-spacing: 0.1em; color: #f3f1ea;
}
.meter-shell[data-meter="logging"] .meter-tagline {
    font-size: 9px; letter-spacing: 0.16em; color: #e8a91d;
}
/* The screen sits inset in the panel, with a little breathing room. */
.meter-shell[data-meter="logging"] .gfx { margin: 0 11px; }

/* Keys: the same dark caps as the field meter, just laid out differently. */
.meter-shell[data-meter="logging"] .softkeys { margin: 9px 11px 0; gap: 7px; }
.meter-shell[data-meter="logging"] .skey { border-radius: 9px; padding: 7px 2px; }

/* The keypad row: two columns of function keys flanking the cursor pad. */
.keypad {
    display: grid; grid-template-columns: 1fr auto 1fr;
    align-items: center; justify-items: center;
    gap: 6px; margin: 8px 13px 0;
}
.keypad[hidden] { display: none; }
.kp-col { display: flex; flex-direction: column; gap: 7px; width: 100%; max-width: 92px; }
.kp-col .mbtn { width: 100%; border-radius: 9px; padding: 8px 4px; }
.meter-shell[data-meter="logging"] .cursor-pad { margin: 0; }

/* Four jacks across the same panel width. */
.meter-shell[data-meter="logging"] .jacks {
    margin: 0 11px; padding-top: 14px;
    border-top-color: rgba(255,255,255,0.1);
}
.meter-shell[data-meter="logging"] .jack { width: 74px; padding: 4px 2px; }
.meter-shell[data-meter="logging"] .jack-label { font-size: 11px; }
.meter-shell[data-meter="logging"] .jack-hole { width: 27px; height: 27px; }
.meter-shell[data-meter="logging"] .jack-ratings { padding-left: 11px; padding-right: 11px; }
.meter-shell[data-meter="logging"] .jr-text {
    font-size: 7.5px; letter-spacing: 0.02em; white-space: pre-line; text-align: center;
    line-height: 1.35;
}
.meter-shell[data-meter="logging"] .jr-bracket { width: 74%; }
/* Four-jack panel: the fuse brackets are drawn to scale across the jack
   row, each one reaching from its terminal to COM. */
.jack-ratings.jr-spans {
    position: relative; display: block; height: 42px;
    padding: 3px 11px 0; grid-template-columns: none;
}
.jack-ratings .jr-span {
    position: absolute; display: block; top: 3px;
    border: 1.5px solid #8f939b; border-top: none;
    border-radius: 0 0 5px 5px;
}
.jack-ratings .jr-lab {
    position: absolute; display: block; transform: translateX(-50%);
    font-family: 'JetBrains Mono', monospace;
    font-size: 7.5px; font-weight: 600; letter-spacing: 0.02em;
    color: #a8acb4; line-height: 1.35; text-align: center;
    white-space: pre-line;
}


/* ===== Buttons row ===== */
.meter-buttons {
    display: flex; gap: 6px; justify-content: center; flex-wrap: wrap;
    margin: 11px 0 4px;
}
/* display:flex would otherwise beat the hidden attribute. */
.meter-buttons[hidden] { display: none; }
.mbtn {
    font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.04em;
    background: #52565e; color: #e8e4da;
    border: 1px solid #23252a; border-bottom-width: 3px;
    border-radius: 7px; padding: 7px 8px; cursor: pointer;
    transition: all 0.08s;
}
.mbtn:active { transform: translateY(1px); border-bottom-width: 2px; }
.mbtn.active { background: #7f858f; color: #16181b; box-shadow: inset 0 1px 3px rgba(0,0,0,0.3); }
.mbtn-yellow { background: var(--yellow-btn); color: #4a3800; border-color: #8a6d10; }
.mbtn-yellow.active { background: #ffe071; color: #4a3800; }

/* ===== Dial ===== */
.dial-area { display: flex; justify-content: center; padding: 7px 0 3px; position: relative; }
/* A blown fuse: a red band straight across the dial, with the button that
   replaces it. It covers the middle of the dial only, so the rest of the
   dial still turns. */
.dial-fuse {
    position: absolute; left: -6px; right: -6px; top: 50%; z-index: 6;
    transform: translateY(-50%);
    background: #c8341a; color: #fff;
    border: 1px solid #7a1d0f; border-radius: 6px;
    box-shadow: 0 6px 18px rgba(80, 12, 4, 0.45);
    padding: 10px 14px 12px; text-align: center;
    animation: dial-fuse-in 260ms ease-out;
}
.dial-fuse[hidden] { display: none; }
.dial-fuse-title {
    font-family: 'JetBrains Mono', monospace; font-size: 15px; font-weight: 800;
    letter-spacing: 0.18em;
}
.dial-fuse-text { margin-top: 4px; font-size: 12.5px; line-height: 1.4; opacity: 0.95; }
.dial-fuse-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-top: 9px; }
.dial-fuse-actions:empty { display: none; }
.btn.dial-fuse-btn {
    background: #fff; color: #9a2818; border-color: #7a1d0f; font-weight: 700;
}
.btn.dial-fuse-btn:hover { background: #fbe9e5; color: #7a1d0f; }
.btn.dial-fuse-btn:disabled { opacity: 0.85; cursor: default; }
.dial-fuse.replaced { background: #2e8c48; border-color: #1f5e33; box-shadow: 0 6px 18px rgba(10, 60, 25, 0.35); }
.dial-fuse.replaced .btn.dial-fuse-btn { color: #1f5e33; border-color: #1f5e33; }
@keyframes dial-fuse-in { from { opacity: 0; transform: translateY(-50%) scale(0.96); } to { opacity: 1; transform: translateY(-50%); } }
@media (prefers-reduced-motion: reduce) { .dial-fuse { animation: none; } }
.dial-wrap { position: relative; width: 256px; height: 256px; }
.dial { cursor: grab; touch-action: none; }
.dial.turning { cursor: grabbing; }
.dial {
    position: absolute; left: 50%; top: 50%;
    width: 150px; height: 150px; margin: -75px 0 0 -75px;
    border-radius: 50%;
    background: radial-gradient(circle at 40% 35%, #63666d, #43464c 65%, #33363b);
    border: 3px solid #202226;
    box-shadow: 0 4px 10px rgba(0,0,0,0.45), inset 0 2px 3px rgba(255,255,255,0.15);
    transform: rotate(var(--rot));
    transition: transform 0.18s ease-out;
    cursor: pointer;
}
.dial:focus-visible { outline: 3px solid var(--legend); outline-offset: 3px; }
.dial-grip {
    position: absolute; left: 50%; top: 50%; width: 40px; height: 116px;
    margin: -58px 0 0 -20px; border-radius: 20px;
    background: linear-gradient(90deg, #3a3d42, #55585f 50%, #3a3d42);
    box-shadow: inset 0 1px 2px rgba(255,255,255,0.15);
}
.dial-pointer {
    position: absolute; left: 50%; top: 5px; width: 9px; height: 26px;
    margin-left: -4.5px; border-radius: 4px;
    background: var(--legend);
    box-shadow: 0 0 4px rgba(0,0,0,0.4);
}
/* One consistent type scale for all panel markings: dial legends 14.5px,
   sub-legends 10.5px, symbols 1.25em, schematic icons sized to the
   cap height of the text they sit beside. */
.dial-label {
    position: absolute; transform: translate(-50%, -50%);
    background: none; border: none; cursor: pointer;
    font-family: 'JetBrains Mono', monospace; font-weight: 700; font-size: 14.5px;
    color: #cfccc2; text-align: center; line-height: 1.15;
    padding: 4px 6px; border-radius: 6px;
    /* Legends stay one line. "A mA" must sit beside A, not wrap under it. */
    white-space: nowrap;
    transition: color 0.12s, background 0.12s;
}
.dial-label small {
    display: block; font-size: 10.5px; color: var(--legend); font-weight: 700;
    /* A sub-legend is a single printed line, never a wrapped paragraph. */
    white-space: nowrap;
}
/* AC (~) and DC (⎓) symbols read larger than the letters, like real dials */
/* AC and DC are panel markings, not text, so they are set at a FIXED size
   rather than relative to whatever legend they sit beside. That keeps the
   pair identical on a position that offers both, and stops the symbol
   shrinking when it appears in a small yellow sub-legend. */.dial-label .dlab-dc,
.dial-label small .dlab-dc {
    height: 11px; width: auto;
    display: inline-block; vertical-align: -1px; margin: 0 1px;
}
/* Schematic icons in the dial legends. On the real panel these symbols are
   printed at about the cap height of the letters beside them, not larger,
   so they sit in the line rather than shouting over it. */
.dial-label .dlab-icon { height: 16px; width: auto; display: block; margin: 1px auto 0; }
.dial-label small .dlab-icon { height: 11px; display: inline-block; vertical-align: -1px; margin: 0 1px; }
/* One dial position carrying two symbols (diode and capacitance). */
.dial-label .dlab-pair {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 2px;
}
.dial-label .dlab-pair .dlab-icon { margin: 0; }
/* Schematic icons on the LCD annunciator row */
.lcd-annun .an-svg { height: 18px; width: auto; vertical-align: -4px; }
/* Same icons on the V jack legend, scaled to the jack text */
.jack-label .dlab-icon { height: 12px; width: auto; vertical-align: -2px; }
.jack-sub .dlab-icon { height: 10px; width: auto; vertical-align: -1px; }
.dial-label:hover { background: rgba(255,255,255,0.08); }
.dial-label.off { color: #8d8a81; }

/* ===== Jacks =====
   Labels ABOVE the holes and a panel-ratings row BELOW them, laid out like
   the real front panel: the "10 A FUSED" bracket spans A–COM, the CAT
   rating sits between COM and VΩ. Every jack shares one footprint so the
   labels, sub-legends, and holes line up in clean rows. */
.jacks {
    display: flex; justify-content: space-around; align-items: flex-start;
    margin-top: 7px; padding-top: 9px;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.jack {
    background: none; border: none; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    user-select: none; -webkit-user-select: none;
    touch-action: manipulation;
    display: flex; flex-direction: column; align-items: center; gap: 2px;
    font-family: 'JetBrains Mono', monospace; color: #cfccc2;
    padding: 4px 6px; border-radius: 8px;
    width: 94px;
    transition: background 0.12s;
}
/* Only the hole ever lights up: the jack's labels and symbols take no
   hover, drop or focus highlight (a keyboard focus ring goes on the hole). */
.jack:focus { outline: none; }
.jack:focus-visible .jack-hole { outline: 2px solid #e8a91d; outline-offset: 3px; }
.jack:disabled { cursor: default; }
.jack-hole {
    width: 26px; height: 26px; border-radius: 50%;
    background: radial-gradient(circle at 45% 40%, #23252a 55%, #0d0e10 60%);
    border: 3px solid #64686f;
    position: relative;
}
.jack-hole.com { border-color: #64686f; }
/* A jack in use shows nothing of its own: the plug drawn over it does
   (#lead-wires). No red or black fill, no glow. */
.jack-label { font-size: 12.5px; font-weight: 700; letter-spacing: 0.03em; }
.jack-sub {
    font-size: 9.5px; color: var(--legend); font-weight: 600;
    letter-spacing: 0.04em; min-height: 13px; line-height: 13px;
}

/* Panel ratings under the jack row, engraved-look markings. Two equal-width
   columns: "10 A FUSED" on the left, the CAT rating on the right. The left and
   right insets pull the outer edges in to sit under the outside jacks (A and
   V), whose centers are ~16.7% in from each edge of the jack row. */
.jack-ratings {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    padding: 2px 16.7% 0;
}
.jr {
    display: flex; flex-direction: column; align-items: center;
    min-width: 0;
    font-family: 'JetBrains Mono', monospace;
}
.jr-bracket {
    width: 82%; height: 7px;
    border: 1.5px solid #8f939b; border-top: none;
    border-radius: 0 0 5px 5px;
}
.jr-text {
    margin-top: 3px;
    font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em;
    color: #a8acb4; white-space: nowrap;
}

/* ===== Lead wires =====
   Two test leads plug into the jacks, fall naturally, and leave through the
   bottom of the screen. Drawn into #lead-wires (a document-anchored SVG)
   by drawLeadWires(), which re-routes the red wire when the red plug moves
   between jacks. Sits IN FRONT of the meter so the wires visibly plug into
   the jack holes (pointer-events: none keeps every control clickable
   through them); the intro card, masthead, lineup and modals (z-index
   40 / 100) still cover the wires. */
#lead-wires {
    position: absolute;
    top: 0; left: 0;
    pointer-events: none;
    overflow: visible;
    z-index: 30;
    /* Touch drags on the plugs, probes and knobs: browsers ignore
       touch-action on SVG shapes, so it goes on the drawing itself. The
       drawing takes no pointer events of its own (above), so a swipe
       anywhere else still scrolls the page. */
    touch-action: none;
}
#lead-wires .lead-hit {
    pointer-events: auto;
    cursor: grab;
    touch-action: none;
}
/* The fuse-check probe: grabbed anywhere along its length. */
#lead-wires .probe-hit {
    pointer-events: stroke;
    cursor: grab;
    touch-action: none;
}
body.is-dragging-lead #lead-wires .probe-hit { cursor: grabbing; }
/* With a probe picked up (tapped), every test point is a tap target; only
   the one under the pointer shows a ring. */
#lead-wires .term-hit {
    pointer-events: all; cursor: pointer;
    fill: rgba(0,0,0,0.001); stroke: transparent; stroke-width: 3;
}
#lead-wires .term-hit:hover { stroke: #c8341a; }
/* A probe that could not go where it was put says why, briefly. */
.bench-hint {
    position: absolute; z-index: 120; width: 280px;
    background: #1d1c1a; color: #f4efe4;
    font-size: 13px; line-height: 1.4; padding: 10px 12px; border-radius: 8px;
    box-shadow: 0 6px 18px rgba(20, 15, 5, 0.25);
    pointer-events: none; opacity: 0; transform: translateY(4px);
    transition: opacity 0.18s, transform 0.18s;
}
.bench-hint.show { opacity: 1; transform: none; }
/* The keyboard way to pick up a plug: two buttons beside the jacks, out of
   sight until one has focus. Enter on a plug button, then on a jack. */
.lead-keys {
    position: absolute; left: 50%; transform: translateX(-50%);
    bottom: 100%; margin-bottom: 4px;
    display: flex; gap: 6px; z-index: 5;
    clip-path: inset(50%); height: 1px; overflow: hidden; white-space: nowrap;
}
.lead-keys:focus-within { clip-path: none; height: auto; overflow: visible; }
.lead-keys button {
    font: 600 11px 'JetBrains Mono', monospace; letter-spacing: 0.06em;
    padding: 5px 9px; border-radius: 6px; border: 1px solid #555a62;
    background: #1f2125; color: #f0ede4; cursor: pointer;
}
/* A plug that should be in the meter (the probes are on something):
   a soft glow behind it, breathing. */
#lead-wires .plug-glow {
    transform-box: fill-box; transform-origin: center;
    animation: plug-glow 1.6s ease-in-out infinite;
    pointer-events: none;
}
@keyframes plug-glow {
    0%, 100% { opacity: 0.35; transform: scale(0.9); }
    50%      { opacity: 1;    transform: scale(1.08); }
}
/* The phone's version, when the plugs are out of sight: a wide, compact
   bar above the tab bar, arrows pointing down. */
.plug-prompt {
    position: fixed; left: 10px; right: 10px; z-index: 85;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 7px 12px; border: none; border-radius: 10px; cursor: pointer;
    background: var(--accent); color: #fff;
    font: 700 12.5px 'JetBrains Mono', monospace; letter-spacing: 0.04em; text-transform: uppercase;
    box-shadow: 0 4px 14px rgba(40, 28, 0, 0.28);
}
.plug-prompt[hidden] { display: none; }
.plug-prompt-arrow { display: inline-flex; width: 16px; animation: plug-prompt-bob 1.1s ease-in-out infinite; }
.plug-prompt-arrow svg { width: 16px; height: 10px; }
@keyframes plug-prompt-bob {
    0%, 100% { transform: translateY(-2px); }
    50%      { transform: translateY(3px); }
}
@media (prefers-reduced-motion: reduce) {
    #lead-wires .plug-glow { animation: none; opacity: 0.8; }
    .plug-prompt-arrow { animation: none; }
}
.lead-keys button[aria-pressed="true"] { background: var(--accent); color: #fff; border-color: var(--accent); }
.lead-keys button:focus-visible { outline: 2px solid #e8a91d; outline-offset: 2px; }
body.is-dragging-lead {
    cursor: grabbing;
    user-select: none;
    -webkit-user-select: none;
}
body.is-dragging-lead #lead-wires .lead-hit { cursor: grabbing; }
/* Hover a plug: it brightens, ready to be picked up. */
#lead-wires .lead-grab .plug-art { transition: filter 0.12s; }
#lead-wires .lead-grab:hover .plug-art { filter: brightness(1.12); }
/* A plug in hand: only the jack it would go into lights up (the one under
   the plug while dragging, the one under the pointer after a tap). Other
   jacks stay plain. */
body.lead-lifted:not(.is-dragging-lead) .jack:hover .jack-hole,
.jack.drop-hover .jack-hole {
    box-shadow: 0 0 0 3px #c8341a, 0 0 12px rgba(200, 52, 26, 0.5);
}
/* Seated: a quick ring out of the jack, the "click" of a plug going home. */
.jack.seat-pulse .jack-hole::after {
    content: ''; position: absolute; inset: -6px; border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.75);
    animation: seat-ring 0.5s ease-out forwards;
    pointer-events: none;
}
@keyframes seat-ring {
    from { transform: scale(0.7); opacity: 1; }
    to   { transform: scale(1.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .jack.seat-pulse .jack-hole::after { animation: none; }
}

/* Fuse-blow drama: a hard jolt on the body plus a flash-then-flicker on
   the LCD, timed with the pop sound (playFusePop in controls.js). */
.meter-shell.bang .meter-boot { animation: bang-shake 0.7s; }
@keyframes bang-shake {
    0%, 100% { transform: translateX(0); }
    8%  { transform: translate(-11px, 2px) rotate(-1.4deg); }
    20% { transform: translate(9px, -2px) rotate(1.1deg); }
    34% { transform: translateX(-7px) rotate(-0.7deg); }
    50% { transform: translateX(5px) rotate(0.4deg); }
    68% { transform: translateX(-3px); }
    84% { transform: translateX(2px); }
}
.lcd.fuse-pop { animation: lcd-pop 0.9s ease-out; }
@keyframes lcd-pop {
    0%   { background: #fff; box-shadow: inset 0 0 24px rgba(255,255,255,0.9), 0 0 18px rgba(255, 240, 200, 0.8); }
    10%  { background: #6a705f; }
    18%  { background: var(--lcd-bg); }
    26%  { background: #7d8471; }
    38%  { background: var(--lcd-bg); }
    100% { background: var(--lcd-bg); }
}

.btn {
    font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 700;
    letter-spacing: 0.05em; border-radius: 6px; cursor: pointer;
    padding: 9px 14px; border: 1px solid var(--rule);
    background: var(--paper); color: var(--ink-2);
    transition: all 0.12s;
}
.btn:hover { border-color: var(--accent); color: var(--ink); }
.btn.big { width: 100%; padding: 12px; font-size: 13px; }
.btn-accent { background: var(--accent); color: #fff; border-color: var(--accent-2); }
.btn-accent:hover { background: var(--accent-2); color: #fff; }
.btn-secondary { background: var(--paper-2); }
.btn.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* The selected device's control panel: condition, waveform, hookup, the
   value knobs, and the connected / disconnected toggle. */
#device-controls {
    margin: 0 0 12px;
    padding: 10px 12px;
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: 8px;
}
.inst-head {
    font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.14em; color: var(--ink-3); margin-bottom: 8px;
}
.inst-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px; padding: 3px 0;
}.inst-seg { display: inline-flex; gap: 4px; }
/* A row of choices too long for one line: the series parts, and a fault
   list with three states in it. */
.inst-seg-wrap { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; }
.inst-seg-wrap .inst-wave { flex: 1 1 auto; justify-content: center; }
.inst-seg-wide { width: 100%; }
/* Up to four short choices to a line, a long one on two lines inside its
   button: the dual-voltage transformer's jumper sets and probe pairs. */
.inst-seg-tight .inst-wave { flex: 1 1 21%; padding: 4px 3px; line-height: 1.25; text-align: center; }
.inst-seg-wide .inst-wave { flex: 1; justify-content: center; font-size: 11px; padding: 7px 8px; }
.inst-wave {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
    padding: 4px 9px; border-radius: 4px; cursor: pointer;
    background: var(--paper-2); border: 1px solid var(--rule); color: var(--ink-2);
}
.inst-wave.active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
/* A choice that cannot be changed right now (the transformer's jumpers
   with the line on): the setting still shows, but the buttons are locked. */
.inst-wave:disabled { cursor: not-allowed; opacity: 0.55; }
.inst-wave.active:disabled { opacity: 0.8; }
/* Locked but still pressable, so a press can open a popup saying why:
   it looks the same as a disabled button. */
.inst-wave.is-locked { cursor: not-allowed; opacity: 0.55; }
.inst-wave.active.is-locked { opacity: 0.8; }
/* Reference figures shown in the panel, not chosen: the circuit boards'
   ideal source voltage and part values. */
.inst-info { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.inst-info-item {
    flex: 1 1 auto; display: flex; flex-direction: column; align-items: center;
    padding: 4px 6px; border: 1px solid var(--rule); border-radius: 4px; background: var(--paper);
}
.inst-info-k { font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 700; letter-spacing: 0.08em; color: var(--ink-3); }
.inst-info-v { font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 700; color: var(--ink); white-space: nowrap; }
.modal.lock-modal { max-width: 380px; }
.lock-modal .modal-header h2 { font-size: 19px; }
.lock-modal .modal-body p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--ink-2); }
.kind-seg { width: 100%; }
.kind-seg .inst-wave {
    flex: 1 1 30%;
    justify-content: center;
    font-size: 9.5px;
    padding: 5px 4px;
}

/* The series slot: what the source is driving, set apart from the source's
   own controls because it is a second thing on the bench, not another
   setting of the first one. */
.bench-series {
    margin-top: 10px; padding-top: 10px;
    border-top: 1px dashed var(--rule);
}
/* Nothing above it to separate it from, so no rule. */
.bench-series:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.bench-series .inst-head { margin-bottom: 6px; }
.bench-series .knob-cluster { margin-top: 4px; }
/* The series part's value field: one full-width row. An <input> left to
   its own default size is about 20 characters wide, which pushed the row
   out past the panel's edge. */
.bench-series .knob-cluster:has(> .field-cell) { display: block; }
.field-cell { min-width: 0; }
.field-readout { width: 100%; }

/* Connected / disconnected sits apart from the rest, with a rule above
   it, because it is the one control that answers "is anything even
   hooked up?" and that question deserves its own place on the panel. */


/* ===== Modals ===== */
.modal-backdrop {
    position: fixed; inset: 0; background: rgba(30, 26, 18, 0.55);
    display: flex; align-items: center; justify-content: center;
    z-index: 100; padding: 16px;
}
.modal-backdrop[hidden] { display: none; }
.modal {
    background: var(--paper); border: 1px solid var(--rule); border-radius: 10px;
    width: 100%; max-width: 560px; max-height: calc(100vh - 40px);
    display: flex; flex-direction: column;
    box-shadow: 0 18px 50px rgba(30, 25, 10, 0.35);
}
.modal.help-modal { max-width: 600px; }
.modal-header {
    display: flex; justify-content: space-between; align-items: center;
    padding: 14px 18px 10px; border-bottom: 1px solid var(--rule);
}
.modal-header h2 { margin: 0; font-size: 21px; font-weight: 500; }
.modal-close {
    background: none; border: none; font-size: 26px; color: var(--ink-3);
    cursor: pointer; line-height: 1; padding: 0 4px;
}
.modal-close:hover { color: var(--accent); }
.modal-body { padding: 14px 18px; overflow-y: auto; flex: 1 1 auto; }
.modal-intro { font-size: 14px; color: var(--ink-3); margin: 0 0 12px; }
.modal-footer {
    display: flex; justify-content: flex-end; gap: 8px;
    padding: 10px 18px 14px; border-top: 1px solid var(--rule);
}

/* Circuit list */
/* The empty bench, the widest button, above everything else, because it
   is both the starting point and the place to come back to. */
/* ===== Quick Reference typography (from the scope tool) ===== */
.quickref-section { padding: 14px 0 2px; border-bottom: 1px solid var(--rule); }
.quickref-section:last-child { border-bottom: none; padding-bottom: 8px; }
.quickref-section:first-child { padding-top: 2px; }
.quickref-section-title {
    font-family: 'Fraunces', Georgia, serif; font-size: 19px; font-weight: 500;
    color: var(--ink); margin: 0 0 4px; letter-spacing: -0.01em;
}
.quickref-section-title em { font-style: normal; font-weight: inherit; }
.quickref-section-sub { font-size: 13.5px; color: var(--ink-2); margin: 0 0 12px; line-height: 1.55; }
.quickref-dl {
    margin: 0; display: grid;
    grid-template-columns: minmax(110px, max-content) 1fr;
    column-gap: 18px; row-gap: 8px; padding-bottom: 12px;
}
.quickref-dl dt { font-weight: 600; color: var(--ink); font-size: 14px; line-height: 1.45; }
.quickref-dl dd { margin: 0; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.quickref-dl code {
    font-family: 'JetBrains Mono', monospace; font-size: 12.5px;
    background: var(--paper-2); border: 1px solid var(--rule); border-radius: 3px;
    padding: 1px 5px; color: var(--ink); white-space: nowrap;
}
.use-when { display: block; margin-top: 4px; font-size: 12.5px; color: var(--ink-3); line-height: 1.4; }
.use-when b { color: var(--accent); font-weight: 600; margin-right: 4px; }
@media (max-width: 560px) {
    .quickref-dl { grid-template-columns: 1fr; row-gap: 4px; }
    .quickref-dl dt { margin-top: 6px; }
}

/* ===== Colophon ===== */
.colophon {
    margin-top: 28px; padding-top: 20px;
    font-size: 12.5px; color: var(--ink-3);
    text-align: center;
    /* Above the test leads, which are drawn over the whole document. */
    position: relative; z-index: 40;
}
.colophon p { margin: 0; }
/* The disclaimer sits quietly under the credit line. Scoped past
   ".colophon p { margin: 0 }", which would otherwise kill the centring. */
.colophon .colophon-note {
    margin: 5px auto 0; font-size: 11.5px; line-height: 1.45;
    max-width: 62ch; opacity: 0.85;
}
.colophon a { color: var(--ink-3); }

/* ===== The Quick Reference page =====
   Its own window, so it is a page rather than a dialog: a column of type
   you can read beside the meter, and print. */
.qr-page { background: var(--paper); }
.qr-wrap { max-width: 760px; margin: 0 auto; padding: 24px 22px 40px; }
.qr-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
    padding-bottom: 12px; margin-bottom: 4px;
    border-bottom: 2px solid var(--ink);
}
.qr-head h1 { margin: 0; font-size: 34px; font-weight: 500; letter-spacing: -0.02em; }
.qr-head h1 em { font-style: normal; font-weight: inherit; }
.qr-head .btn { min-width: 110px; flex: none; }
.qr-body .modal-intro { font-size: 14px; color: var(--ink-3); margin: 14px 0 4px; }
.qr-page .colophon { margin-top: 26px; }

/* ===== Print: the Quick Reference as a paper handout ===== */
@media print {
    .qr-page { background: #fff; background-image: none; }
    .qr-page .qr-head .btn { display: none !important; }
    .qr-wrap { max-width: 100%; padding: 0; }
    .quickref-dl dt, .quickref-dl dd { break-inside: avoid; }
    .quickref-section-title { break-after: avoid; }
    /* One sheet of paper: smaller type, tighter spacing. */
    @page { size: letter; margin: 0.4in; }
    .qr-head h1 { font-size: 18px; }
    .qr-head { margin: 0; }
    .qr-wrap { padding-top: 0 !important; }
    .qr-body .modal-intro { font-size: 10pt; margin: 4px 0 0; }
    .quickref-section { padding: 3px 0 1px; }
    .qr-head { padding-bottom: 4px; }
    .quickref-section-title { font-size: 12pt; margin-bottom: 1px; }
    .quickref-section-sub { font-size: 9pt; line-height: 1.3; margin-bottom: 3px; }
    .quickref-dl { row-gap: 1px; }
    .quickref-dl code { padding: 0 3px; }
    .quickref-dl dt, .quickref-dl dd { font-size: 9pt; line-height: 1.28; }
    .qr-page .colophon { display: none; }
}


/* ===== Bench knobs =====
   The same control as the oscilloscope tool: grab the row and drag to
   sweep, tap either side of the knob to step, or type into the readout.
   Ported so a student who learned one instrument already knows the other. */
.knob-cluster {
    display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
    align-items: start; margin-top: 8px;
}
.knob-cluster:has(> .knob-cell:only-child) {
    display: flex; align-items: center; justify-content: center;
    height: auto; width: auto; padding: 0 6px;
}
.knob-cluster:has(> .knob-cell:only-child) .knob-cell {
    height: 100%; justify-content: center; max-width: 150px;
}
.knob-cell {
    display: flex; flex-direction: column; align-items: center; gap: 7px;
    min-width: 0;
}
.knob-label {
    font-family: 'JetBrains Mono', monospace; font-size: 10px;
    letter-spacing: 0.12em; color: var(--ink-3);
    text-transform: uppercase; font-weight: 600; text-align: center;
}
.knob-readout {
    font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 600;
    color: var(--ink); text-align: center;
    background: var(--paper); border: 1px solid var(--rule); border-radius: 3px;
    padding: 4px 5px; width: 100%; line-height: 1.1;
    appearance: none; -webkit-appearance: none;
}
.knob-readout:focus {
    outline: none; border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(200, 52, 26, 0.15);
}
.knob-row {
    display: flex; align-items: center; justify-content: center; gap: 6px;
    position: relative; width: 100%;
    touch-action: none; user-select: none;
}
/* The knob is what drags; the buttons beside it are clicked. */
.knob-wrap { cursor: ns-resize; touch-action: none; }
.knob-wrap.dragging, .knob-wrap.dragging .knob { cursor: grabbing; }
.knob-step {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; padding: 0; flex-shrink: 0;
    font-family: 'JetBrains Mono', monospace; font-size: 15px; font-weight: 700; line-height: 1;
    color: var(--ink-2, #3a362e); background: var(--paper);
    border: 1px solid var(--rule); border-radius: 5px;
    cursor: pointer; user-select: none; touch-action: none;
}
.knob-step:hover { border-color: var(--ink-3); }
.knob-step.pressed, .knob-step:active { transform: translateY(1px); }
.knob-wrap {
    position: relative; width: 42px; height: 42px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
}
.knob-wrap svg.ticks { position: absolute; inset: -6px; pointer-events: none; }
.knob-wrap svg.ticks line { stroke: var(--rule); stroke-width: 1.4; }
.knob {
    width: 42px; height: 42px; border-radius: 50%; cursor: inherit;
    background: radial-gradient(circle at 30% 25%, #fbf9f3 0%, #ddd6c5 50%, #b8b0a0 100%);
    border: 1px solid #98907f;
    box-shadow: 0 2px 4px rgba(28, 26, 21, 0.15),
        inset 0 -2px 4px rgba(28, 26, 21, 0.1),
        inset 0 2px 3px rgba(255, 255, 255, 0.6);
    position: relative; user-select: none; touch-action: none;
}
.knob:hover {
    box-shadow: 0 3px 6px rgba(28, 26, 21, 0.2),
        inset 0 -2px 4px rgba(28, 26, 21, 0.1),
        inset 0 2px 3px rgba(255, 255, 255, 0.6);
}
.knob:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.knob::before {
    content: ''; position: absolute; inset: 9px; border-radius: 50%;
    background: radial-gradient(circle at 30% 25%, #fefcf6 0%, #e8e2d2 70%, #d4ccba 100%);
    box-shadow: inset 0 1px 2px rgba(28, 26, 21, 0.15);
}
.knob::after {
    content: ''; position: absolute; top: 3px; left: 50%;
    width: 2px; height: 10px; background: var(--accent); border-radius: 1px;
    transform-origin: 50% calc(42px / 2 - 3px);
    transform: translateX(-50%) rotate(var(--rot, 0deg));
    z-index: 2; box-shadow: 0 0 2px rgba(200, 52, 26, 0.3);
}



/* ---------------------------------------------------------------------------
   THE BENCH'S OWN CONTROLS
   ---------------------------------------------------------------------------
   Two cards in a column of their own beside the drawing: what is on the
   leads and what it is set to, then which way round the leads are, whether
   they are on it at all, and the device's own settings. They share a
   width, a card and a way of labeling themselves. */

.bench-head { display: flex; flex-direction: column; gap: 10px; }
@media (min-width: 741px) {
    .bench-head {
        gap: 0;
        padding: 11px 12px 12px;
        border: 1px solid var(--rule); border-radius: 10px;
        background: #faf6ef;
        box-shadow: 0 2px 10px rgba(52, 38, 24, 0.10);
    }
}

/* What is on the leads: a button carrying the current name, opening a
   chooser you can read. A native select here is a small target sitting on
   top of the drawing, with the operating system's own menu landing over the
   bench you are trying to look at. */
.device-picker {
    width: 100%; display: flex; flex-direction: column; align-items: stretch; gap: 5px;
    padding: 0; margin: 0;
    background: none; border: none; cursor: pointer; text-align: left;
    font-family: 'JetBrains Mono', monospace; color: var(--ink);
}
/* What the box is for, over it. */
.device-picker-kicker {
    font-size: 10px; font-weight: 700; letter-spacing: 0.14em; color: var(--ink-3);
}
/* The box itself: a white field with a dark edge and a dark drop button
   on its right, so it reads as a menu at a glance, not as a heading. */
.device-picker-box {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 6px 6px 6px 12px; min-height: 44px; box-sizing: border-box;
    background: #fff; border: 2px solid var(--ink); border-radius: 8px;
    box-shadow: 0 2px 0 rgba(28, 26, 21, 0.14);
    font-size: 13.5px; font-weight: 700; letter-spacing: 0.01em; line-height: 1.25;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.device-picker:hover .device-picker-box { border-color: var(--accent); }
.device-picker:hover .device-picker-chev { background: var(--accent); }
.device-picker:focus-visible { outline: none; }
.device-picker:focus-visible .device-picker-box { outline: 2px solid var(--accent); outline-offset: 2px; }
.device-picker-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.device-picker-chev {
    flex: none; width: 28px; height: 28px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ink); color: #fff; transition: background 0.12s;
}
.device-picker-caret { width: 11px; height: 7px; flex: none; color: currentColor; }
/* Nothing on the leads yet: the box asks for it, in the accent color. */
.device-picker.is-empty .device-picker-box { border-color: var(--accent); color: var(--accent); }
.device-picker.is-empty .device-picker-chev { background: var(--accent); }

/* The chooser. Grouped by how the meter goes on, because that is the
   first decision in any measurement: ACROSS a live source, IN SERIES with
   a load, ON an unpowered part. Two columns where there is room, so the
   whole list fits on one screen. */
.modal.device-modal { max-width: 720px; }
.device-group { margin-bottom: 16px; }
.device-group:last-child { margin-bottom: 0; }
.device-group-head {
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
    letter-spacing: 0.17em; text-transform: uppercase; color: var(--ink-2, var(--ink));
    padding: 0 2px 7px;
}
.device-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.device-grid .device-opt { margin-bottom: 0; }
@media (max-width: 620px) { .device-grid { grid-template-columns: 1fr; } }
.device-opt {
    display: block; width: 100%; text-align: left;
    padding: 10px 12px; margin-bottom: 6px;
    border: 1px solid var(--rule); border-radius: 8px;
    background: var(--paper); cursor: pointer;
    transition: background 0.1s, border-color 0.1s;
}
.device-opt:last-child { margin-bottom: 0; }
.device-opt:hover { background: var(--paper-2); border-color: var(--ink-3); }
.device-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.device-opt.active { background: var(--ink); border-color: var(--ink); }
.device-opt-name {
    display: block;
    font-family: 'JetBrains Mono', monospace; font-size: 12px; font-weight: 700;
    letter-spacing: 0.04em; color: var(--ink);
}
.device-opt-blurb {
    display: block; margin-top: 3px;
    font-size: 12.5px; line-height: 1.4; color: var(--ink-3);
}
.device-opt.active .device-opt-name { color: var(--paper); }
.device-opt.active .device-opt-blurb { color: rgba(246, 241, 232, 0.72); }

/* ---------------------------------------------------------------------------
   A PART'S VALUE
   ---------------------------------------------------------------------------
   No dial. A component has its value printed on it, and the way you change
   one on a bench is to reach into the drawer for a different one, so this is
   a figure you type over with a stepper either side, built as one segmented
   control rather than three separate widgets. The dial is kept for the
   instruments, which really do have dials. */
.field-cluster { display: flex; flex-direction: column; gap: 10px; }
.field-cluster:empty { display: none; }
@media (min-width: 741px) {
    .bench-head .field-cluster:not(:empty) {
        margin-top: 11px; padding-top: 11px; border-top: 1px solid var(--rule);
    }
}
.field-label {
    font-family: 'JetBrains Mono', monospace; font-size: 8.5px; font-weight: 700;
    letter-spacing: 0.17em; color: var(--ink-3); margin-bottom: 6px;
}
.field-row {
    display: flex; align-items: stretch;
    border: 1px solid var(--rule); border-radius: 7px;
    background: var(--paper); overflow: hidden;
}
.field-row:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(207, 65, 48, 0.18);
}
.field-step {
    flex: none; width: 34px; padding: 0;
    font-family: 'Inter', sans-serif; font-size: 17px; font-weight: 500; line-height: 1;
    color: var(--ink-2); background: var(--paper-2);
    border: none; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.1s, color 0.1s;
    -webkit-user-select: none; user-select: none; touch-action: none;
}
.field-step:first-child { border-right: 1px solid var(--rule); }
.field-step:last-child { border-left: 1px solid var(--rule); }
.field-step:hover { background: var(--ink); color: var(--paper); }
.field-step:active { background: var(--accent); color: #fff; }
.field-readout {
    flex: 1; min-width: 0; text-align: center;
    font-family: 'JetBrains Mono', monospace; font-size: 15px; font-weight: 700;
    color: var(--ink); background: transparent;
    border: none; padding: 9px 4px; margin: 0;
}
.field-readout:focus { outline: none; }

/* Thermocouple applicators replace the free-form value stepper. The bead
   moves only while one of these large targets is held, then coasts back to
   the room marker on the temperature rail. */
.thermal-control { width: 100%; }
.thermal-readout {
    display: block; width: 100%; text-align: center;
    font-family: 'JetBrains Mono', monospace; font-size: 15px; font-weight: 700;
    color: var(--ink); font-variant-numeric: tabular-nums;
    padding: 1px 0 7px;
}
.thermal-track {
    position: relative; height: 7px; margin: 0 5px 10px;
    border-radius: 999px;
    background: linear-gradient(90deg, #72a9d2 0%, #d8d7cd 56%, #db7965 100%);
    box-shadow: inset 0 1px 2px rgba(28,26,21,0.22);
}
.thermal-track::after {
    content: ''; position: absolute; left: 60.4%; top: -2px;
    width: 1px; height: 11px; background: rgba(28,26,21,0.48);
}
#thermal-marker {
    position: absolute; top: 50%; width: 12px; height: 12px;
    border-radius: 50%; background: var(--paper); border: 2px solid var(--ink);
    box-shadow: 0 1px 3px rgba(28,26,21,0.25);
    transform: translate(-50%, -50%); transition: left 0.18s linear;
}
.thermal-actions { display: flex; gap: 6px; }
.thermal-apply {
    flex: 1; min-width: 0; padding: 8px 4px 7px;
    border: 1px solid var(--rule); border-radius: 7px;
    background: var(--paper-2); color: var(--ink-2); cursor: pointer;
    touch-action: none; user-select: none;
    transition: background 0.1s, border-color 0.1s, color 0.1s, transform 0.08s;
}
.thermal-apply span,
.thermal-apply b {
    display: block; font-family: 'JetBrains Mono', monospace;
    white-space: nowrap;
}
.thermal-apply span { font-size: 9px; font-weight: 700; letter-spacing: 0.05em; }
.thermal-apply b { margin-top: 3px; font-size: 12px; }
.thermal-apply:hover { border-color: var(--ink-3); }
.thermal-apply:active,
.thermal-apply.active { transform: translateY(1px); color: #fff; }
.thermal-apply.heat.active { background: #b94632; border-color: #8e2e20; }
.thermal-apply.cool.active { background: #3b79a5; border-color: #285d82; }
.thermal-apply:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.thermal-status {
    min-height: 14px; margin-top: 7px; text-align: center;
    font: 700 8.5px/1.3 'JetBrains Mono', monospace;
    letter-spacing: 0.055em; color: var(--ink-2);
}
.thermal-hint {
    margin-top: 3px; text-align: center;
    font: 600 7.5px/1.3 'JetBrains Mono', monospace;
    letter-spacing: 0.035em; color: var(--ink-3);
}

/* ---------------------------------------------------------------------------
   HOW THE LEADS ARE ON IT
   ---------------------------------------------------------------------------
   Which way round, and whether they are on it at all: one question in two
   parts, so one card under the part rather than two boxes floating apart. */
.bench-foot { display: flex; flex-direction: column; gap: 10px; align-items: stretch; }
.bench-leads {
    padding: 11px 12px 12px;
    border: 1px solid var(--rule); border-radius: 10px;
    background: #faf6ef;
}
@media (min-width: 741px) {
    .bench-leads,
    .bench-foot #device-controls {
        margin: 0;
        padding: 11px 12px 12px;
        border: 1px solid var(--rule); border-radius: 10px;
        background: #faf6ef;
        box-shadow: 0 2px 10px rgba(52, 38, 24, 0.10);
    }
    .bench-foot .inst-seg-wide { width: 100%; }
}

.flip-float {
    display: flex; width: 100%;
    align-items: center; justify-content: center; gap: 8px;
    padding: 9px 12px;
    border: 1px solid var(--rule); border-radius: 7px;
    background: #ffffff;
    font: 700 11px/1 'JetBrains Mono', monospace;
    letter-spacing: 0.1em; color: var(--ink-2);
    cursor: pointer; white-space: nowrap;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.flip-float[hidden] { display: none; }
.flip-float:hover { background: #f6f2ea; }
.flip-float.active {
    background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.flip-float[hidden] { display: none; }
.flip-float .flip-ico { width: 20px; height: 15px; flex: none; }
.flip-ico .flip-a { stroke: #cf4130; }
.flip-ico .flip-b { stroke: #26262b; }
.flip-float.active .flip-ico .flip-a { stroke: #f0705c; }
.flip-float.active .flip-ico .flip-b { stroke: #e8e2d6; }

.bench-toggles { display: flex; margin-top: 8px; }
.flip-float .connect-ico { width: 18px; height: 18px; flex: none; }
/* Connected: a white button with a green check.
   Disconnected: a black button with a red X. */
.connect-float.active {
    background: #ffffff; border-color: var(--rule); color: var(--ink);
}
.connect-float.active:hover { background: #f6f2ea; }
.connect-float:not(.active) {
    background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.connect-float:not(.active):hover { background: #2a2622; }
.connect-ico .connect-check { stroke: #1f9d45; }
.connect-ico .connect-x { stroke: #e5402f; }
.connect-float.active .connect-ico .connect-x { display: none; }
.connect-float:not(.active) .connect-ico .connect-check { display: none; }
.bench-toggles[hidden] { display: none; }
.bench-toggles .inst-seg { width: 100%; }
.bench-toggles .inst-wave {
    flex: 1; justify-content: center;
    font-size: 9.5px; letter-spacing: 0.06em; padding: 8px 4px;
}

/* An instrument's dials, sitting on its own front panel. Sized for a
   mouse: a knob big enough to grab, − and + buttons that are real
   targets, and a readout you can click into without aiming. */
.src-knobs { gap: 8px; }
.src-knobs .knob-cell { gap: 4px; flex: 1 1 0; max-width: 150px; }
.src-knobs .knob-label { font-size: 9px; letter-spacing: 0.1em; color: rgba(236,232,224,0.80); }
.src-knobs .knob-readout {
    font-size: 12px; padding: 3px 4px; cursor: text;
    color: #eae6de; background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.18);
}
.src-knobs .knob-readout:hover { border-color: rgba(255,255,255,0.40); }
.src-knobs .knob-row { gap: 4px; }
.src-knobs .knob-step {
    width: 22px; height: 22px; font-size: 14px;
    color: #eae6de; background: rgba(255,255,255,0.08);
    border-color: rgba(255,255,255,0.22);
}
/* Four dials on one panel (the generator): a size smaller, so all four
   fit across the strip. */
.src-knobs.src-knobs-4 { gap: 5px; }
.src-knobs.src-knobs-4 .knob-row { gap: 2px; }
.src-knobs.src-knobs-4 .knob-step { width: 18px; height: 18px; font-size: 12px; }
.src-knobs.src-knobs-4 .knob-wrap, .src-knobs.src-knobs-4 .knob { width: 30px; height: 30px; }
.src-knobs.src-knobs-4 .knob-readout { font-size: 11px; padding: 2px 3px; }
.src-knobs.src-knobs-4 .knob-label { font-size: 8.5px; letter-spacing: 0.06em; white-space: nowrap; }
.src-knobs .knob-step:hover { background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.45); }
.src-knobs .knob-step.pressed, .src-knobs .knob-step:active { background: rgba(255,255,255,0.26); }
.src-knobs .knob-wrap { width: 36px; height: 36px; }
.src-knobs .knob-wrap:hover .knob { box-shadow: 0 0 0 2px rgba(242,200,75,0.45), 0 2px 4px rgba(0,0,0,0.48); }
.src-knobs .knob {
    width: 36px; height: 36px;
    background: radial-gradient(circle at 32% 28%, #555d63 0%, #252a2e 58%, #111416 100%);
    border-color: #0d1012;
    box-shadow: 0 2px 4px rgba(0,0,0,0.48), inset 0 1px 2px rgba(255,255,255,0.16);
}
.src-knobs .knob::before {
    inset: 6px;
    background: radial-gradient(circle at 35% 30%, #626a70, #292e32 70%, #171a1c);
    box-shadow: inset 0 1px 2px rgba(255,255,255,0.14);
}
.src-knobs .knob::after {
    top: 2px; height: 10px; background: #f2c84b;
    transform-origin: 50% 16px;
}

/* ===== The guidance panel (inside the help modal) =====
   A status card first, then plain sections separated by full rules. Every
   box is outlined on all four sides: no single-edge accent bars. */
.gd-status {
    border: 1px solid var(--rule); border-radius: 8px;
    background: var(--paper-2); padding: 12px 14px;
    font-size: 14px; line-height: 1.5; color: var(--ink);
}
.gd-status p { margin: 6px 0 0; }
.gd-status-title {
    display: flex; align-items: center; gap: 9px;
    font-family: 'Inter', sans-serif; font-weight: 700; font-size: 15px;
}
.gd-icon {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%;
    font-size: 13px; font-weight: 800; line-height: 1;
    background: var(--ink-3); color: #fff;
}
.gd-stop  { background: #fbe9e5; border-color: #e0a193; }
.gd-stop .gd-status-title { color: #8a2415; }
.gd-stop .gd-icon { background: var(--accent); }
.gd-check { background: #fcf2df; border-color: #e2bf7c; }
.gd-check .gd-status-title { color: #7a4a06; }
.gd-check .gd-icon { background: #c2800f; }
.gd-ok    { background: #e8f3eb; border-color: #a7d0b3; }
.gd-ok .gd-status-title { color: #1f5e33; }
.gd-ok .gd-icon { background: #2e8c48; }
.gd-info .gd-status-title { color: var(--ink); }
.gd-steps-head {
    margin-top: 10px;
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
    letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
}
.gd-steps { margin: 4px 0 0; padding-left: 22px; }
.gd-steps li { margin: 3px 0; }
.gd-real { font-size: 13px; color: var(--ink-2); }
.gd-status + .gd-status { margin-top: 10px; }

.gd-sec { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rule); }
.gd-status + .gd-sec { border-top: none; padding-top: 0; }
.gd-h {
    display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
    margin: 0 0 8px;
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3);
}
.gd-meter { letter-spacing: 0.08em; color: var(--ink-3); font-weight: 600; }
.gd-fn { display: flex; gap: 12px; align-items: flex-start; }
.gd-sym {
    flex: none; min-width: 56px; height: 42px; padding: 0 8px;
    display: inline-flex; align-items: center; justify-content: center; gap: 2px;
    font-family: 'JetBrains Mono', monospace; font-size: 17px; font-weight: 700;
    color: #e8e4da; background: var(--meter-face);
    border: 1px solid #1c1e21; border-radius: 7px;
}
/* The meter's own panel markings, at the sizes the dial prints them. */
.gd-sym .dlab-dc { height: 12px; width: auto; display: block; }
.gd-sym .dlab-icon { height: 18px; width: auto; display: block; }
.gd-sym-t { line-height: 1; }
.gd-sym-stack { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.gd-fn-name { font-weight: 700; font-size: 15px; color: var(--ink); }
.gd-fn-text p { margin: 2px 0 0; font-size: 14px; line-height: 1.5; color: var(--ink-2); }
.gd-connect {
    display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
    margin-top: 10px; padding: 8px 10px;
    border: 1px solid var(--rule); border-radius: 7px; background: var(--paper);
    font-size: 13.5px; line-height: 1.5; color: var(--ink-2);
}
.gd-connect span:last-child { flex: 1 1 240px; }
.gd-tag {
    flex: none; padding: 2px 8px; border-radius: 999px;
    border: 1px solid var(--ink-2); color: var(--ink);
    font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 700;
    letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap;
}
.gd-note { margin: 0; font-size: 14px; line-height: 1.55; color: var(--ink-2); }
.gd-list { margin: 0; padding-left: 20px; font-size: 14px; line-height: 1.5; color: var(--ink-2); }
.gd-list li { margin: 4px 0; }
.gd-list b { color: var(--ink); }
.gd-safety { margin: 2px 0 0; }
.gd-safety li::marker { color: #b8791b; }

/* Masthead utility buttons stay above the document-anchored lead drawing. */
.meter-actions { position: relative; z-index: 35; }

/* A press-and-hold control (the motor's BRAKE): lit while it is held,
   and never selected as text or dragged by a long press. */
.inst-wave.inst-hold { touch-action: none; user-select: none; -webkit-user-select: none; }
.inst-wave.inst-hold[aria-pressed="true"] { background: #b7791f; border-color: #8a5a12; color: #fff; }
/* The load resistor running over its ½ W rating. */
.load-overheat { stroke-width: 3px; stroke-opacity: 0.9; animation: overheat-pulse 0.6s ease-in-out infinite alternate; }
@keyframes overheat-pulse {
    from { stroke-width: 2px; stroke-opacity: 0.95; }
    to   { stroke-width: 11px; stroke-opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
    .load-overheat { animation: none; stroke-width: 6px; stroke-opacity: 0.75; }
}
/* The glow round the motor's wheel while BRAKE is held. */
.motor-brake-pulse { stroke-width: 3px; stroke-opacity: 0.85; animation: brake-pulse 0.7s ease-in-out infinite alternate; }
@keyframes brake-pulse {
    from { stroke-width: 2px; stroke-opacity: 0.95; }
    to   { stroke-width: 10px; stroke-opacity: 0.25; }
}
@media (prefers-reduced-motion: reduce) {
    .motor-brake-pulse { animation: none; stroke-width: 5px; stroke-opacity: 0.7; }
}

/* ===== The guided introduction (js/intro.js) =====
   Same card as the oscilloscope tool's intro. While it runs the page grid
   gives it a column of its own, left of the bench, so the bench keeps
   drawing the circuit each step sets up; the bench's floating controls
   step aside, and the one a step needs is borrowed into the card.
   Chrome around the instrument (tabs, supply knobs, masthead tools) is
   hidden until the step that teaches it; body.intro-show-* turns each
   piece on. */
.intro-card { grid-area: intro; position: relative; z-index: 40; }
/* On a short window the page scrolls to what a step points at (the parked
   leads, under the meter); the card stays in view while it does. */
body.intro-active .intro-card { position: sticky; top: 12px; align-self: start; }
.intro-card[hidden] { display: none; }
body.intro-active .main-stack {
    grid-template-columns: 300px minmax(272px, 420px) 400px;
    grid-template-rows: auto;
    grid-template-areas: "intro draw meter";
}
body:is(.intro-active, .intro-mobile) .bench-head,
body:is(.intro-active, .intro-mobile) .bench-foot { display: none !important; }

/* Masthead utilities stay out of the way until the step that teaches
   WHAT AM I MEASURING / QUICK REFERENCE (body.intro-show-tools). SHOW
   INTRODUCTION stays gone for the whole intro, since it is already
   running. The mute switch lives in the same row, so it waits too. */
body:is(.intro-active, .intro-mobile) .masthead-tools { display: none; }
body:is(.intro-active, .intro-mobile).intro-show-tools .masthead-tools { display: flex; }
body:is(.intro-active, .intro-mobile) #show-intro-btn,
body.intro-mobile [data-proxy="show-intro-btn"] { display: none; }

/* Meter tabs: only on Three Meters. Supply knobs stay hidden (the tour
   uses the transformer, which has none). HOLD / MIN MAX / SELECT / the
   keypad wait until the intro ends, except on the splash and Three
   Meters, where the full row is visible but look-only. RANGE appears
   from the display step. */
body:is(.intro-active, .intro-mobile):not(.intro-show-tabs) .meter-tabs { display: none; }
body:is(.intro-active, .intro-mobile):not(.intro-show-knobs) #src-knobs,
body:is(.intro-active, .intro-mobile):not(.intro-show-knobs) #src-waves { display: none !important; }
body:is(.intro-active, .intro-mobile) .meter-buttons,
body:is(.intro-active, .intro-mobile) .keypad,
body:is(.intro-active, .intro-mobile) .softkeys { display: none !important; }
body:is(.intro-active, .intro-mobile).intro-show-range .meter-buttons { display: flex !important; }
body:is(.intro-active, .intro-mobile).intro-show-range .meter-buttons .mbtn:not([data-btn="range"]) { display: none; }
body:is(.intro-active, .intro-mobile).intro-show-all-btns .meter-buttons { display: flex !important; }
body:is(.intro-active, .intro-mobile).intro-show-all-btns .meter-buttons .mbtn { display: inline-flex; }
body:is(.intro-active, .intro-mobile).intro-show-all-btns .keypad:not([hidden]) { display: grid !important; }
body:is(.intro-active, .intro-mobile).intro-show-all-btns .softkeys:not([hidden]) { display: grid !important; }
body.intro-look-only #dial,
body.intro-look-only .meter-buttons,
body.intro-look-only .keypad,
body.intro-look-only .softkeys,
body.intro-look-only #jacks,
body.intro-look-only #jack-ratings,
body.intro-look-only #mini-jacks {
    pointer-events: none;
    cursor: default;
}

@keyframes intro-reveal {
    from { opacity: 0; }
    to   { opacity: 1; }
}
body:is(.intro-active, .intro-mobile).intro-show-tools .masthead-tools,
body:is(.intro-active, .intro-mobile).intro-show-knobs #src-knobs,
body:is(.intro-active, .intro-mobile).intro-show-knobs #src-waves {
    animation: intro-reveal 420ms ease;
}

.intro-card {
    background: var(--paper-2);
    border: 1px solid var(--rule);
    border-radius: 10px;
    padding: 18px 18px 16px;
    display: flex; flex-direction: column; gap: 14px;
    box-shadow: 0 1px 0 rgba(0,0,0,0.02), 0 2px 12px rgba(28, 26, 21, 0.05);
}
.intro-count {
    font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 600;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-3);
    margin-bottom: -8px;
}
.intro-title {
    font-family: 'Fraunces', Georgia, serif; font-size: 24px; line-height: 1.2;
    color: var(--ink); margin: 0; font-weight: 600;
}
.intro-body { color: var(--ink-2); font-size: 14px; line-height: 1.55; margin: 0; }
.intro-body strong { color: var(--ink); font-weight: 600; }
.intro-task {
    background: rgba(200, 52, 26, 0.06);
    border: 1px dashed rgba(200, 52, 26, 0.35);
    border-radius: 8px; padding: 12px;
    display: flex; flex-direction: column; align-items: stretch; gap: 10px;
    animation: introTaskIn 360ms ease;
}
.intro-task[hidden] { display: none; }
.intro-task-prompt { font-size: 13px; color: var(--ink-2); text-align: center; line-height: 1.45; }
.intro-task-prompt b { color: var(--accent); font-weight: 600; }
.intro-task.done { background: rgba(46, 140, 72, 0.08); border-color: rgba(46, 140, 72, 0.45); border-style: solid; }
.intro-task.done .intro-task-prompt { color: var(--ink); text-align: left; }
.intro-check { color: #2e8c48; font-weight: 700; }
.intro-task-host:empty { display: none; }
.intro-task-host .flip-float,
.intro-task-host .connect-float { width: 100%; }
.intro-task-host .inst-row { width: 100%; }
.intro-task-host .inst-seg { width: 100%; }
.intro-task-host .inst-wave {
    flex: 1; justify-content: center; min-height: 44px; font-size: 13px; padding: 10px 12px;
}
/* Dial legend in the prompt, drawn with the same SVG as the meter panel. */
.intro-dial-sym {
    display: inline-flex; align-items: center; gap: 0.1em;
    font-family: 'JetBrains Mono', monospace; font-weight: 700;
    font-size: 28px; line-height: 1; vertical-align: -0.12em;
    color: var(--ink);
}
.intro-dial-sym .dlab-dc {
    height: 22px; width: auto; display: block;
}
.intro-task.done .intro-dial-sym { font-size: 22px; }
.intro-task.done .intro-dial-sym .dlab-dc { height: 16px; }
.dial-label.intro-hl {
    z-index: 5;
    outline: 3px solid rgba(200, 52, 26, 0.95);
    outline-offset: 4px;
    background: rgba(200, 52, 26, 0.18);
}
/* Intro: hold the orange motor wheel. SVG groups take a filter better
   than an outline. */
body.intro-brake-wheel .motor-wheel-hit,
.motor-wheel-hit.intro-hl {
    filter: drop-shadow(0 0 3px rgba(200, 52, 26, 1))
            drop-shadow(0 0 8px rgba(200, 52, 26, 0.7));
}
@keyframes introTaskIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.intro-actions { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 6px; }
.intro-actions .intro-skip {
    margin-right: auto; background: transparent; border: none; color: var(--ink-3);
    font-family: 'Inter', sans-serif; font-size: 13px; font-weight: 500;
    padding: 8px 6px; border-radius: 6px; cursor: pointer; white-space: nowrap;
    transition: color 150ms ease, background 150ms ease;
}
.intro-actions .intro-skip:hover { color: var(--ink); background: rgba(28, 26, 21, 0.05); }
.intro-actions .intro-nav { display: flex; gap: 8px; }
.intro-actions button.intro-btn {
    font-family: 'Inter', sans-serif; font-size: 13px; font-weight: 600;
    padding: 9px 14px; border-radius: 6px; cursor: pointer; white-space: nowrap;
    border: 1px solid var(--rule); background: var(--paper); color: var(--ink);
    transition: all 150ms ease;
}
.intro-actions button.intro-btn:hover:not(:disabled) { border-color: var(--ink-3); background: #fff; }
.intro-actions button.intro-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.intro-actions button.intro-btn.primary { background: var(--accent); border-color: var(--accent-2); color: #fff; }
.intro-actions button.intro-btn.primary:hover:not(:disabled) { background: var(--accent-2); }
@keyframes intro-btn-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(200, 52, 26, 0.55); }
    50%      { box-shadow: 0 0 0 6px rgba(200, 52, 26, 0); }
}
.intro-btn.pulse { animation: intro-btn-pulse 1.4s ease-in-out infinite; }

/* The part of the real meter a step is about: a pulsing ring round it. */
.intro-hl {
    outline: 3px solid rgba(200, 52, 26, 0.95);
    outline-offset: 5px;
    animation: intro-hl-pulse 1.6s ease-in-out infinite;
}
.meter-tabs.intro-hl {
    overflow: visible;
    animation: intro-hl-pulse 1.6s ease-in-out infinite;
}
.jack.intro-hl {
    z-index: 5;
    animation: intro-hl-pulse 1.6s ease-in-out infinite;
}
@keyframes intro-hl-pulse {
    0%, 100% { outline-color: rgba(200, 52, 26, 0.9); }
    50%      { outline-color: rgba(200, 52, 26, 0.25); }
}
/* After the intro: the next move, pulsing until it is taken. */
@keyframes picker-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(200, 52, 26, 0.6); }
    70%  { box-shadow: 0 0 0 10px rgba(200, 52, 26, 0); }
    100% { box-shadow: 0 0 0 0 rgba(200, 52, 26, 0); }
}
#device-picker.pulse-attn .device-picker-box { animation: picker-pulse 1.5s ease-out infinite; }
@media (prefers-reduced-motion: reduce) {
    .intro-btn.pulse, .intro-hl, .meter-tabs.intro-hl, #device-picker.pulse-attn .device-picker-box, .intro-task,
    body:is(.intro-active, .intro-mobile).intro-show-tools .masthead-tools,
    body:is(.intro-active, .intro-mobile).intro-show-knobs #src-knobs,
    body:is(.intro-active, .intro-mobile).intro-show-knobs #src-waves { animation: none; }
    #device-picker.pulse-attn .device-picker-box { box-shadow: 0 0 0 3px rgba(200, 52, 26, 0.45); }
}
/* No room for three columns: the card goes above the bench and meter. */
@media (max-width: 1060px) {
    body.intro-active .main-stack {
        grid-template-columns: minmax(272px, 420px) 400px;
        grid-template-rows: auto auto;
        grid-template-areas: "intro intro" "draw meter";
    }
}
@media (max-width: 740px) {
    body.intro-active .main-stack {
        grid-template-columns: min(400px, 100%);
        grid-template-rows: none;
        grid-template-areas: "intro" "bench" "meter";
    }
}

/* Quick Reference: the meter's own panel symbols (an SVG sprite in
   quickref.html), sized to sit in the text the way they sit on the dial. */
.qr-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.qr-sym { display: inline-block; width: auto; vertical-align: -0.12em; }
.qr-sym.qr-wave { height: 0.62em; margin: 0 0.06em; vertical-align: 0.02em; }
.qr-sym.qr-icon { height: 0.95em; margin: 0 0.05em; }
.qr-sym.qr-thermo { height: 1.1em; margin-right: 0.15em; vertical-align: -0.2em; }

/* ===== PHONE LAYOUT: three tabs (METER · BENCH · INFO) =====
   Below 741 px the page shows one section at a time, chosen from a tab bar
   along the bottom. body[data-tab] says which; outside this media query
   nothing here applies, so wide screens are unchanged. The guided intro
   keeps its stacked layout (card, bench, meter), so the tab bar steps
   aside while it runs. */
.tabbar, .info-panel, .mobile-readout, .bench-stage, .mini-jacks { display: none; }
/* Read out, not shown: the INFO tab's warning, for a screen reader. */
.tab-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The instrument's dials, when there is no drawn panel for them to sit on
   (narrow screens): give them a panel of their own, like the instrument. */
.src-knobs:not(.floating):not([hidden]) {
    background: var(--meter-face); border: 1px solid #1c1e21; border-radius: 10px;
    padding: 12px 10px 10px;
}

/* Controls are pressed, held and dragged, not read: a long press on one
   must never start selecting text or pop up the phone's callout menu.
   (Typing fields and the readable text around them stay selectable.) */
button, .btn, .tab, label, .meter-shell, .mobile-readout, .bench-space, .bench-stage,
.device-picker, .mini-jacks, .src-knobs, .src-waves, .dial, .jacks, .jack, [role="slider"],
#lead-wires, .sl-calc, .sl-calc-wrap {
    -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
input, textarea, select { -webkit-user-select: text; user-select: text; -webkit-touch-callout: default; }

@media (max-width: 740px) {
    /* The page does not bounce past its ends: the tab bar stays pinned to
       the bottom of the screen, never dragged up off it with the page. */
    html, body { overscroll-behavior-y: none; }
    body:not(.intro-active) .tabbar {
        display: grid; grid-template-columns: repeat(3, 1fr);
        position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
        background: var(--paper); border-top: 1px solid var(--rule);
        box-shadow: 0 -4px 16px rgba(30, 25, 10, 0.08);
        padding: 4px 6px calc(4px + env(safe-area-inset-bottom, 0px));
    }
    body:not(.intro-active) .wrap { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
    .tabbar .tab {
        position: relative;
        display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
        min-height: 54px; background: transparent; border: none; border-radius: 8px;
        font-family: 'JetBrains Mono', monospace; font-size: 10.5px; font-weight: 700;
        letter-spacing: 0.1em; color: var(--ink-3); cursor: pointer;
    }
    .tabbar .tab svg { width: 24px; height: 24px; }
    .tabbar .tab.active { color: var(--ink); background: var(--paper-2); }
    .tabbar .tab.active svg { color: var(--accent); }
    .tab-flag {
        display: none; position: absolute; top: 6px; left: calc(50% + 8px);
        width: 10px; height: 10px; border-radius: 50%;
        background: var(--accent); border: 2px solid var(--paper);
    }
    .tabbar .tab.warn .tab-flag { display: block; }

    /* The masthead's buttons live on the INFO tab; the speaker stays. */
    .meter-actions { display: none; }

    body:not(.intro-active) .main-stack {
        grid-template-columns: min(400px, 100%);
        grid-template-areas: "readout" "info" "bench" "meter";
        /* No row gap: the hidden sections leave empty rows, and a gap
           would still be drawn for each. Spacing comes from the strip. */
        row-gap: 0;
    }
    body:not(.intro-active) .mobile-readout { grid-area: readout; }
    body:not(.intro-active) .info-panel { grid-area: info; }

    /* One section at a time. */
    body:not(.intro-active)[data-tab="info"]  .bench-space,
    body:not(.intro-active)[data-tab="info"]  .meter-shell,
    body:not(.intro-active)[data-tab="bench"] .meter-shell,
    body:not(.intro-active)[data-tab="meter"] .bench-space { display: none; }
    body:not(.intro-active)[data-tab="info"]  .info-panel { display: block; }
    /* The leads: from the meter's jacks on METER, from the probes into the
       copy of the jacks on BENCH, and not at all on INFO. */
    body:not(.intro-active)[data-tab="info"] #lead-wires { display: none; }
    /* BENCH: the drawing's stage, and the meter's jacks under it. */
    /* BENCH: the controls first, then the drawing, whose probe cables hang
       off the bottom of the screen. */
    body:not(.intro-active)[data-tab="bench"] .bench-head { order: 1; }
    body:not(.intro-active)[data-tab="bench"] .bench-foot { order: 2; }
    body:not(.intro-active)[data-tab="bench"] .src-knobs,
    body:not(.intro-active)[data-tab="bench"] .src-waves { order: 3; }
    body:not(.intro-active)[data-tab="bench"] .mini-jacks { order: 6; }
    body:not(.intro-active)[data-tab="bench"] .bench-stage { order: 5; display: block; width: 100%; }
    /* The cables run on down to the bottom of the page; the footer would
       only sit under them. */
    body:not(.intro-active)[data-tab="bench"] .colophon { display: none; }
    /* The meter-fuse check: the bottom of the meter's own panel, in its
       holster, with room under it for the probe coming up into it. */
    body:not(.intro-active)[data-tab="bench"] .mini-jacks:not([hidden]) {
        display: block; width: 100%; max-width: 380px; margin: 4px auto 250px;
    }
    .mini-jacks-head {
        font-family: 'JetBrains Mono', monospace; font-size: 10px; font-weight: 700;
        letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-3);
        margin: 0 0 6px 4px;
    }
    /* Only the bottom of the meter shows: square across the top, where the
       rest of the meter would carry on, rounded like the holster below. */
    .mini-boot {
        background: linear-gradient(160deg, var(--boot), var(--boot-2));
        border-radius: 6px 6px 24px 24px; padding: 11px;
        box-shadow: 0 10px 28px rgba(30, 25, 10, 0.28), inset 0 2px 0 rgba(255,255,255,0.25);
    }
    .mini-boot[data-meter="field"] {
        background: linear-gradient(155deg, #4389b5 0%, #286b98 48%, #174866 100%);
        border: 1px solid #123c57;
        box-shadow: 0 10px 28px rgba(20, 48, 67, 0.30), inset 0 2px 0 rgba(255,255,255,0.24);
    }
    .mini-boot[data-meter="pocket"] { background: linear-gradient(160deg, #4a4e55, #35383e); padding: 10px; border-radius: 6px 6px 20px 20px; }
    .mini-boot[data-meter="logging"] {
        background: linear-gradient(162deg, #c5512f, #a83c20 55%, #8a2f16);
        padding: 12px 11px 13px; border-radius: 6px 6px 18px 18px;
    }
    .mini-face {
        background: linear-gradient(175deg, var(--meter-body), var(--meter-face));
        border-radius: 6px 6px 16px 16px; padding: 4px 12px 14px;
        box-shadow: inset 0 2px 6px rgba(0,0,0,0.45);
    }
    .mini-boot[data-meter="logging"] .mini-face {
        background: linear-gradient(178deg, #4c5058, #3a3e45 40%, #33373d);
        border-radius: 5px; padding: 0 0 11px;
    }
    #mini-jacks-row { margin-top: 0; border-top: none; }
    #mini-jacks-row .jack { flex: 1 1 0; min-width: 0; width: auto; padding: 4px 2px; }
    .mini-boot[data-meter="logging"] #mini-jacks-row { margin: 0 11px; padding-top: 10px; }
    .mini-boot[data-meter="logging"] #mini-jacks-row .jack-label { font-size: 11px; }
    .mini-boot[data-meter="logging"] #mini-jacks-row .jack-hole { width: 27px; height: 27px; }
    .mini-boot[data-meter="logging"] .jack-ratings { padding-left: 11px; padding-right: 11px; }
    .mini-boot[data-meter="logging"] .jr-text {
        font-size: 7.5px; letter-spacing: 0.02em; white-space: pre-line; text-align: center; line-height: 1.35;
    }
    .mini-boot[data-meter="logging"] .jr-bracket { width: 74%; }

    /* The live reading, on the tabs that do not show the meter: a strip of
       the meter itself, in its own case color, with the dial setting, the
       display and the jack row, using the same symbols as the meter. */
    body:not(.intro-active):not([data-tab="meter"]) .mobile-readout {
        display: flex; align-items: center; gap: 8px; width: 100%;
        position: sticky; top: 0; z-index: 45;   /* above the drawn bench (30) */
        padding: 4px 8px; border-radius: 13px;
        border: 5px solid transparent;
        background: linear-gradient(175deg, var(--meter-body), var(--meter-face)) padding-box,
                    linear-gradient(155deg, #4389b5 0%, #286b98 48%, #174866 100%) border-box;
        box-shadow: 0 4px 12px rgba(20, 48, 67, 0.25);
        color: #e8e4da; font-family: 'JetBrains Mono', monospace; cursor: pointer; text-align: left;
        margin-bottom: 12px;
    }
    body:not(.intro-active):not([data-tab="meter"]) .mobile-readout[data-meter="pocket"] {
        background: linear-gradient(175deg, var(--meter-body), var(--meter-face)) padding-box,
                    linear-gradient(160deg, #5a5e66, #35383e) border-box;
    }
    body:not(.intro-active):not([data-tab="meter"]) .mobile-readout[data-meter="logging"] {
        background: linear-gradient(178deg, #4c5058, #33373d) padding-box,
                    linear-gradient(162deg, #c5512f, #a83c20 55%, #8a2f16) border-box;
    }
    /* The dial setting: the symbol on the dial, the sub-mode under it in
       the panel's yellow. */
    .mobile-readout .mr-setting {
        flex: none; min-width: 42px; display: flex; flex-direction: column; align-items: center; gap: 0;
        color: #f3f1ea; font-size: 15px; font-weight: 700; line-height: 1.1;
    }
    .mr-set-main, .mr-set-sub { display: inline-flex; align-items: center; gap: 1px; white-space: nowrap; }
    .mr-set-sub { color: var(--legend); font-size: 11.5px; }
    .mobile-readout .mr-setting .dlab-dc { width: 16px; height: 9px; }
    .mobile-readout .mr-setting .dlab-icon { width: auto; height: 14px; }
    .mobile-readout .mr-set-sub .dlab-dc { width: 13px; height: 8px; }
    .mobile-readout .mr-set-sub .dlab-icon { height: 11px; }
    /* The display, as the LCD draws it. */
    .mobile-readout .mr-value {
        flex: 1; min-width: 0; display: flex; align-items: baseline; justify-content: flex-end; gap: 4px;
        padding: 1px 8px; border-radius: 5px; background: var(--lcd-bg); color: var(--lcd-ink);
        border: 2px solid #17191c; box-shadow: inset 0 2px 5px rgba(0,0,0,0.25);
        white-space: nowrap; overflow: hidden;
    }
    .mr-neg { font-size: 20px; font-weight: 700; visibility: hidden; }
    .mr-neg.on { visibility: visible; }
    .mr-digits {
        font-size: 21px; font-weight: 700; letter-spacing: 0.02em; line-height: 1.25;
        font-variant-numeric: tabular-nums; transform: skewX(-4deg);
    }
    .mr-unit { font-size: 13px; font-weight: 700; }
    .mobile-readout[data-meter="logging"] .mr-digits { font-size: 19px; }
    /* The jacks: one dot each, in the meter's order. Gray is empty; red
       and black are where the leads are. */
    .mobile-readout .mr-jacks { flex: none; display: flex; gap: 7px; align-items: center; padding: 0 2px; }
    .mr-dot {
        width: 11px; height: 11px; border-radius: 50%; box-sizing: border-box;
        background: #5b5f66; border: 1px solid #3c3f44;
    }
    .mr-dot.red { background: #e04634; border-color: #8f2418; }
    .mr-dot.black { background: #050506; border-color: #000; }
    /* Something to check: a red ring round the case. */
    body:not(.intro-active):not([data-tab="meter"]) .mobile-readout.warn { box-shadow: 0 0 0 3px var(--accent), 0 4px 12px rgba(20, 48, 67, 0.25); }

    /* The INFO tab. */
    .info-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
    .info-actions .btn { padding: 12px 8px; font-size: 11px; min-height: 44px; }
    .info-title { font-size: 22px; font-weight: 500; margin: 18px 0 10px; }
    .info-guidance {
        background: var(--paper); border: 1px solid var(--rule); border-radius: 10px;
        padding: 14px;
    }

    /* Comfortable touch targets on the bench. */
    body:not(.intro-active) .bench-space .inst-wave,
    body:not(.intro-active) .bench-space .flip-float { min-height: 44px; }
    body:not(.intro-active) .device-picker-box { min-height: 48px; }

    /* The phone's own guided intro: the tabs stay, and the card is a sheet
       docked above the tab bar, so the part it is about shows above it. */
    body.intro-mobile .intro-card {
        position: fixed; left: 8px; right: 8px;
        bottom: calc(70px + env(safe-area-inset-bottom, 0px));
        max-height: 46vh; overflow-y: auto; overscroll-behavior: contain;
        z-index: 95; gap: 10px; padding: 14px 14px 12px;
        box-shadow: 0 -2px 0 rgba(0,0,0,0.02), 0 8px 28px rgba(28, 26, 21, 0.22);
    }
    body.intro-mobile .intro-title { font-size: 20px; }
    body.intro-mobile .intro-body { font-size: 14px; line-height: 1.5; }
    body.intro-mobile .intro-count { margin-bottom: -6px; }
    body.intro-mobile .intro-actions { padding-top: 2px; }
    body.intro-mobile .intro-actions button.intro-btn,
    body.intro-mobile .intro-actions .intro-skip { min-height: 44px; }
    /* Room to scroll the page's last parts up above the sheet. */
    body.intro-mobile .wrap { padding-bottom: 50vh; }
    /* The ring must show inside the screen edge, and the tab bar keeps it. */
    body.intro-mobile .tabbar.intro-hl { outline-offset: -3px; }
    body.intro-mobile .tabbar { z-index: 96; }
    body.intro-mobile .mobile-readout.intro-hl { outline-offset: 2px; }
}

/* ===== Lesson embed (reactance.html) =====
   Large Field Meter only: hide the bench, intro, tabs and masthead so the
   instrument fills a projector iframe. */
html.embed, html.embed body {
    background: var(--paper);
    height: 100%;
    overflow: hidden;
}
html.embed .masthead,
html.embed .info-panel,
html.embed .tabbar,
html.embed .colophon,
html.embed .intro-card,
html.embed .meter-tabs,
html.embed .mobile-readout,
html.embed .bench-space,
html.embed .bench-head,
html.embed .bench-foot,
html.embed .bench-draw,
html.embed .src-knobs,
html.embed .src-waves,
html.embed #device-picker,
html.embed #lead-wires,
html.embed .meter-actions,
html.embed .sound-toggle {
    display: none !important;
}
html.embed .wrap {
    max-width: none;
    margin: 0;
    padding: 12px;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}
html.embed .main-stack {
    display: flex;
    width: auto;
    grid-template-columns: none;
    grid-template-areas: none;
}
html.embed .meter-shell {
    grid-area: auto;
    margin-bottom: 0;
    transform: scale(0.92);
    transform-origin: center center;
}
