/* Dog Wif Mask. One printed sheet, light drawn on a near black field.
   Nothing here is a panel: a thing exists because it glows. Every rule and divider is a
   pseudo element, so no block becomes a bordered box with text pressed to its edge; the only
   real surfaces are the generated glass plate and the keys cut from it.

   Two scales and nothing between them. Type: 16 / 20 / 24 / 32 / 40, and the display sizes that
   have to breathe with the window are clamped BETWEEN those steps. Space: 4 / 8 / 12 / 16 / 24 /
   32 / 48 / 64 / 96.

   NO GLOW ON TEXT, at any size (his note, twice). The light on this page is made in the pictures,
   which carry their own halo; a text-shadow under a letter only thickens the letter, and on a
   screenshot it is what pulls the measured contrast of a line down. */

@font-face { font-family: Zodiak; src: url("../fonts/Zodiak-Light.woff2") format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: Zodiak; src: url("../fonts/Zodiak-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Plein; src: url("../fonts/Plein-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: Plein; src: url("../fonts/Plein-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: Plein; src: url("../fonts/Plein-Black.woff2") format("woff2"); font-weight: 900; font-display: swap; }
@font-face { font-family: Plein; src: url("../fonts/Plein-BlackItalic.woff2") format("woff2"); font-weight: 900; font-style: italic; font-display: swap; }

:root {
  --field: #080c09;
  --ink: #e9fdea;
  --ink-2: #a9e8b2;
  --neon: #44e061;
  --neon-2: #2f9f44;
  --haze: rgba(68, 224, 97, .14);

  --display: Zodiak, "Iowan Old Style", Georgia, serif;
  --voice: Plein, "Segoe UI", system-ui, sans-serif;

  /* type */
  --t-1: 16px;
  --t-2: 20px;
  --t-3: 24px;
  --t-4: 32px;
  --t-5: 40px;
  --t-head: clamp(32px, 3vw, 40px);
  --t-value: clamp(24px, 2.4vw, 32px);

  /* space */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px;

  /* the sheet and the rail beside it. The numeral column is the same width in the rail, in every
     band head, in the memo and in the steps, so one vertical line runs down the whole page. */
  --num: 56px;
  --rail: 136px;
  --gap: 40px;
  --edge: clamp(32px, 4.4vw, 96px);
  --page: min(1120px, 100vw - 2 * (var(--rail) + var(--gap) + var(--edge)));
  --band: var(--s-9);
}

* { box-sizing: border-box; }
html { background: var(--field); }
body {
  margin: 0;
  background: var(--field);
  color: var(--ink);
  font: 500 var(--t-1)/1.58 var(--voice);
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  /* rail, sheet, and an empty column the width of the rail: the sheet sits in the middle of the
     window, with the same margin left and right, instead of being pushed right by its own nav */
  display: grid;
  grid-template-columns: var(--rail) var(--page) var(--rail);
  justify-content: center;
  column-gap: var(--gap);
  align-items: start;
  overflow-x: hidden;
}

/* the living field behind everything: stars and haze, drawn once and drifting */
#field { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }

img { max-width: 100%; height: auto; mix-blend-mode: screen; }

::selection { background: var(--neon-2); color: #03150a; }
:focus-visible { outline: 2px solid var(--neon); outline-offset: 3px; }

/* ---------------------------------------------------------------- the rail */
.rail { grid-column: 1; align-self: start; position: sticky; top: var(--s-6); padding-top: var(--s-7); }
.rail ol { list-style: none; margin: 0; padding: 0; }
.rail li + li { margin-top: var(--s-2); }
.rail a {
  position: relative;
  display: grid; grid-template-columns: var(--num) 1fr; align-items: baseline;
  column-gap: var(--s-4); min-height: 40px; padding: var(--s-2) 0;
  text-decoration: none; color: var(--ink-2); transition: color .18s;
}
/* the numeral and the word sit on ONE baseline, and every item steps by the same amount */
.rail .num { font: 300 var(--t-3)/1 var(--display); text-align: right; color: inherit; }
.rail .word { font: 700 var(--t-1)/1 var(--voice); letter-spacing: .08em; text-transform: uppercase; }
/* the current plate is marked ON the item: a rule under its own word, so nothing floats beside
   it and the item never changes width */
.rail .word { position: relative; }
.rail .word::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -7px; height: 2px;
  background: var(--neon); transform: scaleX(0); transform-origin: left center; transition: transform .18s;
}
.rail a:hover { color: var(--ink); }
.rail a:hover .word::after { transform: scaleX(1); background: var(--neon-2); }
.rail a:active { color: var(--neon); }
.rail a[aria-current="true"] { color: var(--ink); }
.rail a[aria-current="true"] .num { color: var(--neon); }
.rail a[aria-current="true"] .word::after { transform: scaleX(1); background: var(--neon); }
.rail-toggle { display: none; }

/* --------------------------------------------------------------- the sheet */
.sheet { grid-column: 2; width: 100%; min-width: 0; padding: var(--s-7) 0 var(--s-9); }
.band { position: relative; padding-top: var(--band); min-width: 0; }
.band-head { padding-top: 0; }
.band + .band::before {
  content: ""; position: absolute; left: 0; right: 0; top: calc(var(--band) / 2);
  height: 1px; background: linear-gradient(90deg, transparent, var(--neon-2) 12%, var(--neon) 50%, var(--neon-2) 88%, transparent);
  opacity: .5;
}

/* ------------------------------------------------------------ I. masthead */
.masthead { margin: 0; }
.masthead img { display: block; width: 97%; }
.subtitle {
  margin: calc(var(--s-1) * -1) 0 0; text-align: right;
  font: 900 italic clamp(24px, 3.1vw, 40px)/1.1 var(--voice);
  color: var(--ink);
}
.headfoot { display: flex; align-items: center; justify-content: space-between; gap: var(--s-5); flex-wrap: wrap; margin-top: var(--s-5); }
.stamp { display: flex; align-items: center; gap: var(--s-3); }
.stamp img { width: 56px; height: auto; }
.stamp-text { display: grid; }
.stamp-text b { font: 700 var(--t-1)/1.3 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.stamp-text i { font: 500 var(--t-1)/1.3 var(--voice); font-style: normal; color: var(--ink-2); }
.ticker { margin: 0; font: 700 var(--t-1)/1.3 var(--voice); letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); }
.ticker .sep { color: var(--neon-2); padding: 0 var(--s-2); }

/* The state row: four equal columns, flush with both edges of the sheet, and the three lines of
   every cell on the SAME baseline as the other three cells (subgrid), so the row reads across. */
.state {
  position: relative; margin: var(--s-6) 0 0; padding: var(--s-5) 0;
  display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto auto auto;
  column-gap: var(--s-7);
}
.state::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--neon-2); opacity: .75; }
.state .cell { position: relative; grid-row: span 3; display: grid; grid-template-rows: subgrid; min-width: 0; }
.state .cell + .cell::before { content: ""; position: absolute; left: calc(var(--s-5) * -1); top: 0; bottom: 0; width: 1px; background: var(--neon-2); opacity: .55; }
.state dt { font: 700 var(--t-1)/1.2 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.state dd { margin: 0; }
.state .val {
  font: 300 var(--t-value)/1.12 var(--display); color: var(--ink);
  margin-top: var(--s-2);
  font-variant-numeric: tabular-nums; overflow-wrap: anywhere;
}
.state .val small { font: 700 var(--t-1)/1 var(--voice); letter-spacing: .06em; color: var(--ink-2); }
.state .note { margin-top: var(--s-2); font: 500 var(--t-1)/1.35 var(--voice); color: var(--ink-2); }
.state .val.live { color: var(--neon); }

/* the memo keeps its label in the same column the numerals run down */
.memo { position: relative; margin: 0; padding: var(--s-5) 0 0; display: grid; grid-template-columns: var(--num) 1fr; column-gap: var(--s-4); align-items: baseline; }
.memo::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--neon-2); opacity: .45; }
.memo-label { font: 700 var(--t-1)/1.45 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.memo code { font: 300 var(--t-1)/1.45 var(--display); color: var(--ink-2); overflow-wrap: anywhere; min-width: 0; }
.memo code.on { color: var(--ink); }
.memo a { color: var(--ink); text-decoration-color: var(--neon-2); text-underline-offset: 4px; }

/* ------------------------------------------------------------- I. the field */
/* The dog STANDS on the floor: the picture is cut to the animal, its box bottom is the paw line,
   and the canvas draws the shadow and the contact pool there. See js/field.mjs: HORIZON. */
.field { position: relative; margin-top: var(--s-6); height: clamp(460px, 46vw, 580px); }
.field #floor { position: absolute; inset: 0; width: 100%; height: 100%; }
.field .dog { position: absolute; left: 50%; bottom: 20%; width: auto; height: 58%; transform: translateX(-50%); }
.field .bill { position: absolute; }
/* every object at exactly half of its own file, so the stipple is the same density on all four */
.field .b050 { width: 240px; left: 4%;  top: 18%; }
.field .b010 { width: 134px; right: 5%; top: 10%; filter: brightness(.88); }
.field .b005 { width: 104px; left: 27%; top: 3%;  filter: brightness(.76); }
.field .b001 { width: 76px;  right: 26%; top: 30%; filter: brightness(.68); }

/* the statement is set in two columns: one printed band of 1120 px would run 140 characters */
.statement {
  margin: var(--s-6) 0 0; text-align: justify; text-justify: inter-word; hyphens: auto;
  font: 700 var(--t-1)/1.62 var(--voice); color: var(--ink-2);
  columns: 2; column-gap: var(--s-7);
}

/* --------------------------------------------------------------- band heads */
.bandhead { display: grid; grid-template-columns: var(--num) 1fr; column-gap: var(--s-4); align-items: baseline; }
.bandhead .plate { font: 300 var(--t-4)/1 var(--display); color: var(--neon); text-align: right; }
.bandhead h2 { margin: 0; font: 300 var(--t-head)/1 var(--display); color: var(--ink); }
.bandhead p { grid-column: 2; margin: var(--s-3) 0 0; font: 500 var(--t-1)/1.5 var(--voice); color: var(--ink-2); max-width: 62ch; }

/* ------------------------------------------------------------- II. the bills */
.denoms { list-style: none; margin: var(--s-6) 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); align-items: end; }
.denoms li { display: grid; justify-items: center; align-content: end; row-gap: var(--s-3); }
.denoms img { display: block; }
/* the ladder sits INSIDE its cell: at 1440 a 240 px object fills a 240 px column edge to edge
   and the first one reads as cut by the sheet */
