/* site.css — babd.pub: one long page, the way every website reads, in the TUI's clothes.
   A status line on top (tmux's place, opencode's colours), a hero with the wordmark over a quiet
   wind of dust, then one section per part of the site: an opencode session header, the content on
   the left and its ascii scene on the right (above it on a phone). Sizes are cells (--cw) and rows
   (--row) of shared/base.css; no rounded corners, no shadows, no gradients: fills and glyphs only.
   index.html holds every word; where the script changes how something first appears (the typed
   about, the stream-in, the wordmark on a canvas), a browser with scripts hides it until the script
   runs, and shows it anyway after 2.5 s if the script never comes (the "show" keyframes); a script
   that comes later still leaves it shown (site.mjs "late"). index.html preloads every module the
   script imports, so on a slow link it arrives with the stylesheet rather than in rounds after it. */

html { scroll-behavior: smooth; scroll-padding-top: calc(var(--row) * 2); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { min-height: 100vh; }
@media (scripting: none) { .js-only { display: none !important; } }
@keyframes show { to { visibility: visible; opacity: 1; transform: none; } }

/* the width everything below the bar lines up to: 128 cells at most, two cells of air a side */
.wrap { width: min(calc(100% - var(--cw) * 4), calc(var(--cw) * 128)); margin-inline: auto; }

/* ---------------------------------------------------------------- the status line */
#bar {
  position: sticky; top: 0; z-index: 20;
  height: var(--row); background: var(--panel); white-space: nowrap; overflow: hidden;
}
/* the strip spans the screen, as a terminal's status line does, and its items stand in the page's
   column (the owner: "align with the width of the rest of the site"): the brand where the section
   panels start (.wrap and one cell), the last item ending where their words end (two cells in) */
#bar > .in, .status > .in { display: flex; align-items: stretch; height: 100%; padding-left: var(--cw); }
#bar .brand { line-height: var(--row); padding: 0 var(--cw); }
#bar .brand:focus-visible { outline-offset: -2px; }
#nav { display: flex; margin-left: var(--cw); }
#nav a { padding: 0 calc(var(--cw) * .5); color: var(--subtle); line-height: var(--row); } /* half a cell a side: eight sections and the chain's height fit the line (a cell a side did with seven) */
#nav a:hover { color: var(--text); }
#nav a.on { background: var(--hl-med); color: var(--text); }
/* the number of a section is its key (tmux's window list) */
#nav .n { color: var(--gold); margin-right: var(--cw); }
#nav a:not(.on) .n { color: var(--gold-dim); }
#bar .right { margin-left: auto; display: flex; align-items: center; gap: calc(var(--cw) * 3); padding-right: calc(var(--cw) * 2); color: var(--muted); }
#bar .right kbd { font: inherit; color: var(--text); margin-right: var(--cw); }
#bar .right button { color: var(--muted); line-height: var(--row); }
#bar .right button:hover, #bar .right button:hover kbd { color: var(--text); }
#cur { display: none; padding: 0 var(--cw); line-height: var(--row); color: var(--text); background: var(--hl-med); }
#menu { display: none; }
#menu .k { color: var(--gold); }
/* vim's ruler (site.mjs): Top, Bot or how far down, always three cells (" 5%"); on the narrowest
   phones it would touch the longest section's name, so it is left out there */
