:root {
    --unitWidth: 4px;
    --unitHeight: 5px;
    --ledColor: radial-gradient(circle at 4px 4px, yellow, red);
}

/* ===== Authentic VT52 display font (fritzm/vt52) =====
   Declared globally so every VT52 rendering path uses the same bitmap-style
   glyphs: the canvas CRT (ctx.font in src/vt52.js) and the text-mode
   <textarea> (CSS font-family). 'monospace' stays the fallback until the
   webfont has finished loading (see loadVT52Font in src/pdp11-app.js). */
@font-face {
    font-family: 'VT52';
    src: url('../assets/fonts/vt52.otf') format('opentype');
    font-weight: normal;
    font-style: normal;
    font-display: swap;
}

/* ===== Global scrollbar theming (DEC 1960s palette) =====
   Every scrolling container in the app (quick-boot OS list, Info / Config /
   Storage pages, teletype & LP11 paper) gets the same look, so no native
   scrollbar sticks out of the dark amber scheme. Chromium / Edge / Safari /
   WKWebView (Tauri desktop) use the WebKit pseudo-elements; Firefox uses the
   standards-based properties below. */

* {
    scrollbar-width: thin;
    /* Firefox: narrow scrollbar */
    scrollbar-color: #8a7650 #1a1815;
    /* Firefox: thumb, track */
}

/* WebKit / Blink / WebView scrollbars */
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
    /* horizontal bars, e.g. Info page <pre> */
}

::-webkit-scrollbar-track {
    background: #1a1815;
    border: 1px solid #4a453a;
    border-radius: 6px;
}

::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, #8a7650, #6b5a40);
    border: 2px solid #1a1815;
    /* inset "bevel" look like the buttons */
    border-radius: 6px;
    box-shadow: inset 0 1px 0 rgba(255, 200, 80, 0.12);
}

::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, #c8a860, #a89060);
    box-shadow: inset 0 1px 0 rgba(255, 200, 80, 0.2);
}

