/* Artificial Selection. Five colours, one desk, windows made of generated plates.
   Every surface on this page is a nine sliced picture from img/v4/, never a CSS box. */

@font-face { font-family: Galmuri; src: url(fonts/Galmuri11.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Galmuri; src: url(fonts/Galmuri11-Bold.woff2) format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: Excon; src: url(fonts/Excon-Regular.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Excon; src: url(fonts/Excon-Medium.woff2) format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: Excon; src: url(fonts/Excon-Bold.woff2) format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: RX; src: url(fonts/RX100-Regular.woff2) format("woff2"); font-weight: 400; font-display: swap; }

:root {
  --desk: #12acac;
  --bright: #2edc7b;
  --mid: #007950;
  --ink: #034c2f;
  --screen: #d9ffea;

  /* What text may be, measured rather than judged by eye. Every pair below is a WCAG contrast
     ratio against the surface it is named for, and nothing on this page is set outside this list.
     A window body and a specimen cell are INK; a panel inside them is SCREEN; a title strip, a
     pressed key and a disabled key are MID; a key is BRIGHT.

       on ink     screen 9.35   bright 5.60   (body text, then labels and numbers)
       on screen  ink    9.35   mid    5.05   (body text, then headings and secondary)
       on mid     screen 5.05                 (the title strip and the pressed states)
       on bright  ink    5.60                 (every key)

     Nothing is dimmed with opacity: a muted tone is a named colour that still measures 4.5:1. */
  --on-dark: var(--screen);      /* body copy and values on an ink surface   9.35:1 */
  --on-dark-label: var(--bright);/* labels, pixel subheads, numbers on ink    5.60:1 */
  --on-light: var(--ink);        /* body copy and values on a screen panel   9.35:1 */
  --on-light-label: var(--mid);  /* headings and secondary on a screen panel 5.05:1 */
  --on-strip: var(--screen);     /* the window title strip and pressed keys  5.05:1 */
  --on-key: var(--ink);          /* every key face                           5.60:1 */

  /* hairlines, mixed from the palette so no sixth colour enters the page */
  --rule-dark: color-mix(in srgb, var(--mid) 72%, var(--ink));
  --rule-light: color-mix(in srgb, var(--mid) 32%, var(--screen));

  --pixel: Galmuri, "Courier New", monospace;
  --text: Excon, "Segoe UI", system-ui, sans-serif;
  --mono: RX, ui-monospace, "Cascadia Mono", monospace;

  /* Galmuri11 is drawn on an 11 px grid: only multiples of 11 land on whole pixels, anything else
     smears the glyphs. Every pixel size on this page comes from here. */
  --px-s: 22px;
  --px-m: 33px;
  --px-l: 44px;

  --gap: 24px;
  --pad: 32px;
  --band: 72px;
}

* { box-sizing: border-box; }

html { background: var(--desk); }

body {
  margin: 0;
  background: var(--desk);
  color: var(--on-light);
  font-family: var(--text);
  font-size: 18px;
  line-height: 1.55;
  font-synthesis: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
}

img, canvas { image-rendering: pixelated; }

/* The pixel face now carries four things and nothing else: a window's title strip, the countdown,
   and a genome's code wherever it appears. It is a bitmap, so smoothing it is what turns a glyph
   into a smudge, and every element below asks the browser for the raw bitmap instead. Everything
   that used to be set in it (labels, values, headings, button faces) is on the text face or the
   mono now, because at 22 px a bitmap face is a texture and not a word. */
.win__name, .win__sub, .clock, .stage__id, .cell__id, .tbl td:nth-child(2), .tree__node b {
  -webkit-font-smoothing: none;
  -moz-osx-font-smoothing: auto;
  font-smooth: never;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  font-family: var(--text); font-weight: 700; font-size: 19px; color: var(--on-key);
  background: var(--bright); padding: 14px 24px; z-index: 50;
}
.skip:focus { left: 16px; top: 16px; }

/* Two rings, so the focus is visible on every surface this page has: the near white ring reads on
   ink and mid, the ink ring reads on a screen panel and on a key. */
:focus-visible {
  outline: 4px solid var(--screen);
  outline-offset: 3px;
  box-shadow: 0 0 0 11px var(--ink);
}

/* ---------------------------------------------------------------- the desk */

.desk {
  max-width: 1680px;
  margin: 0 auto;
  padding: 48px 40px 96px;
  display: flex;
  flex-direction: column;
  gap: var(--band);
}

.band { display: grid; grid-template-columns: 1fr; gap: var(--gap); align-items: stretch; }
.band--7-5 { grid-template-columns: 7fr 5fr; }
.stack { display: grid; grid-template-rows: auto 1fr; gap: var(--gap); min-width: 0; }

/* ------------------------------------------------------------- the windows */

.win {
  min-width: 0;
  border: 12px solid transparent;
  border-image: url(img/v4/plate-win.png) 12 fill / 12px / 0 stretch;
  box-shadow: 9px 9px 0 var(--ink);
  display: flex;
  flex-direction: column;
  container-type: inline-size;
}

.win__bar {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 84px;
  padding: 24px 28px;
  border: 0 solid transparent;
  border-bottom-width: 6px;
  border-image: url(img/v4/plate-bar.png) 0 0 6 0 fill / 0 0 6px 0 / 0 stretch;
  font-weight: 400;
  cursor: grab;
  touch-action: none;
}
.win__bar:active { cursor: grabbing; }

/* Every sprite ships at 1x (16 px for an icon or a control, 12 px for a gene glyph) and is shown
   at an exact multiple of that grid, so no pixel is ever resampled, on a 1x or a 2x screen. */
.win__icon { width: 48px; height: 48px; flex: none; }

.win__name {
  min-width: 0;
  overflow-wrap: break-word;
  font-family: var(--pixel);
  font-weight: 700;
  font-size: var(--px-m);
  line-height: 1;
  color: var(--on-strip);
  letter-spacing: 0;
}

.win__sub {
  font-family: var(--pixel);
  font-weight: 700;
  font-size: var(--px-s);
  color: var(--on-strip);
  padding-top: 7px;
}

.win__ctl { margin-left: auto; display: flex; gap: 10px; flex: none; }

.ctl {
  width: 52px; height: 52px; padding: 0;
  border: 9px solid transparent;
  border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch;
  background: none;
  font-family: var(--text); font-weight: 700; font-size: 19px; line-height: 1;
  color: var(--on-key);
  cursor: pointer;
  display: grid; place-items: center;
}
.ctl img { width: 32px; height: 32px; }
.ctl:hover { filter: brightness(1.12); }
.ctl:active, .ctl[aria-pressed="true"] { border-image: url(img/v4/plate-key-down.png) 9 fill / 9px / 0 stretch; color: var(--on-strip); }

.win__body { padding: var(--pad); display: flex; flex-direction: column; gap: 24px; flex: 1; min-width: 0; }
.win--rolled .win__body { display: none; }

/* --------------------------------------------------------------- the text */

.lead { margin: 0; font-size: 21px; line-height: 1.5; color: var(--on-dark); max-width: 62ch; }
.rowlabel { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); max-width: 70ch; }
.note { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); }
.limits { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); max-width: 78ch; }