.denoms li:nth-child(1) img { width: 204px; }
.denoms li:nth-child(2) img { width: 114px; }
.denoms li:nth-child(3) img { width: 88px; }
.denoms li:nth-child(4) img { width: 64px; }
.denoms b { font: 300 var(--t-4)/1 var(--display); color: var(--ink); }
.denoms span { font: 700 var(--t-1)/1 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }

.splitter { position: relative; margin-top: var(--s-7); display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s-7); }
.splitter::before { content: ""; position: absolute; left: 0; right: 0; top: calc(var(--s-5) * -1); height: 1px; background: var(--neon-2); opacity: .55; }
.splitter label { display: block; font: 700 var(--t-1)/1.2 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.inputrow { display: flex; align-items: baseline; gap: var(--s-3); margin-top: var(--s-3); }
.inputrow input {
  width: 100%; max-width: 320px; min-width: 0; background: transparent; color: var(--ink);
  border: 0; border-bottom: 1px solid var(--neon-2); padding: var(--s-2) 0;
  font: 300 var(--t-5)/1.1 var(--display); font-variant-numeric: tabular-nums;
}
.inputrow input:focus { outline: none; border-bottom-color: var(--neon); }
.inputrow .unit { font: 700 var(--t-1)/1 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.hint { margin: var(--s-4) 0 0; font: 500 var(--t-1)/1.5 var(--voice); color: var(--ink-2); max-width: 46ch; }
.bills-strip { margin: 0; display: flex; flex-wrap: wrap; gap: var(--s-2); min-height: 56px; }
.bills-strip span {
  font: 300 var(--t-2)/1 var(--display); color: var(--ink); padding: var(--s-4) var(--s-5);
  background: var(--haze); border-radius: 28px;
}
.bills-strip .none { background: none; padding: var(--s-4) 0; color: var(--ink-2); font: 500 var(--t-1)/1 var(--voice); }
.mini { display: grid; grid-template-columns: repeat(3, 1fr); margin: var(--s-5) 0 0; column-gap: var(--s-5); }
.mini dt { font: 700 var(--t-1)/1.2 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.mini dd { margin: var(--s-2) 0 0; font: 300 var(--t-3)/1.1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; }
.aside { margin: var(--s-6) 0 0; font: 500 var(--t-1)/1.55 var(--voice); color: var(--ink-2); max-width: 78ch; }

/* ------------------------------------------------------------ III. the board */
.baskets { display: grid; grid-template-columns: repeat(3, 1fr); column-gap: var(--s-7); margin-top: var(--s-6); }
.basket { position: relative; }
.basket + .basket::before { content: ""; position: absolute; left: calc(var(--s-5) * -1); top: var(--s-1); bottom: var(--s-1); width: 1px; background: var(--neon-2); opacity: .55; }
.basket b { display: block; font: 300 var(--t-5)/1 var(--display); color: var(--ink); font-variant-numeric: tabular-nums; }
.basket span { display: block; margin-top: var(--s-2); font: 500 var(--t-1)/1.4 var(--voice); color: var(--ink-2); }

.board { margin-top: var(--s-6); display: flex; flex-wrap: wrap; gap: var(--s-3); }
.board .empty { margin: 0; font: 500 var(--t-1)/1.6 var(--voice); color: var(--ink-2); }
.maskchip {
  display: inline-grid; grid-template-columns: auto auto; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-5); border-radius: 28px; background: var(--haze);
  font: 300 var(--t-3)/1 var(--display); color: var(--ink-2); font-variant-numeric: tabular-nums;
}
.maskchip img { width: 20px; height: 20px; }
.maskchip.b6 { color: var(--ink); background: rgba(68, 224, 97, .22); }
.maskchip.b21 { color: var(--ink); background: rgba(68, 224, 97, .34); }

/* ------------------------------------------------------------- IV. your line */
.mine { margin-top: var(--s-6); display: grid; grid-template-columns: 340px 1fr; column-gap: var(--s-7); align-items: start; }
.mine-out .empty { margin: 0; font: 500 var(--t-1)/1.6 var(--voice); color: var(--ink-2); }
.mine-rows { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5) var(--s-7); margin: 0; }
.mine-rows dt { font: 700 var(--t-1)/1.2 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.mine-rows dd { margin: var(--s-2) 0 0; font: 300 var(--t-4)/1.1 var(--display); color: var(--ink); overflow-wrap: anywhere; }
.proof { margin: var(--s-5) 0 0; font: 500 var(--t-1)/1.55 var(--voice); color: var(--ink-2); }
.proof b { color: var(--ink); }
.proof code { font: 300 var(--t-1)/1.5 var(--display); color: var(--ink-2); overflow-wrap: anywhere; }

/* ----------------------------------------------------------------- V. steps */
.steps { margin: var(--s-6) 0 0; padding: 0; list-style: none; counter-reset: step; display: grid; gap: var(--s-5); }
.steps li { position: relative; padding-left: calc(var(--num) + var(--s-4)); font: 500 var(--t-1)/1.6 var(--voice); color: var(--ink-2); max-width: 86ch; counter-increment: step; }
.steps li::before {
  content: counter(step); position: absolute; left: 0; top: calc(var(--s-1) * -1); width: var(--num); text-align: right;
  font: 300 var(--t-4)/1 var(--display); color: var(--neon);
}
.steps b { color: var(--ink); font-weight: 700; }

.cuts { position: relative; margin-top: var(--s-7); display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s-7); }
.cuts::before { content: ""; position: absolute; left: 0; right: 0; top: calc(var(--s-5) * -1); height: 1px; background: var(--neon-2); opacity: .55; }
.cut h3 { margin: 0 0 var(--s-3); font: 300 var(--t-3)/1.1 var(--display); color: var(--ink); }
.cut p { margin: 0 0 var(--s-3); font: 500 var(--t-1)/1.58 var(--voice); color: var(--ink-2); }
.cut p b { color: var(--ink); font-weight: 700; }

/* --------------------------------------------------------------- VI. the plate */
.band-mint { padding-top: calc(var(--band) + var(--s-2)); }
.plateframe {
  border-style: solid; border-width: 36px;
  border-image: url("../img/keyplate.webp") 26 fill / 36px / 0 stretch;
}
.platebody { padding: var(--s-3) var(--s-5) var(--s-4); }
.plate-ticker { margin: 0; font: 300 var(--t-head)/1 var(--display); color: var(--ink); }
.plate-label { margin: var(--s-4) 0 0; font: 700 var(--t-1)/1.2 var(--voice); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-2); }
.carow { display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap; margin-top: var(--s-3); }
.ca {
  font: 300 clamp(20px, 1.7vw, 24px)/1.45 var(--display); color: var(--ink);
  letter-spacing: .02em; overflow-wrap: anywhere; min-width: 0; flex: 0 1 auto; max-width: 100%;
  user-select: all;
}
.ca.empty { color: var(--ink-2); user-select: none; }
.keys { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-3); margin-top: var(--s-5); }

