html,
body {
    height: 100%;
}

/* The design tokens: Material 3's roles, shapes and states, in a dark
   scheme around the panel's amber (docs/ui-design.md, P11). Every
   control takes its colours, corners and type from here, so that one
   kind of thing looks the same wherever it is. The Teletype's paper is
   the one surface outside the scheme: it is paper. */
:root {
    /* Surfaces, from the darkest - the wells that hold code and data -
       up through the page, the dock and the chrome, to the dialogs and
       the tonal buttons. */
    --c-well: #171717;
    --c-surface: #1f1f1f;
    --c-surface-low: #242424;
    --c-surface-container: #2b2b2b;
    --c-surface-high: #333;
    --c-tonal: #464646;
    --c-divider: #111;
    --c-on-surface: #e6e6e6;
    --c-on-surface-variant: #a8a8a8;
    --c-on-tonal: #ededed;
    --c-outline: #8c8c8c;
    --c-outline-variant: #444;
    /* The amber: what is active, raised, or to be pressed. */
    --c-primary: #f90;
    --c-on-primary: #241500;
    --c-primary-text: #ffb340;
    --c-primary-container: rgba(255, 153, 0, 0.18);
    --c-on-primary-container: #ffc670;
    /* A machine that is on; the power switch while it is off. */
    --c-success: #3ddc63;
    --c-on-success: #0b2a14;
    --c-info: #4da3ff;
    --c-link: #8ab4f8;
    --c-warn-container: #5a4a1a;
    --c-on-warn-container: #ffd98a;
    --c-error: #ff8a80;
    --c-error-container: #5a2323;
    --c-on-error-container: #ffb4b4;
    /* A control that cannot be used just now: on-surface at 12% and
       38%, as Material greys one out. */
    --c-disabled-bg: rgba(230, 230, 230, 0.12);
    --c-disabled: rgba(230, 230, 230, 0.38);
    /* State layers: the control's own text colour laid over its fill,
       so that a grey, an amber and a green button all answer alike. */
    --layer-hover: color-mix(in srgb, currentColor 8%, transparent);
    --layer-press: color-mix(in srgb, currentColor 14%, transparent);
    /* The flat chrome's hover - toolbar buttons, dock tabs, the strip's
       tab - and a menu button's while its menu is open. */
    --hover-bg: color-mix(in srgb, var(--c-on-surface) 8%, transparent);
    --open-bg: color-mix(in srgb, var(--c-on-surface) 14%, transparent);
    /* Corners. */
    --r-xs: 4px;
    --r-s: 8px;
    --r-m: 12px;
    --r-l: 16px;
    --r-xl: 28px;
    --r-full: 999px;
    /* Type: the app's own words in the system's sans, and the machine's
       - its legends, dumps, paper and code - in monospace. */
    --font-ui: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    --font-mono: 'Consolas', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Liberation Mono', 'DejaVu Sans Mono', 'Courier New', monospace;
}

body {
    background-color: var(--c-surface);
    color: var(--c-on-surface);
    font-family: var(--font-ui);
    font-size: 16px;
    margin: 0;
    padding: 0;
}

/* The whole app: toolbar, front panel, dock, status line, top to
   bottom, filling the window and never scrolling as a page. Growing the
   dock shrinks the panel rather than pushing it off the screen (P1 and
   U1 in docs/ui-design.md). */
#app {
    display: flex;
    flex-direction: column;
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
}

/* Browsers give form controls and preformatted text a font of their
   own. A control takes the page's; text, code and the machine's own
   things take the monospace - so that a new button cannot come out in
   Arial, nor the Teletype's paper in Courier. */
button, input, select {
    font-family: inherit;
}

textarea, pre, code, kbd, samp,
#cpu-dump, #mem-dump, #instr-pane, #mem-window-label, .debug-field,
#tty-paper, .tty-keys, .strip-body, .asm-editor, .asm-listing,
.dialog-field, #debug-data-input {
    font-family: var(--font-mono);
}

/* One focus ring for every control, drawn the same way everywhere: the
   keyboard's place, in the amber of what is active. */
button:focus-visible,
[role="button"]:focus-visible,
[role="tab"]:focus-visible,
.button:focus-visible,
.dock-tab:focus-visible,
.dock-tool:focus-visible,
.view-tab:focus-visible,
.strip-tab:focus-visible {
    outline: 2px solid var(--c-primary);
    outline-offset: 2px;
}

/* Controls are pressed, not read. Dragging across one, or pressing it
   twice, selects none of its words, as in any app: buttons, the dock's
   tabs, the menus and their items, the front panel and its switches,
   Share's choices, the logo. What they act on - the editor, the
   Teletype's paper, the dumps, a dialog's text and its link field -
   can still be selected and copied, and links keep the browser's own
   ways, selected or dragged like any link. */
button,
[role="button"],
[role="tab"],
[role="option"],
.button,
.dropdown-heading,
.dialog-option,
.logo,
#panel {
    -webkit-user-select: none;
    user-select: none;
}

div, img, pre {
    border: 0;
    margin: 0;
    padding: 0;
}

a {
    color: var(--c-link);
}

.mt-8 {
    margin-top: 8px;
}

/* The toolbar: the title, the menus for what is done to the machine
   (P4), then the app's own actions on the right (U3). */
#toolbar {
    align-items: center;
    background-color: var(--c-surface-container);
    border-bottom: 1px solid var(--c-divider);
    display: flex;
    flex: none;
    flex-wrap: wrap;
    gap: 4px;
    padding: 6px 10px;
}

#header-title {
    display: flex;
    margin-right: 8px;
}

/* The logo, wherever it is shown: a picture to look at, not an image
   to drag off (Firefox takes draggable="false" on the <img> instead). */
.logo {
    -webkit-user-drag: none;
    display: block;
}

/* In the toolbar, one size wider than a phone: as wide as the longest
   language leaves room for at 701px, the narrowest it is drawn at (at
   24px, French and Portuguese wrap the toolbar up to 712px). */
#header-logo {
    height: 22px;
    width: auto;
}

.toolbar-spacer {
    flex: 1;
}

/* A button in the toolbar, or the dock's tab strip: flat until pointed
   at, like the rest of the instrument's chrome. */
.tool-button {
    align-items: center;
    background: none;
    border: 0;
    border-radius: var(--r-full);
    color: var(--c-on-surface);
    cursor: pointer;
    display: flex;
    font-size: 14px;
    font-weight: 500;
    gap: 6px;
    line-height: 20px;
    padding: 6px 10px;
    white-space: nowrap;
}

.tool-button:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

.tool-value {
    color: var(--c-primary-text);
}

/* A toolbar action shown as an icon alone: Share, About. Its name is in
   a tooltip and on the element (panel.TOOLTIPS). */
.icon-button {
    align-items: center;
    background: none;
    border: 0;
    border-radius: var(--r-full);
    color: var(--c-on-surface);
    cursor: pointer;
    display: flex;
    height: 34px;
    justify-content: center;
    padding: 0;
    width: 34px;
}

.icon-button:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

.icon {
    fill: currentColor;
    flex: none;
    height: 20px;
    width: 20px;
}

/* The language's short code beside its icon. */
.tool-code {
    font-size: 13px;
}

/* A heading inside a menu or a tool. Small and quiet: the dock is a
   tool, and reads like one rather than like a page (P5). */
.section-label {
    color: var(--c-on-surface-variant);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.02em;
    line-height: 20px;
    margin: 6px 4px 2px 4px;
    white-space: nowrap;
}

/* Dialogs: for what needs more than a choice from a menu. A title,
   what it is for, the controls, and the actions at the bottom right.
   See js/dialog.js. The padding is on the body, so that a click on the
   <dialog> itself can only be on the backdrop. Material's dialog: a
   raised surface with large corners, its title in the headline type. */
.dialog {
    background-color: var(--c-surface-high);
    border: 0;
    border-radius: var(--r-xl);
    /* So the body's scrolling keeps the rounded corners. */
    overflow: hidden;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.55);
    color: var(--c-on-surface);
    max-width: calc(100vw - 24px);
    padding: 0;
    width: 480px;
}

.dialog::backdrop {
    background-color: rgba(0, 0, 0, 0.55);
}

/* Taller than the window - About in German on a small phone - the body
   scrolls, and the title and its close button stay in reach. */
.dialog[open] {
    display: flex;
    flex-direction: column;
    max-height: calc(100dvh - 24px);
}

.dialog-head {
    flex: none;
}

.dialog-body {
    min-height: 0;
    overflow-y: auto;
    padding: 8px 24px 20px 24px;
}

/* The title, and the close button at its right: it stays at the top
   while a long body scrolls under it. */
