/* ===========================================================================
   archive.css -- the house style, shared by every page in the ring.

   Each page still carries its own <style> block AFTER the link to this file,
   so anything a page declares for itself wins. This holds the rules that were
   being copy-pasted (and drifting: three pages had lost their button/select
   styling entirely) plus the ring chrome, which is identical everywhere by
   construction.
   =========================================================================== */

/* --- base ---------------------------------------------------------------- */

/* The column. Everything on a page lines up to one width: 880px on a desktop,
   the whole space inside the body's padding on anything narrower. The canvas
   is the one thing allowed to be narrower, because its width is bound by the
   height it can have. */
:root { --col:min(880px, 100%) }

/* Widths include borders. Without this the canvas, the DAC strip and the ring
   are the full column plus a 1px border either side, which on a phone is two
   pixels wider than the screen. */
*, *::before, *::after { box-sizing:border-box }

html, body { min-height:100%; margin:0; background:#111; color:#999;
             font:13px/1.6 ui-monospace, Consolas, "DejaVu Sans Mono", monospace }
body { display:flex; flex-direction:column; align-items:center; gap:12px; padding:20px;
       overflow-wrap:break-word }

/* A table wider than the screen scrolls inside itself rather than pushing the
   whole page sideways -- circle's five-column cost table, on a phone. */
table { display:block; max-width:100%; overflow-x:auto }

canvas { background:#000; image-rendering:pixelated; border:1px solid #333 }

/* --- the 4:3 correction ---------------------------------------------------
   Every program here ran in a full-screen VGA mode, and every full-screen VGA
   mode filled the same 4:3 monitor -- so the pixels were not square. 320x200
   pixels stood 1.2x taller than wide; 360x480 and 320x400 pixels were wider
   than tall by a good deal more than that. Only pattern.html's 640x480 came
   out square. Drawing the backing store 1:1, which is what a canvas does left
   alone, is therefore wrong on every page but that one, and most wrong on the
   eight 360x480 Mode X pages, which stood nearly 2.4x too tall.

   The correction needs to know nothing about the mode: whatever the backing
   store, the picture is 4:3. `screenAspect()` in archive.js hangs the reader's
   toggle off this and supplies --nat, the backing store's own ratio, for the
   square-pixel side of it.

   Every page sizes its canvas the same way: as wide as the column, unless the
   screen is too short for that, in which case as large as fits under the strip.
   "Under the strip" because that is what a link in the prose scrolls to the
   top of the window: the strip row, its caption, the canvas and the bar below
   it. --chrome is that stack less the canvas, overestimated a little so the bar
   is never cut off. The height is read through whichever ratio is in force, so
   square pixels give a tall canvas rather than an overflowing one. */

:root { --chrome:140px }
#screen { --ar:1.3333; aspect-ratio:4/3;
          width:min(var(--col), calc((100vh - var(--chrome)) * var(--ar))) }

/* Square pixels: either the reader asked for them, or the canvas is not a
   screen at all -- modex's whole-page view is a picture of video memory, the
   visible window outlined inside it, and stretching memory to 4:3 would be
   saying something false about it. */
html[data-par="sq"] #screen,
#screen[data-native] { --ar:var(--nat,1.3333); aspect-ratio:auto }