#bar .ruler { white-space: pre; line-height: var(--row); }
@media (max-width: 339px) { #bar .ruler { display: none; } }
/* between the phone's bar and 1200 px, seven sections (numbered from 1120 px), the chain's height and
   the hints fill the line: the ruler, the least of them, gives way there */
@media (min-width: 760px) and (max-width: 1199px) { #bar .ruler { display: none; } }
/* a phone from 371 px (where the chain's height shows) to 429 px has room beside the longest section's
   name for the height or the ruler, not both: the height stays */
@media (min-width: 371px) and (max-width: 429px) { #chain:not([hidden]) + .right .ruler { display: none; } }

/* ---------------------------------------------------------------- hero */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: calc(100vh - var(--row)); min-height: calc(100svh - var(--row));
  display: grid; align-content: center; justify-items: center;
  padding: calc(var(--row) * 3) 0 calc(var(--row) * 6);
}
.hero-field, .hero-storm { position: absolute; inset: 0; z-index: -1; }
.hero-field canvas { opacity: .6; transition: opacity .8s ease-out; }
/* a strike lights the dust at once, then lets it go dim again (site.mjs) */
.hero-field.lit canvas { opacity: 1; transition: none; }
.hero-inner {
  position: relative; z-index: 1; display: grid; justify-items: center; gap: calc(var(--row) * 2);
  width: min(calc(100% - var(--cw) * 4), calc(var(--cw) * 96));
}
.hero-logo { width: 100%; display: flex; justify-content: center; }

/* the wordmark (Hewn, 72 x 12 cells; build.mjs checks the size): its room is reserved here so the
   page does not move when the canvas arrives, a whole number of pixels a cell (art.mjs reads --lc),
   the largest that fits the column: 4 cells of air (--cw * 4) out of the width */
.logo-box { --lc: 4px; position: relative; width: calc(var(--lc) * 72); height: calc(var(--lc) * 24); }
@media (max-width: 320px) { .logo-box { --lc: 3px; } }
@media (min-width: 393px) { .logo-box { --lc: 5px; } }
@media (min-width: 466px) { .logo-box { --lc: 6px; } }
@media (min-width: 540px) { .logo-box { --lc: 7px; } }
@media (min-width: 700px) { .logo-box { --lc: 8px; } }
@media (min-width: 900px) { .logo-box { --lc: 10px; } }
@media (min-width: 1200px) { .logo-box { --lc: 11px; } }
@media (min-width: 1600px) { .logo-box { --lc: 12px; } }
/* a short screen (a phone on its side, a small laptop window): the first screen still holds the
   wordmark, the about and the cue */
@media (max-height: 560px) and (min-width: 540px) {
  .logo-box { --lc: 5px; }
  .hero { padding: var(--row) 0 calc(var(--row) * 3.5); }
  .hero-inner { gap: var(--row); }
  .cue { bottom: calc(var(--row) * .25); }
}
@media (min-height: 561px) and (max-height: 760px) and (min-width: 900px) { .logo-box { --lc: 8px; } }
/* without a script the wordmark is text, drawn the homepage's way: the glyph a hair larger than its
   cell so the blocks join */
.logo-text {
  margin: 0; color: var(--pine); user-select: none; -webkit-user-select: none;
  font-size: calc(var(--lc) * 1.75); line-height: calc(var(--lc) * 2);
  letter-spacing: calc(var(--lc) - var(--lc) * 1.75 * .5859375);
}
.logo-text .dot { color: var(--gold); }
@media (scripting: enabled) {
  .logo-text { visibility: hidden; }
  html:not(.js) .logo-text { animation: show 0s 2.5s forwards; }
}

/* the about at the prompt: as much room under it as over it (opencode ends its prompt half a row
   under a second line; with one paragraph that read as cut off) */
.hero .about { width: min(calc(100% - var(--cw)), calc(var(--cw) * 68)); padding-bottom: var(--row); }
.about p { position: relative; min-height: calc(var(--row) * 2); }
.about .typing { position: absolute; inset: 0 0 auto 0; }
/* the cursor takes no room in the line (its right margin gives its width back), so a full last line
   keeps it at its end instead of wrapping it alone onto a row of its own, which made the prompt a
   row taller under the text than over it (at 320-329 and 575-583 px) */
.about .cursor { display: inline-block; width: var(--cw); height: var(--row); vertical-align: top; background: var(--text); margin-left: 1px; margin-right: calc(-1px - var(--cw)); animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  html:not(.typed) .about .text { opacity: 0; }
  html:not(.js) .about .text { animation: show 0s 2.5s forwards; }
}
.hero .under { width: min(calc(100% - var(--cw)), calc(var(--cw) * 68)); margin-left: var(--cw); display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 0 calc(var(--cw) * 3); }
/* the terminal's way in at the prompt's left edge, as the keys end at its right one: the command as
   the keys are drawn, its $ muted; a click selects it whole, like an address */
.hero .curl { color: var(--text); }
.hero .curl .dollar { color: var(--muted); }

/* the way on, at the foot of the first screen: the word, and under it the gold arrow nudging
   down (the owner: the first arrow, with the word; three chevrons were "too bold") */
.cue {
  position: absolute; left: 50%; bottom: var(--row); transform: translateX(-50%); z-index: 1;
  display: grid; justify-items: center; padding: 0 calc(var(--cw) * 2);
  color: var(--subtle); transition: opacity .3s, color .15s;
}
.cue:hover { color: var(--text); }
.cue .word { letter-spacing: .08em; }
.cue .arrow { color: var(--gold); }
@media (prefers-reduced-motion: no-preference) { .cue .arrow { animation: nudge 2.4s ease-in-out infinite; } }
@keyframes nudge { 0%, 60%, 100% { transform: none; } 30% { transform: translateY(calc(var(--row) * .25)); } }
.cue.gone { opacity: 0; pointer-events: none; }

/* ---------------------------------------------------------------- sections */
.sec { margin-top: calc(var(--row) * 6); } /* a margin, not padding: a jump to a section lands on its header */
.sec:last-of-type { padding-bottom: calc(var(--row) * 4); }
.sec > .header { margin-bottom: calc(var(--row) * 2); }
.sec h2 { font-weight: 700; }
.sec h2 .hash { color: var(--muted); font-weight: 400; }
.sec .meta { color: var(--muted); }
.cols { display: grid; grid-template-columns: minmax(0, 1fr) calc(var(--cw) * 46); gap: 0 calc(var(--cw) * 5); align-items: start; margin-left: var(--cw); }
.cols.single { grid-template-columns: minmax(0, 1fr); }
.scene { position: sticky; top: calc(var(--row) * 3); height: calc(var(--cw) * 2 * 23); }
.scene.tall { height: calc(var(--cw) * 2 * 26); }
.scene.figure { height: calc(var(--cw) * 2 * 19); }
.scene-canvas { width: 100%; height: 100%; }
/* the signing key's picture (scenes/bishop.mjs): 19 x 11 characters at twice the page's size, so
   its cell is twice the page's (art.mjs reads the cell from the font size); the height is 11 such
   rows, and a little for rounding the cell to whole pixels */
.scene.key { height: calc(var(--cw) * 44 + 12px); }
.scene.key .scene-canvas { font-size: 200%; }
@media (max-width: 359px) { .scene.key .scene-canvas { font-size: 170%; } }
/* the donate scene's money (scenes/coin.mjs) in cells two thirds of the page's, in the same box: 6 px
   where the page's are 9, 5 where they are 8 (the owner's pick of ways to draw it in more detail) */
.scene-canvas[data-scene=coin] { font-size: 66.667%; }

/* the stream-in: blocks of a section arrive one after another the first time it is seen */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .sec:not(.in) .rv { opacity: 0; transform: translateY(calc(var(--row) * .6)); }
  .sec .rv { transition: opacity .38s ease-out, transform .38s ease-out; transition-delay: calc(var(--i, 0) * 55ms); }
  html:not(.js) .sec .rv { animation: show 0s 2.5s forwards; }
}

/* h3 inside a section: an icon in pine, the name, a muted description */
.item-head { display: flex; flex-wrap: wrap; gap: 0 var(--cw); align-items: baseline; }
.item-head .ic { color: var(--pine); width: calc(var(--cw) * 2); flex: none; }
.item-head b { font-weight: 700; }
.item-head .desc { color: var(--muted); }
.item-head .desc::before { content: '· '; }
/* the three addresses the README's signature covers say so, and lead to it */
.signed-mark { margin-left: auto; color: var(--pine); white-space: nowrap; }
.signed-mark:hover { text-decoration: underline; text-underline-offset: .2em; }

/* actions under a value, drawn as text: "<icon> copy   <icon> open" */
.acts { display: flex; flex-wrap: wrap; gap: 0 calc(var(--cw) * 3); }
.acts .act { padding: 0 1px; }
/* web fonts blocked (site.mjs): the Nerd Font icons would be boxes, so they are left out, in place */
.nofont .ic, .nofont .act .k { visibility: hidden; }

/* ---------------------------------------------------------------- pay */
.cards { display: grid; gap: var(--row); }
.card {
  background: var(--panel); padding: var(--row) calc(var(--cw) * 2);
  display: grid; grid-template-columns: calc(var(--cw) * 22) minmax(0, 1fr); gap: 0 calc(var(--cw) * 3);
  align-items: start; position: relative;
}
.card::before { content: ''; position: absolute; top: 0; bottom: 0; left: calc(var(--cw) * -.5 - var(--bar) / 2); width: var(--bar); background: var(--hl-med); transition: background .15s; }
.card:hover::before, .card:focus-within::before { background: var(--pine); }
.card .qrbox { grid-row: 1 / span 3; background: var(--text); }
.card .body { display: grid; gap: calc(var(--row) * .5); min-width: 0; }
.code {
  background: var(--element); padding: calc(var(--row) * .5) var(--cw);
  color: var(--text); overflow-wrap: anywhere; word-break: break-all;
}
.card .code { cursor: text; }
.card .code:hover { background: var(--hl-med); }
/* a phone cannot scan its own screen: under a finger the code folds away behind "qr" (it opens
   under the buttons) and the wallet link is the way to pay; with a mouse the code stays */
.qr-toggle { display: none; }
/* a code coming into being (shared/qrfx.mjs): its canvas over it, the code itself hidden until done */
.card .qrbox { position: relative; }
.qrbox.fx svg.qr { visibility: hidden; }
.qr-fx { position: absolute; inset: 0; width: 100%; height: 100%; }
@media (hover: none) and (pointer: coarse) {
  html.js .qr-toggle { display: inline; }
  html.js .card { grid-template-columns: minmax(0, 1fr); }
  html.js .card .qrbox { display: none; order: 2; grid-row: auto; width: min(100%, calc(var(--cw) * 30)); margin: var(--row) 0 0; }
  html.js .card.qr-open .qrbox { display: block; }
}

/* cashu: paste a token, a prompt line in the card, the answer under the actions */
.eat { display: grid; gap: calc(var(--row) * .5); }
.paste-line { display: flex; align-items: center; gap: var(--cw); background: var(--element); padding: calc(var(--row) * .25) var(--cw); }
.paste-line .prompt-mark { color: var(--pine); }
.paste-line .go { flex: none; }
/* line-height normal, the height set: iOS Safari draws a field's caret out of line with its text when
   the line is taller than the font's own (the owner saw it sit too high) */
.paste-in { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text); caret-color: var(--pine); padding: 0; line-height: normal; height: var(--row); }
.paste-in::placeholder { color: var(--muted); }
.eat-status { color: var(--subtle); transition: opacity .4s; }
.eat-status.gone { opacity: 0; }
.eat-status:empty { display: none; }
.eat-status.ok { color: var(--pine); }
.eat-status.bad { color: var(--gold); }