.dialog-head {
    align-items: center;
    display: flex;
    justify-content: space-between;
    padding: 18px 14px 6px 24px;
}

.dialog-title {
    font-size: 22px;
    font-weight: 400;
    line-height: 28px;
    margin: 0;
}

.dialog-subtitle {
    color: var(--c-on-surface-variant);
    font-size: 14px;
    font-weight: 500;
    margin: 16px 0 6px 0;
}

.dialog-text {
    color: var(--c-on-surface-variant);
    font-size: 14px;
    line-height: 1.5;
    margin: 0 0 12px 0;
}

.dialog-error {
    color: var(--c-error);
    font-size: 14px;
    line-height: 1.5;
    margin: 8px 0 0 0;
}

/* Material's outlined text field: an outline that turns amber, and
   thicker, while it has the keyboard. */
#debug-data-input,
.dialog-field {
    background-color: transparent;
    border: 1px solid var(--c-outline);
    border-radius: var(--r-xs);
    box-sizing: border-box;
    color: var(--c-on-surface);
    font-size: 14px;
    line-height: 1.5;
    padding: 9px 12px;
    width: 100%;
}

#debug-data-input {
    resize: vertical;
}

#debug-data-input:hover,
.dialog-field:hover {
    border-color: var(--c-on-surface);
}

#debug-data-input:focus,
.dialog-field:focus {
    border-color: var(--c-primary);
    box-shadow: inset 0 0 0 1px var(--c-primary);
    outline: none;
}

/* A choice with a line saying what it means, under its name. */
.dialog-option {
    align-items: flex-start;
    border-radius: var(--r-s);
    cursor: pointer;
    display: flex;
    gap: 10px;
    margin: 0 -8px 4px -8px;
    padding: 8px;
}

.dialog-option:hover {
    background-color: var(--hover-bg);
}

.dialog-option input {
    accent-color: var(--c-primary);
    margin: 3px 0 0 0;
}

.dialog-option-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dialog-option-title {
    font-size: 14px;
}

.dialog-option-desc {
    color: var(--c-on-surface-variant);
    font-size: 13px;
}

#share-link {
    margin-top: 8px;
}

.dialog-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 20px;
}

/* Material's text button for the other actions - Cancel, References -
   and its filled button for the one the dialog is for. */
.dialog-button {
    background-color: transparent;
    border: 0;
    border-radius: var(--r-full);
    color: var(--c-primary-text);
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    height: 40px;
    letter-spacing: 0.01em;
    padding: 0 16px;
}

.dialog-button:hover {
    background-image: linear-gradient(var(--layer-hover), var(--layer-hover));
}

.dialog-button:active {
    background-image: linear-gradient(var(--layer-press), var(--layer-press));
}

/* The amber says enough: an action button keeps the ordinary weight,
   like every other button. (A button holding a state - Follow PC, a
   raised switch - is bold as well, to mark the state.) */
.dialog-button.primary {
    background-color: var(--c-primary);
    color: var(--c-on-primary);
    padding: 0 24px;
}

/* Copy Link while there is nothing to copy: it still answers. */
.dialog-button.disabled,
.dialog-button.primary.disabled:hover {
    background-color: var(--c-disabled-bg);
    background-image: none;
    color: var(--c-disabled);
}

/* The logo heads About, the version under it, both centred. */
#about-logo {
    height: auto;
    margin: 4px auto 8px;
    max-width: 100%;
    width: 320px;
}

.about-version {
    color: var(--c-on-surface-variant);
    text-align: center;
}

.about-links {
    font-size: 14px;
    line-height: 1.5;
    list-style: none;
    margin: 0;
    padding: 0;
}

.about-links li {
    padding: 4px 0;
}

/* What, then whose: a label column as wide as the longest label. */
.about-licences {
    color: var(--c-on-surface);
    column-gap: 14px;
    display: grid;
    font-size: 14px;
    grid-template-columns: max-content 1fr;
    line-height: 1.5;
    margin: 0;
    row-gap: 4px;
}

.about-licences dt {
    color: var(--c-on-surface-variant);
}

.about-licences dd {
    margin: 0;
}

/* A name or a licence is never broken across two lines; the line
   breaks between them instead. */
.about-licences dd a,
.about-licences dd span {
    white-space: nowrap;
}

/* A drop down the page draws itself: a button, and a list under it.
   Shared by the Load, Memory and language menus, so that they look and
   behave the same. js/dropdown.js says why this is not
   a <select>. */
.dropdown {
    /* The list below is positioned against this. */
    position: relative;
}

.dropdown > button {
    align-items: center;
    background-color: var(--c-tonal);
    border: none;
    border-radius: var(--r-full);
    box-sizing: border-box;
    color: var(--c-on-tonal);
    cursor: pointer;
    display: flex;
    font-size: 14px;
    font-weight: 500;
    /* Roomier on the right so the arrow is not against the edge. */
    gap: 10px;
    /* The same 32px the buttons beside it come to. */
    height: 32px;
    padding: 0 14px 0 16px;
}

.dropdown-arrow {
    font-size: 10px;
    line-height: 1;
}

/* Material's menu: a raised surface, a little lighter than what it
   opens over. */
.dropdown ul {
    background-color: var(--c-surface-high);
    /* Its padding inside the height Dropdown.fit() gives it. */
    box-sizing: border-box;
    border-radius: var(--r-s);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
    color: var(--c-on-surface);
    left: 0;
    list-style: none;
    margin: 0;
    max-height: 60vh;
    /* Never wider than the window, however long an entry is. */
    max-width: calc(100vw - 32px);
    overflow-y: auto;
    padding: 6px 0;
    /* Always directly under the button, never over it. */
    position: absolute;
    top: calc(100% + 6px);
    z-index: 10;
}

.dropdown li {
    align-items: baseline;
    cursor: pointer;
    display: flex;
    font-size: 14px;
    gap: 24px;
    justify-content: space-between;
    padding: 10px 16px;
    white-space: nowrap;
}

/* What an item is, or why it is grey, quieter at its right. */
.dropdown-detail {
    color: var(--c-on-surface-variant);
    font-size: 12px;
}

/* Names the group of items under it. Not an item - the arrow keys step
   over it - so it is a label under a rule, in the small quiet type of
   a heading, never filled as an item pointed at is. */
.dropdown li.dropdown-heading {
    border-top: 1px solid var(--c-outline-variant);
    color: var(--c-on-surface-variant);
    cursor: default;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.02em;
    margin: 6px 0 0 0;
    padding: 10px 16px 4px;
}

.dropdown li.dropdown-heading:first-child {
    border-top: 0;
    margin-top: 0;
}

/* An item that cannot be used just now. It still answers, in the status
   line (D19). */
.dropdown li.disabled {
    color: var(--c-disabled);
}

.dropdown li:hover,
.dropdown li:focus {
    background-color: var(--hover-bg);
    outline: none;
}

.dropdown li.dropdown-heading:hover {
    background-color: transparent;
}

.dropdown li[aria-selected='true'] {
    background-color: var(--c-primary-container);
    color: var(--c-on-primary-container);
}

/* The toolbar's menu buttons are tool buttons, not the light buttons
   a dropdown has elsewhere. */
#toolbar .dropdown > .tool-button {
    background: none;
    border-radius: var(--r-full);
    color: var(--c-on-surface);
    height: auto;
    padding: 6px 10px;
}

#toolbar .dropdown > .tool-button:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

#toolbar .dropdown > .tool-button[aria-expanded="true"] {
    background-color: var(--open-bg);
}

/* The menus open under the toolbar's own buttons, which are on the
   right as often as the left. */
#load-list,
#memory-list {
    min-width: 260px;
}

/* Anchored to the button's right edge: it sits at the right of the
   toolbar, where a list growing rightwards would leave the window. */
#locale-list {
    left: auto;
    right: 0;
}

/* What a Show points at on the 2D panel. */
.tutorial-outline {
    fill: none;
    stroke: #f90;
    stroke-width: 5;
}

/* The Tutorial's headings: it is a document, so it has them. */
.subheader-bar {
    color: var(--c-on-surface);
    font-size: 15px;
    font-weight: bold;
    margin: 18px 0 8px 0;
}

.subheader-bar:first-child {
    margin-top: 4px;
}

/* The front panel, the one primary surface. It takes whatever height
   the toolbar, the dock and the status line leave, and the artwork
   scales to fit, keeping its shape. */
#stage {
    align-items: center;
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    min-height: 0;
    padding: 8px 12px;
}

#panel {
    flex: 1 1 0;
    min-height: 0;
    width: 100%;
}

