:root {
  --bg: #050705;
  --phosphor: #7dd88f;
  --phosphor-dim: rgba(125, 216, 143, 0.30);
  --bleach: #eafff0;
  --alert: #ff5a36;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "DejaVu Sans Mono", monospace;

  --measure: 62ch;
  --pad: clamp(1.25rem, 4vw, 3rem);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--phosphor);
}

body {
  font-family: var(--mono);
  font-size: clamp(0.95rem, 0.9rem + 0.35vw, 1.05rem);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.screen {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  padding: var(--pad);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

/* --- canonical manifesto (also the no-JS / reduced-motion view) --- */

.manifesto {
  width: 100%;
  max-width: var(--measure);
  margin: 0 auto;
  padding: 3rem 0;
}

.manifesto__mark {
  font-size: clamp(1.6rem, 1rem + 3.5vw, 2.75rem);
  letter-spacing: 0.42em;
  font-weight: 400;
  color: var(--bleach);
  margin: 0 0 3rem;
  text-indent: 0.42em;
}

.stanza {
  margin: 0 0 2.5rem;
}

.stanza p {
  margin: 0;
}

.stanza[data-emphasis] p {
  color: var(--bleach);
}

/*
 * Flash guard. The manifesto is hidden from sight the moment we know JS is
 * available, and stays hidden until main.js adds `revealed` to <html> — after
 * the boot sequence, or immediately under reduced motion. With JS disabled the
 * root keeps `no-js`, neither rule matches, and the manifesto renders normally.
 *
 * Hidden here means visually hidden only: the text stays in the accessibility
 * tree so screen-reader users get the full manifesto while sighted users watch
 * the animation.
 */
html.js #manifesto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

html.js.revealed #manifesto {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  white-space: normal;
}

/* --- cold open ---------------------------------------------------------- */

.boot {
  width: 100%;
  max-width: var(--measure);
  margin: 0 auto;
  text-align: center;
}

.boot[hidden] { display: none; }

.boot__log {
  margin: 0 0 3rem;
  font-family: var(--mono);
  font-size: 0.82em;
  line-height: 1.9;
  color: var(--phosphor-dim);
  white-space: pre;
  text-align: left;
  display: inline-block;
  min-height: 5.7em;
}

.boot__mark {
  opacity: 0;
  transition: opacity 0.18s linear;
}

.boot__mark[data-landed="true"] { opacity: 1; }

.boot__word {
  margin: 0;
  font-size: clamp(1.5rem, 0.9rem + 3.6vw, 2.9rem);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: var(--bleach);
}

.boot__tag {
  margin: 0.75rem 0 0;
  color: var(--phosphor-dim);
  letter-spacing: 0.12em;
}

.boot__prompt {
  margin: 4rem 0 0;
  color: var(--phosphor);
  letter-spacing: 0.06em;
}

.boot__prompt[hidden] { display: none; }

/* --- transmission viewport ---------------------------------------------- */

.tx {
  width: 100%;
  max-width: var(--measure);
  margin: 0 auto;
  border: 1px solid var(--phosphor-dim);
  background: rgba(125, 216, 143, 0.015);
}

.tx[hidden] { display: none; }

.tx__bar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.55rem 0.9rem;
  font-size: 0.74em;
  letter-spacing: 0.1em;
  color: var(--phosphor-dim);
  border-bottom: 1px solid var(--phosphor-dim);
  text-transform: lowercase;
}

.tx__bar--foot {
  border-bottom: none;
  border-top: 1px solid var(--phosphor-dim);
}

.tx__pct { color: var(--phosphor); }

/*
 * Fixed-height viewport. Only the last few lines sit at full brightness; the
 * mask fades everything above them out rather than clipping abruptly.
 */
.tx__view {
  height: 46vh;
  min-height: 15rem;
  padding: 1.5rem 1.25rem;
  overflow: hidden;
  scroll-behavior: smooth;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 100%);
}

.tx__line {
  margin: 0 0 0.35rem;
  color: var(--phosphor);
  transition: opacity 0.5s linear, color 0.5s linear;
  min-height: 1.7em;
}

.tx__line--em { color: var(--bleach); }

.tx__line--dim { opacity: 0.30; }

.tx__gap { height: 1.4rem; }

/*
 * Transcript mode: the visitor skipped and wants the words. The terminal
 * stays — dropping them onto a full-page wall of text loses the whole look.
 */
.tx--transcript .tx__view {
  height: 78vh;
  height: 78svh;
  /* The page itself must never scroll: all scrolling happens in here. Cap the
     frame so it can't outgrow the viewport once the two bars and the screen
     padding are accounted for. */
  max-height: calc(100svh - 2 * var(--pad) - 6rem);
  overflow-y: auto;
  overscroll-behavior: contain;   /* don't chain scroll to the page */
  scroll-behavior: auto;
  -webkit-mask-image: none;
          mask-image: none;       /* the fade would obscure the top line */

  /* Thin, on-palette scrollbar rather than the OS default on near-black. */
  scrollbar-width: thin;
  scrollbar-color: var(--phosphor-dim) transparent;
}

/* Every line is being read now, so nothing is dimmed. */
.tx--transcript .tx__line--dim { opacity: 1; }

.tx--transcript .tx__view::-webkit-scrollbar { width: 6px; }
.tx--transcript .tx__view::-webkit-scrollbar-track { background: transparent; }
.tx--transcript .tx__view::-webkit-scrollbar-thumb {
  background: var(--phosphor-dim);
  border-radius: 3px;
}

/* --- ending ------------------------------------------------------------- */

.ending {
  width: 100%;
  max-width: var(--measure);
  margin: 0 auto;
  text-align: center;
}

.ending[hidden] { display: none; }

.ending__word {
  margin: 0;
  font-size: clamp(1.5rem, 0.9rem + 3.6vw, 2.9rem);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  color: var(--bleach);
}

.ending__tag {
  margin: 0.9rem 0 0;
  color: var(--phosphor-dim);
  letter-spacing: 0.12em;
}

.ending__idle {
  margin: 3.5rem 0 0;
}

/* --- narrow viewports ---------------------------------------------------- */

@media (max-width: 34rem) {
  :root { --measure: 100%; }

  .screen { padding: 1rem 0.85rem; }

  /* Full-bleed on phones: the frame chrome costs more than it earns. */
  .tx {
    border-left: none;
    border-right: none;
  }

  .tx__view {
    height: 58vh;
    height: 58svh;
    padding: 1.1rem 0.9rem;
  }

  /* Phones have less chrome to spare, so the transcript takes more of it. */
  .tx--transcript .tx__view {
    height: 76vh;
    height: 76svh;
    max-height: calc(100svh - 2 * var(--pad) - 5rem);
  }

  .tx__bar {
    font-size: 0.68em;
    letter-spacing: 0.06em;
    padding: 0.5rem 0.9rem;
  }

  /* The channel label is decoration; the percentage is information. */
  .tx__chan { display: none; }

  .boot__log { font-size: 0.72em; }

  .manifesto { padding: 1.5rem 0; }
}

/* Very short viewports (landscape phones) */
@media (max-height: 30rem) {
  .tx__view { height: 52vh; min-height: 9rem; }
  .boot__prompt { margin-top: 2rem; }
  .ending__idle { margin-top: 1.5rem; }
}
