/* zaalyo.ai, screen. One stylesheet for every page.
 *
 * This file styles the exact tag and class vocabulary that worker/index.ts
 * markdown(), page(), archive(), sessionPage() and arcade() emit, and nothing
 * else. That is the whole trick: the vocabulary is closed, so once it is
 * styled, every session sheet the ops folder ever publishes is on brand with
 * no work here and no change to the worker.
 *
 * Rule for this file: no hex codes, no font names, no pixel values. If a value
 * is not in tokens/, it does not belong on the site.
 *
 * The restraint budget, per page: one orange owner, one brush, one mascot.
 * On a session page the code block owns the orange. Nothing else may claim it.
 *
 * On an article the owner is code, block and inline both. An article is read
 * alone by a stranger, and the things they have to type or recognise, an
 * address, a password, a pattern to avoid, are the whole point of the page.
 * That is one owner, not two: the same colour on the same kind of thing.
 * Italics stay plain, so emphasis never gets mistaken for something to type.
 */

@import url("tokens/fonts.css");
@import url("tokens/colors.css");
@import url("tokens/typography.css");
@import url("tokens/space.css");
@import url("tokens/motion.css");

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; color-scheme: dark; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-body);
  line-height: var(--lh-body);
  text-wrap: pretty;
  -webkit-font-smoothing: antialiased;
}

main {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-9);
}

/* page() passes "wide" for the arcade. Games are square, prose is not. */
main.wide { max-width: var(--page-max); }

:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* Headings.
 * h1 is the page title, set by page(). markdown() starts at h2, so h2 and h3
 * are a sheet's own structure. h4 and h5 become mono labels: deep headings in a
 * sheet are always short markers, so they get the brand's interface furniture
 * rather than another size of display type. */
h1 {
  font-family: var(--font-display);
  font-size: var(--text-h1); line-height: var(--lh-h1);
  letter-spacing: var(--ls-h1); font-weight: var(--weight-h1);
  margin: 0 0 var(--space-2);
}
h2 {
  font-family: var(--font-display);
  font-size: var(--text-h2); line-height: var(--lh-h2);
  font-weight: var(--weight-h2);
  margin: var(--space-7) 0 var(--space-3);
}
h3 {
  font-family: var(--font-display);
  font-size: var(--text-h3); line-height: var(--lh-h3);
  font-weight: var(--weight-h3);
  margin: var(--space-6) 0 var(--space-2);
}
h4, h5 {
  font-family: var(--font-mono);
  font-size: var(--text-label); line-height: var(--lh-small);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  font-weight: var(--weight-label); color: var(--text-faint);
  margin: var(--space-5) 0 var(--space-2);
}

p, ul, ol { margin: 0 0 var(--space-4); }
ul, ol { padding-left: var(--space-5); }
li { margin: 0 0 var(--space-2); }
li::marker { color: var(--text-faint); font-family: var(--font-mono); }
strong { font-weight: 600; }

a { color: var(--brand-text); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--orange-300); }

hr {
  border: 0;
  border-top: var(--border-width) solid var(--border);
  margin: var(--space-7) 0;
}

/* Set by page(). The label under a title: session number and date. */
.tagline {
  font-family: var(--font-mono);
  font-size: var(--text-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--text-faint);
  margin: 0 0 var(--space-6);
}

/* The quiet line at the foot of a page. */
.note { font-size: var(--text-small); line-height: var(--lh-small); color: var(--text-faint); }

/* The way back, on every page except the landing one. */
.back {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  margin: 0 0 var(--space-5);
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-muted); text-decoration: none;
}
.back::before { content: "</>"; color: var(--text-faint); }
.back:hover { color: var(--brand-text); }

/* A session in the archive list. Depth is the surface step plus a 1px border,
 * and nothing else: no shadow, because a shadow does not survive greyscale. */
.card {
  display: block;
  padding: var(--space-5);
  margin: 0 0 var(--space-3);
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur) var(--ease);
}
.card:hover { border-color: var(--brand); }
.card .n {
  display: block;
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-faint);
}
.card .t {
  display: block;
  font-family: var(--font-display); font-size: var(--text-h3);
  line-height: var(--lh-h3); font-weight: var(--weight-h3);
  margin: var(--space-2) 0;
}
.card:hover .t { color: var(--brand-text); }
.card .idea { margin: 0; font-size: var(--text-small); line-height: var(--lh-small); color: var(--text-muted); }