.sub {
  margin: 0;
  font-family: var(--text); font-weight: 700; font-size: 23px; line-height: 1.25;
  color: var(--on-dark-label);
}

/* A link inside a panel, which is every signature and every wallet on this page. Without this the
   browser paints its own blue, which only shows once there is something to link to. The vertical
   padding buys a 44 px hit area on a phone and moves nothing: padding on an inline box does not
   grow the line it sits in. */
.screen a {
  color: var(--on-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 2px;
  padding: 10px 0;
}
.screen a:hover { text-decoration-thickness: 4px; }
.screen a:active { color: var(--on-light-label); }

/* ------------------------------------------------- the near white surfaces */

.screen {
  border: 6px solid transparent;
  border-image: url(img/v4/plate-screen.png) 6 fill / 6px / 0 stretch;
  padding: 24px;
  color: var(--on-light);
  min-width: 0;
}

/* The honest "nothing here yet" line. It sits on a near white panel and is the first thing read on
   a cold page, so it is the panel's own body colour, not a dimmed one. */
.empty { margin: 0; padding: 16px; font-size: 18px; line-height: 1.55; color: var(--on-light); }

/* ----------------------------------------------------------- the dark stage */

.stage {
  border: 6px solid transparent;
  border-image: url(img/v4/plate-ink.png) 6 fill / 6px / 0 stretch;
  padding: 32px;
  display: grid;
  justify-items: center;
  align-content: space-between;
  text-align: center;
  gap: 10px;
  min-width: 0;
}

.stage__label { margin: 0; font-family: var(--text); font-weight: 700; font-size: 19px; letter-spacing: .04em; color: var(--on-dark-label); }
.stage__sub { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); max-width: 86ch; }