/* The toggle, directly under the canvas: the state, then what it means. */
.parbar { display:flex; gap:10px; align-items:baseline; justify-content:center;
          flex-wrap:wrap; font-size:11px; color:#666; width:var(--col) }
.parbar button { font-size:11px; padding:2px 7px; min-width:3.4em }
.parbar b { color:#8a8a7a; font-weight:normal }
/* restart and pause, moved here by underScreen(): set off from the aspect
   toggle by a rule, since one acts on the demo and the other on the display */
.parbar .parctl { display:inline-flex; gap:6px; padding-right:12px;
                  border-right:1px solid #333 }

button, select { background:#1a1a1a; color:#ccc; border:1px solid #444;
                 padding:4px 8px; font:inherit }
button:hover, select:hover { border-color:#666 }

.panel { display:flex; gap:16px; align-items:center; flex-wrap:wrap;
         justify-content:center; max-width:880px }
label  { display:flex; gap:6px; align-items:center; cursor:pointer }
input[type=range] { width:120px }

/* The selector row: which of the files you are looking at, and nothing else.
   Always directly above the canvas. Restart lives under the canvas (see
   underScreen() in archive.js); options and sliders go below it too. */
.panel.selector { width:var(--col); max-width:none; gap:8px;
                  flex-wrap:nowrap; margin-bottom:2px; scroll-margin-top:10px }

/* The sub-demo strip (demoStrip() in archive.js) takes the selector's place in
   that row: every file on the page visible at once, the current one lit, and
   its caption directly underneath. Unchosen tabs are drawn quieter than an
   ordinary button so the lit one is what the eye lands on. */
.demos { display:flex; flex-wrap:wrap; justify-content:center; gap:4px;
         flex:1 1 auto; min-width:0 }
.demos button { padding:3px 9px; font-size:12px; color:#8a8a8a;
                background:#151515; border-color:#333 }
.demos button:hover { color:#bbb }
.demos button[aria-selected="true"] { color:#dd9; background:#20201a;
                                      border-color:#6a6a4a }

/* Captions: a sentence or two per demo, directly under the strip and above the
   canvas, so what you are looking at is on screen while you look at it. The
   longer story is one narrative in the prose. Two lines are held open -- a
   caption is written to fit the column in two -- so the canvas does not jump
   when a short caption follows a long one. */
#notes.captions { min-height:3.2em; margin-top:-6px; align-items:flex-start }
#notes.captions .note { text-align:center }

/* a heading in the prose that is also a way back to its demo */
.prose h2 a { color:inherit; border-bottom:1px dotted #6a6a4a }
.prose h2 a:hover { border-bottom-style:solid }

.cap    { color:#666; font-size:11px; text-align:center; width:var(--col) }

/* The DAC strip. Most of these programs animate color registers rather than
   pixels, so this row is often the only thing on the page that is moving. */
#strip { image-rendering:pixelated; border:1px solid #333;
         width:var(--col); height:22px; display:block }

/* Clickable key buttons. Every one of these programs reads its keyboard with
   ReadKey inside the main loop, so these are not an addition to the interface --
   they are that interface, clickable, because a canvas that only responds to
   typing is easy to walk past. `.on` marks a key whose effect is currently
   active. */
#keys { display:flex; gap:6px; flex-wrap:wrap; justify-content:center;
        width:var(--col) }
.keybtn { display:flex; flex-direction:column; align-items:center; gap:0;
          line-height:1.25; padding:3px 9px; min-width:2.6em; cursor:pointer }
.keybtn b { color:#ccc; font-weight:normal; font-size:13px }
.keybtn span { color:#666; font-size:10px }
.keybtn.on { border-color:#5a6a4a; background:#20241e }
.keybtn.on b { color:#cc9 }
.hidden { display:none }
/* The HTML hidden attribute has only a weak UA rule behind it, so any
   display:flex above would silently defeat it -- which is how per-demo options
   would have stayed on screen for every demo. Make it win outright. */
[hidden] { display:none !important }

/* The captions' markup: hidden siblings -- plain HTML, no escaping, and unable
   to break the page's script. The strip only flips `hidden`, so keep any
   display rule off .note itself. */
#notes { width:var(--col); display:flex; justify-content:center }
.note { color:#888; font-size:12px; text-align:left }
.note[hidden] { display:none }
.note b { color:#cc9; font-weight:normal }
.note i { color:#9a9 }
.note code { color:#9a9 }

/* --- ring chrome --------------------------------------------------------- */

a { color:#8aa; text-decoration:none }

.ring { display:flex; width:var(--col); border:1px solid #3a3a3a;
        background:#161616 }
.ring a, .ring .here { flex:1 1 0; display:flex; flex-direction:column; gap:2px;
          padding:10px 14px; border-right:1px solid #2c2c2c; min-width:0 }
.ring a:last-child, .ring .here:last-child { border-right:0 }
.ring a:hover { background:#1e2020 }
/* the hub's own middle cell: same shape, dimmed, not a link */
.ring .here { cursor:default }
.ring .here b { color:#7a7a6a }
.ring .here span { color:#5a5a5a }
.ring b { color:#cc9; font-weight:normal; font-size:15px; letter-spacing:.06em }
.ring span { color:#777; font-size:11px; white-space:nowrap; overflow:hidden;
             text-overflow:ellipsis }
.ring .home { flex:0 0 auto; text-align:center; align-items:center }
.ring .next { text-align:right; align-items:flex-end }

header.entry { width:var(--col); border-bottom:1px solid #333;
               padding-bottom:14px }
header.entry .num { color:#555; font-size:34px; line-height:1 }
header.entry h1 { margin:2px 0 12px; color:#ddd; font-size:20px; font-weight:normal }

/* Details: file sizes, timestamps and provenance, collapsed by default, just
   above the source listings. That is research, and belongs with the code
   rather than between the title and the demo. Drawn to match the source
   summaries beside it. */
body > details.meta { width:var(--col) }
body > details.meta summary { cursor:pointer; color:#8aa; padding:7px 0;
                              font-size:13px }
body > details.meta dl { margin:2px 0 14px; display:grid;
                         grid-template-columns:max-content 1fr; gap:3px 14px;
                         font-size:12px }
body > details.meta dt { color:#666 }
body > details.meta dd { margin:0; color:#9a9a9a }
body > details.meta code { color:#b8b8a0 }

/* The lede: a short personal note between the title and the demo. The
   technical commentary stays below the demo. */
.lede { color:#9a9a9a; font-size:13px; margin:10px 0 0 }
.lede p { margin:0 0 10px }
.lede p:last-child { margin-bottom:0 }
.lede b { color:#cc9; font-weight:normal }
.lede code { color:#b8b8a0 }
/* placeholder lede -- deliberately conspicuous so it cannot ship unnoticed.
   `node utils/check.js` lists every page still carrying one. */
.lede p.todo { color:#c96; border:1px dashed #5a4a34; background:#1d1a15;
               padding:7px 10px; margin:0; font-size:12px }

/* gap:inherit keeps each page's own body spacing. */
.demo { display:flex; flex-direction:column; align-items:center; gap:inherit;
        width:100%; padding:8px 0 4px }

.prose { width:var(--col); color:#8f8f8f; font-size:13px }
.prose h2 { color:#cc9; font-size:14px; font-weight:normal; margin:22px 0 6px;
            letter-spacing:.04em }
.prose p { margin:0 0 11px }
.prose b { color:#cc9; font-weight:normal }
.prose code { color:#b8b8a0 }
.prose table { border-collapse:collapse; font-size:12px; margin:0 0 12px }
.prose th, .prose td { border:1px solid #333; padding:4px 9px; text-align:left;
                       vertical-align:top }
.prose th { color:#777; font-weight:normal }

details.source { width:var(--col) }
details.source summary { cursor:pointer; color:#8aa; padding:7px 0; font-size:13px }
details.source .cap { color:#666; font-size:11px; margin:0 0 6px; text-align:left }
details.source pre { background:#0c0c0c; border:1px solid #2c2c2c; padding:12px;
                     overflow-x:auto; color:#9a9a8a; font-size:12px;
                     line-height:1.45; white-space:pre-wrap; word-break:break-word;
                     margin:0 0 14px }

/* --- small screens --------------------------------------------------------
   The column already does most of the work: everything is sized to the page,
   not the window, so a phone just gets a narrower column. What is left is
   what assumed room -- padding, the ring's three cells, the Details grid --
   and targets sized for a mouse rather than a finger. */
@media (max-width: 640px) {
  body { padding:12px 10px; gap:10px }

  /* the ring: three cells still fit side by side once they stop insisting on
     one line of subtitle and a 15px letter-spaced label */
  .ring a, .ring .here { padding:7px 8px }
  .ring b { font-size:12px; letter-spacing:.02em }
  .ring span { white-space:normal; display:-webkit-box; -webkit-line-clamp:2;
               -webkit-box-orient:vertical }

  header.entry .num { font-size:26px }
  header.entry h1 { font-size:18px; margin-bottom:8px }

  /* Details: label above value, since a label column sized to the longest
     label leaves the values a sliver */
  body > details.meta dl { grid-template-columns:1fr; gap:0 }
  body > details.meta dt { margin-top:8px }
  body > details.meta dt:first-child { margin-top:0 }

  /* fingers, not a mouse */
  .demos { gap:6px }
  .demos button { padding:7px 11px; font-size:13px }
  .parbar button { padding:6px 10px; font-size:12px }
  .keybtn { padding:6px 11px }
  .panel { gap:10px 14px }
  input[type=range] { width:100px }
}