/* ---------------------------------------------------------------- contact / host rows */
.rows { display: grid; }
.row {
  display: grid; grid-template-columns: calc(var(--cw) * 2) calc(var(--cw) * 9) minmax(0, 1fr) auto;
  gap: 0 var(--cw); align-items: baseline; padding: calc(var(--row) * .25) var(--cw);
}
.row:hover, .row:focus-within { background: var(--hl-low); }
.row .ic { color: var(--pine); }
.row .label { color: var(--subtle); }
.row .v { min-width: 0; overflow-wrap: anywhere; word-break: break-all; }
.row .v.fp { word-break: normal; overflow-wrap: normal; }
.row .v.fp .half { display: inline-block; white-space: pre; } /* gpg's two groups of five, each whole on its line (the two spaces between them are the first one's text) */
.row .acts { justify-content: flex-end; }
.row .note { grid-column: 3 / -1; color: var(--muted); }
.host .row { grid-template-columns: calc(var(--cw) * 2) calc(var(--cw) * 18) minmax(0, 1fr) auto; }
/* a note with its service's status at its end: the minecraft server's, from /live/ (site.mjs) */
.row .note.live { display: flex; flex-wrap: wrap; justify-content: space-between; column-gap: calc(var(--cw) * 2); }
.row .state { color: var(--subtle); }
.row .state .dot { color: var(--pine); }
.row .state .ver, .row .state.down, .row .state.down .dot { color: var(--muted); }