.key {
  display: inline-grid; grid-auto-flow: column; align-items: center; justify-content: center;
  gap: var(--s-3); min-height: 52px; padding: 0 var(--s-5); cursor: pointer; text-decoration: none;
  color: var(--ink); background: transparent;
  font: 700 var(--t-1)/1 var(--voice); letter-spacing: .06em; text-transform: uppercase;
  border-style: solid; border-width: 14px;
  border-image: url("../img/keyplate.webp") 26 fill / 14px / 0 stretch;
  transition: transform .08s, filter .18s;
}
.key img { width: 22px; height: 22px; }
.key.wide { width: 100%; }
.key:hover, .key:focus-visible { filter: brightness(1.25); }
.key:active { transform: translateY(1px); }
.key[disabled], .key[aria-disabled="true"] { cursor: not-allowed; color: var(--ink-2); filter: brightness(.74); }
.key.done { color: var(--ink); }

.risk { margin: var(--s-6) 0 0; font: 500 var(--t-1)/1.55 var(--voice); color: var(--ink-2); max-width: 86ch; }

/* ------------------------------------------------------------------ narrow */
/* Below this the rail cannot keep a column of its own without squeezing the sheet off centre,
   so it becomes the drawer at the top and the sheet takes the window with equal margins. */
@media (max-width: 1279px) {
  :root { --page: min(1120px, 100vw - var(--s-7)); }
  body { grid-template-columns: var(--page); column-gap: 0; }
  .sheet { grid-column: 1; padding-top: var(--s-9); }
  .rail {
    grid-column: 1; position: fixed; top: 0; left: 0; right: 0; padding: 0; z-index: 2;
    background: rgba(8, 12, 9, .94); backdrop-filter: blur(6px);
  }
  .rail-toggle {
    display: block; width: 100%; min-height: 52px; padding: 0 var(--s-5); text-align: left;
    background: transparent; border: 0; border-bottom: 1px solid var(--neon-2); color: var(--ink);
    font: 700 var(--t-1)/52px var(--voice); letter-spacing: .08em; text-transform: uppercase; cursor: pointer;
  }
  .rail ol { display: none; padding: var(--s-3) var(--s-5) var(--s-5); border-bottom: 1px solid var(--neon-2); }
  .rail.open ol { display: block; }
  .rail a { min-height: 44px; }
}
@media (max-width: 900px) {
  :root { --band: var(--s-8); }
  .state { grid-template-columns: repeat(2, 1fr); grid-template-rows: none; row-gap: var(--s-5); }
  .state .cell { grid-row: auto; display: block; }
  .splitter, .cuts, .mine { grid-template-columns: 1fr; row-gap: var(--s-6); }
  .field { height: clamp(380px, 62vw, 480px); }
  /* a quarter of each file now, still one scale for all four */
  .field .b050 { width: 100px; left: 4%; top: 20%; }
  .field .b010 { width: 56px; right: 6%; top: 10%; }
  .field .b005 { width: 44px; left: 28%; top: 3%; }
  .field .b001 { width: 32px; right: 20%; top: 34%; }
  .statement { columns: 1; text-align: left; }
  .denoms { grid-template-columns: repeat(2, 1fr); row-gap: var(--s-6); }
  .baskets { grid-template-columns: 1fr; row-gap: var(--s-5); }
  .basket + .basket::before { left: 0; right: 0; top: calc(var(--s-3) * -1); bottom: auto; width: auto; height: 1px; margin-left: 0; }
  .mine-rows { grid-template-columns: 1fr; }
  .keys { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  :root { --page: min(1120px, 100vw - var(--s-6)); }
  .subtitle { text-align: left; margin-top: var(--s-2); }
  .denoms li:nth-child(1) img { width: 120px; }
  .denoms li:nth-child(2) img { width: 67px; }
  .denoms li:nth-child(3) img { width: 52px; }
  .denoms li:nth-child(4) img { width: 38px; }
  .plateframe { border-width: 26px; border-image-width: 26px; }
  .platebody { padding: var(--s-1) var(--s-3) var(--s-3); }
  .keys { grid-template-columns: 1fr; }
  .key { justify-content: start; }
}
@media (max-width: 480px) {
  /* at this width two cells each hold three wrapped words, so the row becomes a list */
  .state { grid-template-columns: 1fr; }
  .state .cell + .cell::before { left: 0; right: 0; top: calc(var(--s-3) * -1); bottom: auto; width: auto; height: 1px; }
  .memo { grid-template-columns: 1fr; row-gap: var(--s-1); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}