/* Downloads and the starter file. */
.links { list-style: none; padding: 0; display: grid; gap: var(--space-2); }
.links li { margin: 0; }
.links a {
  display: inline-flex; align-items: baseline; gap: var(--space-2);
  font-family: var(--font-mono); font-size: var(--text-small);
}
.links a::before { content: "$"; color: var(--text-faint); }

/* Code. The 3px orange left rule is the one orange a sheet page owns, so
 * nothing else on a generated page gets an orange rule. */
code {
  font-family: var(--font-mono); font-size: 0.9em;
  background: var(--bg-sunken);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.1em 0.35em;
}
pre {
  margin: 0 0 var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-sunken);
  border: var(--border-width) solid var(--border);
  border-left: var(--rule-code) solid var(--brand);
  border-radius: var(--radius-sm);
  overflow-x: auto;
}
pre code {
  background: none; border: 0; padding: 0;
  font-size: var(--text-code); line-height: var(--lh-code);
}

/* A pull line. Deliberately not orange and not ruled: the code block already
 * owns the orange on this page. */
blockquote {
  margin: var(--space-6) 0;
  font-family: var(--font-display); font-size: var(--text-h3);
  line-height: var(--lh-h3); font-weight: var(--weight-h3);
  color: var(--text-muted);
}

table { border-collapse: collapse; width: 100%; margin: 0 0 var(--space-4); font-size: var(--text-small); }
th, td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--border); }
th {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  font-weight: var(--weight-label); color: var(--text-faint);
}

/* Tracker rungs. One added class in markdown(): a "- [ ]" line becomes
 * <li class="rung">, so the five rungs are the same object on the screen and in
 * a learner's hand. The tick is a mono x, never a checkmark. */
.rung { list-style: none; display: flex; align-items: baseline; gap: var(--space-3); }
.rung::before {
  content: ""; flex: none;
  width: var(--space-4); height: var(--space-4);
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-sm);
  transform: translateY(2px);
}
.rung[data-done]::before {
  content: "x";
  font-family: var(--font-mono); font-weight: 700; line-height: 0.8;
  text-align: center; color: var(--brand-text); border-color: var(--brand);
}
ul:has(> .rung) { padding-left: 0; }

/* The arcade wall. One article per game, each a card with a stage in it.
 * The orange owner on this page is the hovered card border, so a stage never
 * gets an orange frame. */
.wall { display: grid; gap: var(--space-5); }
@media (min-width: 60rem) { .wall { grid-template-columns: 1fr 1fr; } }

.game {
  margin: 0;
  padding: var(--space-5);
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
}
.game h2 {
  font-size: var(--text-h3); line-height: var(--lh-h3);
  font-weight: var(--weight-h3); margin: 0;
}
.game .idea {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-faint);
  margin: var(--space-2) 0 var(--space-4);
}

/* The frame a game runs in. Fixed height, so one long game cannot push the
 * rest of the wall off the screen. White ground, because a learner's game
 * assumes a white page and we are not going to repaint it for them. */
.stage {
  display: block;
  width: 100%; height: 26rem;
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--paper);
}

/* Forms. Two on the whole site: ask for a link, and send in a file. Both are
 * a stack of labels and controls, because a form that is one column is a form
 * a ten year old can fill in on a phone. The button owns the orange here, so
 * these pages have no other. */
.ask { display: grid; gap: var(--space-2); margin: 0 0 var(--space-4); }
.ask label {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-faint);
  margin-top: var(--space-3);
}
.ask input {
  font-family: var(--font-body); font-size: var(--text-body);
  color: var(--text); background: var(--bg-sunken);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  width: 100%;
}
.ask input::placeholder { color: var(--text-faint); }
.ask input:hover { border-color: var(--border-strong); }

.ask button {
  justify-self: start;
  margin-top: var(--space-5);
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--on-brand); background: var(--brand);
  border: 0; border-radius: var(--radius-btn);
  padding: var(--space-3) var(--space-6);
  cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.ask button:hover { background: var(--brand-hover); }
.ask button:disabled { background: var(--border-strong); cursor: default; }