/* The stage's top edge (docs/3d-view.md, V1): the [2D | 3D] toggle,
   and in 3D its camera's tools, at the right. A band of its own, not
   laid over the panel, so it costs the panel only its height. */
#view-tools {
    align-items: center;
    align-self: stretch;
    display: flex;
    flex: none;
    gap: 6px;
    height: 34px;
    justify-content: flex-end;
    margin-bottom: 4px;
}

/* Material's segmented button: one outline round both, the chosen one
   filled. */
#view-switch {
    border: 1px solid var(--c-outline);
    border-radius: var(--r-full);
    display: flex;
    order: 2;
    overflow: hidden;
}

.view-tab {
    color: var(--c-on-surface);
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
    line-height: 20px;
    padding: 4px 14px;
    position: relative;
}

.view-tab + .view-tab {
    border-left: 1px solid var(--c-outline);
}

.view-tab:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

.view-tab:focus-visible {
    outline-offset: -2px;
}

.view-tab.selected {
    background-color: var(--c-primary-container);
    color: var(--c-on-primary-container);
    cursor: default;
}

.view-tab.disabled {
    color: var(--c-disabled);
    cursor: default;
}

/* Until the 3D view has been seen once: the dock tabs' activity dot. */
.view-tab.has-news::after {
    background-color: var(--c-primary);
    border-radius: 50%;
    content: '';
    height: 6px;
    position: absolute;
    right: 3px;
    top: 3px;
    width: 6px;
}

#view3d-tools {
    align-items: center;
    display: flex;
    gap: 2px;
    order: 1;
}

#view3d-tools[hidden] {
    display: none;
}

#view3d-tools .icon-button {
    height: 30px;
    width: 30px;
}

/* Zoom out and in, one joined pair. */
.view-zoom {
    display: flex;
}

#view3d-tools .icon-button.disabled,
#view3d-tools.loading .icon-button,
#view3d-tools.loading .tool-button {
    color: var(--c-disabled);
    cursor: default;
}

/* The 3D view's menu buttons are tool buttons, as the toolbar's are. */
#view3d-tools .dropdown > .tool-button {
    background: none;
    border-radius: var(--r-full);
    color: var(--c-on-surface);
    font-size: 13px;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
}

#view3d-tools .dropdown > .tool-button:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

#view3d-tools .dropdown > .tool-button[aria-expanded="true"] {
    background-color: var(--open-bg);
}

/* A Show other than the whole machine: the button says something is
   left out, as a changed setting does on the toolbar. */
#view3d-tools #show-button.changed {
    color: var(--c-primary-text);
}

#views-list,
#show-list {
    left: auto;
    min-width: 200px;
    right: 0;
}

/* A label as wide as the longest it can say (Dropdown.setLabel): every
   one in the same cell, the unchosen ones taking room unseen. */
.dropdown-label-sized {
    display: inline-grid;
    text-align: start;
}

.dropdown-label-sized > span {
    grid-area: 1 / 1;
    white-space: nowrap;
}

.dropdown-label-room {
    visibility: hidden;
}

.dropdown li.with-icon {
    align-items: center;
    gap: 10px;
    justify-content: flex-start;
}

.dropdown-icon {
    flex: none;
    height: 20px;
    width: 20px;
}

/* The whole machine in 3D: it takes the room the panel would. */
#stage3d {
    background: radial-gradient(ellipse at 50% 40%, #3a3a3a 0%, #262626 70%);
    border-radius: var(--r-m);
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
    position: relative;
    width: 100%;
}

#stage3d[hidden] {
    display: none;
}

#stage3d canvas {
    display: block;
    height: 100%;
    touch-action: none;
    width: 100%;
}

#stage3d canvas:focus-visible {
    outline: 2px solid var(--c-primary);
    outline-offset: -2px;
}

.stage3d-message {
    color: #bbb;
    font-size: 14px;
    left: 0;
    margin: 0;
    padding: 0 16px;
    position: absolute;
    right: 0;
    text-align: center;
    top: 45%;
}

/* How much of the model has arrived. */
.stage3d-progress {
    background-color: #444;
    border-radius: 2px;
    height: 4px;
    left: 25%;
    overflow: hidden;
    position: absolute;
    right: 25%;
    top: calc(45% + 32px);
}

.stage3d-progress > div {
    background-color: var(--c-primary);
    height: 100%;
    transform: scaleX(var(--progress, 0));
    transform-origin: left;
    transition: transform 0.2s;
}

/* What the pointer is over: its name, what it does, what a click does. */
/* What the pointer is over: beside it once it rests, gone at a press
   (js/view3d/view3d.js places it). */
.part-label {
    background-color: rgba(51, 51, 51, 0.94);
    border: 0;
    border-radius: var(--r-s);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
    box-sizing: border-box;
    color: var(--c-on-surface);
    font-size: 12px;
    max-width: min(320px, calc(100% - 16px));
    padding: 8px 12px;
    pointer-events: none;
    position: absolute;
    z-index: 2;
}

.part-label .part-name {
    font-weight: bold;
}

.part-label .part-role {
    color: var(--c-on-surface-variant);
    margin-top: 2px;
}

.part-label .part-hint {
    color: var(--c-primary-text);
    margin-top: 4px;
}

/* Material's extended floating action button. */
.box-restore {
    align-items: center;
    background-color: var(--c-primary);
    border: 0;
    border-radius: var(--r-l);
    bottom: 12px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
    color: var(--c-on-primary);
    cursor: pointer;
    display: flex;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    gap: 8px;
    left: 50%;
    padding: 10px 18px 10px 14px;
    position: absolute;
    transform: translateX(-50%);
    white-space: nowrap;
    z-index: 3;
}

.box-restore[hidden] {
    display: none;
}

.box-restore:hover {
    background-image: linear-gradient(var(--layer-hover), var(--layer-hover));
}

.box-restore:focus-visible {
    outline-color: #fff;
}

/* The Switch Board Helper, a strip under the panel and as wide as its
   artwork (panel.fitSwitchStrip). Its tab, on its top edge, folds it
   away; folded, the tab is all that is left. */
#switch-strip {
    align-items: center;
    display: flex;
    flex: none;
    flex-direction: column;
    margin-top: 4px;
    max-width: 100%;
}

.strip-tab {
    align-items: center;
    background-color: var(--c-surface-container);
    border: 1px solid var(--c-outline-variant);
    border-bottom: 0;
    border-radius: var(--r-s) var(--r-s) 0 0;
    color: var(--c-on-surface-variant);
    cursor: pointer;
    display: flex;
    height: 14px;
    justify-content: center;
    width: 44px;
}

.strip-tab:hover {
    background-color: var(--c-surface-high);
    color: #fff;
}

.strip-tab .icon {
    height: 18px;
    transition: transform 0.15s;
    width: 18px;
}

#switch-strip.folded .strip-tab {
    border-bottom: 1px solid var(--c-outline-variant);
    border-radius: var(--r-s);
}

#switch-strip.folded .strip-tab .icon {
    transform: rotate(180deg);
}

#switch-strip.folded .strip-body {
    display: none;
}

.strip-body {
    background-color: var(--c-surface-container);
    border: 1px solid var(--c-outline-variant);
    border-radius: var(--r-l);
    box-sizing: border-box;
    padding: 8px 10px;
    width: 100%;
}

/* Each row on one line where the window has room for it, so that the
   strip is always two rows high. */
.strip-row {
    display: flex;
    flex-wrap: nowrap;
    gap: 6px 14px;
    justify-content: center;
}

.strip-row + .strip-row {
    margin-top: 8px;
}

/* One lever, or one octal digit of the address: Material's connected
   button group, round at its two ends and nearly square where its
   buttons meet. A lever with two directions - STOP and RUN, EXAMINE
   and EXAMINE-NEXT - is one control with two halves, as on the metal. */
.lever,
.octal {
    display: flex;
    gap: 2px;
}

.lever .button:not(:first-child),
.octal .button:not(:first-child) {
    border-bottom-left-radius: var(--r-xs);
    border-top-left-radius: var(--r-xs);
}

.lever .button:not(:last-child),
.octal .button:not(:last-child) {
    border-bottom-right-radius: var(--r-xs);
    border-top-right-radius: var(--r-xs);
}

.strip-body .button {
    font-size: 13px;
    font-weight: normal;
    /* 30px tall, a step denser than the app's other buttons: the strip
       is two rows on a desktop and four on a phone, and every pixel it
       takes comes out of the panel or the dock. */
    line-height: 26px;
    min-width: 30px;
    padding: 2px 10px;
    /* A label never breaks inside its button: a row too narrow for
       its levers wraps between them instead. */
    white-space: nowrap;
}