::-webkit-scrollbar-thumb:active {
    background: linear-gradient(180deg, #e8d080, #c8a860);
}

::-webkit-scrollbar-corner {
    background: #1a1815;
    /* no white square where axes meet */
}

.frame {
    width: calc(var(--unitWidth) * 272);
    height: calc(var(--unitHeight) * 93);
    position: relative;
    background: linear-gradient(#c3bcaa, #a39c8a);
    -webkit-text-size-adjust: none;
    text-size-adjust: none;
}

.decBase {
    width: calc(var(--unitWidth) * 106);
    height: calc(var(--unitHeight) * 8);
    position: absolute;
    top: calc(var(--unitHeight) * 1);
    left: calc(var(--unitWidth) * 3);
    border: 1px solid #736c62;
    border-radius: calc(var(--unitWidth) * 2);
    color: #736c62;
    font-family: arial, helvetica, sans-serif;
}

.smallSpace {
    width: calc(var(--unitWidth) * 2.66);
    height: 1px;
    float: left;
}

.decLetter {
    width: calc(var(--unitWidth) * 4);
    height: calc(var(--unitHeight) * 5);
    border: 1px solid #736c62;
    border-bottom-color: #534c42;
    font-weight: 100;
    font-size: calc(var(--unitHeight) * 4);
    line-height: calc(var(--unitHeight) * 5);
    text-align: center;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    float: left;
}

.decName {
    position: absolute;
    top: 0;
    height: 100%;
    font-size: calc(var(--unitHeight) * 2);
    line-height: calc(var(--unitHeight) * 8);
    float: left;
}

.topEdge {
    width: calc(var(--unitWidth) * 256);
    height: 0;
    position: absolute;
    top: calc(var(--unitHeight) * 10);
    left: 0;
    right: 0;
    margin: auto;
    padding: calc(var(--unitWidth) * 3.33);
    background: #837c72;
    border: none;
    border-radius: calc(var(--unitWidth) * 8);
}

.sideEdges {
    width: calc(var(--unitWidth) * 263);
    height: 0;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    border-bottom: calc(var(--unitHeight) * 80) solid #9c9781;
    border-left: calc(var(--unitWidth) * 2) solid transparent;
    border-right: calc(var(--unitWidth) * 2) solid transparent;
}

.switchBevel {
    width: calc(var(--unitWidth) * 265);
    height: calc(var(--unitHeight) * 1);
    background: #a39c8a;
    border-top: calc(var(--unitHeight) * 8) solid #9c9781;
    border-bottom: calc(var(--unitHeight) * 7) solid #534c42;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

.switchPanel {
    position: relative;
    top: calc(var(--unitHeight) * 12);
    left: calc(var(--unitWidth) * 8);
}

.panel {
    width: calc(var(--unitWidth) * 256);
    height: calc(var(--unitHeight) * 65);
    background: #181818;
    border-radius: calc(var(--unitWidth) * 4);
    color: white;
    font-family: arial, helvetica, sans-serif;
    font-size: calc(var(--unitHeight) * 1.4);
    text-align: center;
}

/* Drop zone — drag & drop disk/tape image import */
.drop-zone {
    display: inline-block;
    vertical-align: middle;
    padding: 4px 10px;
    margin-left: 8px;
    border: 1px dashed #7a7468;
    border-radius: 4px;
    background: #22221e;
    color: #e0d8c8;
    font-size: 12px;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    transition: border-color 0.15s, background 0.15s;
    line-height: 1.4;
    max-width: 320px;
}

.drop-zone:hover,
.drop-zone.dragover {
    border-color: #c8a860;
    background: #2e2c26;
}

.drop-zone-icon {
    color: #c8a860;
    font-size: 14px;
    margin-right: 4px;
}

.drop-zone-text {
    font-weight: bold;
}

.drop-zone-hint {
    color: #9a9488;
    font-size: 11px;
    margin-left: 6px;
}

/* Full-window drop overlay — shown while dragging files over the page */
.drop-overlay {
    position: fixed;
    inset: 0;
    z-index: 99999;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(10, 8, 6, 0.65);
}

.drop-overlay.visible {
    display: flex;
}

.drop-overlay-box {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 48px 72px;
    border: 3px dashed #c8a860;
    border-radius: 14px;
    background: rgba(22, 18, 14, 0.95);
    color: #e0d8c8;
    pointer-events: none;
    box-shadow: 0 8px 40px rgba(0, 0, 0, 0.5);
}

.drop-overlay-icon {
    font-size: 52px;
    color: #c8a860;
    line-height: 1;
}

.drop-overlay-title {
    font-size: 24px;
    font-weight: bold;
    letter-spacing: 1px;
}

.drop-overlay-hint {
    font-size: 14px;
    color: #9a9488;
}

/* Floating fullscreen toggle — bottom-right, above the app content but below
   the drop/modal overlays so they keep focus while they are active. */
.fullscreen-btn {
    position: fixed;
    bottom: 12px;
    right: 12px;
    z-index: 1000;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(180deg, #3a352a, #2a2722);
    border: 1px solid #5a554a;
    border-radius: 4px;
    color: #b8b0a0;
    cursor: pointer;
    padding: 0;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.4);
    transition: background 0.2s, border-color 0.2s, color 0.2s;
    user-select: none;
}

.fullscreen-btn:hover {
    background: linear-gradient(180deg, #4a453a, #3a352a);
    border-color: #8a7a5a;
    color: #e0d8c8;
}

/* Active (fullscreen) state — lit like a DEC indicator lamp. */
.fullscreen-btn.fullscreen-on {
    background: linear-gradient(180deg, #5a4a30, #3a3528);
    border-color: #c8a860;
    color: #f0e6c8;
    box-shadow: inset 0 1px 0 rgba(255, 200, 80, 0.15), 0 1px 3px rgba(0, 0, 0, 0.5);
}

.fullscreen-btn .fullscreen-icon {
    width: 18px;
    height: 18px;
    display: block;
}

/* Shared modal dialog overlay — used by the first-run onboarding hint, the
   reboot confirmation, the CONFIG leave dialog and the image-load error
   dialog (imgerror.js). */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(10, 8, 6, 0.72);
}

.modal-overlay.visible {
    display: flex;
}

.modal-box {
    max-width: 540px;
    padding: 28px 34px;
    border: 1px solid #c8a860;
    border-radius: 10px;
    background: #1c1814;
    color: #e0d8c8;
    box-shadow: 0 10px 46px rgba(0, 0, 0, 0.6);
    line-height: 1.5;
}

/* Image load error dialog (imgerror.js): error accent on the modal box. */
.modal-box.error {
    border-color: #b5544a;
}

.modal-box.error .modal-title {
    color: #ff9b8a;
}

.modal-box.error code {
    background: #2a2a2a;
    color: #ffd27f;
    border: 1px solid #4a4438;
    border-radius: 3px;
    padding: 1px 6px;
    font-family: "Courier New", Courier, monospace;
}

.modal-title {
    display: block;
    font-size: 22px;
    font-weight: bold;
    letter-spacing: 1px;
    color: #c8a860;
    margin-bottom: 12px;
}

.modal-intro {
    margin: 0 0 10px;
    font-size: 14px;
    color: #cfc7b8;
}

.modal-steps {
    margin: 0 0 6px 22px;
    padding: 0;
    font-size: 14px;
}

.modal-steps li {
    margin: 4px 0;
}

.modal-boots {
    list-style: none;
    margin: 2px 0 8px;
    padding: 6px 0 6px 10px;
    border-left: 3px solid #c8a860;
    background: rgba(200, 168, 96, 0.07);
    font-size: 13px;
}

.modal-boots li {
    margin: 3px 0;
}

.modal-boot code {
    background: #2a2a2a;
    color: #ffd27f;
    border: 1px solid #4a4438;
    border-radius: 3px;
    padding: 1px 6px;
    font-family: "Courier New", Courier, monospace;
}

.modal-boot.modal-more {
    color: #9a9488;
}

.modal-drag {
    margin: 8px 0 16px;
    font-size: 13px;
    color: #b8b0a0;
}

/* Emphasised words inside modal dialogs use the dialog-title amber instead of
   the global bold default (b { color: blue } used to bleed through). */
.modal-box b {
    color: #c8a860;
}

.modal-close {
    display: inline-block;
    padding: 8px 28px;
    border: 1px solid #c8a860;
    border-radius: 5px;
    background: #2c261c;
    color: #ffd27f;
    font-size: 14px;
    font-weight: bold;
    letter-spacing: 0.5px;
    cursor: pointer;
}

.modal-close:hover {
    background: #3a3224;
}

/* Reboot confirmation dialog: the "don't ask again" checkbox above the buttons. */
.modal-dontask {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 16px;
    font-size: 13px;
    color: #b8b0a0;
    cursor: pointer;
    user-select: none;
}

.modal-dontask input {
    accent-color: #c8a860;
    cursor: pointer;
}

/* Modal dialogs: even side-by-side spacing between action buttons. */
.modal-box .modal-close+.modal-close {
    margin-left: 10px;
}

/* Modal dialogs: amber selection and focus ring (matching the dialog title)
   instead of the browser's blue default, which clashed with the theme. */
.modal-overlay ::selection {
    background: #c8a860;
    color: #1c1814;
}

.modal-overlay button:focus-visible {
    outline: 2px solid #c8a860;
    outline-offset: 1px;
}

/* Front-panel page stays a positioning context for its inner layers (the
   .frame tree provides the actual relative containing blocks). */
#page-panel {
    position: relative;
}

/* Operator's hand-written sticky note taped to the cabinet, left of the
   front panel (see pdp11.html .panel-sticker). Purely decorative: it must
   never swallow clicks, hence pointer-events: none. Anchored to the LEFT of
   .frame (right:100% = just outside the frame's left edge), so it stays put
   regardless of how the page is centred. The note tilts like a real stuck-on
   Post-it; the text is handwritten (system cursive) — only the machine-code
   listing stays monospaced so the address columns line up. */
.panel-sticker {
    position: absolute;
    right: calc(100% + var(--unitWidth) * 2);
    top: calc(var(--unitHeight) * 11);
    width: 260px;
    padding: 24px 20px 20px;
    background: linear-gradient(135deg, #fff59d 0%, #ffeb3b 50%, #fdd835 100%);
    box-shadow:
        0 4px 6px rgba(0, 0, 0, 0.3),
        0 10px 20px rgba(0, 0, 0, 0.2),
        inset 0 -20px 40px rgba(0, 0, 0, 0.05);
    transform: rotate(-3deg);
    font-family: 'Segoe Script', 'Bradley Hand', 'Comic Sans MS', cursive;
    font-size: 11px;
    line-height: 1.4;
    color: #1a1a1a;
    /* auto: the note sits to the LEFT of the panel (right:100%), so letting
       the pointer hover it for the hide-tooltip never conflicts with panel
       clicks. The hint itself keeps pointer-events:none. */
    pointer-events: auto;
    user-select: none;
    z-index: 5;
}

/* Folded-in corner flap: a dark triangle tucked into the bottom-right corner
   of the (rectangular) note, drawn on top of the paper. Its hypotenuse runs
   from the right edge down to the bottom edge (a clean 45° fold), and it
   carries no shadow of its own, so nothing sticks out beyond the note. */
.panel-sticker::after {
    content: "";
    position: absolute;
    bottom: 0;
    right: 0;
    width: 42px;
    height: 42px;
    background: #7a6a38;
    /* dark folded flap */
    clip-path: polygon(100% 100%, 100% 0, 0 100%);
}

/* Hover tooltip on the note telling the operator how to hide it. The note is
   decorative, so the hint appears only while the pointer is over it. */
.panel-sticker-hint {
    position: absolute;
    bottom: 44px;
    left: 10px;
    right: 10px;
    padding: 4px 8px;
    background: rgba(20, 18, 14, 0.85);
    color: #ffe9a8;
    font-family: arial, helvetica, sans-serif;
    font-size: 9px;
    line-height: 1.35;
    text-align: center;
    border-radius: 3px;
    pointer-events: none;
    z-index: 6;
    opacity: 0;
    visibility: hidden;
    /* Dismiss quickly when the pointer leaves the note. */
    transition: opacity 0.15s ease, visibility 0s;
}

/* Tooltips normally appear after a short delay: fade the hint in ~0.45s after
   the pointer settles on the note, then keep it visible while hovering. */
.panel-sticker:hover .panel-sticker-hint {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.15s ease 0.45s, visibility 0s 0.45s;
}

/* Translucent tape holding the note to the cabinet. */
.panel-sticker-tape {
    position: absolute;
    top: -12px;
    left: 50%;
    transform: translateX(-50%);
    width: 90px;
    height: 24px;
    background: rgba(255, 255, 255, 0.32);
    border: 1px solid rgba(200, 200, 200, 0.4);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    border-radius: 2px;
}

.panel-sticker-title {
    font-weight: bold;
    text-align: center;
    margin-bottom: 10px;
    font-size: 14px;
    text-decoration: underline;
    color: #111;
}

.panel-sticker-step {
    font-size: 11px;
    color: #111;
    margin: 6px 0;
}

/* The listing inherits the handwritten font from .panel-sticker: it is a
   hand-written cheat sheet, so every line (words and boot commands) is in
   the same black ink. */
.panel-sticker-code {
    font-size: 11px;
    white-space: pre;
    margin: 6px 0;
    color: #111;
    letter-spacing: 0.5px;
}

.panel-sticker-note {
    font-size: 11px;
    margin-top: 10px;
    border-top: 1px dashed rgba(0, 0, 0, 0.2);
    padding-top: 8px;
    color: #111;
    white-space: pre;
}

/* The sticker is hidden through the Sticker button (choice persisted across
   sessions in localStorage). Scoped to .panel-sticker so it stays independent
   of the .hidden toggles used by .quick-boot-btn / .console-reboot. */
.panel-sticker.hidden {
    display: none;
}

/* Action buttons pinned to the bottom of the front-panel page (absolute in
   #page-panel, which is a relative flex column filling the viewport): the
   Help Me! sticker toggle and the Boot now! button. Same look as the shared
   modal buttons (.modal-close), so they belong to the amber-on-dark style. */
.panel-actions {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 12px;
    display: flex;
    gap: 10px;
    justify-content: center;
    padding: 0;
}

.panel-action-btn {
    padding: 6px 16px;
    border: 1px solid #c8a860;
    border-radius: 4px;
    background: linear-gradient(180deg, #5a4a30, #3a3528);
    color: #f0e6c8;
    font-size: 12px;
    font-weight: bold;
    cursor: pointer;
    user-select: none;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.panel-action-btn:hover {
    background: linear-gradient(180deg, #6a5a38, #4a3a2c);
    border-color: #e0c070;
}

/* Help Me! works like a checkbox: the lit state (sticker visible) glows a
   brighter amber, matching the printer buttons' hover but kept on while on. */
.panel-action-btn.active {
    background: linear-gradient(180deg, #7a6a40, #5a4a30);
    border-color: #e0c070;
    color: #fff3d0;
    box-shadow: inset 0 1px 0 rgba(255, 200, 80, 0.15), 0 1px 3px rgba(0, 0, 0, 0.5);
}

.panel-action-btn:focus-visible {
    outline: 2px solid #c8a860;
    outline-offset: 1px;
}

/* Quick-boot magic wand — floating button in the top-right corner of the
   window, visible on every page except INFO (toggled via the .hidden class
   by switchPage() in src/pdp11-panel.js). */
.quick-boot-btn {
    position: fixed;
    top: 12px;
    right: 14px;
    z-index: 1000;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #5a554a;
    border-radius: 50%;
    background: linear-gradient(180deg, #3a352a, #2a2722);
    color: #b8b0a0;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
}

.quick-boot-btn:hover {
    background: linear-gradient(180deg, #4a453a, #3a352a);
    border-color: #8a7a5a;
    color: #e0d8c8;
}

.quick-boot-btn.hidden {
    display: none !important;
}

/* Global sound mute — round magic-wand-style button fixed to the bottom-left
   corner, just right of the navigation sidebar (78px wide + 12px gap). Acts
   like a checkbox: the muted state dims the button and shows the diagonal
   slash instead of the sound waves (toggled via the .muted class by
   initMuteButton in src/pdp11-app.js). */
.mute-btn {
    position: fixed;
    bottom: 12px;
    left: 90px;
    z-index: 1000;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #5a554a;
    border-radius: 50%;
    background: linear-gradient(180deg, #3a352a, #2a2722);
    color: #b8b0a0;
    cursor: pointer;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
    transition: background 0.2s, border-color 0.2s, color 0.2s;
}

.mute-btn:hover {
    background: linear-gradient(180deg, #4a453a, #3a352a);
    border-color: #8a7a5a;
    color: #e0d8c8;
}

/* Muted state — dimmed like an unlit DEC lamp, slash shown, waves hidden. */
.mute-btn.muted {
    border-color: #3a352a;
    background: #241f18;
    color: #6a655a;
}

.mute-btn .mute-waves {
    display: block;
}

.mute-btn .mute-slash {
    display: none;
}

.mute-btn.muted .mute-waves {
    display: none;
}

.mute-btn.muted .mute-slash {
    display: block;
}

/* Quick-boot OS picker list inside the shared modal box. */
.quickboot-box {
    max-width: 480px;
}

.quickboot-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 4px 0 16px;
    max-height: 60vh;
    overflow-y: auto;
}

.quickboot-option {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 2px 12px;
    width: 100%;
    padding: 8px 12px;
    border: 1px solid #4a4438;
    border-radius: 5px;
    background: #241f18;
    color: #e0d8c8;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.quickboot-option:hover {
    border-color: #c8a860;
    background: #2f2820;
}

.quickboot-name {
    font-weight: bold;
    color: #ffd27f;
}

.quickboot-cmd {
    color: #9a9488;
    font-family: "Courier New", Courier, monospace;
    font-size: 12px;
    white-space: nowrap;
}

.quickboot-req {
    flex-basis: 100%;
    color: #8f8878;
    font-size: 11px;
}

/* "Autoloading in progress" toast (quickboot.js) — pinned to the top centre
   of the window, below the floating round buttons (magic wand / REBOOT), so
   it stays visible without covering the middle of the console output. Above
   the content but below the modal overlays, so it never covers the OS picker
   dialog. */
.quickboot-balloon {
    position: fixed;
    left: 50%;
    top: 64px;
    transform: translateX(-50%);
    z-index: 50000;
    display: none;
    padding: 16px 28px;
    border: 2px solid #d84a3f;
    border-radius: 10px;
    background: rgba(62, 16, 12, 0.6);
    color: #ffd7d0;
    font-size: 20px;
    font-weight: bold;
    letter-spacing: 0.5px;
    white-space: nowrap;
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.7);
}

.quickboot-balloon.visible {
    display: block;
}

.floatLeft {
    float: left;
}

.floatRight {
    float: right;
}

.clear {
    clear: both;
}

.blankLine {
    width: 100%;
    height: calc(var(--unitHeight) * 5);
    clear: both;
}

.smallLine {
    width: 100%;
    height: calc(var(--unitHeight) * 4);
    clear: both;
}

.space {
    width: calc(var(--unitWidth) * 8);
    height: 1px;
    float: left;
}

.margin {
    margin-right: 1px;
    width: calc(100% - 1px);
}

.logo {
    width: calc(var(--unitWidth) * 40);
    float: left;
}

.statusBlock {
    width: calc(var(--unitWidth) * 8);
    background-color: black;
    font-size: calc(var(--unitHeight) * 1.4);
    float: left;
}

.statusLabel1 {
    width: 100%;
    height: calc(var(--unitHeight) * 2);
    line-height: calc(var(--unitHeight) * 3);
}

.statusLabel2 {
    width: calc(var(--unitWidth) * 8 - 1px);
    height: calc(var(--unitHeight) * 7);
    position: relative;
    float: left;
}

.ledBlock {
    width: calc(var(--unitWidth) * 24);
    float: left;
}

.ledBase {
    margin-right: 1px;
    width: calc(100% - 1px);
    height: calc(var(--unitHeight) * 2);
    line-height: calc(var(--unitHeight) * 2);
    font-size: calc(var(--unitHeight) * 1.45);
    position: relative;
    float: left;
}

.statusPanel {
    width: calc(var(--unitWidth) * 88);
    height: calc(var(--unitHeight) * 8);
    position: relative;
    background: black;
    border-radius: calc(var(--unitWidth) * 2);
    float: left;
}

.statusTable {
    display: table;
    table-layout: fixed;
    width: 100%;
    height: 85%;
    position: relative;
    top: 15%;
    left: 5%;
    text-align: left;
    float: left;
}

.nick {
    height: 0;
    width: 0;
    border-bottom: calc(var(--unitHeight) * 1.7) solid black;
    border-left: calc(var(--unitWidth) * 0.3) solid transparent;
    border-right: calc(var(--unitWidth) * 1) solid transparent;
    position: absolute;
    left: calc(var(--unitWidth) * 7);
    bottom: 0;
}

.notch {
    height: 0;
    width: 1px;
    border-top: calc(var(--unitHeight) * 1.9) solid purple;
    border-left: calc(var(--unitWidth) * 1.0) solid transparent;
    border-right: calc(var(--unitWidth) * 1.0) solid transparent;
    position: absolute;
    left: calc(var(--unitWidth) * 7);
    top: 0;
    z-index: 1;
}

.ledPad {
    position: relative;
    margin-right: 1px;
    width: calc(var(--unitWidth) * 8 - 1px);
    height: calc(var(--unitHeight) * 10);
    background-color: black;
    border-bottom-left-radius: calc(var(--unitWidth) * 1.5);
    border-bottom-right-radius: calc(var(--unitWidth) * 1.5);
    float: left;
}

.mainLed,
.rotaryLed {
    width: calc(var(--unitWidth) * 3);
    height: calc(var(--unitWidth) * 3);
    border-radius: 32%;
    background: var(--ledColor);
}

.mainLed {
    position: absolute;
    bottom: calc(var(--unitWidth) * 2);
    left: 0;
    right: 0;
    margin-left: auto;
    margin-right: auto;
}

.rotaryLed {
    margin-left: 5%;
    margin-right: 10%;
    float: left;
}

.lockPanel {
    position: relative;
    width: calc(var(--unitWidth) * 15);
    height: calc(var(--unitHeight) * 12);
    font-size: calc(var(--unitHeight) * 1.4);
    float: left;
}

.atBottom {
    position: absolute;
    bottom: 0;
}

.lock {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    margin-left: auto;
    margin-right: auto;
    width: 55%;
    height: 55%;
    border-radius: 50%;
    background: linear-gradient(15deg, #808080, #383838);
    border: solid 1px #707070;
}

.lock::before {
    content: "";
    display: block;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    margin-left: auto;
    margin-right: auto;
    width: 45%;
    height: 45%;
    border-radius: 50%;
    background: linear-gradient(15deg, #101010, silver);
    border: solid 2px #11100e;
    box-shadow: 0 0 0 1px #404040;
}

.lockKey {
    content: "";
    display: block;
    position: absolute;
    border: solid 1px #101010;
    top: -25%;
    left: 46%;
    width: 8%;
    height: 150%;
    background: #b0b0b0;
    transform: rotate(-45deg);
    transition: 0.5s;
}

/* OFF / POWER / LOCK position labels are clickable states: clicking one
   selects that position directly (mirroring the CCU LINE/OFF/LOCAL switch
   of the Model 33 teletype). The lock key itself stays decorative and shows
   the current position, so the labels are never "lit up". */
.lockPanelPos {
    background: transparent;
    border: 0;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

/* Keep the POWER / LOCK labels above the key disc (.lock) so a click always
   lands on the label for a direct selection; the disc itself stays clickable
   for the old cycling reaction but never steals label clicks. */
.lockPanelPos[data-power-state="run"],
.lockPanelPos[data-power-state="lock"] {
    position: relative;
    z-index: 2;
}

/* OFF label anchors to the bottom-left corner. .atBottom only pins the
   vertical edge; an explicit left keeps it in place when rendered as an
   inline button instead of a block div. */
.lockPanelPos[data-power-state="off"] {
    left: 0;
    z-index: 2;
}

.rotaryPanel {
    width: calc(var(--unitWidth) * 88);
    height: calc(var(--unitHeight) * 12);
    position: relative;
    background: black;
    border-radius: calc(var(--unitWidth) * 3);
    float: left;
}

.rotaryTopPanel {
    width: calc(var(--unitWidth) * 56);
    height: calc(var(--unitHeight) * 25);
    position: relative;
    background: black;
    border-radius: calc(var(--unitWidth) * 3);
    float: left;
}

.rotaryBottomPanel {
    width: calc(var(--unitWidth) * 56);
    height: calc(var(--unitHeight) * 12);
    position: relative;
    background: black;
    border-radius: calc(var(--unitWidth) * 3);
    float: left;
}

.rotaryTable {
    display: table;
    table-layout: fixed;
    width: 70%;
    height: 85%;
    position: absolute;
    top: 15%;
    left: 5%;
    text-align: left;
}

.rotaryTableCell {
    display: table-cell;
}

.rotaryTableRow {
    display: table-row;
}

.rotaryBase {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    right: 10%;
}

.rotarySwitch {
    height: calc(var(--unitWidth) * 10);
    width: calc(var(--unitWidth) * 10);
    position: relative;
    border: solid 1px #202020;
    border-radius: 50%;
    background: linear-gradient(0deg,
            #b0b0c0,
            #020212 25%,
            #404050 35%,
            #303040 65%,
            #020212 75%,
            #b0b0c0);
    transform: rotate(-45deg);
    transition: 0.5s;
}

.rotarySwitch:before {
    position: absolute;
    display: block;
    content: "";
    width: 50%;
    height: 6%;
    top: 47%;
    background: #faf8f9;
    margin: 0 auto;
}

.rotaryCentre {
    position: relative;
    background: #faf8f9;
    left: 43%;
    top: 44%;
    width: 12%;
    height: 12%;
    border-radius: 50%;
}

.switchLabels {
    position: absolute;
    bottom: 0px;
}

.switchPad {
    margin: 2px 1px 2px 1px;
    width: calc(var(--unitWidth) * 8 - 2px);
    height: calc(var(--unitHeight) * 8);
    line-height: calc(var(--unitHeight) * 8);
    float: left;
}

.switchPadHalf {
    width: 100%;
    height: 49%;
    line-height: calc(var(--unitHeight) * 4);
}

.switchPadBar {
    width: 100%;
    height: 4%;
    background: black;
}

.multiText {
    display: inline-block;
    vertical-align: middle;
    line-height: calc(var(--unitHeight) * 1.5);
}

.switch {
    width: calc(var(--unitWidth) * 5);
    height: calc(var(--unitHeight) * 1);
    border-top: calc(var(--unitHeight) * 8) solid rgba(0, 0, 0, .16);
    border-bottom: calc(var(--unitHeight) * 7) solid rgba(0, 0, 0, 0.42);
    border-left: calc(var(--unitWidth) * 1.5) solid rgba(0, 0, 0, 0.46);
    border-right: calc(var(--unitWidth) * 1.5) solid rgba(0, 0, 0, 0.50);
    transition: 0.33s;
    float: left;
}

.textRight {
    text-align: right;
}

.single {
    width: calc(var(--unitWidth) * 8);
}

.double {
    width: calc(var(--unitWidth) * 16);
}

.triple {
    width: calc(var(--unitWidth) * 24 - 1px);
}

.roundTopLeft,
.roundLeft,
.roundTop {
    border-top-left-radius: calc(var(--unitWidth) * 1.5);
}

.roundTopRight,
.roundRight,
.roundTop {
    border-top-right-radius: calc(var(--unitWidth) * 1.5);
}

.roundBottomLeft,
.roundLeft {
    border-bottom-left-radius: calc(var(--unitWidth) * 1.5);
}

.roundBottomRight,
.roundRight {
    border-bottom-right-radius: calc(var(--unitWidth) * 1.5);
}

.red {
    background: linear-gradient(crimson, firebrick);
}

.redBase {
    background: crimson;
}

.purple {
    background: linear-gradient(darkmagenta, purple);
}

.purpleBase {
    background: darkmagenta;
}

.black {
    background-color: black;
}

.white {
    background-color: #f0e6d9;
}

thead {
    font-weight: bold;
}

.disk {
    font-weight: bold;
}

.system {
    white-space: nowrap;
    font-weight: bold;
}

pre {
    font-family: "Courier New", Courier, "Lucida Console", Monaco, monospace;
    font-size: 14px;
}

b {
    color: inherit;
}

/* ===== Page layout & sidebar (DEC 1960s style) ===== */
body {
    margin: 0;
    padding: 0;
    overflow: hidden;
    /* PDP-11 backdrop: dark fallback + dimming overlay over the machine-room photo.
       Adjust the overlay alpha to control how strongly the photo shows through. */
    background-color: #2a2722;
    background-image:
        linear-gradient(rgba(24, 21, 17, 0.82), rgba(24, 21, 17, 0.82)),
        url("../assets/images/pdp11-room.jpg");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    font-family: arial, helvetica, sans-serif;
}

.app-layout {
    display: flex;
    height: 100vh;
}

.app-sidebar {
    width: 78px;
    min-width: 78px;
    background: linear-gradient(180deg, #1a1815 0%, #2a2722 40%, #1a1815 100%);
    border-right: 2px solid #4a453a;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding-top: 12px;
    gap: 2px;
    box-shadow: 2px 0 6px rgba(0, 0, 0, 0.5);
    z-index: 10;
}

.app-sidebar .nav-btn {
    box-sizing: border-box;
    /* Anchors the absolute .nav-led activity lamp in the top-right corner. */
    position: relative;
    width: 68px;
    height: 72px;
    margin: 2px 0;
    background: linear-gradient(180deg, #3a352a, #2a2722);
    border: 1px solid #5a554a;
    border-radius: 4px;
    color: #b8b0a0;
    font-size: 9px;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    line-height: 1.3;
    padding: 4px 8px;
    transition: background 0.2s, border-color 0.2s, color 0.2s;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.4);
    user-select: none;
}

.app-sidebar .nav-btn:hover {
    background: linear-gradient(180deg, #4a453a, #3a352a);
    border-color: #8a7a5a;
    color: #e0d8c8;
}

.app-sidebar .nav-btn.active {
    background: linear-gradient(180deg, #5a4a30, #3a3528);
    border-color: #c8a860;
    color: #f0e6c8;
    box-shadow: inset 0 1px 0 rgba(255, 200, 80, 0.15), 0 1px 3px rgba(0, 0, 0, 0.5);
}

.app-sidebar .nav-btn .nav-icon {
    font-size: 16px;
    margin-bottom: 3px;
    opacity: 0.8;
}

.app-sidebar .nav-btn .nav-icon-svg {
    width: 16px;
    height: 16px;
    display: block;
    margin: 0 auto;
}

.app-sidebar .nav-btn.active .nav-icon {
    opacity: 1;
}

/* Activity lamp: a tiny green LED in the top-right corner of a sidebar
   button. Hidden while the device is idle; NavActivity.pulse() adds the
   .on class when the PDP-11 writes output, and the CSS animation blinks
   it like the LP11 READY LED (see .lp11-led-ready.busy). */
.app-sidebar .nav-btn .nav-led {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #1a1a1a;
    box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.6);
    opacity: 0;
    transition: opacity 0.1s;
    pointer-events: none;
}

.app-sidebar .nav-btn .nav-led.on {
    background: #4c4;
    box-shadow: 0 0 8px #4c4, inset 0 1px 1px rgba(255, 255, 255, 0.5);
    opacity: 1;
    animation: nav-led-blink 0.4s steps(2, start) infinite;
}

/* Power lamp on the Panel nav button: lit steadily while the machine is
   powered on (regardless of the CPU run state). Toggled by
   PanelLed.update() in src/panel-led.js. */
.app-sidebar .nav-btn .nav-led.power-on {
    opacity: 1;
    background: #4c4;
    box-shadow: 0 0 8px #4c4, inset 0 1px 1px rgba(255, 255, 255, 0.5);
    animation: none;
}

/* Run-state icon on the Panel nav button: a tiny glyph in the top-left
   corner showing whether the CPU is halted (pause, the default) or running
   (play, when the .run class is present). Drawn with pure CSS shapes so it
   needs no icon font. Toggled by PanelLed.update() in src/panel-led.js. */
.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon {
    position: absolute;
    top: 3px;
    left: 4px;
    /* Same size as the power lamp (.nav-led) on the right. */
    width: 7px;
    height: 7px;
    color: #d8d0c0;
    opacity: 0.9;
    pointer-events: none;
}

/* Hidden while the machine is powered off (neither pause nor play). */
.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon.off {
    opacity: 0;
}

/* Pause (default): two vertical bars. */
.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon::before,
.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon::after {
    content: "";
    position: absolute;
    top: 0;
    width: 2px;
    height: 7px;
    background: currentColor;
}

.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon::before {
    left: 0;
}

.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon::after {
    right: 0;
}

/* Play (CPU running): a filled triangle pointing right. */
.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon.run::before {
    left: 0;
    width: 0;
    height: 0;
    background: none;
    border-top: 3px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 7px solid currentColor;
}

.app-sidebar .nav-btn[data-page="panel"] .nav-run-icon.run::after {
    display: none;
}

@keyframes nav-led-blink {
    to {
        opacity: 0.15;
    }
}

.page {
    display: none;
    flex: 1;
    /* Transparent so the PDP-11 photo backdrop on body shows through */
    background: transparent;
}

.page.active {
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Instructions page — uses block layout + max-width for readability */
#page-instructions.active {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
    color: #e0d8c8;
    max-width: 960px;
    margin: 0 auto;
    padding: 16px 24px;
    box-sizing: border-box;
    /* Dark translucent slab so the long text stays readable over the photo */
    background: rgba(28, 25, 21, 0.82);
}

#page-instructions.active h2,
#page-instructions.active h3 {
    color: #f0e6c8;
}

#page-instructions.active a {
    color: #c8a860;
}

#page-instructions.active a:hover {
    color: #e8d080;
}

#page-instructions.active code {
    color: #d4c4a0;
    background: rgba(0, 0, 0, 0.3);
    padding: 1px 4px;
    border-radius: 2px;
}

#page-instructions.active pre {
    color: #d0c8b8;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid #4a453a;
    border-radius: 4px;
    padding: 8px 12px;
    overflow-x: auto;
}

#page-instructions.active table {
    color: #e0d8c8;
}

#page-instructions.active table thead {
    color: #f0e6c8;
}

#page-instructions b,
#page-instructions strong {
    color: inherit;
}

/* ===== Front panel — centre vertically like the console/terminals ===== */
#page-panel.active {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

/* ===== Printer page — centre the printer block vertically ===== */
/* The LP11 paper rises above the cabinet through the top slot; the paper's
   own window scrolls (its scrollbar belongs to the paper), so the page itself
   stays fixed and centred. */
#page-printer.active {
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
}

/* ===== Teletype page — centre vertically like the console/terminals ===== */
/* The base .page.active only centres horizontally (align-items: center);
   this adds vertical centring so the Model 33 ASR printer + keyboard block sits
   in the middle of the page just like the VT52 / panel / printer pages. */
#page-teletype.active {
    justify-content: center;
    overflow: hidden;
    /* Positioning context for the operator buttons (#teletype-controls), so
       their absolute bottom-centring is relative to the screen page, exactly
       like #page-panel is for its .panel-actions buttons. */
    position: relative;
}

/* ===== REBOOT button (round, floating, top-left of the window) ===== */
/* Round magic-wand-style button fixed to the top-left corner, just right of
   the navigation sidebar (78px wide + 12px gap) — mirrors the sound-mute
   button in the bottom-left corner. Shown only on the operator console pages
   (teletype / VT52 console); switchPage() toggles the .hidden class. */
.console-reboot {
    position: fixed;
    top: 12px;
    left: 90px;
    z-index: 1000;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid #5a554a;
    border-radius: 50%;
    background: linear-gradient(180deg, #3a352a, #2a2722);
    color: #b8b0a0;
    cursor: pointer;
    padding: 0;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
    transition: background 0.2s, border-color 0.2s, color 0.2s;
    user-select: none;
}

.console-reboot:hover {
    background: linear-gradient(180deg, #4a453a, #3a352a);
    border-color: #8a7a5a;
    color: #e0d8c8;
}

.console-reboot .console-reboot-icon {
    width: 20px;
    height: 20px;
    display: block;
}

/* The REBOOT action is offered on the Panel, teletype and VT52 (TTY 1) pages;
   switchPage() toggles this class. */
.console-reboot.hidden {
    display: none !important;
}

/* Real-printer actions (Print / Save .txt) below the machine */
.printer-actions {
    margin-top: 8px;
    text-align: center;
}

.printer-actions button {
    background: linear-gradient(180deg, #5a4a30, #3a3528);
    color: #f0e6c8;
    border: 1px solid #c8a860;
    border-radius: 4px;
    padding: 6px 16px;
    font-size: 12px;
    font-weight: bold;
    cursor: pointer;
    margin: 0 6px;
}

.printer-actions button:hover {
    background: linear-gradient(180deg, #6a5a38, #4a3a2c);
}

/* ===== VT52 Page — CRT terminal styling ===== */
/* Applies to the console VT52 and both user-terminal pages so they all
   centre the CRT the same way. */
#page-vt52.active,
#page-vt52-console.active,
#page-vt52-2.active,
#page-vt11.active {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Transparent so the PDP-11 photo backdrop on body shows through */
    overflow: hidden;
}

.vt52-container {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    box-sizing: border-box;
    /* Do not let the page's centering flexbox squeeze the cabinet below its
       content — otherwise the side panel would spill out of the case. */
    flex-shrink: 0;
}

/* The VT11 keeps its own dark cabinet (built from HTML, not initVT52Page). */
.vt11-terminal {
    position: relative;
    background:
        linear-gradient(180deg, #4a4438 0%, #3a352a 22%, #2b2822 100%);
    border: 1px solid #6a655a;
    border-top-color: #7b756a;
    border-radius: 16px 16px 12px 12px;
    padding: 14px 18px 18px 18px;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.10),
        inset 0 0 26px rgba(0, 0, 0, 0.6),
        0 8px 32px rgba(0, 0, 0, 0.65),
        0 0 0 1px #6a655a;
}

/* DECscope VT52 cabinet (built by buildVT52Cabinet in pdp11-app.js). A slanted
   off-white (beige) moulded-plastic monoblock: the top recedes with a soft
   catch-light while the keyboard deck below sits on a dark base. */
.vt52-terminal {
    position: relative;
    /* Size to content so the side panel always sits inside the case. Use
       max-content rather than fit-content: fit-content clamps the case to the
       viewport when the window is narrower than the cabinet, so the CRT and
       the dark side panel overflow the case edge — and the proportional
       scaler never compensates because it measures the already-clamped width
       (see installVT52Scaling in pdp11-app.js). */
    width: max-content;
    background:
        radial-gradient(ellipse at 50% -12%, rgba(255, 255, 255, 0.38), transparent 55%),
        linear-gradient(180deg, #e8e2d4 0%, #ddd6c6 20%, #d0c9b6 60%, #c0b8a2 100%);
    border: 1px solid #a89f88;
    border-top-color: #ece6d8;
    border-radius: 18px 18px 12px 12px;
    padding: 14px 18px 10px 18px;
    box-shadow:
        inset 0 2px 6px rgba(255, 255, 255, 0.35),
        inset 0 0 30px rgba(0, 0, 0, 0.16),
        0 1px 0 rgba(255, 255, 255, 0.45),
        0 26px 44px rgba(0, 0, 0, 0.5);
}

/* Upper-face highlight: soft light suggesting the top of the cabinet recedes
   backwards — pure lighting, so the rounded corners and drop shadow survive. */
.vt52-terminal::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 24%;
    border-radius: 18px 18px 0 0;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.30), rgba(255, 255, 255, 0));
    pointer-events: none;
}

/* DEC badge on terminal bezel */
.vt52-badge {
    text-align: center;
    font-family: arial, helvetica, sans-serif;
    font-size: 9px;
    letter-spacing: 2px;
    color: #8a8274;
    text-transform: uppercase;
    margin-bottom: 6px;
    user-select: none;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
}

/* ===== DECscope VT52 cabinet detail styles ===== */
/* Vent grille: a row of short vertical slots on the top panel, drawn with a
   repeating gradient so no per-slot DOM is needed. */
.vt52-vents {
    height: 10px;
    width: 100%;
    margin: -2px auto 12px auto;
    border-radius: 2px;
    background: repeating-linear-gradient(90deg,
            transparent 0px,
            transparent 3px,
            #7d7565 3px,
            #7d7565 4px);
    box-shadow:
        inset 0 1px 2px rgba(0, 0, 0, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.5);
    pointer-events: none;
}

/* Top section: screen bezel (left) + plain plastic side (right). */
.vt52-top {
    display: flex;
    align-items: stretch;
    gap: 14px;
}

.vt52-screen-side {
    flex: 1 1 auto;
    /* Never squeeze the screen column below its tube: this is what previously
       let the right side panel overlap the right edge of the display. Use
       max-content, not fit-content — fit-content in min-width is unreliable
       inside flex containers in older WebView2 (Windows 10) and lets the
       column collapse, overflowing the dark side panel past the case edge. */
    min-width: max-content;
    display: flex;
}

/* Deep, wide bezel around the tube — the screen sits recessed inside it. */
.vt52-bezel {
    position: relative;
    flex: 1 1 auto;
    /* Never squeeze the bezel below its contents: the canvas keeps its native
       80x24 aspect and the dark side panel sits inside the same beige bezel,
       so the cabinet embraces both as one piece. max-content is the reliable
       spelling of this guard (fit-content in min-width misbehaves in older
       WebView2 on Windows 10, letting the side panel spill out of the case). */
    min-width: max-content;
    display: flex;
    align-items: center;
    /* The dark side panel is absolutely positioned against the right edge, so
       its fixed width must be reserved inside the padding: flexbox max-content
       measurement of this bezel ignores flex-basis-length items (flex: 0 0
       180px) in older WebView2 on Windows 10 and collapses the bezel, letting
       the panel spill past the case edge. Reserved slot = 180px panel + 14px
       gap, mirrored by the 16px padding on the left. */
    gap: 14px;
    padding: 16px;
    padding-right: calc(16px + 14px + 180px);
    border-radius: 12px;
    background: linear-gradient(180deg, #e2dbc9 0%, #d4ccb8 60%, #c4bba5 100%);
    border: 1px solid #a89f88;
    box-shadow:
        inset 0 4px 12px rgba(0, 0, 0, 0.28),
        inset 0 -4px 10px rgba(255, 255, 255, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.5);
}

/* Right plastic side panel — very dark charcoal, recessed beside the screen. */
.vt52-side-plastic {
    /* Out of the flex flow: anchored to the bezel's right edge so the bezel
       width is decided by its padding reservation (see .vt52-bezel) instead
       of a flex max-content measurement that older WebView2 on Windows 10
       gets wrong. */
    position: absolute;
    top: 16px;
    right: 16px;
    bottom: 16px;
    width: 180px;
    /* Square corners, like the real DECscope side panel. */
    border-radius: 0;
    background: linear-gradient(180deg, #3a3a3a, #1b1b1b);
    border: 1px solid #0e0e0e;
    box-shadow:
        inset 0 3px 8px rgba(0, 0, 0, 0.5),
        0 1px 0 rgba(255, 255, 255, 0.08);
}

/* A single raised horizontal ridge, sitting just above the lower edge. */
.vt52-side-ridge {
    position: absolute;
    left: 10%;
    right: 10%;
    bottom: 14px;
    height: 8px;
    border-radius: 4px;
    background: linear-gradient(180deg, #6e6e6e 0%, #3e3e3e 45%, #262626 100%);
    box-shadow:
        0 1px 1px rgba(255, 255, 255, 0.18),
        0 2px 4px rgba(0, 0, 0, 0.6);
}

/* DEC "digital" wordmark stamped at the top of the dark side panel, echoing
   the boxed letters of the front panel's .decLetter block, light on dark. */
.vt52-dec-logo {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 2px;
    pointer-events: none;
    user-select: none;
}

.vt52-dec-letter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 18px;
    border: 1px solid #8a8274;
    /* Light bottom edge so the full square reads on the dark panel and the
       letters look debossed (bright lower rim catches the top light). */
    border-bottom-color: #b6ae9c;
    border-radius: 2px;
    color: #d0c9b6;
    font-family: arial, helvetica, sans-serif;
    font-weight: 100;
    font-size: 11px;
    line-height: 1;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
}

/* CRT tube (the glass area) */
.vt52-crt {
    position: relative;
    /* Keep the 80x24 canvas at its native size inside the bezel so the screen
       proportions never stretch or get clipped by the side panel. */
    flex-shrink: 0;
    border-radius: 10px;
    overflow: hidden;
    /* The real VT52 faceplate is very dark grey-green glass, not pure black. */
    background: #141914;
    border: 2px solid #151515;
    box-shadow:
        /* Vignette + glass curvature */
        inset 0 0 40px rgba(0, 0, 0, 0.30),
        inset 0 0 90px rgba(0, 0, 0, 0.65),
        inset 0 2px 6px rgba(255, 255, 255, 0.06),
        /* Tube edge highlight and depth */
        0 0 0 1px rgba(0, 0, 0, 0.9),
        0 0 26px rgba(0, 0, 0, 0.7),
        0 0 30px rgba(255, 255, 255, 0.06);
    cursor: text;
}

/* Glass reflection: a soft curved highlight swept across the tube plus a faint
   diagonal glare. Painted as ::before so it sits above the canvas but below
   the scanlines and never grabs pointer events. When CRT effects are enabled
   this layer is repurposed as the animated vertical-hold roll band (see
   body.crt-effects .vt52-crt::before). */
.vt52-crt::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
    pointer-events: none;
    background:
        radial-gradient(ellipse at 50% -25%, rgba(255, 255, 255, 0.09), transparent 62%),
        linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, transparent 42%);
}

/* Scanlines overlay (a genuine CRT texture in normal mode). */
.vt52-crt::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: repeating-linear-gradient(0deg,
            rgba(0, 0, 0, 0.12) 0px,
            rgba(0, 0, 0, 0.12) 1px,
            transparent 1px,
            transparent 3px);
    pointer-events: none;
    z-index: 2;
}

.vt52-crt canvas {
    display: block;
    /* Phosphor halo: a soft glow around the white (P4) writing. */
    filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.30));
    outline: none;
}

/* Plain text-mode terminal (CONFIG → Visual → "VT52 text mode"): the terminal
   renders through a real <textarea> instead of the canvas, so native text
   selection and Windows Clipboard (Ctrl+C / Ctrl+V / right-click paste) work.
   It is styled to echo the P4-phosphor CRT — black tube, light-grey text, the
   same monospace grid and inner margin (screenPadding) as the canvas path.
   The scanline/glow overlays (::after/::before, pointer-events: none) stay on
   top, so the tube keeps its CRT flair without blocking the input. */
.vt52-crt textarea.vt52-textarea {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    padding: 12px;
    border: 0;
    outline: none;
    resize: none;
    background: #141914;
    color: #e0e0e0;
    caret-color: #e0e0e0;
    font-family: 'VT52', monospace;
    font-size: 20px;
    line-height: 20px;
    overflow: auto;
}

/* Visual bell flash for the plain text-mode terminal (vt52TextMode): a
   one-shot reverse-video blink driven by a CSS animation, since there is no
   canvas to invert. Added/removed by bell() in src/vt52.js; removal happens
   on animationend so consecutive bells restart the animation. */
.vt52-textarea.vt52-bell-flash {
    animation: vt52-bell-flash 0.15s steps(2) 2 alternate;
}

@keyframes vt52-bell-flash {
    from {
        background: #e0e0e0;
        color: #141914;
    }

    to {
        background: #141914;
        color: #e0e0e0;
    }
}

/* Subtle phosphor shimmer animation */
@keyframes phosphor-shimmer {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.97;
    }
}

.vt52-crt canvas {
    animation: phosphor-shimmer 4s ease-in-out infinite;
}

/* ===== CRT effects (CONFIG → Visual → "CRT effects") ===== */
/* Enabled by toggling 'crt-effects' on <body> (see pdp11-app.js
   applyCRTEffects). Everything is pure CSS layered on top of the
   canvas-rendered VT52 tube, so the emulator's drawing pipeline is
   untouched. Only .vt52-crt terminals are affected (VT11 keeps its own
   green-phosphor look). Compositor-friendly properties only (opacity,
   transform, filter, background-position), pointer-events: none so the
   overlays never steal keyboard/click focus from the canvas. */
body.crt-effects .vt52-crt canvas {
    animation:
        phosphor-shimmer 4s ease-in-out infinite,
        crt-flicker 0.09s steps(2) infinite,
        crt-jitter 8s steps(1, end) infinite;
}

/* Rapid, irregular brightness flicker — as if the HV supply is marginal.
   The drop-shadow glow from the base rule is re-stated in every keyframe
   so the phosphor halo persists while the brightness snaps. */
@keyframes crt-flicker {

    0%,
    100% {
        filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.12)) brightness(1);
    }

    50% {
        filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.08)) brightness(0.96);
    }
}