/* What the form said back. Hidden until there is something to say. */
.said {
  padding: var(--space-3) var(--space-4);
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-left: var(--rule-code) solid var(--border-strong);
  border-radius: var(--radius-sm);
  font-size: var(--text-small); line-height: var(--lh-small);
}

/* Signing out is not a thing to encourage, so it does not look like a button. */
.quiet {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-faint); background: none;
  border: 0; padding: 0; cursor: pointer;
}
.quiet:hover { color: var(--brand-text); text-decoration: underline; }

/* Two things the form block above cannot do on its own.
 *
 * color-scheme tells the browser this page is dark, so the controls it draws
 * itself, the number spinner, the file picker, the autofill wash and the
 * scrollbar, come back dark instead of a light grey box on an ink page.
 * The file picker's button is a separate control that inherits none of the
 * button rules, so it is styled here by name. */
.ask input[type="file"] { padding: var(--space-2); }
.ask input[type="file"]::file-selector-button {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text); background: var(--bg-raised);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  margin-right: var(--space-3);
  cursor: pointer;
}
.ask input[type="file"]::file-selector-button:hover { border-color: var(--brand); }

/* The bug hunt, on a session page. A step rather than a row in the links
 * list, because the file only makes sense once the starter one is built.
 * The panel is the same surface step and 1px border as everything else: no
 * shadow, and no orange, because the code block on this page owns that. */
.next-step {
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5) var(--space-6);
  margin: 0 0 var(--space-4);
}
.next-step h2 { margin-top: 0; }

/* A real checkbox, sized up and given the brand colour. Native controls
 * inherit nothing, so accent-color is what makes it ours without rebuilding
 * it out of divs. */
.confirm {
  display: flex; align-items: flex-start; gap: var(--space-3);
  cursor: pointer;
  margin: var(--space-4) 0 0;
}
.confirm input {
  flex: none;
  width: var(--space-4); height: var(--space-4);
  margin: 0; transform: translateY(3px);
  accent-color: var(--brand);
  cursor: pointer;
}
.confirm span { font-size: var(--text-small); line-height: var(--lh-small); }

/* The agreement on the join form. A checkbox like the others, but its text
 * carries links, so they need to look like links inside a small line. */
.confirm.agree { margin-top: var(--space-5); }
.confirm.agree a { color: var(--brand-text); }

.reveal { margin: var(--space-5) 0 0; }
.reveal[hidden] { display: none; }

/* An empty page. Zall at a size where the face reads, and the sentence under
 * him, both centred. This is the only place a mascot appears on the site. */
.empty {
  display: grid; justify-items: center; gap: var(--space-4);
  padding: var(--space-7) 0;
  text-align: center;
}
.empty img { width: 140px; height: auto; }
.empty p { margin: 0; color: var(--text-muted); max-width: 34ch; }

/* Buttons ----------------------------------------------------------------- */

/* Two variants and two sizes, matching the design system's Button. Primary
   lifts to a lighter orange on hover, never darker, and never scales. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.2;
  font-size: var(--text-body);
  padding: var(--space-3) var(--space-5);
  border: var(--border-width) solid transparent;
  border-radius: var(--radius-btn);
  background: transparent;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn.lg { font-size: var(--text-h3); padding: var(--space-4) 28px; }
.btn.sm { font-size: var(--text-small); padding: var(--space-2) 14px; border-radius: var(--space-2); }
.btn.wide { width: 100%; }

.btn.primary { background: var(--brand); color: var(--on-brand); }
.btn.primary:hover { background: var(--brand-hover); color: var(--on-brand); }

.btn.secondary { border-color: var(--border-strong); color: var(--text); }
.btn.secondary:hover { border-color: var(--brand); color: var(--text); }

/* Page furniture, added by page(). Sticky and blurred is one of only two
 * sanctioned uses of transparency in this system. */
.site-head {
  position: sticky; top: 0; z-index: 5;
  background: rgba(13, 12, 17, 0.88);
  backdrop-filter: blur(10px);
  border-bottom: var(--border-width) solid var(--border);
}
.site-head > div,
.site-foot > div {
  max-width: var(--page-max); margin: 0 auto;
  padding: var(--space-3) var(--space-6);
  display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap;
}
.site-head a, .site-foot a { text-decoration: none; }
/* The mark. Every page shows the wordmark artwork, so the site looks like one
 * site: the header does not change when you click through from the landing
 * page to the archive. .mark is the text fallback, still styled because a
 * page can be rendered before the image arrives. */