.strip-address .button {
    padding: 2px 4px;
}

/* A name with a shorter form for a phone (#29): the full one
   elsewhere. */
.label-short {
    display: none;
}

/* Between A08 and A07: the line the panel draws between the high byte
   and the low. */
.byte-divider {
    align-self: stretch;
    background-color: var(--c-outline-variant);
    flex: none;
    width: 2px;
}

/* Just above a phone's width the five names and icons only just fit:
   a little less room around each, so that they do. Wider than 700px,
   rather than from 701px, so that no width between the two (at a zoom)
   is left out. */
@media (width > 700px) and (width <= 820px) {
    .dock-tab {
        padding: 0 9px;
    }
}

/* A little narrower, and the levers close up to keep to one line. The
   address row has room to spare, and keeps its octal groups apart. */
@media (width > 700px) and (width <= 1100px) {
    .strip-row:not(.strip-address) {
        gap: 6px 6px;
    }

    .strip-row:not(.strip-address) .button {
        padding: 2px 5px;
    }
}

/* A window too narrow for the rows lets them wrap. */
@media (max-width: 940px) {
    .strip-row {
        flex-wrap: wrap;
    }
}

/* The handle between the panel and the dock. */
#dock-splitter {
    background-color: var(--c-divider);
    cursor: row-resize;
    flex: none;
    height: 6px;
    position: relative;
    touch-action: none;
}

#dock-splitter::after {
    background-color: var(--c-outline-variant);
    border-radius: 2px;
    content: '';
    height: 2px;
    left: 50%;
    position: absolute;
    top: 2px;
    transform: translateX(-50%);
    width: 40px;
}

#dock-splitter:hover,
#dock-splitter:focus-visible,
#dock-splitter.dragging {
    background-color: var(--c-primary);
    outline: none;
}

.dock-closed #dock-splitter {
    display: none;
}

/* The dock: one tool at a time, under the panel (P3). */
#dock {
    background-color: var(--c-surface-low);
    display: flex;
    flex: none;
    flex-direction: column;
    height: var(--dock-height, 40vh);
    min-height: 0;
}

.dock-closed #dock {
    height: auto;
}

/* Should the tabs ever be too many for the row - names in French just
   above a phone's width, or icons on the narrowest phone - it scrolls
   under the fold button rather than pushing it off. */
#dock-tabs {
    align-items: stretch;
    background-color: var(--c-surface-container);
    border-bottom: 1px solid var(--c-divider);
    display: flex;
    flex: none;
    min-height: 34px;
    overflow-x: auto;
    /* So a tab scrolled to is not left under the fold button. */
    scroll-padding-right: 36px;
    scrollbar-width: none;
}

#dock-tabs::-webkit-scrollbar {
    display: none;
}

#dock-toggle {
    background-color: var(--c-surface-container);
    position: sticky;
    right: 0;
}

/* Solid, to cover the tabs scrolled under it, but lit when pointed at
   as the other tools are. */
#dock-toggle:hover {
    background-image: linear-gradient(var(--hover-bg), var(--hover-bg));
}

.dock-closed #dock-tabs {
    border-bottom: 0;
}

/* Material's primary tabs, dense: a tool's tabs, not a page's. The open
   one in amber, over an indicator with rounded ends. */
.dock-tab {
    align-items: center;
    color: var(--c-on-surface-variant);
    cursor: pointer;
    display: flex;
    font-size: 14px;
    font-weight: 500;
    padding: 0 14px;
    /* For the activity dot and the indicator below. */
    position: relative;
    white-space: nowrap;
}

.dock-tab:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

.dock-tab:focus-visible {
    outline-offset: -2px;
}

.dock-tab.selected {
    color: var(--c-primary-text);
}

.dock-tab.selected::before {
    background-color: var(--c-primary);
    border-radius: 3px 3px 0 0;
    bottom: 0;
    content: '';
    height: 3px;
    left: 8px;
    position: absolute;
    right: 8px;
}

.dock-tool {
    align-items: center;
    color: var(--c-on-surface-variant);
    cursor: pointer;
    display: flex;
    font-size: 14px;
    justify-content: center;
    min-width: 36px;
}

.dock-tool:hover {
    background-color: var(--hover-bg);
    color: #fff;
}

#dock-body {
    flex: 1 1 0;
    min-height: 0;
    overflow: auto;
    /* Room below the end for the status message that rises over the
       dock's foot (panel.fitStatus). */
    padding-bottom: var(--status-rise, 0px);
}

.dock-closed #dock-body {
    display: none;
}

.dock-pane {
    box-sizing: border-box;
    min-height: 100%;
    padding: 8px 12px;
}

/* The Debugger: the CPU across the top - its registers and the
   instruction it will run next, side by side and the same height,
   stacked in a narrow dock - and memory under them, the whole width. */
.debug-top {
    align-items: stretch;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
}

.debug-box {
    display: flex;
    flex: 1 1 300px;
    flex-direction: column;
    min-width: 0;
}

.debug-box > #cpu-dump,
.debug-box > #instr-pane {
    box-sizing: border-box;
    flex: 1;
}

/* Step and Run to (#28), on the foot of the box of the instruction
   they act on: the pane gives up its rounded bottom to them, and they
   sit on a darker strip of its grey, so that the two read as one box.
   Each button keeps its box beside it; a row too narrow for both
   breaks between them, never inside one. */
.debug-box > #instr-pane {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

.instr-tools {
    align-items: center;
    background-color: var(--c-surface-container);
    border: 1px solid var(--c-outline-variant);
    border-radius: 0 0 var(--r-m) var(--r-m);
    border-top: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    padding: 6px 10px;
}

.instr-tool {
    align-items: center;
    display: flex;
    gap: 4px;
}

/* Material's outlined text field, dense, beside the button it feeds. */
.debug-field {
    background-color: var(--c-well);
    border: 1px solid var(--c-outline);
    border-radius: var(--r-xs);
    box-sizing: content-box;
    color: var(--c-on-surface);
    font-size: 14px;
    height: 30px;
    padding: 0 8px;
    text-align: right;
    /* Wide enough for its most digits: five for a count, four for an
       address. */
    width: 5.2ch;
}

#debug-run-to-address {
    text-align: left;
    text-transform: uppercase;
    width: 4.2ch;
}

#debug-run-to-address::placeholder {
    color: var(--c-disabled);
    text-transform: none;
}

.debug-field:hover {
    border-color: var(--c-on-surface);
}

.debug-field:focus {
    border-color: var(--c-primary);
    box-shadow: inset 0 0 0 1px var(--c-primary);
    outline: none;
}

/* The dump's own toolbar: one row, on one baseline, with the one
   control that destroys something kept apart at the far right. */
.mem-toolbar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

.mem-toolbar .section-label {
    margin: 0 4px 0 0;
}

/* The flags by letter, lit when set. */
.flag {
    color: var(--c-on-surface-variant);
}

.flag-set {
    background-color: #5c5c5c;
    border-radius: 3px;
    color: #fff;
    padding: 0 2px;
}

/* The machine's state, read out: wells of the darkest surface, under
   a quiet outline, as code is shown. */
#cpu-dump,
#mem-dump,
#instr-pane {
    background-color: var(--c-well);
    border: 1px solid var(--c-outline-variant);
    border-radius: var(--r-m);
    color: var(--c-on-surface);
    font-size: 14px;
    line-height: 24px;
    min-height: 24px;
    /* Fixed width text: a narrow window scrolls across it rather than
       cutting the right hand columns off. */
    overflow-x: auto;
    padding: 5px 12px;
}

/* A machine that is off: the registers' layout with dashes, the
   instruction a dash too, and the memory a page tall with what to do
   in the middle of it, so that switching on fills the boxes in rather
   than moving everything under them. */
.dump-off {
    color: var(--c-on-surface-variant);
}

.mem-off {
    align-items: center;
    display: flex;
    justify-content: center;
    /* Sixteen lines, as a page of a live machine's memory is. */
    min-height: calc(16 * 24px);
}

.dump-empty {
    color: var(--c-on-surface-variant);
    font-family: var(--font-ui);
    font-size: 14px;
    line-height: 1.6;
    margin: 0;
    max-width: 420px;
    padding: 0 16px;
    text-align: center;
    white-space: normal;
}

/* The Tutorial (docs/ui-design.md, U11): a bar of numbered lessons,
   one lesson at a time, in a column down the middle of the dock's own
   dark. Colour means one thing each: amber is what to press (Show - the
   orange a Show lights the machine with - and the lesson open), green
   is what you should see, blue is the story and the asides, and code
   sits on the darkest panel. */