/* Occasional horizontal micro-jerks — a loose horizontal-hold pot. */
@keyframes crt-jitter {
    0% {
        transform: translateX(0);
    }

    90% {
        transform: translateX(0);
    }

    91% {
        transform: translateX(1px);
    }

    92% {
        transform: translateX(0);
    }

    95% {
        transform: translateX(-1px);
    }

    96%,
    100% {
        transform: translateX(0);
    }
}

/* Vertical-hold roll: a single soft bright band sweeps down the tube on a
   loop, like a drifting vertical sync. It is a separate ::before layer
   (z-index 1) beneath the scanlines (::after, z-index 2). */
body.crt-effects .vt52-crt::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 40%;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(180deg,
            transparent 0%,
            rgba(255, 255, 255, 0.05) 45%,
            rgba(255, 255, 255, 0.12) 50%,
            rgba(255, 255, 255, 0.05) 55%,
            transparent 100%);
    mix-blend-mode: screen;
    animation: crt-roll 6s linear infinite;
}

@keyframes crt-roll {
    0% {
        transform: translateY(-100%);
    }

    100% {
        transform: translateY(250%);
    }
}

/* Scanline shimmer: the line pattern itself flickers subtly, reinforcing
   the interlaced feel of a real raster CRT. */
body.crt-effects .vt52-crt::after {
    animation: crt-scanline-shimmer 0.18s steps(2) infinite;
}