.site-head .wordmark { display: block; line-height: 0; }
.site-head .wordmark img { height: 26px; width: auto; display: block; }
.site-head .spacer { flex: 1; }

.site-head .mark {
  font-family: var(--font-display); font-weight: var(--weight-h2);
  font-size: var(--text-h3); color: var(--text);
}
.site-head nav { display: flex; gap: var(--space-5); margin-left: var(--space-4); }
.site-head nav a {
  font-family: var(--font-mono); font-size: var(--text-label);
  letter-spacing: var(--ls-label); text-transform: uppercase;
  color: var(--text-muted);
}
.site-head nav a:hover { color: var(--text); }
.site-head nav a[aria-current] { color: var(--brand-text); }
.site-foot { border-top: var(--border-width) solid var(--border); margin-top: var(--space-9); }

/* Ctrl-P on a session page. The palette inverts wholesale: same file, ink on
 * paper. The A5 participant sheet is a separate stylesheet, ops/templates/sheet.css. */
@media print {
  body {
    --bg: #FFFFFF; --bg-raised: #FFFFFF; --bg-sunken: #FAF9FA;
    --border: #C3C1CD; --border-strong: #7C7891;
    --text: #0D0C11; --text-muted: #57526F; --text-faint: #7C7891;
    --brand: #B54D08; --brand-text: #B54D08;
  }
  .site-head, .site-foot, .back, .stage, .ask, .said, .quiet,
  .next-step { display: none; }
  main, main.wide { padding: 0; max-width: none; }
  body { font-size: 10pt; }
  pre code { font-size: 10pt; }
  a { text-decoration: none; }
  pre, .card, .game, blockquote { break-inside: avoid; }
}

/* ---------------------------------------------------------------------------
   Articles. The only two blocks a session sheet does not have.

   A sheet is read in a room with a facilitator in it. An article is read alone
   by a stranger who arrived from a search engine, so it gets one box for the
   thing they must not miss and one for the questions they arrived with. That
   is the whole extension, and section 16a in the ops folder keeps it closed.
   --------------------------------------------------------------------------- */

/* The standfirst answers the question in the title, so it is the one line a
   skimming reader is guaranteed to see. Sized between the body and a heading. */
.standfirst {
  font-size: var(--text-h3); line-height: var(--lh-h3);
  color: var(--text-muted);
  margin: 0 0 var(--space-6);
}
.standfirst strong { font-weight: 500; color: var(--text); }

/* The thing a parent must not miss. One per article is the budget, the same
   way one mascot per page is. Orange is the owner here. */
aside.key {
  border-left: var(--space-1) solid var(--brand);
  background: var(--bg-raised);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: var(--space-5);
  margin: var(--space-6) 0;
}
aside.key > :first-child { margin-top: 0; }
aside.key > :last-child { margin-bottom: 0; }

/* A block of reference held apart from the prose: what we store, a checklist,
   anything a reader comes back to rather than reads once. Bordered and not
   orange, because the key box owns the orange and there is one of those. */
aside.panel {
  display: block;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
  padding: var(--space-5) var(--space-6);
  margin: var(--space-6) 0;
}
aside.panel h4 {
  font-size: var(--text-body); line-height: var(--lh-h3);
  margin: var(--space-5) 0 var(--space-2);
}
aside.panel > h4:first-child { margin-top: 0; }
aside.panel p { color: var(--text-muted); margin: 0 0 var(--space-3); }
aside.panel > :last-child { margin-bottom: 0; }

/* A picture in an article. Full width of the column, because a screenshot
   shrunk to sit beside text is a screenshot nobody can read. The caption is
   the accessible text, so it says what the picture shows rather than naming
   it. Articles only: a sheet has no images and the print stylesheet has no
   rule for one. */
figure {
  margin: var(--space-6) 0;
}
figure img {
  display: block;
  width: 100%;
  height: auto;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
  background: var(--bg-sunken);
}
figure figcaption {
  color: var(--text-muted);
  font-size: var(--text-small);
  line-height: var(--lh-body);
  margin-top: var(--space-3);
}

@media print {
  aside.key, aside.panel { break-inside: avoid; }
  figure { break-inside: avoid; }
}