/* promises: opencode's todo list look, ✓ in pine */
.promises { margin-bottom: calc(var(--row) * 2); }
.promises h3 { color: var(--subtle); margin-bottom: calc(var(--row) * .5); }
.promises ul { display: grid; grid-template-columns: repeat(2, minmax(0, max-content)); gap: 0 calc(var(--cw) * 6); }
.promises li::before { content: '✓'; color: var(--pine); margin-right: var(--cw); }

/* ---------------------------------------------------------------- coinjoin */
/* the call to it, loud on purpose (the owner: "advertise the coinjoin more radical ... like a ad
   from agorists"): a poster on the panel colour, a gold bar, the words big */
.call { position: relative; margin: 0 0 calc(var(--row) * 2) var(--cw); background: var(--panel); padding: var(--row) calc(var(--cw) * 3); } /* as wide as the header over it (the owner: as wide as its words was "too small in width") */
.call::before { content: ''; position: absolute; top: 0; bottom: 0; left: calc(var(--cw) * -.5 - var(--bar) / 2); width: var(--bar); background: var(--gold); }
.call p { font-weight: 700; }
.call-1, .call-2 { font-size: 1em; } /* the page's size: the owner found anything larger too big next to the rest */
.call-1 { color: var(--text); }
.call-1 .hot { color: var(--gold); }
.call-2 { color: var(--pine); }
.cj-intro { margin-bottom: calc(var(--row) * 1.5); max-width: calc(var(--cw) * 64); }
.parts { display: grid; gap: calc(var(--row) * 1.5); }
.part h3 { color: var(--pine); font-weight: 700; }
.part p { color: var(--text); max-width: calc(var(--cw) * 64); }
.part ul { margin-top: calc(var(--row) * .25); }
.part li::before { content: '→ '; color: var(--muted); }