@keyframes crt-scanline-shimmer {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.85;
    }
}

/* Accessibility: users who prefer reduced motion get a stable, readable
   screen (the static scanlines and glow remain, but nothing animates). */
@media (prefers-reduced-motion: reduce) {

    body.crt-effects .vt52-crt canvas,
    body.crt-effects .vt52-crt::before,
    body.crt-effects .vt52-crt::after {
        animation: none;
    }
}

/* Status label below screen */
.vt52-status {
    margin-top: 10px;
    font-family: arial, helvetica, sans-serif;
    font-size: 11px;
    color: #6a655a;
    text-align: center;
    user-select: none;
    letter-spacing: 0.5px;
}

.vt52-status .led {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 4px;
    vertical-align: middle;
}

.vt52-status .led.on {
    background: #0f0;
    box-shadow: 0 0 6px #0f0;
}

/* ===== VT11 Display page — vector-graphics CRT ===== */
/* The VT11 canvas (1024x768) is created lazily by src/vt11.js inside the
   #vt11 container; this wraps it in a matching DEC bezel + scanlines. */
.vt11-container {
    position: relative;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    box-sizing: border-box;
}

/* CRT tube (green-phosphor vector display) */
/* The tube starts at the native 1024x768 canvas size but is CSS-scaled down
   to fit the available viewport (sidebar, bezel and status bar accounted for)
   while preserving the 4:3 aspect ratio. The internal 1024x768 coordinate
   space in src/vt11.js stays untouched — only the displayed size changes, so
   the page no longer overflows a 1080p window (especially with OS display
   scaling). */