/* The draft desk. A facilitator reviewing an article before it publishes.
   Nobody else can load a page that has this on it. */

/* Orange is the owner on a draft page, because "not published yet" is the
   most important thing on it. */
.draft-flag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-label); letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--on-brand); background: var(--brand);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  margin: 0 0 var(--space-4);
}

/* The same word in the article list, where it is a label and not a banner. */
.draft {
  color: var(--brand-text);
  font-weight: 600;
}

.desk {
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-card);
  background: var(--bg-raised);
  padding: var(--space-6);
  margin: var(--space-7) 0 0;
}
.desk h2 { margin-top: 0; }
.desk-row {
  display: flex; align-items: center; gap: var(--space-3);
  margin-top: var(--space-4); flex-wrap: wrap;
}
.desk-said { font-size: var(--text-small); color: var(--text-muted); }

/* A draft is never printed. */
@media print { .desk, .draft-flag { display: none; } }

/* Whose address is this. Two radios on the join form, styled like the confirm
   step on a session sheet so the site has one way of asking a question. */
.whose {
  border: 0; padding: 0; margin: var(--space-4) 0 0;
}
.whose legend {
  padding: 0;
  font-family: var(--font-mono);
  font-size: var(--text-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--text-faint);
  margin-bottom: var(--space-2);
}
.whose .confirm { margin: 0 0 var(--space-2); }

/* An article's inline code is orange. These are the things a reader has to
   type or recognise: an address, a password, a pattern to avoid. On a session
   sheet the block keeps the orange and inline code stays quiet, because a
   sheet is read next to a facilitator and a page is not.

   brand-text rather than brand, because brand is the fill colour and this is
   text on a dark ground. On paper the token flips to the print orange, which
   is the only step that survives a home printer. */
main.article :not(pre) > code {
  color: var(--brand-text);
  border-color: var(--border-strong);
}

/* Emphasis stays plain. If italics were orange too, a reader would have two
   different things wearing one colour and neither would mean anything. */
main.article em { color: inherit; }

/* Who is signed in, top right, and the menu behind it. Replaces the Sign in
   button once who.js has asked. The orange belongs to the page rather than to
   a permanent fixture, so none of this is orange. */
.whoami { position: relative; }
.signed-in {
  display: inline-flex; align-items: center; gap: var(--space-2);
  text-decoration: none; color: var(--text-muted);
  font-size: var(--text-small);
  padding: var(--space-1) var(--space-2) var(--space-1) var(--space-1);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-btn);
}
.signed-in:hover { color: var(--text); border-color: var(--border-strong); }
.signed-in img {
  width: var(--space-6); height: var(--space-6);
  border-radius: 50%;
  background: var(--bg-raised);
  object-fit: cover;
}
.signed-in .chev { opacity: 0.6; transition: transform var(--dur) var(--ease); }
.signed-in[aria-expanded="true"] .chev { transform: rotate(180deg); }

/* The menu. Anchored to the right so it never runs off a narrow screen. */
.whoami-menu {
  position: absolute; top: calc(100% + var(--space-2)); right: 0;
  min-width: 11rem; z-index: 20;
  display: flex; flex-direction: column;
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
}
/* One row, whether it is a link or the sign out button, so the menu reads as
   one list rather than two kinds of thing. */
