/* knockport, candidate terminal.
   Direction validated in mockups and in the design system (brand/DESIGN.md):
   dark by default, a terminal on a radial gradient, solid gray dots (red,
   yellow, green is for screenshot tutorials), IBM Plex Mono. The light theme
   is documented in DESIGN.md but not toggled here, so the terminal stays
   dark. */

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/terminal/ibm-plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  /* `swap` would cause a visible reflow on a fully monospace page.
     With the preload in the head, the font arrives in time. */
  font-display: optional;
}

:root {
  --bg: #0b0d0e;
  --fg: #e8e6e1;
  --dim: #7d8285;
  --accent: #7fd6d1;
  --stage: radial-gradient(115% 80% at 50% 0%, #171c1e 0%, #0a0c0d 70%);
  --chrome: rgba(232, 230, 225, 0.045);
  --dot: #3d4447;
  --edge: rgba(232, 230, 225, 0.1);
  --shadow: 0 20px 45px rgba(0, 0, 0, 0.6);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--stage);
  color: var(--fg);
  font: 14px/1.62 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}

.stage {
  /* dvh not vh: on mobile, the address bar would eat the input. */
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
}

.window {
  width: 100%;
  /* A flex item shrinks below its declared width by default. Without this,
     the window didn't take full width on mobile. */
  flex: 0 0 auto;
  max-width: 82ch;
  /* A minimum height: without it, the window on first load is a small box
     floating in the void, reading as a dialog box rather than a terminal. */
  min-height: min(30rem, calc(100dvh - 64px));
  max-height: calc(100dvh - 64px);
  background: var(--bg);
  border: 1px solid var(--edge);
  border-radius: 8px;
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: var(--chrome);
  border-bottom: 1px solid var(--edge);
  flex: none;
}

.dot { width: 9px; height: 9px; border-radius: 99px; background: var(--dot); }
.chrome .title { margin-left: 10px; font-size: 11px; color: var(--dim); }

.body {
  padding: 14px 16px 16px;
  overflow-y: auto;
  flex: 1;
}

.scrollback {
  margin: 0 0 10px;
  white-space: pre-wrap;
  word-break: break-word;
  font: inherit;
}

.prompt { display: flex; gap: 8px; align-items: baseline; }
.sigil { color: var(--accent); white-space: pre; flex: none; }

input {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  padding: 0;
}
input:focus { outline: none; }
input:disabled { opacity: 0.5; }

.dim { color: var(--dim); }
.bold { font-weight: 600; }
.accent { color: var(--accent); }

/* The skip link is the first focusable element and becomes visible as soon
   as it has focus. Without JavaScript there is no terminal at all, so it is
   the only path for those visitors. */
.skip { position: absolute; left: -9999px; color: var(--accent); }
.skip:focus {
  position: static;
  display: block;
  margin-bottom: 12px;
  text-align: center;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

/* Below 768px the window loses its frame and takes the full screen. A window
   within a window wastes a phone's screen. */
@media (max-width: 768px) {
  .stage { padding: 0; align-items: stretch; }
  .window {
    max-width: none;
    max-height: none;
    min-height: 100dvh;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .chrome { position: sticky; top: 0; z-index: 1; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