.vt11-crt {
    position: relative;
    width: min(1024px, calc(100vw - 140px), calc((100vh - 120px) * 4 / 3));
    aspect-ratio: 4 / 3;
    height: auto;
    border-radius: 10px;
    overflow: hidden;
    background: #001000;
    border: 2px solid #1a1a1a;
    box-shadow:
        inset 0 0 40px rgba(0, 255, 0, 0.04),
        inset 0 0 80px rgba(0, 0, 0, 0.6),
        0 0 30px rgba(0, 255, 0, 0.08);
}

/* Scanlines overlay (same treatment as the VT52) */
.vt11-crt::after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: repeating-linear-gradient(0deg,
            rgba(0, 0, 0, 0.12) 0px,
            rgba(0, 0, 0, 0.12) 1px,
            transparent 1px,
            transparent 3px);
    pointer-events: none;
    z-index: 2;
}

/* The green-phosphor canvas appended by vt11.js: stretch it to fill the
   (possibly CSS-scaled) tube so the 1024x768 rendering scales with it. */
.vt11-crt #vt11 {
    width: 100%;
    height: 100%;
}

.vt11-crt canvas {
    display: block;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 0 3px rgba(0, 255, 0, 0.3));
    outline: none;
    animation: phosphor-shimmer 4s ease-in-out infinite;
}

