/* NomadNet-style fullscreen TUI takeover, with terminal-honest constraints:
   no CSS borders, no rounded corners, no thin lines. Every visible boundary
   is either a glyph in a cell (dividers) or a background-colour shift.
   Page can override --mu-bg / --mu-fg via the #!bg / #!fg directives.

   Rendering model: every glyph is its own fixed cell (.mu-cell), so the page
   is a rigid character grid like a real terminal — a wide or font-substituted
   glyph is clamped to its slot instead of shoving the row out of alignment.
   See lib/micron/render.js (toCells) and docs/micron.md. */

/* Authentic IBM VGA 8x16 ROM glyphs, pre-stretched ×1.2 vertically for the
   4:3 CRT aspect (8×19.2 display cell, 1:2.4) — the same aspect correction
   SyncTERM applies to the 720×400 text mode. Built from the public ROM
   bitmap — see src/assets/fonts/NOTICE.md. Covers the CP437 repertoire
   (ASCII + line/block drawing); anything outside it falls back but stays
   cell-aligned. */
@font-face {
  font-family: "PxPlus IBM VGA 8x16";
  src: url("/assets/fonts/PxPlus_IBM_VGA8.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* Bundled fallbacks for glyphs outside the VGA font's CP437 repertoire
   (▃ ╱ ▞ ⣿ ★ ⭒ …), so every visitor sees the exact same substitute glyphs
   instead of whatever their OS happens to ship. Full fonts, not subsets.
   Order (via --mu-mono below): Noto Sans Mono → DejaVu Sans (braille, ★,
   Hebrew points) → Noto Sans Symbols 2 (⭒ ⏾ and other pictographs).
   Licences: Noto — SIL OFL 1.1; DejaVu — Bitstream Vera/DejaVu licence.
   See NOTICE.md. Declaring these families here shadows any same-named
   system font, which is exactly what we want for determinism. */
@font-face {
  font-family: "Noto Sans Mono";
  src: url("/assets/fonts/NotoSansMono-Regular.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "DejaVu Sans";
  src: url("/assets/fonts/DejaVuSans.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Noto Sans Symbols 2";
  src: url("/assets/fonts/NotoSansSymbols2-Regular.woff2") format("woff2");
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

body.mode-micron {
  /* Theme colours come straight from the Synchronet / IBM VGA 16-colour
     palette (sbbs src/conio/vidmodes.c dac_default — 0x00/0x54/0xA8/0xFF
     component levels). Classic ANSI-BBS scheme: light-gray-on-black text,
     yellow highlights, blue panels, green rules. Author colours are snapped
     to the same 16 entries at render time (lib/micron/render.js snapToVga). */
  --mu-bg: #000000;      /* 0  black */
  --mu-fg: #a8a8a8;      /* 7  light gray */
  --mu-accent: #ffff54;  /* 14 yellow */
  --mu-section-bg: #0000a8; /* 1 blue */
  --mu-divider-color: #00a800; /* 2 green */
  --mu-link: #ffff54;    /* 14 yellow */
  --mu-status-bg: #0000a8; /* 1 blue */

  /* Terminal font stack. The bundled VGA 8x16 face leads; the next three
     are also bundled (see @font-face above), so non-CP437 glyphs render
     identically for every visitor. Anything still uncovered (rare CJK
     like 〜 ､) falls through to the system list at the end. */
  --mu-mono: "PxPlus IBM VGA 8x16", "Noto Sans Mono", "DejaVu Sans",
             "Noto Sans Symbols 2",
             "DejaVu Sans Mono", "SF Mono", Monaco, Menlo, Consolas,
             ui-monospace, monospace;

  background: var(--mu-bg);
  color: var(--mu-fg);
  font-family: var(--mu-mono);
  /* Base size is the native VGA cell (8×16 px at 16px font). The actual
     document scales itself up SyncTERM-style — see .mu-doc below. The body
     is an inline-size container so children can size type off its real
     width (cqw excludes the scrollbar, unlike vw). */
  font-size: 16px;
  container-type: inline-size;
  line-height: 1;
  font-variant-ligatures: none;
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.mu-doc {
  background: var(--mu-bg);
  color: var(--mu-fg);
  /* SyncTERM-style scaling: the column budget — the BBS-standard 80 columns
     (Synchronet TERM_COLS_DEFAULT), or N when #!width=N sets --mu-cols —
     scales like SyncTERM's screen: fill the window width, but never wider
     than a 4:3 screen fitted to the window height (266.67vh = 4/3 height,
     ×2 for the 0.5em cell advance). On a modern wide monitor the terminal
     sits centred at 4:3 with black borders either side, exactly like
     SyncTERM full-screen; for an 80-column page the 4:3 frame shows the
     classic 25 rows per screenful. vw line is a fallback for browsers
     without container-query units. */
  font-size: min(calc(200vw / var(--mu-cols, 80)), calc(266.67vh / var(--mu-cols, 80)));
  font-size: min(calc(200cqw / var(--mu-cols, 80)), calc(266.67vh / var(--mu-cols, 80)));
  /* Integer-pixel snapping (browsers with CSS round(); others keep the
     fluid size above). A multiple-of-10px font-size makes the cell an
     exact 5k×12k device-pixel box (width = fs/2, height = 1.2·fs), so
     glyph ink and cell edges land on whole pixels and box-drawing rows
     join seamlessly — the same reason SyncTERM's non-blurry scaling
     uses integer zoom steps and eats the black border instead. */
  font-size: max(10px, round(down,
    min(calc(200cqw / var(--mu-cols, 80)), calc(266.67vh / var(--mu-cols, 80))),
    10px));
  width: calc(var(--mu-cols, 80) * 1ch);
  /* Centre the screen in the window, both axes — SyncTERM letterboxes a
     screen that doesn't fill the window. margin:auto centres only when
     there's spare room; a page taller than the viewport just grows the
     body and scrolls normally. */
  margin: auto;
  /* No padding: a terminal screen starts at row 0, column 0 — SyncTERM
     draws flush to its edges. Authors add blank rows/columns of spaces
     if they want breathing room. */
  padding: 0;
  flex: 0 0 auto;
  overflow-x: auto;
}

/* ── The character grid ───────────────────────────────────────────────────
   One inline-block cell per glyph: fixed 1ch wide, 2.4ch tall (1:2.4,
   VGA 4:3 aspect-corrected — matches SyncTERM's screen). overflow
   clips anything that doesn't fit so the grid can never be pushed apart. */
.mu-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1ch;
  height: 2.4ch;
  line-height: normal;
  vertical-align: top;
  overflow: hidden;
  white-space: pre;
}
/* A run of same-styled SPACES batched into one span — purely a
   background-coloured box n×1ch wide (spaces have no ink, so nothing is
   rasterised and no text-placement artifact is possible). Visible glyphs
   always get their own .mu-cell: merging them into text runs caused faint
   horizontal banding on ░▒▓-heavy art at fractional display scales
   (subpixel glyph placement inside long runs vs. per-box snapping). */
.mu-run {
  display: inline-block;
  height: 2.4ch;
  line-height: 2.4ch;
  vertical-align: top;
  white-space: pre;
}

/* Glyphs are centred in the cell both ways. For the bundled VGA font this
   is exact and changes nothing (its line box is precisely 1.2em = 2.4ch =
   the full cell, ascent 3072/2560 em, zero rounding), so the pixel grid is
   untouched; fallback glyphs (non-CP437) get properly centred instead of
   sitting baseline-to-cell-bottom. Space cells are emitted as U+00A0 by the
   renderer so flex layout can't drop whitespace-only content. */

/* Wide glyphs (CJK / fullwidth / emoji) are scaled down to fit one cell
   rather than spilling into the next. */
.mu-cell.mu-wide > span {
  flex: 0 0 auto;
  line-height: 1;
  transform: scale(0.5);
  transform-origin: center center;
}

.mu-line {
  white-space: nowrap; /* a row is a row — no fluid wrapping */
  line-height: 0; /* row height comes entirely from the cells */
  min-height: 2.4ch;
}
.mu-empty {
  height: 2.4ch;
}

.mu-align-default,
.mu-align-left   { text-align: left; }
.mu-align-center { text-align: center; }
.mu-align-right  { text-align: right; }

.mu-bold      { font-weight: 700; }
.mu-italic    { font-style: italic; }
.mu-underline { text-decoration: underline; }

.mu-link {
  color: var(--mu-fg);
  text-decoration: none;
}
.mu-link:hover { text-decoration: underline; }

/* Sections: pure background-colour distinction. No CSS borders or radii
   — a terminal can't draw those. A 1ch left/right indent stands in for
   what a TUI would do with spaces. */
.mu-section {
  background: var(--mu-section-bg);
  padding: 0 1ch;
  margin: 2.4ch 0 0;
}
.mu-section .mu-section { margin-top: 2.4ch; }

.mu-heading {
  margin: 0 0 2.4ch;
  font-weight: 700;
  color: var(--mu-accent);
}
.mu-h1, .mu-h2 { font-size: 1em; }
.mu-h3, .mu-h4, .mu-h5, .mu-h6 { font-size: 1em; color: var(--mu-fg); }

/* Dividers are real glyphs (one cell per column) so they line up with the
   content rows around them. Honest characters, no CSS line. */
.mu-divider {
  color: var(--mu-divider-color);
  overflow: hidden;
  white-space: nowrap;
  user-select: none;
  line-height: 0;
  height: 2.4ch;
  margin: 0;
}

/* ── #!width=N: explicit column budget ────────────────────────────────────
   Sizing/centring is shared with the default 80-column frame above (the
   directive just sets --mu-cols). In fixed-width mode the author owns every
   visible cell, so the section background shift and indent would throw off
   hand-drawn framing. */
.mu-doc.mu-fixed .mu-section {
  padding: 0;
  margin: 0;
  background: transparent;
}
.mu-doc.mu-fixed .mu-heading {
  margin: 0;
  color: inherit;
  font-weight: 400;
}

/* ── Scenes (`%%` breaks): all scenes are stacked in the same grid cell so
   the document keeps the height of its tallest scene (no reflow or jumping
   while cycling); only the active one is visible. Without JS the first
   scene simply stays on. */
.mu-doc.mu-scenes { display: grid; }
.mu-scene {
  grid-area: 1 / 1;
  visibility: hidden;
  min-width: 0;
}
.mu-scene.is-active { visibility: visible; }

/* Scene groups (`%%%id hotkeys`): only the active group exists on screen;
   the active group is itself a scene stack (grid), so the `%%` cycle runs
   inside it. Without JS the first group / first scene stays on. */
.mu-scene-group { display: none; }
.mu-scene-group.is-active { display: grid; }

/* Status bar: distinguished by bg color, not by a CSS line. Scales at the
   default 80-column size, like SyncTERM's own status line. */
.mu-escape {
  flex: 0 0 auto;
  font-size: min(calc(200vw / 80), calc(266.67vh / 80));
  font-size: min(calc(200cqw / 80), calc(266.67vh / 80));
  font-size: max(10px, round(down, min(calc(200cqw / 80), calc(266.67vh / 80)), 10px));
  background: var(--mu-status-bg);
  padding: 0 1ch;
  min-height: 2.4ch;
  display: flex;
  align-items: center;
}
.mu-escape a {
  color: var(--mu-accent);
  text-decoration: none;
}
.mu-escape a:hover { text-decoration: underline; }