/* The countdown steps down the 11 px grid rather than scaling with the column: a fractional pixel
   size is what smeared it. Every step below is 11 x n. */
.clock {
  margin: 6px 0 18px;
  font-family: var(--pixel); font-weight: 700;
  font-size: 88px; line-height: 1;
  color: var(--on-dark);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

#livingFinch { width: 100%; max-width: 288px; aspect-ratio: 6 / 5; display: block; margin: 0 auto; }
.stage__id { margin: 10px 0 0; font-family: var(--pixel); font-weight: 700; font-size: var(--px-s); color: var(--on-dark-label); }

.stage--small { padding: 20px; gap: 6px; }
.stage--small #yourFinch { width: 100%; max-width: 252px; aspect-ratio: 6 / 5; display: block; margin: 0 auto; }

/* ------------------------------------------------------------- the genes */

.live { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 24px; align-items: stretch; }
@container (max-width: 1080px) { .clock { font-size: 66px; } }
@container (max-width: 820px) {
  .live { grid-template-columns: minmax(0, 1fr); }
  .clock { font-size: 77px; }
}
@container (max-width: 560px) { .clock { font-size: 55px; } }
@container (max-width: 420px) { .clock { font-size: 44px; } }
/* On the narrowest phone the stage is 208 px wide inside its own frame, and a 33 px countdown would
   stand closer to the edge than its own type size. One more step down the 11 px grid. */
@container (max-width: 340px) { .clock { font-size: 22px; } }

.genes { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-content: start; }
@container (max-width: 820px) { .genes { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 28px; } }
@container (max-width: 520px) { .genes { grid-template-columns: minmax(0, 1fr); } }

.gene { display: grid; grid-template-columns: 36px minmax(0, 1fr) 96px; gap: 14px; align-items: center; min-width: 0; }
@container (max-width: 820px) { .gene { grid-template-columns: 36px minmax(0, 1fr) auto; } }
/* On a phone the share drops under its own name rather than squeezing it: a gene name is one
   word and has nowhere to wrap to. It keeps its right alignment, so the column still reads. */
@container (max-width: 380px) {
  .gene { grid-template-columns: 36px minmax(0, 1fr); }
  .gene__val { grid-column: 2; }
}
.gene__icon { width: 36px; height: 36px; }
.gene__name { font-family: var(--text); font-weight: 700; font-size: 21px; color: var(--on-dark); }
/* The groove is ink with a bright rim; the fill is bright and never thinner than two drawn pixels,
   so a share of a few per cent is still a bar and not a hairline. */
.gene__bar { height: 24px; border: 3px solid transparent; border-image: url(img/v4/plate-track.png) 3 fill / 3px / 0 stretch; position: relative; }
.gene__fill { position: absolute; inset: 0 auto 0 0; background: var(--bright); }
.gene__val { font-family: var(--mono); font-size: 23px; line-height: 1.2; color: var(--on-dark-label); text-align: right; font-variant-numeric: tabular-nums; }
.gene__line { grid-column: 1 / -1; font-size: 18px; line-height: 1.5; color: var(--on-dark); margin: 0; }

/* ------------------------------------------------------------ the keys */

.keys { display: flex; flex-wrap: wrap; gap: 14px; }
.keys--grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }

.key {
  min-height: 56px;
  padding: 12px 28px;
  border: 9px solid transparent;
  border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch;
  background: none;
  font-family: var(--text); font-weight: 700; font-size: 19px; line-height: 1.2;
  color: var(--on-key);
  text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  cursor: pointer;
  text-align: center;
}
.key:hover { filter: brightness(1.1); }
.key:active { border-image: url(img/v4/plate-key-down.png) 9 fill / 9px / 0 stretch; color: var(--on-strip); }
/* A key with nothing behind it yet: the mid face it wears carries the near white label at 5.05:1.
   It was the bright green on mid at 3.02:1, which is where "not clickable" became "not readable". */
.key[disabled], .key[aria-disabled="true"] {
  border-image: url(img/v4/plate-key-off.png) 9 fill / 9px / 0 stretch;
  color: var(--on-strip); cursor: not-allowed; pointer-events: none;
}
.key--mark img { width: 20px; height: 20px; image-rendering: auto; }

/* ------------------------------------------------------------ the mint */

.mint {
  font-family: var(--mono); font-size: 20px; line-height: 1.5;
  word-break: break-all; overflow-wrap: anywhere;
  user-select: all;
}
.mint.is-empty { font-family: var(--text); font-size: 18px; line-height: 1.55; color: var(--on-light); user-select: auto; word-break: normal; overflow-wrap: normal; }

/* ------------------------------------------------------------ fact lists */

/* The label is the quieter of the two and the value is the loudest thing in the row: 5.60:1 for
   the label, 9.35:1 for the number, so "not yet" is read before the words that introduce it. */
.facts { margin: 0; display: grid; gap: 0; }
.facts > div {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; align-items: baseline;
  padding: 14px 24px;
  border-bottom: 3px solid var(--rule-dark);
  min-width: 0;
}
/* A value sized `auto` takes what it needs, and a long one ("1 of 10 generations" set in the mono)
   leaves the label nothing and pushes its words out of the row. Under a short row the two stop
   sharing a line. */
@container (max-width: 420px) {
  .facts > div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
}
.facts > div:last-child { border-bottom: 0; }
.facts dt { font-size: 18px; line-height: 1.5; color: var(--on-dark-label); }
.facts dd { margin: 0; font-family: var(--mono); font-size: 21px; color: var(--on-dark); text-align: right; }

/* ------------------------------------------------------------ the log */

.log { display: grid; gap: 0; padding: 4px; }
.log__row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 16px; align-items: baseline; padding: 12px 26px; border-bottom: 3px solid var(--rule-light); }
.log__row:last-child { border-bottom: 0; }
.log__time { font-family: var(--mono); font-size: 19px; color: var(--on-light-label); }
.log__what { font-size: 18px; line-height: 1.5; color: var(--on-light); min-width: 0; }
.log__sig { font-family: var(--mono); font-size: 19px; color: var(--on-light); text-decoration: underline; white-space: nowrap; }

/* On a narrow desk the log row stops being three columns: the time and the signature keep the top
   line, and what the genome did gets the whole width under them. */
@container (max-width: 560px) {
  .log__row { grid-template-columns: auto 1fr; gap: 6px 16px; }
  .log__time { grid-area: 1 / 1; }
  .log__sig { grid-area: 1 / 2; justify-self: end; }
  .log__what { grid-area: 2 / 1 / 3 / 3; }
}

/* ------------------------------------------------------------ the notes */