/* ===== LP11 line printer page — DEC cabinet ===== */
/* Authentic DEC LP11/LA180-style enclosure drawn with CSS gradients around
   the unchanged G60 paper path (the dark mechanics bay itself is styled in
   g60printer.css). Follows the same "cabinet around the working renderer"
   pattern as the VT52 terminal (.vt52-terminal): beige/grey metal body,
   a top cover with a vent grille, the "digital lp11" badge and an operator
   console with a ready LED plus TOP OF FORM / PAPER FEED keys. */
.lp11-cabinet {
    position: relative;
    width: fit-content;
    box-sizing: border-box;
    /* Pin the cabinet to the bottom of the page so that halving the printer
       bay height keeps the cabinet's lower edge where it was. */
    margin-top: auto;
    background:
        radial-gradient(ellipse at 50% -12%, rgba(255, 255, 255, 0.30), transparent 55%),
        linear-gradient(180deg, #e4ded0 0%, #d8d1c0 22%, #c9c1ac 100%);
    border: 1px solid #a89f88;
    border-top-color: #ece6d8;
    border-radius: 12px 12px 8px 8px;
    padding: 12px 16px 10px 16px;
    box-shadow:
        inset 0 2px 6px rgba(255, 255, 255, 0.35),
        inset 0 0 30px rgba(0, 0, 0, 0.16),
        0 1px 0 rgba(255, 255, 255, 0.45),
        0 26px 44px rgba(0, 0, 0, 0.5);
}

/* Upper-face catch-light — pure lighting, so the rounded corners survive. */
.lp11-cabinet::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 22%;
    border-radius: 12px 12px 0 0;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.30), rgba(255, 255, 255, 0));
    pointer-events: none;
}