.tutorial-pane {
    --reading-width: 780px;
    --t-text: #e2e4e7;
    --t-muted: #a3a8af;
    --t-edge: #3a3e44;
    --t-amber: #f9a23b;
    --t-amber-bg: rgba(255, 153, 0, 0.12);
    --t-green: #93d48c;
    --t-green-bg: rgba(110, 190, 100, 0.11);
    --t-blue: #8db9f2;
    --t-blue-bg: rgba(90, 140, 220, 0.12);
    color: var(--t-text);
    container-type: inline-size;
    font-size: 14px;
    line-height: 1.6;
    padding-top: 0;
}

/* The lessons, numbered, across the top: it stays in sight while a
   lesson scrolls under it. Its rule runs the dock's width; its tabs
   line up with the lesson's column under them. */
.lesson-bar {
    background-color: var(--c-surface-low);
    border-bottom: 1px solid var(--t-edge);
    display: flex;
    gap: 4px;
    margin: 0 -12px;
    overflow-x: auto;
    padding: 6px max(12px, calc((100% - var(--reading-width)) / 2 + 12px)) 0;
    position: sticky;
    scrollbar-width: none;
    top: 0;
    z-index: 1;
}

.lesson-tab {
    align-items: center;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    color: var(--t-muted);
    cursor: pointer;
    display: flex;
    flex: none;
    font: inherit;
    font-size: 13px;
    gap: 8px;
    margin-bottom: -1px;
    padding: 6px 10px 8px 6px;
    white-space: nowrap;
}

.lesson-tab:hover,
.lesson-tab:focus-visible {
    color: var(--t-text);
    outline: none;
}

.lesson-tab:focus-visible .lesson-num {
    box-shadow: 0 0 0 2px var(--t-amber);
}

.lesson-tab.current {
    border-bottom-color: var(--t-amber);
    color: var(--t-text);
}

.lesson-num {
    border: 1.5px solid currentColor;
    border-radius: 50%;
    box-sizing: border-box;
    flex: none;
    font-size: 12px;
    font-weight: bold;
    height: 22px;
    line-height: 19px;
    text-align: center;
    width: 22px;
}

.lesson-tab.current .lesson-num {
    background-color: var(--t-amber);
    border-color: var(--t-amber);
    color: #222;
}

/* Narrow, the other lessons are their numbers alone; their names are
   their tooltips. */
@container (max-width: 560px) {
    .lesson-tab:not(.current) .lesson-name {
        display: none;
    }
}

.tutorial-chapter {
    counter-reset: step;
    margin: 0 auto;
    max-width: var(--reading-width);
    padding: 16px 0 24px 0;
}

.lesson-kicker {
    color: var(--t-muted);
    font-size: 11px;
    font-weight: bold;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.lesson-title {
    color: #fff;
    font-size: 20px;
    line-height: 1.3;
    margin: 2px 0 6px 0;
}

.lesson-lead {
    color: var(--t-muted);
    margin: 0 0 16px 0;
}

/* Meet the Machine opens on the real thing, and why it matters. */
.lesson-intro {
    align-items: start;
    display: grid;
    gap: 16px;
    grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
    margin: 0 0 8px 0;
}

@container (max-width: 560px) {
    .lesson-intro {
        grid-template-columns: minmax(0, 1fr);
    }
}

.lesson-photo {
    margin: 0;
}

.lesson-photo img {
    border-radius: var(--r-s);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
    display: block;
    height: auto;
    width: 100%;
}

.lesson-photo figcaption {
    color: var(--t-muted);
    font-size: 12px;
    line-height: 1.45;
    margin-top: 6px;
}

.photo-credit {
    white-space: nowrap;
}

.photo-credit a {
    color: var(--t-muted);
}

.photo-credit a:hover {
    color: var(--t-text);
}

/* The story, and the asides: blue. */
.lesson-story,
.tutorial-note {
    background-color: var(--t-blue-bg);
    border-left: 3px solid var(--t-blue);
    border-radius: var(--r-s);
    margin: 0;
    padding: 10px 14px;
}

.tutorial-note {
    margin: 20px 0 0 0;
}

/* A lesson's steps come in a few groups, each named. */
.step-group {
    color: var(--t-muted);
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 0.06em;
    margin: 22px 0 10px 0;
    text-transform: uppercase;
}

.tutorial-code {
    background-color: var(--c-well);
    border: 1px solid var(--t-edge);
    border-radius: var(--r-s);
    color: #d6dbe0;
    font-size: 13px;
    line-height: 1.5;
    margin: 0 0 8px 0;
    overflow-x: auto;
    padding: 10px 14px;
}

/* The steps: numbered down a thin line, one lesson's numbers running on
   from group to group, as the steps refer to each other by them. The
   numbers are grey: they are where you are, not something to press. */
.steps {
    list-style: none;
    margin: 0;
    padding: 0;
}

.steps > li {
    counter-increment: step;
    margin: 0;
    min-height: 24px;
    padding: 1px 0 14px 38px;
    position: relative;
}

.steps > li::before {
    border: 1.5px solid #6b7078;
    border-radius: 50%;
    box-sizing: border-box;
    color: #c4c8ce;
    content: counter(step);
    font-size: 12px;
    font-weight: bold;
    height: 24px;
    left: 0;
    line-height: 21px;
    position: absolute;
    text-align: center;
    top: 0;
    width: 24px;
}

.steps > li:not(:last-child)::after {
    background-color: var(--t-edge);
    bottom: 2px;
    content: '';
    left: 11px;
    position: absolute;
    top: 28px;
    width: 2px;
}

.steps .tutorial-code {
    margin: 8px 0 0 0;
}

/* What you should see: green. */
.steps > li.result::before {
    background-color: var(--t-green);
    border-color: var(--t-green);
    color: #1a1a1a;
}

.steps > li.result > span {
    background-color: var(--t-green-bg);
    border-radius: var(--r-xs);
    color: var(--t-green);
    display: inline-block;
    padding: 1px 8px;
}

/* A step's Show: it points at what the step is about, an eye before its
   word - look - in the amber of something to press. */
/* Material's assist chip. */
.show-chip {
    align-items: center;
    background-color: var(--t-amber-bg);
    border: 1px solid var(--t-amber);
    border-radius: var(--r-s);
    color: var(--t-amber);
    cursor: pointer;
    display: inline-flex;
    font: inherit;
    font-size: 12px;
    gap: 4px;
    line-height: 18px;
    margin-left: 6px;
    padding: 0 9px 0 7px;
    vertical-align: 1px;
    white-space: nowrap;
}

.show-chip .icon {
    fill: currentColor;
    flex: none;
    height: 14px;
    width: 14px;
}

.show-chip:hover,
.show-chip:focus-visible {
    background-color: var(--t-amber);
    color: #222;
    outline: none;
}

/* On to the next lesson, at the end of each. */
/* Material's outlined button. */
.lesson-next {
    background: none;
    border: 1px solid var(--c-outline);
    border-radius: var(--r-full);
    color: var(--t-text);
    cursor: pointer;
    display: block;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    margin: 24px 0 0 auto;
    padding: 9px 20px;
}

.lesson-next:hover,
.lesson-next:focus-visible {
    border-color: var(--t-amber);
    color: var(--t-amber);
    outline: none;
}

/* The References tab reads as the Tutorial does: one column down the
   middle of the dock (U11). */
#tab-links > * {
    box-sizing: border-box;
    margin-left: auto;
    margin-right: auto;
    max-width: 780px;
}

/* The References tab's source code and further reading: a compact
   list, as a reference list is, with each entry's wrapped lines hanging
   under its first. Underlined only under the pointer, so that the
   column reads as titles rather than as a wall of underscores. */
.link-list {
    font-size: 14px;
    line-height: 1.45;
    list-style: none;
    margin: 0 0 12px 0;
    padding: 0 10px;
}

.link-list li {
    padding: 3px 0 3px 16px;
    position: relative;
}

.link-list li::before {
    color: var(--c-on-surface-variant);
    content: '\2022';
    left: 2px;
    position: absolute;
}

.link-list a {
    text-decoration: none;
}

.link-list a:hover,
.link-list a:focus-visible {
    text-decoration: underline;
}

/* Material's tonal button: the app's ordinary button, 32px, dense. */
.button {
    background-color: var(--c-tonal);
    border: 0;
    border-radius: var(--r-full);
    box-sizing: border-box;
    color: var(--c-on-tonal);
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 28px;
    padding: 2px 16px;
    text-align: center;
}

/* Every button answers the pointer, as the toolbar, the dock and the
   dialogs do: a state layer of its own text colour over its fill, so
   that a raised switch's amber, a live OFF/ON's green and a grey
   button each keep their own colour under it. */