.notes { display: grid; gap: 0; padding: 4px; }
.note__item { padding: 18px 26px; border-bottom: 3px solid var(--rule-light); }
.note__item:last-child { border-bottom: 0; }
.note__head { margin: 0 0 6px; font-family: var(--text); font-weight: 700; font-size: 19px; color: var(--on-light-label); }
.note__text { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-light); }

/* ------------------------------------------------------- the population */

/* Six across on a full desk, then four, three and two. The step is chosen by what a cell still has
   room for: a cell needs about 150 px to hold a bird at x4 and the genome code beside it, and the
   grid drops a column before it goes under that rather than after. One column only on the very
   narrowest phone, where two would leave 50 px of picture. */
.pop { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; grid-template-columns: repeat(6, minmax(0, 1fr)); }
@container (max-width: 1400px) { .pop { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@container (max-width: 1000px) { .pop { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container (max-width: 700px) { .pop { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; } }
@container (max-width: 330px) { .pop { grid-template-columns: minmax(0, 1fr); } }

/* One frame of one thickness on all twelve. The live cell used to wear a 12 px plate against the
   others' 9 px, which moved its whole content in by three pixels and read as a second border. */
.cellbox {
  border: 9px solid transparent;
  border-image: url(img/v4/plate-cell.png) 9 fill / 9px / 0 stretch;
  padding: 18px 16px 20px;
  display: grid;
  grid-template-rows: auto auto auto auto;
  justify-items: center;
  align-content: start;
  gap: 10px;
  height: 100%;
  text-align: center;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
.cellbox--live { border-image: url(img/v4/plate-cell-live.png) 9 fill / 9px / 0 stretch; }

/* A cell is a link to this genome's row in the score sheet, so it is a real control with real
   states rather than a card that only pretends to be one. */
.cellbox:hover, .cellbox:focus-visible { border-image: url(img/v4/plate-cell-hover.png) 9 fill / 9px / 0 stretch; }
.cellbox:active { border-image: url(img/v4/plate-cell-live.png) 9 fill / 9px / 0 stretch; }
.cellbox:active .cell__id { color: var(--on-dark); }
.cellbox:hover .cell__id, .cellbox:focus-visible .cell__id { color: var(--on-dark-label); }

/* The bird gets a budget, not a size: paint() picks the largest whole multiple of its 36 x 30 grid
   that fits and writes the exact pixels back, so nothing is ever resampled. */
.cellbox canvas { width: 100%; max-width: 144px; aspect-ratio: 6 / 5; display: block; }

.cell__id { margin: 0; font-family: var(--pixel); font-weight: 700; font-size: var(--px-s); color: var(--on-dark); }
.cell__when { margin: 0; font-size: 18px; line-height: 1.4; color: var(--on-dark); }
.cell__score { margin: 0; font-family: var(--mono); font-size: 22px; line-height: 1.2; color: var(--on-dark-label); }
.cellbox--live .cell__id { color: var(--on-dark-label); }

/* ------------------------------------------------------------ the table */

.tablewrap { overflow-x: auto; overscroll-behavior-x: contain; padding: 14px 24px; }
.tbl { border-collapse: collapse; width: 100%; min-width: 0; }
.tbl th, .tbl td { text-align: left; padding: 14px 24px; border-bottom: 3px solid var(--rule-light); }
.tbl th { font-family: var(--text); font-weight: 700; font-size: 18px; color: var(--on-light-label); white-space: nowrap; }
.tbl td { font-family: var(--mono); font-size: 21px; color: var(--on-light); }
.tbl td:nth-child(2) { font-family: var(--pixel); font-weight: 700; font-size: var(--px-s); white-space: nowrap; }
.tbl .win-row td { color: var(--on-light-label); }
/* arrived at from a cell in the population: the row says so */
.tbl tr { scroll-margin-top: 96px; }
.tbl tr:target td, .tbl tr.is-found td { background: var(--bright); color: var(--on-key); }

/* ------------------------------------------------------------ the formula */

.formula { font-family: var(--mono); font-size: 21px; line-height: 1.6; color: var(--on-light); overflow-wrap: anywhere; }
.defs { margin: 0; display: grid; gap: 0; }
.defs > div { padding: 14px 24px; border-bottom: 3px solid var(--rule-dark); }
.defs > div:last-child { border-bottom: 0; }
.defs dt { font-family: var(--text); font-weight: 700; font-size: 20px; color: var(--on-dark-label); margin-bottom: 4px; }
.defs dd { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); max-width: 86ch; }
.basket { display: flex; flex-wrap: wrap; gap: 10px; }
.basket__chip { font-family: var(--mono); font-size: 19px; color: var(--on-light); }

/* ------------------------------------------------------------ the editor */

.editor { display: grid; grid-template-columns: minmax(0, 1fr) 324px; gap: 28px; align-items: start; }
@container (max-width: 760px) { .editor { grid-template-columns: minmax(0, 1fr); } }
.editor__sliders { display: grid; gap: 18px; }
.slider { display: grid; grid-template-columns: 36px minmax(0, 1fr) 76px; gap: 14px; align-items: center; min-width: 0; }
@container (max-width: 380px) {
  .slider { grid-template-columns: 36px minmax(0, 1fr); }
  .slider__val { grid-column: 2; }
}
.slider__name { font-family: var(--text); font-weight: 700; font-size: 21px; color: var(--on-dark); grid-column: 2; }
.slider__val { font-family: var(--mono); font-size: 23px; color: var(--on-dark-label); text-align: right; font-variant-numeric: tabular-nums; }
.slider input[type="range"] { grid-column: 1 / -1; width: 100%; margin: 0; accent-color: #2edc7b; height: 32px; }
.slider__what { grid-column: 1 / -1; margin: 0; font-size: 18px; line-height: 1.5; color: var(--on-dark); }
.editor__bird { display: grid; gap: 14px; justify-items: stretch; text-align: center; min-width: 0; }
.editor__bird canvas { margin: 0 auto; }
.editor__sum { margin: 0; font-size: 18px; line-height: 1.5; color: var(--on-dark); text-align: center; overflow-wrap: anywhere; }
.editor__rules { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; }
@container (max-width: 640px) { .editor__rules { grid-template-columns: minmax(0, 1fr); } }
.rule { margin: 0; border: 6px solid transparent; border-image: url(img/v4/plate-screen.png) 6 fill / 6px / 0 stretch; padding: 20px 24px 24px; }
.rule { padding: 24px; min-inline-size: 0; display: grid; gap: 4px; }
.rule::after { content: ""; display: table; clear: both; }
.rule legend { float: left; width: 100%; font-family: var(--text); font-weight: 700; font-size: 20px; color: var(--on-light-label); padding: 0; margin: 0 0 16px; display: flex; align-items: center; gap: 10px; }
.rule legend img { width: 36px; height: 36px; }
.rule label { display: flex; align-items: center; gap: 12px; font-size: 18px; line-height: 1.5; color: var(--on-light); min-height: 48px; min-width: 0; }
.rule input[type="range"] { width: 100%; margin: 0; accent-color: #007950; height: 32px; }
.rule output { font-family: var(--mono); font-size: 21px; color: var(--on-light); }
.subs { display: grid; gap: 10px; }
.sub__row { margin: 0; font-family: var(--mono); font-size: 19px; color: var(--on-light); overflow-wrap: anywhere; }

/* ------------------------------------------------------------ the season */

.seasonbar { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 10px; }
.seasonbar li { height: 60px; border: 3px solid transparent; border-image: url(img/v4/plate-track.png) 3 fill / 3px / 0 stretch; display: grid; place-items: center; font-family: var(--mono); font-size: 21px; color: var(--on-dark-label); }
.seasonbar li.is-done { background: none; border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch; border-width: 9px; color: var(--on-key); }
.split { display: grid; gap: 10px; }
.split__row { margin: 0; display: flex; align-items: baseline; gap: 16px; font-size: 18px; line-height: 1.5; color: var(--on-dark); }
.split__n { font-family: var(--mono); font-size: 32px; color: var(--on-dark-label); min-width: 96px; }

/* ------------------------------------------------------------ the pedigree */

.tree { padding: 24px; }
.tree__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 32px 40px; align-items: start; }
.tree__gen { display: grid; gap: 14px; align-content: start; }
.tree__nodes { display: grid; gap: 10px 36px; grid-auto-flow: column; grid-template-rows: repeat(6, auto); align-content: start; }
@container (max-width: 680px) { .tree__nodes { grid-auto-flow: row; grid-template-rows: none; } }
.tree__head { margin: 0 0 6px; font-family: var(--text); font-weight: 700; font-size: 19px; color: var(--on-light-label); }
.tree__node { font-family: var(--mono); font-size: 19px; color: var(--on-light); overflow-wrap: anywhere; }
.tree__node b { font-family: var(--pixel); font-weight: 700; font-size: var(--px-s); }
.tree__node.is-holder b { color: var(--on-light-label); }

/* ------------------------------------------------------------ the manual */

/* The four pictures are 96 x 64 and may only ever be shown at a whole multiple of that, or they
   resample and smear. A whole multiple is a fixed number of pixels, and a fixed number of pixels
   inside a `minmax(0, 1fr)` column overflows that column the moment the column is narrower than
   the picture: between about 624 and 760 px of viewport the picture ran up to 36 px past its own
   column and out through the right hand frame of the panel, which is why the panel looked as if it
   had padding on the left and none on the right. The fix is not overflow: it is that the picture
   steps DOWN a whole multiple before the column gets that narrow.
   The arithmetic every breakpoint below comes from, where c is the window's content width and p is
   the body's padding (32 px, 24 px under a 760 px viewport):
     four columns   col = (c - 2p - 3 x 24) / 4   needs col >= 288  ->  c >= 1288
     two columns    col = (c - 2p - 20) / 2       needs col >= 288  ->  c >= 660
     two columns at the smaller picture           needs col >= 192  ->  c >= 452
   `tools/audit.mjs` asserts the result rather than the arithmetic: nothing may cross the padding
   box of the window it lives in, at any width. */
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--gap); }
@container (max-width: 1287px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 20px; } }
@container (max-width: 451px) { .steps { grid-template-columns: minmax(0, 1fr); } }

/* Three rows shared by all four columns, so the picture, the heading and the paragraph each start
   on one line across the row however many lines a heading takes. */
.step { display: grid; grid-row: span 3; grid-template-rows: subgrid; gap: 14px; align-content: start; }
@supports not (grid-template-rows: subgrid) {
  .step { grid-row: auto; grid-template-rows: auto auto 1fr; }
  .step h3 { min-height: 2.7em; }
}

/* The size here is a BUDGET, never a width. snapPictures() in the app measures the column this
   actually lands in and writes back the largest whole multiple of 96 x 64 that fits, exactly as the
   bird canvases do. `max-width: 100%` is what holds if that script never runs: the picture then
   scales to the column and loses its crispness, which is a far smaller fault than bursting out
   through the side of the panel. Nothing here depends on a breakpoint being right any more. */
.step img { display: block; margin: 0 auto; width: 288px; height: 192px; max-width: 100%; }
.step h3 { margin: 0; font-family: var(--text); font-weight: 700; font-size: 20px; line-height: 1.35; color: var(--on-dark-label); }
.step p { margin: 0; font-size: 18px; line-height: 1.55; color: var(--on-dark); }

/* ------------------------------------------------------------ dragging */

.win.is-dragged { position: relative; z-index: 20; }

/* ------------------------------------------------------------ widths */

@media (max-width: 1180px) {
  .band--7-5 { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .desk { padding: 28px 20px 64px; gap: 48px; }
  :root { --pad: 24px; }
  .win__bar { min-height: 64px; padding: 0 20px; gap: 12px; }
  .win__name { font-size: var(--px-s); padding-top: 3px; }
  .win__icon { width: 32px; height: 32px; }
  .stage { padding: 28px 24px; }
  .stage--small #yourFinch { max-width: 180px; }
  #livingFinch { max-width: 216px; }
  .win__bar { cursor: default; }
  .lead { font-size: 19px; }
  .desk { gap: 40px; }
}

@media (max-width: 420px) {
  .win__name { font-size: var(--px-s); }
  .split__n { font-size: var(--px-s); min-width: 64px; }
  #livingFinch { max-width: 180px; }
}

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

@media (max-width: 760px) {
  .win__bar { min-height: 64px; padding: 14px 20px; }
  .win__sub { display: none; }
  /* A window cannot be dragged on a phone, so "put it back" has nothing to put back: the strip
     keeps only the control that still does something, and the name gets the room. */
  .ctl[data-act="home"] { display: none; }
}

/* the narrow desk: the cells lie down, the season splits in two, the readout fits */
@container (max-width: 520px) {
  .seasonbar { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 420px) {
  .desk { padding: 20px 14px 56px; }
  .win__bar { padding: 12px 14px; gap: 10px; min-height: 60px; }
  .win__icon { width: 32px; height: 32px; }
  .ctl { width: 44px; height: 44px; }
  .ctl img { width: 16px; height: 16px; }
  .win__ctl { gap: 8px; }
}

@media (max-width: 352px) {
  #livingFinch { max-width: 144px; }
  .stage { padding: 22px 24px; }
}

/* The two sliders are the only native controls on the page, so they wear the same plates as
   everything else: the track is the generated groove, the thumb is a generated key. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  height: 44px;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: 18px;
  border: 3px solid transparent;
  border-image: url(img/v4/plate-track.png) 3 fill / 3px / 0 stretch;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 34px;
  height: 40px;
  margin-top: -11px;
  box-sizing: border-box;
  border: 9px solid transparent;
  border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch;
}
input[type="range"]::-moz-range-track {
  height: 18px;
  border: 3px solid transparent;
  border-image: url(img/v4/plate-track.png) 3 fill / 3px / 0 stretch;
}
input[type="range"]::-moz-range-thumb {
  width: 34px;
  height: 40px;
  box-sizing: border-box;
  border: 9px solid transparent;
  border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch;
}
input[type="range"]:focus-visible::-webkit-slider-thumb { outline: 4px solid var(--screen); outline-offset: 2px; }

/* The radios of the pace gene wear the same two plates. */
.rule input[type="radio"] {
  appearance: none;
  width: 36px;
  height: 36px;
  flex: none;
  margin: 0;
  border: 9px solid transparent;
  border-image: url(img/v4/plate-key-off.png) 9 fill / 9px / 0 stretch;
}
.rule input[type="radio"]:checked { border-image: url(img/v4/plate-key.png) 9 fill / 9px / 0 stretch; }

/* On a narrow desk the score sheet stops being a table and becomes one block per life, each row a
   label and its number, so nothing scrolls sideways and no column is hidden. The table's own
   min-content width is 837 px with the gutters the padding rule asks for, and the panel around it
   costs 172 px, so it is a real table down to a window of 1010 px and only then lies down. */
@container (max-width: 1010px) {
  .tablewrap { padding: 14px; }
  .tbl, .tbl tbody, .tbl tr, .tbl td { display: block; min-width: 0; }
  .tbl thead { display: none; }
  .tbl tr { padding: 14px 0; border-bottom: 3px solid var(--rule-light); }
  .tablewrap { padding: 14px 0; }
  .tbl tr:last-child { border-bottom: 0; }
  .tbl td { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 16px; padding: 8px 22px; border: 0; }
  .tbl td::before { content: attr(data-label); font-family: var(--text); font-weight: 400; font-size: 18px; color: var(--on-light-label); }
  .tbl td:nth-child(2) { font-size: var(--px-s); }
}