.whoami-menu a,
.whoami-menu button {
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%; box-sizing: border-box; text-align: left;
  font: inherit; font-size: var(--text-small);
  color: var(--text-muted); background: none; border: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.whoami-menu a:hover,
.whoami-menu button:hover { background: var(--bg-sunken); color: var(--text); }
.whoami-menu form { margin: 0; }
/* Sign out is the last thing and a different kind of thing, so it is fenced
   off rather than sitting in the list as though it were another page. */
.whoami-menu form { border-top: var(--border-width) solid var(--border);
  margin-top: var(--space-2); padding-top: var(--space-2); }
/* display: flex above beats the browser's own [hidden] rule, so the menu would
   never hide. Anything given a display needs this alongside it, which is the
   same trap .reveal hit further up. */
.whoami-menu[hidden] { display: none; }

/* Privacy, terms, and how to reach a person. Quiet on purpose: they have to be
   there and findable, and they are not what the page is for. */
.legal {
  display: flex; gap: var(--space-4); flex-wrap: wrap;
}
.legal a {
  color: var(--text-faint); text-decoration: none;
  font-size: var(--text-small);
}
.legal a:hover { color: var(--text-muted); text-decoration: underline; }

@media print { .signed-in, .legal { display: none; } }

/* The settings page. A picture of the avatar somebody cannot change yet, so it
   is shown small and quiet rather than as a feature. */
.avatar-preview {
  width: var(--space-9); height: var(--space-9);
  border-radius: 50%;
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
}

/* The one time we ask for a picture. Zall does the asking, which is why he is
   in it: a robot inviting you is friendlier than a box of text telling you. */
.invite {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  margin: var(--space-5) 0;
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
}

.invite img { width: var(--space-8); height: auto; flex-shrink: 0; }
.invite h2 { margin-top: 0; }
.invite > div > :last-child { margin-bottom: 0; }

@media (max-width: 30rem) {
  .invite { flex-direction: column; text-align: center; }
}

/* The two ways out of the picture page, side by side. */
.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

/* Picking a face. A grid that fits whatever the screen has, because this is
   read on a parent's laptop and on a phone in a kitchen. */
.avatar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--space-9), 1fr));
  gap: var(--space-3);
  margin: var(--space-5) 0;
}

.avatar-pick {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-2);
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-card);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--text-small);
  cursor: pointer;
}

.avatar-pick img {
  width: 100%;
  max-width: var(--space-8);
  height: auto;
  border-radius: 50%;
  /* The art is drawn on white. Without this it floats on the dark ground with
     a hard edge, which looks like a mistake rather than a choice. */
  background: var(--paper);
}

.avatar-pick:hover { border-color: var(--border-strong); color: var(--text); }

.avatar-pick:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* The chosen one. Orange is the site's one emphasis and this is the only
   thing on this page competing for it, so it can have it. */
.avatar-pick.on {
  border-color: var(--brand);
  color: var(--text);
}

/* Deleting everything. The only red on the site, and it is here because this
   is the only thing on the site that cannot be undone. It is not a warning
   colour used for emphasis: nothing else may borrow it. */
.danger {
  border: var(--border-width) solid var(--stop);
  border-radius: var(--radius-card);
  padding: var(--space-5) var(--space-6);
  margin: var(--space-6) 0;
}
.danger h2 { margin-top: 0; color: var(--stop); }
.danger label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-label); letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--text-faint);
  margin: var(--space-4) 0 var(--space-2);
}
.danger input {
  font-family: var(--font-mono); font-size: var(--text-code);
  color: var(--text); background: var(--bg);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  max-width: 14rem;
}
.danger input:focus-visible {
  outline: var(--space-1) solid var(--focus); outline-offset: 2px;
}
.btn.danger {
  border-color: var(--stop); color: var(--stop);
  background: none; padding: var(--space-2) var(--space-4);
}
.btn.danger:hover:not(:disabled) { background: var(--stop); color: var(--paper); }
.btn.danger:disabled { opacity: 0.4; cursor: not-allowed; }

/* The cookie bar. Fixed to the bottom, above everything, and it only exists
 * until somebody answers. Added by cookies.js, never present in the markup,
 * so a visitor who has already chosen never pays for it.
 *
 * z-index sits above the menu at 20: this asks a question, and a question
 * behind a menu is a question nobody answers. */
.cookie-bar {
  position: fixed; z-index: 30;
  left: var(--space-4); right: var(--space-4); bottom: var(--space-4);
  margin: 0 auto; max-width: 46rem;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-raised);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-card);
}
.cookie-bar p {
  flex: 1 1 16rem; margin: 0;
  font-size: var(--text-small); line-height: var(--lh-small);
  color: var(--text);
}
.cookie-bar a { color: var(--brand-text); }

/* Both buttons are the same weight. Neither is the tempting one. */
.cookie-buttons { display: flex; flex: none; gap: var(--space-3); }

/* Narrow: the buttons go full width and side by side, still equal. */
@media (max-width: 30rem) {
  .cookie-buttons { width: 100%; }
  .cookie-buttons .btn { flex: 1; }
}

/* What you chose, on the privacy page. Hidden until cookies.js has something
 * to report, so somebody who has never answered is not told about a choice
 * they have not made. */
.cookie-choice {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  font-size: var(--text-small); line-height: var(--lh-small);
}
.cookie-choice[hidden] { display: none; }