.button:hover {
    background-image: linear-gradient(var(--layer-hover), var(--layer-hover));
}

.button:active {
    background-image: linear-gradient(var(--layer-press), var(--layer-press));
}

/* The hidden attribute has to beat author rules such as .mem-map's
   display: flex. */
[hidden] {
    display: none !important;
}

/* The memory map strip above the memory dump: one cell per 256-byte
   page of memory, so that a machine too large to print on one screen
   still fits on one screen. See docs/ms-basic-4k.md. */
.mem-map {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 2px;
    /* Its own element rather than part of the dump, so that its cells
       outlive the dump's repaints. See panel.renderMemMap. */
    margin: 5px 0 0 0;
}

.mem-page {
    background-color: #353535;
    border-bottom: 3px solid transparent;
    border-top: 3px solid transparent;
    cursor: pointer;
    flex-grow: 1;
    height: 18px;
    min-width: 10px;
}

/* Shaded by how much of the page is not zero, so that the shape of
   what is loaded - a program, a BASIC interpreter - is visible at a
   glance. */
.mem-page-1 { background-color: #555; }
.mem-page-2 { background-color: #787878; }
.mem-page-3 { background-color: #9c9c9c; }
.mem-page-4 { background-color: #c4c4c4; }

/* The page the dump is printing. An outline, so that it does not paint
   over the PC and SP marks below. No :hover rule: it would use the
   same property and hide this one on the very cell it marks. */
.mem-page-shown {
    outline: 2px solid var(--c-primary);
}

/* Where the program counter and the stack pointer are. These sit on
   cells that may be filled light or dark, and often on the outlined
   cell too, so they are brighter than the marks the dump below uses. */
.mem-page-pc { border-bottom-color: #3ddc63; }
.mem-page-sp { border-top-color: #4da3ff; }

/* The same two, on the byte itself inside the dump. */
.at-pc {
    background-color: #157a35;
    color: #fff;
}

.at-sp {
    background-color: #36c;
    color: #fff;
}

/* The bytes after the opcode that belong to the same instruction: the
   PC's green, paler, so the whole instruction reads as one piece. */
.at-operand {
    background-color: #8fd6a4;
    color: #222;
}

/* A button holding a current choice: Follow PC while it is on.
   Matches the selected dock tab. A helper
   button standing for a raised address switch reads the same way -
   amber means active, wherever it appears - filled, as Material's
   selected toggle button is. */
.button.selected,
.button.switch-on {
    background-color: var(--c-primary);
    color: var(--c-on-primary);
    font-weight: bold;
}

/* Material's filled button: the one action a place is for. */
.button.filled,
.asm-assemble {
    background-color: var(--c-primary);
    color: var(--c-on-primary);
}

/* A control that cannot be used just now. It keeps the pointer cursor
   on purpose: pressing it answers in the status bar with the reason it
   is grey (D19 in docs/ms-basic-4k.md). Coming after .selected means a
   button that is both reads as unavailable. Items in a menu and buttons
   in a dialog grey out by their own rules. */
.button.disabled,
.button.disabled.selected {
    background-color: var(--c-disabled-bg);
    background-image: none;
    color: var(--c-disabled);
    font-weight: normal;
}

/* The power switch, the one control that has to be found before
   anything else works, so the loudest thing on the helper board: a
   ring while off, green and glowing while on. No amber, which here
   means a raised address switch, and no red: switched off is not
   faulty. */
.button.power-button {
    background-color: var(--c-tonal);
    box-shadow: 0 0 0 2px var(--c-info);
    color: var(--c-on-tonal);
    font-weight: bold;
    letter-spacing: 1px;
    padding: 2px 18px;
}

.button.power-button.on {
    background-color: var(--c-success);
    box-shadow: 0 0 12px rgba(61, 220, 99, 0.6);
    color: var(--c-on-success);
}

/* Copy Link, for a moment after it has copied. The same green as a
   machine that is on. */
.dialog-button.copied,
.dialog-button.copied:hover {
    background-color: var(--c-success);
    color: var(--c-on-success);
}

/* The Teletype. A printer, not a screen: paper coloured stock, 72
   columns wide, scrolled to wherever the carriage is. The paper takes
   the dock's height, less the row of keys above it. It is the one
   surface outside the colour scheme (P11): a roll of the canary paper
   of the time, with a grain, a shadow where it comes up from behind
   the platen, and ink that sits a little soft in it. */
#tab-tty:not([hidden]) {
    display: flex;
    flex-direction: column;
    height: 100%;
}

#tty-paper {
    background-color: #ebe3cb;
    /* The grain: a fine noise, in the paper's own browns, that scrolls
       with what is printed on it. */
    background-attachment: local;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.45 0 0 0 0 0.38 0 0 0 0 0.25 0 0 0 0.09 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23g)'/%3E%3C/svg%3E");
    border-radius: var(--r-xs);
    /* Where the paper comes up from behind the platen. */
    box-shadow: inset 0 12px 10px -10px rgba(60, 45, 20, 0.35);
    color: #2a2620;
    cursor: text;
    flex: 1 1 0;
    font-size: 16px;
    line-height: 26px;
    min-height: 52px;
    overflow-x: auto;
    overflow-y: auto;
    padding: 5px 10px;
    /* For the empty paper's explanation, centred in it. */
    position: relative;
}

/* The keys a PC keyboard lacks, as the paper's toolbar. */
.tty-keys {
    align-items: center;
    display: flex;
    flex: none;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}

/* The empty paper's own explanation, until anything prints. */
.tty-empty {
    box-sizing: border-box;
    color: #8a8270;
    font-size: 14px;
    left: 50%;
    line-height: 1.6;
    max-width: 90%;
    pointer-events: none;
    position: absolute;
    text-align: center;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 520px;
}

/* The typeface struck through a ribbon: a little soft at its edges. */
#tty-text {
    text-shadow: 0 0 0.7px rgba(42, 38, 32, 0.55);
    white-space: pre;
}

/* The carriage. It only blinks while the machine is on, so a dark
   panel is visibly a dark panel. */
.tty-cursor {
    background-color: #2a2620;
    color: #ebe3cb;
    text-shadow: none;
}

.powered-on .tty-cursor {
    animation: tty-blink 1s step-end infinite;
}

@keyframes tty-blink {
    50% {
        background-color: transparent;
        color: #2a2620;
    }
}

/* Holds the dump and its hidden input, placed against it. */
.mem-dump-wrap {
    position: relative;
}

/* A byte in the memory dump is text you can type over, as in a hex
   editor: the I-beam says so, and pointing tints it - with a shadow
   laid over it, so that the marks of PC and SP show through. */
#mem-dump span[data-a] {
    border-radius: 3px;
    cursor: text;
}

#mem-dump span[data-a]:hover {
    box-shadow: inset 0 0 0 2em rgba(255, 255, 255, 0.16);
}

/* The byte picked for editing: filled with the amber that means
   active, over the pointer's tint and the marks of PC and SP alike. */
#mem-dump span.mem-selected,
#mem-dump span.mem-selected:hover {
    background-color: var(--c-primary);
    box-shadow: none;
    color: var(--c-on-primary);
}

/* Where the next hex digit goes: an underline cursor, the sign of
   typing over rather than inserting, blinking as cursors do. */
#mem-dump .mem-caret {
    animation: mem-caret-blink 1s steps(1) infinite;
    box-shadow: inset 0 -2px 0 var(--c-on-primary);
}

@keyframes mem-caret-blink {
    50% {
        box-shadow: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    #mem-dump .mem-caret {
        animation: none;
    }
}

/* The first digit typed, held until its second arrives. */
#mem-dump .mem-typed {
    font-weight: bold;
}

/* The Assembler tab (U2 in docs/assembler.md): a toolbar, the source
   with its line numbers and the listing beside it, the errors under. */
#tab-asm:not([hidden]) {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.asm-toolbar {
    align-items: center;
    display: flex;
    flex: none;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 6px;
}

/* The tabs on the editor's top edge: only a phone has them (U2). */
.asm-views {
    display: none;
}

.asm-work {
    background-color: var(--c-well);
    border: 1px solid var(--c-outline-variant);
    border-radius: var(--r-m);
    display: flex;
    flex: 1 1 0;
    min-height: 120px;
    overflow: hidden;
}

/* The source, its line numbers and its listing share one line grid:
   the same font, size, line height and top padding, and no wrapping,
   so that a line's number, colours and bytes are always on its row. */
.asm-editor,
.asm-listing {
    --asm-line: 26px;
    font-size: 16px;
    line-height: var(--asm-line);
    tab-size: 8;
}