/* DEC badge on the top cover */
.lp11-badge {
    text-align: center;
    font-family: arial, helvetica, sans-serif;
    font-size: 9px;
    letter-spacing: 2px;
    color: #8a8274;
    text-transform: uppercase;
    margin-bottom: 6px;
    user-select: none;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}

/* Operator console strip below the mechanics bay */
.lp11-console {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 10px;
    padding: 6px 12px;
    border-radius: 5px;
    background: linear-gradient(180deg, #3a352c 0%, #2b2720 100%);
    border: 1px solid #1a1712;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 1px 2px rgba(0, 0, 0, 0.5);
}

.lp11-label {
    font-family: arial, helvetica, sans-serif;
    font-size: 10px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: #d8cfba;
    /* Pin the name plate to the LEFT of the operator console; the auto margin
       absorbs the free space so the LEDs and keys sit on the RIGHT. */
    margin-right: auto;
    user-select: none;
}

/* Ready indicator — green LED: steady while the printer is ready/idle and
   blinking while a line is printing (the .busy class is toggled by the LP11
   operator-panel ticker in src/iopage.js). */
.lp11-led {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #1a1a1a;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.8);
}

.lp11-led-ready {
    background: #3f3;
    box-shadow: 0 0 6px #3f3, inset 0 1px 1px rgba(255, 255, 255, 0.5);
}

/* While a line prints, blink the READY LED to show the machine is busy. */
.lp11-led-ready.busy {
    background: #4c4;
    box-shadow: 0 0 8px #4c4, inset 0 1px 1px rgba(255, 255, 255, 0.5);
    animation: lp11-ready-blink 0.4s steps(2, start) infinite;
}

@keyframes lp11-ready-blink {
    to {
        opacity: 0.2;
    }
}

/* DEC-style operator keys */
.lp11-key {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    background: linear-gradient(180deg, #8f8672 0%, #6f6754 100%);
    color: #2a261e;
    border: 1px solid #4a4436;
    border-radius: 3px;
    padding: 3px 10px;
    font-family: arial, helvetica, sans-serif;
    font-size: 9px;
    font-weight: bold;
    letter-spacing: 0.5px;
    cursor: pointer;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.35),
        0 1px 2px rgba(0, 0, 0, 0.5);
    user-select: none;
}

.lp11-key:active {
    background: linear-gradient(180deg, #6f6754 0%, #8f8672 100%);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4);
}

/* Top cover (hood) with a vent grille: a beige metal lid drawn with gradients
   above the mechanics bay. The fanfold rises through the central dark paper
   slot; the vent grilles run down either side of the slot. */
.lp11-hood {
    display: flex;
    align-items: stretch;
    margin-bottom: 6px;
    border: 1px solid #a89f88;
    border-bottom-color: #8f876f;
    border-radius: 6px 6px 2px 2px;
    background: linear-gradient(180deg, #e8e2d4 0%, #d8d1c0 70%, #c9c1ac 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.5),
        inset 0 -3px 6px rgba(0, 0, 0, 0.12),
        0 1px 2px rgba(0, 0, 0, 0.25);
}

/* Vent grille: a row of short vertical slots drawn with a repeating gradient,
   so no per-slot DOM is needed (mirrors .vt52-vents, taller for the LP11). */
.lp11-vents {
    flex: 1 1 0;
    height: 22px;
    background: repeating-linear-gradient(90deg,
            transparent 0px,
            transparent 5px,
            #6f6754 5px,
            #6f6754 7px);
    box-shadow:
        inset 0 1px 3px rgba(0, 0, 0, 0.35),
        0 1px 0 rgba(255, 255, 255, 0.5);
    pointer-events: none;
}

/* Paper slot in the hood through which the fanfold rises. The paper element is
   later in the DOM, so it draws over this slot. Its backing is the same beige
   as the surrounding hood (transparent — the hood shows through), and it
   carries the DEC "digital" wordmark (dark letters, see .lp11-dec-letter). */
.lp11-paper-slot {
    flex: 0 0 100px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    background: transparent;
    border-left: 1px solid #a89f88;
    border-right: 1px solid #a89f88;
}

/* DEC "digital" wordmark letters in frames, echoing the front-panel .decLetter
   block: each letter sits in its own dark frame, stamped dark on the beige
   cover (matching the surrounding hood background). */
.lp11-dec-letter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 9px;
    height: 14px;
    border: 1px solid #6b6350;
    background: transparent;
    color: #4a4436;
    font-family: arial, helvetica, sans-serif;
    font-size: 8px;
    font-weight: bold;
    line-height: 1;
    text-transform: uppercase;
    user-select: none;
}

/* Amber ONLINE indicator — lit while the printer is on line; the .off modifier
   dims it (operator pressed ON LINE → OFF LINE). */
.lp11-led-online {
    background: #fa0;
    box-shadow: 0 0 6px #fa0, inset 0 1px 1px rgba(255, 255, 255, 0.5);
}

/* Any indicator when its function is off (applies to the ONLINE LED). */
.lp11-led.off {
    background: #1a1a1a;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.8);
}

/* ON LINE key: engaged (pressed) look while the printer is on line — the key
   reads as pushed in, matching the lit ONLINE LED. */
.lp11-key-online {
    background: linear-gradient(180deg, #6f6754 0%, #8f8672 100%);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4),
        0 1px 0 rgba(255, 255, 255, 0.2);
}

/* The amber ONLINE LED is built into the LEFT side of the ON LINE keycap
   (a small lamp inside the key), so it must be smaller than the free-standing
   READY LED and keep the key's text aligned. */
.lp11-key-online .lp11-led {
    width: 6px;
    height: 6px;
    margin: 0;
    flex: none;
}

/* OFF LINE (key released): the key pops back out to the normal raised look,
   and the ONLINE LED is dimmed (.lp11-led.off). */
.lp11-key-online.off {
    background: linear-gradient(180deg, #8f8672 0%, #6f6754 100%);
    color: #2a261e;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
        0 1px 2px rgba(0, 0, 0, 0.5);
}

/* ===== Hidden sidebar buttons (toggled by the CONFIG page) ===== */
.nav-btn.hidden {
    display: none !important;
}

/* ===== Config page (DEC-styled form) ===== */
#page-config.active {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
    color: #e0d8c8;
    max-width: 720px;
    margin: 0 auto;
    padding: 16px 24px;
    box-sizing: border-box;
    /* Dark translucent slab so the form stays readable over the photo */
    background: rgba(28, 25, 21, 0.82);
}

#page-config.active h2,
#page-config.active h3 {
    color: #f0e6c8;
}

#page-config.active p {
    line-height: 1.5;
}

/* ===== Storage page (media management) ===== */
#page-storage.active {
    display: block;
    overflow-y: auto;
    overflow-x: hidden;
    color: #e0d8c8;
    max-width: 720px;
    margin: 0 auto;
    padding: 16px 24px;
    box-sizing: border-box;
    /* Dark translucent slab so the controls stay readable over the photo */
    background: rgba(28, 25, 21, 0.82);
}

#page-storage.active h2,
#page-storage.active h3 {
    color: #f0e6c8;
}