/* ---------------------------------------------------------------- signature */
/* the key's fingerprint as a row (as it stood in contact), the key on a panel under it; the panel
   lines up with every other one (the headers, the cards, the coinjoin call): its column already
   sits a cell in, like theirs */
#signature .rows { margin-bottom: calc(var(--row) * .75); }
.pubkey {
  position: relative; background: var(--panel);
  padding: var(--row) calc(var(--cw) * 2);
  white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-all;
}
.pubkey::before { content: ''; position: absolute; top: 0; bottom: 0; left: calc(var(--cw) * -.5 - var(--bar) / 2); width: var(--bar); background: var(--gold); }
.pubkey .armor { color: var(--muted); }
.sig-acts { margin: var(--row) 0 0 calc(var(--cw) * 2); } /* under the text of the panel */

/* ---------------------------------------------------------------- footer */
footer { margin-top: calc(var(--row) * 3); }
.band { height: calc(var(--cw) * 2 * 7); width: 100%; cursor: crosshair; touch-action: manipulation; } /* a click drops a glider (site.mjs) */
.band canvas { opacity: .55; }
.status { height: var(--row); background: var(--panel); white-space: nowrap; overflow: hidden; }
.status .brand { line-height: var(--row); padding: 0 var(--cw); }
.status .hints { align-items: center; margin-left: calc(var(--cw) * 2); flex-wrap: nowrap; overflow: hidden; }
.status .top { margin-left: auto; padding: 0 calc(var(--cw) * 2); color: var(--subtle); line-height: var(--row); }
.status .top:hover { color: var(--text); }
.status .top .k { color: var(--gold); }

/* ---------------------------------------------------------------- the keys dialog (?) */
.dialog.keys dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0 calc(var(--cw) * 3); padding: var(--row) calc(var(--cw) * 4) calc(var(--row) * .5); margin: 0; }
.dialog.keys dt { color: var(--gold); white-space: pre; }
.dialog.keys dd { margin: 0; color: var(--subtle); }
.dialog.keys:focus, .dialog:focus { outline: none; }