.asm-editor {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
}

.asm-gutter,
.asm-listing,
.asm-highlight,
.asm-source {
    box-sizing: border-box;
    margin: 0;
    padding-bottom: 8px;
    padding-top: 8px;
}

/* The text area's scrollbars take room from its view, so it scrolls
   further than the layers beside and behind it; they get that room at
   their ends instead, measured by asmtab.matchScrollbars (H1). */
.asm-gutter,
.asm-listing,
.asm-highlight {
    padding-bottom: calc(8px + var(--asm-bar-below, 0px));
}

.asm-gutter {
    background-color: #1e1e1e;
    color: #7f7f7f;
    flex: none;
    overflow: hidden;
    padding-left: 6px;
    padding-right: 8px;
    text-align: right;
    width: 3.6em;
}

.asm-gutter-line,
.asm-listing-line,
.asm-line {
    display: block;
    height: var(--asm-line);
    white-space: pre;
}

.asm-gutter-error {
    color: var(--c-error);
    font-weight: bold;
}

/* The text area does the editing, its text transparent; the coloured
   copy behind it shows through (H1). */
.asm-code {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    position: relative;
}

.asm-highlight,
.asm-source {
    border: 0;
    font-size: inherit;
    height: 100%;
    inset: 0;
    letter-spacing: normal;
    line-height: inherit;
    overflow: auto;
    padding-left: 10px;
    padding-right: 10px;
    position: absolute;
    tab-size: inherit;
    white-space: pre;
    width: 100%;
}

.asm-highlight {
    color: #d8d8d8;
    overflow: hidden;
    padding-right: calc(10px + var(--asm-bar-beside, 0px));
    pointer-events: none;
}

/* As wide as its text, so a long line ends with the padding above, and
   the coloured copy scrolls as far right as the text area does; never
   narrower than the editor, so a mark across a line still spans it. */
.asm-highlight .asm-line {
    min-width: 100%;
    width: max-content;
}

.asm-source {
    background: transparent;
    caret-color: transparent;
    color: transparent;
    outline: none;
    resize: none;
}

/* The caret, a block over the character it is at, as the Teletype's
   carriage is: dark, the character light on it, blinking at the same
   rate. It holds still while the cursor moves, and for readers who ask
   their system for less motion. */
.asm-caret {
    background-color: #e6e6e6;
    color: var(--c-well);
    pointer-events: none;
    position: absolute;
    white-space: pre;
    z-index: 1;
}

.asm-caret.blinking {
    animation: asm-caret-blink 1s step-end infinite;
}

/* Its own blink, not the Teletype's: the character under it keeps its
   colour in the off half, rather than turning the paper's black. */
@keyframes asm-caret-blink {
    50% {
        background-color: transparent;
        color: transparent;
    }
}

@media (prefers-reduced-motion: reduce) {
    .asm-caret.blinking {
        animation: none;
    }
}

/* Ten characters of the editor's type, out of sight, to measure: their
   width, and the height of their box within a line, which is the
   caret's, as the Teletype's carriage covers a character's box. */
.asm-measure {
    left: 0;
    position: absolute;
    top: 0;
    visibility: hidden;
    white-space: pre;
}

/* Copy and Clear, in the editor's corner, as code boxes on the web
   have them. Clear stands a little apart: the two do very different
   things. */
.asm-corner {
    background-color: rgba(255, 255, 255, 0.08);
    border-radius: var(--r-full);
    color: var(--c-on-surface);
    height: 30px;
    opacity: 0.8;
    position: absolute;
    top: 6px;
    width: 30px;
    z-index: 2;
}

.asm-copy {
    right: 18px;
}

.asm-clear {
    right: 60px;
}

/* On the editor's dark, pointing lightens the icon, as the toolbar's
   icon buttons do. */
.asm-corner:hover,
.asm-corner:focus-visible {
    background-color: rgba(255, 255, 255, 0.16);
    color: #fff;
    opacity: 1;
}

/* Pointed at and focused look alike; the keyboard's focus also gets a
   ring, so it can be told where it is. */
.asm-corner:focus-visible {
    outline: 2px solid var(--c-primary);
    outline-offset: 1px;
}

/* Nothing to clear. */
.asm-corner:disabled,
.asm-corner:disabled:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: var(--c-on-surface);
    cursor: default;
    opacity: 0.3;
}

.asm-copied-icon,
.asm-copy.copied .asm-copy-icon {
    display: none;
}

.asm-copy.copied .asm-copied-icon {
    color: #81c784;
    display: block;
}

.asm-source::selection {
    background-color: rgba(130, 170, 255, 0.3);
    color: transparent;
}

.asm-line-error,
.asm-listing-error {
    background-color: rgba(255, 82, 82, 0.13);
}

/* The colours (H2), each 4.5:1 or more on the editor's dark. Bold
   alone is not enough for mnemonics: some monospaced fonts have no
   bold face, and the browser's stand-in barely shows. */
.asm-comment { color: #9a9a9a; font-style: italic; }
.asm-label { color: #82aaff; }
.asm-mnemonic { color: #ff9e80; font-weight: bold; }
.asm-pseudo { color: #c792ea; }
.asm-macro { color: #c792ea; font-style: italic; }
.asm-register { color: #5fd3bc; }
.asm-number { color: #e6d36b; }
.asm-string { color: #a5d6a7; }
.asm-operator { color: #c792ea; }
.asm-bad {
    color: #ff8a80;
    text-decoration: underline wavy #ff5370;
}

.asm-listing {
    background-color: #1c1c1c;
    border-left: 1px solid var(--c-outline-variant);
    color: #cfcfcf;
    flex: none;
    overflow: hidden;
    padding-left: 10px;
    padding-right: 10px;
    width: 27ch;
}

/* A row's parts as the source colours them (H2): the address in the
   grey of the line numbers, a position rather than data; the bytes,
   and a name's value after its =, in the colour of numbers. */
.asm-listing .asm-addr {
    color: #7f7f7f;
}

.asm-listing .asm-bytes {
    color: #e6d36b;
}

/* The line the caret is on, across the line numbers, the source and
   the listing, so that a line's bytes can be followed across to it
   (U2): lighter, over whatever the line already shows - an error's
   red too. The PC's line is marked already, in green, and keeps it. */
.asm-current:not(.asm-line-pc):not(.asm-gutter-pc):not(.asm-listing-pc) {
    box-shadow: inset 0 0 0 100vmax rgba(255, 255, 255, 0.07);
}

/* The line the program counter is on, in the green the Debugger's dump
   marks the PC with (U7): the line tinted, its number marked, its
   bytes in the listing filled. */
.asm-line-pc {
    background-color: rgba(61, 220, 99, 0.13);
}

.asm-gutter-line.asm-gutter-pc,
.asm-listing-line.asm-listing-pc {
    background-color: #157a35;
    color: #fff;
}

/* On the PC's green, the parts are its light text, as the rest is. */
.asm-listing-pc .asm-addr,
.asm-listing-pc .asm-bytes {
    color: inherit;
}

.asm-errors {
    flex: none;
    list-style: none;
    margin: 6px 0 0 0;
    max-height: 6.5em;
    overflow-y: auto;
    padding: 0;
}

.asm-error {
    background: none;
    border: 0;
    border-radius: var(--r-xs);
    color: var(--c-on-error-container);
    cursor: pointer;
    display: block;
    font-size: 13px;
    padding: 2px 4px;
    text-align: left;
    width: 100%;
}

.asm-error:hover,
.asm-error:focus-visible {
    background-color: var(--hover-bg);
}

/* Takes the soft keyboard on a phone without showing a text box; also
   used for the memory dump's input, beside it. */
.tty-hidden-input {
    border: 0;
    height: 1px;
    opacity: 0;
    padding: 0;
    position: absolute;
    width: 1px;
}

/* Each dock tab is an icon and its name (U1 in docs/assembler.md). */
.dock-tab .icon {
    height: 18px;
    margin-right: 6px;
    width: 18px;
}

/* Marks the Teletype tab while its machine is printing and you are
   looking at something else. Out of the flow, so the tab does not move. */
.dock-tab.has-activity::after {
    background-color: var(--c-primary);
    border-radius: 50%;
    content: '';
    height: 7px;
    position: absolute;
    right: 4px;
    top: 8px;
    width: 7px;
}

/* The status line along the foot of the app. Everything the simulator
   wants to tell you - the power went off, a board was installed, a
   tape was loaded, something would not work - says it here, so there
   is one place to look. It is never hidden (P7).

   It takes one line's height in the layout, whatever it says: a message
   that needs more grows upwards, over the foot of the dock, rather than
   pushing the page up - which shrank the panel, and the 3D view with
   it, each time a two-line message gave way to a one-line one. */
#status-bar {
    background-color: var(--c-surface-container);
    box-sizing: border-box;
    color: var(--c-on-surface);
    flex: none;
    font-size: 14px;
    height: 33px;
    line-height: 20px;
    position: relative;
    z-index: 3;
}

#status-text {
    background-color: inherit;
    border-top: 1px solid var(--c-divider);
    bottom: 0;
    box-sizing: border-box;
    left: 0;
    min-height: 33px;
    padding: 6px 12px;
    position: absolute;
    right: 0;
}


/* The narrowest phones have no room to spare in the toolbar, so the
   logo goes, as it did on every phone before v1.7.0. */
@media (max-width: 374px) {
    #header-title {
        display: none;
    }
}

/* Opened off the disk, where nothing else can work, the page is this
   alone (see index.html). */
.needs-server #app,
.needs-server dialog {
    display: none !important;
}

.needs-server body {
    box-sizing: border-box;
    padding: 15vh 16px 0;
}

#file-notice {
    background-color: var(--c-warn-container);
    border-radius: var(--r-m);
    box-sizing: border-box;
    color: var(--c-on-warn-container);
    font-size: 16px;
    line-height: 1.6;
    margin: 0 auto;
    max-width: 36em;
    padding: 20px 24px;
}

#file-notice a,
#file-notice code {
    color: #fff;
}

#file-notice code {
    white-space: nowrap;
}

#status-bar.status-warn {
    background-color: var(--c-warn-container);
    color: var(--c-on-warn-container);
}

#status-bar.status-error {
    background-color: var(--c-error-container);
    color: var(--c-on-error-container);
}

#mem-window-label {
    color: var(--c-on-surface-variant);
    font-size: 14px;
    padding: 0 6px 0 0;
    white-space: nowrap;
}