#page-storage.active p {
    line-height: 1.5;
}

#page-storage.active code {
    color: #d4c4a0;
    background: rgba(0, 0, 0, 0.3);
    padding: 1px 4px;
    border-radius: 2px;
}

.config-form {
    margin-top: 8px;
}

.config-field {
    display: flex;
    align-items: baseline;
    gap: 16px;
    padding: 10px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.config-label {
    flex: 0 0 220px;
    font-size: 12px;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: #c8a860;
}

.config-control {
    flex: 1;
    font-size: 13px;
}

.config-control label {
    display: inline-block;
    margin-right: 18px;
    color: #e0d8c8;
    cursor: pointer;
}

.config-radios label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.config-control input[type="radio"],
.config-control input[type="checkbox"] {
    accent-color: #c8a860;
    cursor: pointer;
}

.config-control select {
    background: #2a2722;
    color: #e0d8c8;
    border: 1px solid #5a554a;
    border-radius: 4px;
    padding: 4px 8px;
    font-size: 13px;
}

.config-control button {
    background: linear-gradient(180deg, #5a4a30, #3a3528);
    color: #f0e6c8;
    border: 1px solid #c8a860;
    border-radius: 4px;
    padding: 6px 14px;
    font-size: 12px;
    font-weight: bold;
    cursor: pointer;
}

.config-control button:hover {
    background: linear-gradient(180deg, #6a5a38, #4a3a2c);
}

/* Apply button highlight while the CONFIG form has uncommitted changes. */
.config-control button#config-apply.dirty {
    background: linear-gradient(180deg, #8a6a30, #5a4a28);
    border-color: #ffd27f;
    box-shadow: 0 0 8px rgba(255, 210, 127, 0.45);
}

.config-hint {
    display: block;
    margin-top: 4px;
    font-size: 11px;
    color: #8a857a;
}

/* Paper tape reader state indicator (Storage page). */
.tape-state {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    font-size: 11px;
    font-weight: bold;
    border-radius: 3px;
    border: 1px solid transparent;
    vertical-align: middle;
}

.tape-state.none {
    color: #8a857a;
}

.tape-state.at-start {
    color: #7fbf7f;
    border-color: #4a7a4a;
    background: rgba(79, 122, 79, 0.15);
}

.tape-state.ready {
    color: #7fb8d8;
    border-color: #3a6a8a;
    background: rgba(63, 106, 138, 0.15);
}

.tape-state.consumed {
    color: #d08080;
    border-color: #8a4a4a;
    background: rgba(138, 74, 74, 0.15);
}

/* Punch tape size / mounted image count indicators (Storage page). */
.punch-size,
.mounted-count {
    display: inline-block;
    margin-left: 8px;
    font-size: 11px;
    font-weight: bold;
    color: #7fb8d8;
    vertical-align: middle;
}

/* CONFIG page tabbed layout: a top tab bar splits the growing configuration
   into Equipment (hardware), Look & sound (presentation: visual + audio),
   Behaviour (dialogs) and Development (dev aids) panels. Every panel lives in
   the same grid cell (the inactive ones are hidden with visibility:hidden, so
   the row stays as tall as the tallest panel). The Defaults/Apply action bar
   sits right below that row, so it never jumps vertically when a tab is
   selected. */
.config-tabs {
    display: grid;
    grid-template-columns: 1fr;
}

.config-tab-bar {
    grid-row: 1;
    display: flex;
    gap: 4px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    margin-bottom: 4px;
}

.config-tab {
    background: transparent;
    color: #a89e8c;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: 4px 4px 0 0;
    padding: 8px 16px;
    font-size: 12px;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    cursor: pointer;
}

.config-tab:hover {
    color: #f0e6c8;
    background: rgba(255, 255, 255, 0.04);
}

.config-tab.active {
    color: #f0e6c8;
    background: rgba(28, 25, 21, 0.6);
    border-color: rgba(255, 255, 255, 0.12);
    /* Blend the active tab into the translucent page slab underneath. */
    border-bottom-color: rgba(28, 25, 21, 0.82);
}

.config-tab-panel {
    grid-row: 2;
    grid-column: 1;
    /* Hidden panels still take part in the grid sizing (visibility keeps the
       layout box), so the row always matches the tallest panel. */
    visibility: hidden;
}

.config-tab-panel.active {
    visibility: visible;
}

.config-actions {
    grid-row: 3;
    margin-top: 8px;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
}

/* The last field of a tab panel would otherwise double up with the action
   bar's top border when the panel is as tall as the tallest one, producing
   two stacked lines before the Defaults/Apply buttons. */
.config-tab-panel .config-field:last-child {
    border-bottom: none;
}

/* Conditionally hidden CONFIG fields (Equipment tab: teletype-only parameters,
   LP11 printer width) keep their layout box via visibility instead of
   display:none — mirroring how inactive tab panels hide. This keeps the panel
   row as tall as the tallest panel, so the Defaults/Apply action bar below it
   never jumps vertically when the console/printer choice changes. */
.config-field.config-hidden {
    visibility: hidden;
}

/* ===== Photo backdrop toggle (CONFIG) ===== */
/* body.no-photo-bg — the PDP-11 machine-room photo is switched off: restore
   the plain dark background. The whole .app-layout is painted a deep
   near-black tone (so the lighter body colour never shows in the page
   gutters), while the CONFIG/CONTROL/INFO forms keep a slightly lighter solid
   card (#1c1915 — the same tone as their photo-mode slabs) so they stay
   visually distinct from the backdrop instead of blending into it. */
body.no-photo-bg {
    background-image: none;
    background-color: #0d0c0a;
}

body.no-photo-bg .app-layout {
    background: #0d0c0a;
}

body.no-photo-bg #page-config.active,
body.no-photo-bg #page-storage.active,
body.no-photo-bg #page-instructions.active {
    /* Solid card on the dark backdrop: keeps the form readable and separates
       it from the window background (there is no photo to sit a translucent
       slab on, so a translucent one would only blend into the backdrop). */
    background: #1c1915;
}