/* ==========================================================================
   memori tty01 — Terminal chrome
   The tube (.tty), the scrollback (.screen), the prompt line with its
   block caret, ghost suggestions, output blocks, the statusbar and the
   CRT overlay. Pure terminal: no cards, no shadows, hairlines only.
   ========================================================================== */

/* ---- The machine ------------------------------------------------------------ */
.tty {
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

/* ---- Screen: scrollback + live prompt ---------------------------------------- */
.screen {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--screen-pad);
  padding-bottom: 12px;
  cursor: text;
}

.buffer {
  max-width: var(--buffer-max);
}

/* Every executed command leaves an echo line + its output. */
.block {
  margin-bottom: 1.35em;
}
.block .out:empty {
  display: none;
}

/* The echoed `visitor@memori:~$ ls` line above each output. */
.echo {
  color: var(--soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.echo .ps1 {
  color: var(--faint);
}
.echo .ps1 b {
  font-weight: 400;
  color: var(--accent-hi);
}

/* Plain output line. */
.out-line {
  color: var(--soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.out-line--cream { color: var(--cream); }
.out-line--faint { color: var(--faint); }

/* Errors are ember, never red — brand rule. Optional shake. */
.out-error {
  color: var(--accent-hi);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.out-error.shake {
  animation: shake 0.3s var(--ease-out);
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  60% { transform: translateX(3px); }
  80% { transform: translateX(-2px); }
}

/* ---- The prompt line -------------------------------------------------------------
   A real <input> sits over the line with transparent ink (a11y, IME, mobile
   keyboards); the visible text is a mirror. The caret is our own block —
   CRT-accurate 1.06 s blink — and slides with the selection. */
.promptline {
  display: block;
}

.line {
  position: relative;
  max-width: var(--buffer-max);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ps1 {
  color: var(--soft);
  white-space: pre-wrap;
}
.ps1 .user { font-weight: 600; }
.ps1 .host { font-weight: 600; color: var(--accent-hi); }
.ps1 .dim  { color: var(--faint); }
.ps1 .path { font-weight: 500; color: var(--cream); }

/* The real input: invisible, but it owns focus, selection and the IME. */
.cmdline {
  position: absolute;
  inset: 0;
  width: 100%;
  border: 0;
  background: transparent;
  color: transparent;
  caret-color: transparent;
  font: inherit;
  font-size: var(--fs-input-touch);
  line-height: inherit;
  letter-spacing: inherit;
}
.cmdline:focus {
  outline: none;
}
.cmdline::selection {
  background: var(--accent);
  color: transparent;
}

.mirror,
.cursor,
.ghost {
  pointer-events: none;
}

.cursor {
  display: inline-block;
  width: 0.62em;
  height: 1.15em;
  vertical-align: text-bottom;
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--hair-strong);
  transition: background-color var(--dur-fast) var(--ease-out);
}
/* Focused: a solid ember block. Unfocused: a hollow outline. */
.line.is-focused .cursor {
  background: var(--accent);
  box-shadow: none;
}
.line.is-focused .cursor {
  animation: blink var(--blink) steps(1, end) infinite;
}
/* Typing pauses the blink — solid while you work, blink resumes ~0.6s after. */
.line.is-typing .cursor {
  animation: none;
}
@keyframes blink {
  0%, 57%  { opacity: 1; }
  58%, 100% { opacity: 0.08; }
}

/* Ghost suggestion — the grey fish-style text ahead of the caret. */
.ghost {
  color: var(--ghost);
  white-space: pre-wrap;
}
.ghost.pop {
  animation: ghostFlicker 0.34s steps(3, end);
}
@keyframes ghostFlicker {
  0%   { opacity: 0; }
  40%  { opacity: 1; }
  60%  { opacity: 0.35; }
  100% { opacity: 1; }
}
/* Tab commit: one ember flash on the caret. */
.cursor.flash {
  animation: caretFlash 0.22s var(--ease-pop);
}
@keyframes caretFlash {
  0%   { transform: scaleY(1); }
  40%  { transform: scaleY(1.35); background: var(--accent-hi); }
  100% { transform: scaleY(1); }
}

/* ---- Boot: the wordmark + MOTD ------------------------------------------------ */
.boot {
  margin-bottom: 1.6em;
}
.boot-banner {
  color: var(--accent);
  line-height: 1.24;
  white-space: pre;
  font-weight: 600;
  overflow-x: auto;
  padding-bottom: 0.3em;
}
.boot-banner .dot {
  color: var(--cream);
}
.boot-motd .out-line {
  margin-bottom: 0.15em;
}
.boot-motd .rule {
  color: var(--faint);
}

/* ---- ls: flowing columns, dirs in ember with a trailing slash ------------------ */
.out-ls {
  display: flex;
  flex-wrap: wrap;
  column-gap: 28px;
}
.out-ls .ent {
  color: var(--cream);
  white-space: pre;
}
.out-ls .ent--dir {
  color: var(--accent-hi);
  font-weight: 500;
}
.out-ls .ent--hidden {
  color: var(--faint);
}

/* A text that runs a command when clicked — the terminal's <a>.
   Buttons reset to look like their surroundings; hover is the only tell. */
button.cmdlink {
  border: 0;
  background: transparent;
  font: inherit;
  color: inherit;
  padding: 0;
  cursor: pointer;
  text-align: left;
  white-space: pre;
}
button.cmdlink:hover {
  color: var(--accent-hi);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.out-ls .ent button.cmdlink,
.out-lsl .n button.cmdlink {
  color: inherit;
}
.out-ls .ent--dir button.cmdlink:hover,
.out-lsl .n button.cmdlink:hover {
  color: var(--accent);
}

/* ls -l — one file per row: date · size · tags · name */
.out-lsl {
  display: grid;
  grid-template-columns: max-content max-content 1fr;
  column-gap: 20px;
}
.out-lsl .d { color: var(--faint); white-space: pre; }
.out-lsl .s { color: var(--soft); text-align: right; white-space: pre; }
.out-lsl .n { color: var(--cream); overflow-wrap: anywhere; }
.out-lsl .n .tag { color: var(--faint); }
.out-lsl .n .tag b { font-weight: 400; color: var(--accent-hi); }

/* ---- File header/footer around cat output --------------------------------------- */
.filehead {
  margin-bottom: 1em;
}
.filehead .fname {
  color: var(--accent-hi);
  font-weight: 600;
  overflow-wrap: anywhere;
}
.filehead .fmeta {
  color: var(--faint);
  overflow-wrap: anywhere;
}
.filehead .fmeta b {
  font-weight: 400;
  color: var(--accent-hi);
}
.filehead .frule {
  border: 0;
  border-top: 1px solid var(--hair);
  margin-top: 0.55em;
}
.filefoot {
  margin-top: 1.2em;
  color: var(--faint);
}
.filefoot a { color: var(--accent-hi); }

/* ---- man page ---------------------------------------------------------------------- */
.man {
  border: 1px solid var(--hair);
  border-radius: var(--radius-l);
  padding: 1.2em 1.4em;
  background: var(--bg-2);
}
.man-title {
  display: flex;
  justify-content: space-between;
  gap: 1em;
  color: var(--faint);
  border-bottom: 1px solid var(--hair);
  padding-bottom: 0.6em;
  margin-bottom: 0.8em;
  overflow-wrap: anywhere;
}
.man-line {
  color: var(--soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.man-line b {
  font-weight: 600;
  color: var(--cream);
}
.man-line .cmd {
  font-weight: 600;
  color: var(--accent-hi);
}
.man-line .dim {
  color: var(--faint);
}
.man-line--sec {
  margin-top: 0.9em;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.08em;
}

/* ---- mail composer echoes ------------------------------------------------------------ */
.mail-hint {
  color: var(--faint);
}

/* ---- history list ---------------------------------------------------------------------- */
.out-history {
  color: var(--faint);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.out-history b {
  font-weight: 400;
  color: var(--soft);
}

/* ---- The statusbar — persistent chrome under the tube ----------------------------------- */
.statusbar {
  flex: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 18px;
  min-height: var(--statusbar-h);
  padding: 4px var(--screen-pad);
  border-top: 1px solid var(--hair);
  background: var(--bg-2);
  font-size: var(--fs-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--faint);
  user-select: none;
}
.statusbar .sb-path {
  color: var(--soft);
  text-transform: none;
  letter-spacing: 0;
}
.statusbar .sb-path b { font-weight: 400; color: var(--accent-hi); }
.statusbar .sb-brand { color: var(--faint); }
.statusbar .sb-brand b { font-weight: 400; color: var(--accent); }
.statusbar button {
  border: 0;
  background: transparent;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: var(--faint);
  padding: 2px 0;
  cursor: pointer;
}
.statusbar button:hover { color: var(--cream); }
.statusbar button .st { color: var(--accent-hi); }
.statusbar button[aria-pressed="false"] .st { color: var(--faint); }
.statusbar .sb-spring { flex: 1; }
.statusbar .sb-hint { color: var(--faint); }
.statusbar .sb-hint kbd {
  font: inherit;
  color: var(--soft);
  border: 1px solid var(--hair-strong);
  border-radius: var(--radius-s);
  padding: 0 5px;
}

/* ---- The CRT overlay — scanlines + vignette + faint flicker ------------------------------
   Purely decorative: pointer-events none, aria-hidden, gated by html.crt-on.
   ------------------------------------------------------------------------------ */
.crt {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur-med) var(--ease-out);
}
html.crt-on .crt {
  opacity: 1;
}
/* scanlines */
.crt::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.16) 0px,
    rgba(0, 0, 0, 0.16) 1px,
    transparent 1px,
    transparent 3px
  );
  mix-blend-mode: multiply;
}
/* vignette + the faintest rolling flicker */
.crt::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent 58%,
    rgba(0, 0, 0, 0.26) 100%
  );
  animation: crtFlicker 3.7s steps(24) infinite;
}
@keyframes crtFlicker {
  0%, 100% { opacity: 1; }
  47% { opacity: 0.93; }
  52% { opacity: 1; }
  83% { opacity: 0.96; }
}
/* phosphor bloom while the tube is on — whisper-quiet */
html.crt-on .screen {
  text-shadow: 0 0 9px color-mix(in srgb, var(--accent) 10%, transparent);
}

/* ---- noscript ---------------------------------------------------------------------------- */
.noscreen {
  max-width: var(--buffer-max);
  margin: 0 auto;
  padding: var(--screen-pad);
  height: 100dvh;
  overflow: auto;
}
.noscreen h1 {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--accent-hi);
  margin-bottom: 1em;
}
.noscreen p, .noscreen li {
  color: var(--soft);
  margin-bottom: 0.6em;
}
.noscreen ul {
  list-style: none;
}
.noscreen .n-date { color: var(--faint); padding-right: 1.2em; }

/* ---- Small screens ------------------------------------------------------------------------ */
@media (max-width: 700px) {
  .boot-banner {
    font-size: 0.31rem;
    line-height: 1.3;
  }
  .screen {
    padding-bottom: 10px;
  }
  .statusbar .sb-hint {
    display: none;
  }
}