/* Phones: the same app, packed down (P9). The panel takes the height
   its width gives it and the dock has the rest, so there is nothing to
   drag. Everything wide - the dumps, the teletype paper - already
   scrolls inside its own box. */
@media (max-width: 700px) {
    #stage {
        flex: none;
        padding: 6px;
    }

    #panel {
        flex: none;
        height: auto;
    }

    /* In 3D the stage gives way before the dock does (#29): it may
       shrink, and the dock keeps a floor of its own, so that a tall 3D
       view, the switch strip and a two-line status message cannot leave
       the open tab no room at all. The 2D panel cannot shrink, so in
       2D the stage keeps its height, strip and all. */
    .view-3d #stage {
        flex: 0 1 auto;
        min-height: 0;
    }

    /* The 3D view has no shape of its own to keep: on a phone it takes
       a near-square of the width, as the panel takes its own shape -
       but it is the one part of the stage that shrinks, since the
       camera draws the machine at any shape, which the panel's
       artwork cannot. */
    #stage3d {
        aspect-ratio: 5 / 4;
        flex: 0 1 auto;
        min-height: 140px;
    }

    /* The switch strip, packed down (#29). The longer names shortened;
       the full ones stay, out of sight, for a screen reader. */
    .label-short {
        display: inline;
    }

    .label-long {
        clip-path: inset(50%);
        height: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
        width: 1px;
    }

    .strip-row + .strip-row {
        margin-top: 6px;
    }

    .strip-body .button {
        min-width: 0;
    }

    .strip-body .button.power-button {
        padding: 2px 10px;
    }

    /* The fold tab is small to look at, but takes a thumb: its hit area
       reaches past its edges, with no room taken from the page. */
    .strip-tab {
        position: relative;
    }

    .strip-tab::after {
        content: '';
        inset: -10px -16px -4px;
        position: absolute;
    }

    #view-tools {
        height: 30px;
    }

    #dock-splitter {
        display: none;
    }

    #dock {
        flex: 1 1 0;
        height: auto;
    }

    /* The floor the 3D view gives way to (#29). */
    .view-3d #dock {
        min-height: 30vh;
        min-height: 30dvh;
    }

    .dock-closed #dock,
    .view-3d.dock-closed #dock {
        flex: none;
        min-height: 0;
    }

    /* Five tabs across a phone: the icons alone. The names stay for
       screen readers, and as each tab's tooltip. */
    .dock-tab .icon {
        margin-right: 0;
    }

    .dock-tab-name {
        clip-path: inset(50%);
        height: 1px;
        overflow: hidden;
        position: absolute;
        white-space: nowrap;
        width: 1px;
    }

    /* The Teletype's paper takes the whole of the open tab, and its
       keys go under it, to scroll down to: three rows of them above
       it left a phone a slit of paper. */
    #dock-body {
        container-type: size;
    }

    #tab-tty:not([hidden]) {
        height: auto;
    }

    /* As tall as the dock shows, less the pane's top padding; the
       keys come after it, in the flow, so that scrolled to the end
       they clear a status message risen over the dock. */
    #tty-paper {
        flex: none;
        height: calc(100cqh - 8px);
        order: 1;
    }

    .tty-keys {
        margin: 8px 0 0;
        order: 2;
    }

    /* The Assembler's source and listing take turns. */
    #tab-asm .asm-listing {
        display: none;
    }

    #tab-asm.show-listing .asm-listing {
        display: block;
        flex: 1;
        overflow-y: auto;
        width: auto;
    }

    /* The bytes keep the source's line numbers beside them, the same
       column, scrolled with them: line 12's bytes are on line 12. */
    #tab-asm.show-listing .asm-editor {
        flex: none;
    }

    #tab-asm.show-listing .asm-code {
        display: none;
    }

    /* Which of the two is open, as the top edge of the editor's box:
       cut from its own greys, square and flush, so that they read as
       part of the editor - not as the dock's tabs above, nor the
       toolbar's buttons beside. The open one is the pane under it,
       carried up into the tab, its name in bold; the other is the
       darker grey of the gutter, behind. */
    .asm-views {
        border: 1px solid var(--c-outline-variant);
        border-bottom: 0;
        border-radius: var(--r-m) var(--r-m) 0 0;
        display: flex;
        flex: none;
        overflow: hidden;
    }

    .asm-view {
        background-color: var(--c-surface-container);
        border: 0;
        border-bottom: 1px solid var(--c-outline-variant);
        color: var(--c-on-surface-variant);
        cursor: pointer;
        flex: 1 1 0;
        font-size: 14px;
        line-height: 20px;
        margin: 0;
        min-width: 0;
        overflow: hidden;
        padding: 6px 8px;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .asm-view + .asm-view {
        border-left: 1px solid var(--c-outline-variant);
    }

    .asm-view:hover {
        background-color: var(--c-surface-high);
    }

    .asm-view[aria-selected="true"] {
        border-bottom-color: transparent;
        color: var(--c-on-surface);
        cursor: default;
        font-weight: bold;
    }

    #asm-view-source[aria-selected="true"] {
        background-color: var(--c-well);
    }

    #asm-view-bytes[aria-selected="true"] {
        background-color: #1c1c1c;
    }

    .asm-view:focus-visible {
        outline: 2px solid var(--c-primary);
        outline-offset: -2px;
    }

    /* The box's top corners are the tabs'. */
    #tab-asm .asm-work {
        border-top: 0;
        border-top-left-radius: 0;
        border-top-right-radius: 0;
    }

    /* The labels go, the icons and the installed size stay. */
    #toolbar .tool-label,
    #toolbar .tool-code {
        display: none;
    }

    /* The machine alone, from the <picture> (index.html): the name
       would take the room the menus need. At the same height, it is
       39px across, and with no margin past the toolbar's gap it fits
       the room the toolbar has to spare at 375px. */
    #header-title {
        margin-right: 0;
    }

    /* The strip packed tight, so the dock keeps some room: the levers
       as they fall, and the sixteen address switches eight to a row,
       still a thumb wide each. The octal groups give way to the grid. */
    .strip-body {
        padding: 6px;
    }

    .strip-row {
        gap: 4px 8px;
    }

    .strip-body .button {
        padding: 2px 6px;
    }

    .strip-address {
        display: grid;
        gap: 4px;
        grid-template-columns: repeat(8, 1fr);
    }

    .strip-address .octal {
        display: contents;
    }

    /* Eight to a row already puts the high byte above the low. */
    .strip-address .byte-divider {
        display: none;
    }

    .strip-address .button {
        min-width: 0;
        padding: 2px 0;
    }

    /* PROTECT is for now and then, and the dock needs the height more;
       the panel's own lever stands apart enough to tap. */
    .strip-protect {
        display: none;
    }

}
