.stage__terminal {
  --prompt-height: 2.1rem;
  position: relative;
  /* The character screen is positioned against this box, so this box is what
     stops it painting over the drawing above it. */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border-left: 1px solid var(--edge);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
}

@media (max-width: 46rem) {
  .stage__terminal {
    border-left: none;
    border-top: 1px solid var(--edge);
  }
}

.terminal__output {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 0.6rem 0.75rem;
  white-space: pre-wrap;
  word-break: break-word;
}

/* In Apple mode the terminal pane is one row: the line you are typing. The
   transcript is not here at all — it is drawn into the bottom of the screen
   above, because on the hardware the text window was the bottom of the same
   picture rather than a second display beside it.

   The line you type is the one part that stays a real, visible input. It was
   drawn on the character grid at first, with the actual field hidden behind the
   canvas — one pixel and clipped, then full size and transparent. Both are
   fragile ways to hide a field and it showed: focus was taken and never came
   back, keystrokes reached nothing, and the page looked frozen. A visible field
   costs one row of the illusion and buys focus, selection, an input method and a
   phone keyboard, all of which the browser does properly. */
body[data-mode="apple"] .stage__terminal { background: #000; border-color: #1d1d1d; }
body[data-mode="apple"] .terminal__output { display: none; }

/* FULLSCREEN hides the transcript — never the field you type into. */
body[data-screen="full"] .terminal__output { display: none; }

/* The row you type on, once it has been moved onto the screen.
 *
 * The field is full size, on top, and hit-testable: it is the element at its own
 * centre and a test says so in every screen mode. Only its *text* is
 * transparent, because the same characters are being drawn underneath it out of
 * the machine's own glyphs, one row of the picture like any other. Hiding the
 * field is what cost days; hiding the text it duplicates costs nothing.
 *
 * Top and height come from the renderer as percentages of the glass. Nothing
 * here needs the pixel size of anything.
 *
 * Every selector below carries `body[data-mode="apple"]`, matching the rules
 * further up that give this field its green. Without it these are one class less
 * specific and the field paints its own text over the glyphs — the third time
 * the cascade has quietly decided something in this file. */
body[data-mode="apple"] .glass .terminal__prompt {
  position: absolute;
  left: 0;
  right: 0;
  padding: 0;
  border-top: 0;
  z-index: 2;
}

body[data-mode="apple"] .glass .terminal__caret { display: none; }

body[data-mode="apple"] .glass .terminal__prompt input {
  height: 100%;
  padding: 0;
  color: transparent;
  caret-color: transparent;
  /* The field's text is invisible, but its *metrics* are not: an input method
     opens its candidate window at the field's caret, and the reader is looking
     at the drawn cursor. Measured before this was set, the field's twenty
     characters were half the width of the twenty on screen and started two
     cells to the left — the candidate window would have opened around the
     middle of the row while the cursor sat at the end of it.
     One cell is a fortieth of the screen, so a character has to advance 2.5cqw:
     a monospace advances about 0.6em, and the rest is made up in tracking. The
     padding is the two cells the drawn prompt occupies, which the field does not
     contain. */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 3.4cqh;
  letter-spacing: calc(2.5cqw - 0.6em);
  padding-left: 5cqw;
}

/* At eighty columns a cell is an eightieth of the screen, so the invisible
   field's advance halves with it — same arithmetic as above with 1.25cqw as the
   cell. Without this the IME candidate window and the browser caret sit at
   forty-column positions over an eighty-column row: twice as far right as the
   drawn cursor the reader is watching. */
body[data-mode="apple"][data-columns="80"] .glass .terminal__prompt input {
  letter-spacing: calc(1.25cqw - 0.6em);
  padding-left: 2.5cqw;
}

/* Except with no text window under it, where there is nothing drawn to read and
   the field shows its own text — see promptRowBox() for why that deviation is
   deliberate. */
body[data-mode="apple"][data-screen="full"] .glass .terminal__prompt input {
  color: #6f6;
  caret-color: #6f6;
  background: rgb(0 0 0 / 0.55);
}
body[data-mode="apple"] .terminal__prompt {
  margin-top: auto;
  height: var(--prompt-height);
  border-top: 1px solid #1d1d1d;
  color: #6f6;
}
body[data-mode="apple"] .terminal__caret,
body[data-mode="apple"] .terminal__prompt input { color: #6f6; }

.line--echo { color: var(--ink-dim); }
.line--meta { color: var(--accent); }
.line--error { color: var(--error); }

.terminal__prompt {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  /* The border goes on the prompt row itself and the padding sits inside it, so
     the rule does not stretch across the padding of the parent. */
  border-top: 1px solid var(--edge);
  padding: 0.5rem 0.75rem;
}

.terminal__caret { color: var(--accent); }

.terminal__prompt input {
  flex: 1;
  min-width: 0;
  font: inherit;
  color: var(--ink);
  background: transparent;
  border: 0;
  padding: 0;
  outline: none;
}