/* ---------------------------------------------------------------- phones and small windows */
@media (max-width: 1119px) { #nav .n { display: none; } }
/* one column: a section's words first, its scene after them (the art is what a phone scrolled
   past to reach them before); the coinjoin figure stays first, since it is the document's own
   first part (coinjoin.md opens with it) */
@media (max-width: 999px) {
  .cols { grid-template-columns: minmax(0, 1fr); margin-left: 0; }
  .scene, .scene.tall { position: relative; top: 0; height: calc(var(--cw) * 2 * 13); margin-top: calc(var(--row) * 1.5); }
  .scene.figure { order: -1; height: calc(var(--cw) * 2 * 18); margin: 0 0 calc(var(--row) * 1.5); }
  .scene.key { height: calc(var(--cw) * 44 + 12px); }
  .cols > .content { margin-left: var(--cw); }
}
@media (max-width: 759px) {
  #nav, #bar .right .hint { display: none; }
  #cur, #menu { display: inline-block; }
  .card { grid-template-columns: minmax(0, 1fr); }
  .card .qrbox { grid-row: auto; width: min(100%, calc(var(--cw) * 30)); margin-bottom: var(--row); }
  .row, .host .row { grid-template-columns: calc(var(--cw) * 2) minmax(0, 1fr) auto; }
  .row .v { grid-column: 2 / -1; }
  .row .label { grid-column: 2; }
  .row .acts { grid-column: 3; grid-row: 1; }
  .row .note { grid-column: 2 / -1; }
  .promises ul { grid-template-columns: minmax(0, 1fr); }
  .status .hints .hint:nth-child(n + 2) { display: none; }
  .sec { margin-top: calc(var(--row) * 4); }
  .hero { padding: calc(var(--row) * 3) 0 calc(var(--row) * 6); }
  .cue { bottom: calc(var(--row) * .5); }
  .call { padding-inline: calc(var(--cw) * 2); }
}
/* keys mean nothing under a finger: the hints go, the menu stays */
@media (hover: none) {
  .hero .under .hints, .status .hints, #bar .right .hint { display: none; }
  #menu { display: inline-block; }
}
/* the screensaver (shared/saver.mjs): over everything, the toasts too, the canvas in the middle of
   the screen; no pointer on it, and no scrolling or zooming under a finger */
.saver { position: fixed; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center; background: var(--bg); cursor: none; touch-action: none; }
.saver canvas { display: block; flex: none; }
@media print {
  #bar, .hero-field, .hero-storm, .scene, .band, .cue, .js-only, .qr-fx, .saver { display: none; }
  .qrbox.fx svg.qr { visibility: visible; }
  .sec .rv { opacity: 1 !important; transform: none !important; }
}

/* ---------------------------------------------------------------- books and the chain's height */
/* the height waits hidden for its data (site.mjs); a page without a script drops the nav's numbers:
   they are keys, and there are no keys without one */
#chain[hidden] { display: none; }
@media (scripting: none) { #nav .n { display: none; } }

/* the chain's height in the status line (/live/chain.json): a block, its number; a new block lights
   it gold once */
#chain { display: flex; align-items: center; gap: var(--cw); color: var(--subtle); line-height: var(--row); white-space: nowrap; }
#chain .k { color: var(--pine); }
#chain:hover { color: var(--text); } /* a link to the mempool section */
#chain:not([hidden]) { margin-left: auto; }
#chain:not([hidden]) + .right { margin-left: calc(var(--cw) * 3); }
/* the status line has the page's 128 cells at most, and seven sections take 74 of them with their
   numbers: while the height shows it takes the place of "? keys" (the hero and the footer still
   name it, and ? works anywhere); in a narrower window the hints go first, then the height; on a
   phone it stands between the section and the menu, down to 371 px */
#chain:not([hidden]) + .right [data-keys] { display: none; }
@media (max-width: 979px) { #bar .right .hint { display: none; } }
@media (min-width: 760px) and (max-width: 839px), (max-width: 370px) { #chain { display: none; } }
@media (prefers-reduced-motion: no-preference) { #chain.new, #chain.new .k { animation: found 1.8s ease-out; } }
@keyframes found { from { color: var(--gold); } }


/* books: a pile of them on their sides, each spine a link on its own fill, a band near either end,
   the title, then the author and the year; as thick as the book is long (thick-0 to thick-3), laid a
   cell or a few off the pile's edge (x-0 to x-4), pulled out a little under the pointer */
.pile { display: grid; justify-items: start; overflow-x: clip; }
.pile li { max-width: 100%; }
.spine {
  position: relative; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 calc(var(--cw) * 3);
  padding: 0 calc(var(--cw) * 3); background: var(--tone); color: var(--text); overflow-wrap: anywhere;
  transition: transform .18s ease-out;
}
.spine::before, .spine::after { content: ''; position: absolute; top: 0; bottom: 0; width: var(--bar); background: var(--band); }
.spine::before { left: var(--cw); }
.spine::after { right: var(--cw); }
.spine .t { font-weight: 700; }
.spine .by { display: flex; gap: calc(var(--cw) * 2); margin-left: auto; color: var(--subtle); }
.spine .y { color: var(--gold); }
.tone-0 { --tone: var(--pine-deep); --band: var(--pine); }
.tone-1 { --tone: var(--element); --band: var(--gold); }
.tone-2 { --tone: var(--pine-dim); --band: var(--gold); }
.tone-3 { --tone: var(--hl-med); --band: var(--pine); }
.tone-4 { --tone: var(--gold-dim); --band: var(--gold); }
.tone-4 .by, .tone-4 .y { color: var(--text); }
.thick-1 { padding-block: calc(var(--row) * .25); }
.thick-2 { padding-block: calc(var(--row) * .5); }
.thick-3 { padding-block: calc(var(--row) * .75); }
.pile .x-1 { padding-left: var(--cw); } .pile .x-2 { padding-left: calc(var(--cw) * 2); } .pile .x-3 { padding-left: calc(var(--cw) * 3); } .pile .x-4 { padding-left: calc(var(--cw) * 4); }
.spine:hover, .spine:focus-visible { transform: translateX(calc(var(--cw) * 2)); }
/* the whitepaper sticks out of the pile, pulled out for good, dark pine with its title and bands in
   gold (the owner: "make it stick out a little as its important"; a gold spine was "too bright"); the
   books beside it never take its dark pine (src/page.mjs); its row keeps room for it */
.pile li.key { max-width: calc(100% - var(--cw) * 5); }
.spine.key { --tone: var(--pine-deep); --band: var(--gold); transform: translateX(calc(var(--cw) * 4)); }
.spine.key .t { color: var(--gold); }
.spine.key:hover, .spine.key:focus-visible { transform: translateX(calc(var(--cw) * 5)); }
@media (prefers-reduced-motion: reduce) { .spine { transition: none; } .spine:hover, .spine:focus-visible { transform: none; } .spine.key, .spine.key:hover, .spine.key:focus-visible { transform: translateX(calc(var(--cw) * 4)); } }

/* ---------------------------------------------------------------- mempool */
/* the chain's tip across the section (scenes/blocks.mjs: 16 rows of art, the blocks, their words
   under them), then the numbers in panels (shared/mempool.mjs fills them in), the hourglass beside */
.strip { height: calc(var(--cw) * 2 * 17); margin: 0 0 calc(var(--row) * 2) var(--cw); }
/* two columns where each panel gets 36 cells (its longest line, "~apr 2028 · 3.125 → 1.5625 btc", is
   30, its padding 4), else one: beside the hourglass the column is 58 to 76 cells (from 1000 px), and
   under about 1160 px two panels cut their lines; never three (a track is half the width at least) */
.stats {
  display: grid; gap: var(--row) calc(var(--cw) * 2);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, max(calc(var(--cw) * 36), calc(50% - var(--cw)))), 1fr));
}
.stat {
  position: relative; background: var(--panel); padding: calc(var(--row) * .5) calc(var(--cw) * 2);
  display: grid; align-content: start; min-width: 0;
}
.stat::before { content: ''; position: absolute; top: 0; bottom: 0; left: calc(var(--cw) * -.5 - var(--bar) / 2); width: var(--bar); background: var(--hl-med); }
.stat[data-stat="fees"] { grid-column: 1 / -1; }
.stat-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 calc(var(--cw) * 2); margin-bottom: calc(var(--row) * .25); }
.stat-head .t { color: var(--subtle); }
.stat-head .note { color: var(--muted); }
.stat .big { font-weight: 700; color: var(--text); }
.stat .big .unit { font-weight: 400; color: var(--subtle); }
.stat .sub { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* one line: no number arriving moves the page under it */
/* a row tall before its glyphs come (the sparkline's line is empty till then): in one column (a phone,
   or beside the hourglass under about 1160 px) the panels under it moved down a row as they came */
.stat .bar, .stat .spark { white-space: pre; overflow: hidden; color: var(--muted); min-height: var(--row); }
.bar .done, .spark .done { color: var(--pine); }
.bar .tip, .spark .tip { color: var(--gold); }
.bar .left { color: var(--hl-med); }
.bar .pct { color: var(--subtle); }
/* the fees: mempool.space's four, a column each, the rate in its colour (set by the script) */
.fees { margin: 0; display: grid; grid-template-columns: repeat(4, max-content); justify-content: space-between; gap: 0 calc(var(--cw) * 3); }
.fees dt { color: var(--muted); }
.fees dd { margin: 0; font-weight: 700; }
@media (max-width: 759px) {
  .stats { grid-template-columns: minmax(0, 1fr); }
  .fees { grid-template-columns: repeat(2, max-content); justify-content: start; gap: calc(var(--row) * .25) calc(var(--cw) * 6); }
}
