/* The Reserve List — base layer.
 *
 * Reset, page ground, masthead, footer. Everything every page has.
 * Loaded after tokens.css and before components.css.
 */

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  padding: 26px 20px 44px;
  color: var(--ink);
  font-family: var(--mono);

  /* The graph-paper backdrop: two 1px gradients on a 32px lattice. Identical in
     all 42 source files, and the single most recognisable thing about the site. */
  background:
    linear-gradient(var(--grid) 1px, transparent 1px) 0 0 / var(--grid-size) var(--grid-size),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px) 0 0 / var(--grid-size) var(--grid-size),
    var(--bg);
}

/* Body modifiers, replacing the per-file <body> divergence.
   The hub padded 26px/20px/44px; signup centred its card; the drills used a
   narrower column. Three classes cover all 42. */
body.page-center {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
}
body.page-narrow { --wrap-max: 660px; }
body.page-slim   { --wrap-max: 460px; }

.wrap {
  max-width: var(--wrap-max);
  margin: 0 auto;
  width: 100%;
}

/* --- Masthead ---------------------------------------------------------- */

.mast { text-align: center; margin-bottom: 20px; }

.mast h1 {
  font-family: var(--disp);
  font-weight: 700;
  font-size: 40px;
  letter-spacing: .03em;
  margin: 0;
  line-height: 1.05;
}

.mast .sub { font-size: 12.5px; color: var(--ink-dim); margin-top: 8px; }

.mast a { color: inherit; text-decoration: none; }

/* The six stars. Twelve would be the actual flag; six is the joke. */
.stars { display: flex; justify-content: center; gap: 5px; margin-bottom: 11px; }
.star  { width: 5px; height: 5px; background: var(--drill); border-radius: 50%; opacity: .85; }

/* --- hidden means hidden ----------------------------------------------------
 *
 * `[hidden] { display: none }` comes from the browser's own stylesheet, which
 * is the LOWEST priority there is. So any author rule that sets `display` on
 * an element beats it, and `el.hidden = true` sets the attribute, passes every
 * assertion you can write about the property, and changes nothing on screen.
 *
 * This has now happened three times in this codebase:
 *
 *   .hero-shelf   display:flex          an empty trophy cabinet on the hub
 *   .bubble-cons  display:block         the consultation stayed on screen
 *                                       after you voted -- 220px of it, with
 *                                       the attribute correctly set
 *   .bubble-cta   display:inline-block  a nudge with no link kept the previous
 *                                       nudge's link, text and href
 *
 * The second was fixed once, per element, with a note saying "the next person
 * to add a display to a hideable element will hit the same thing". The next
 * person was me, in the same file, twice.
 *
 * So it is fixed here instead, for everything, and `!important` is the point
 * rather than a smell: `hidden` is not a style, it is the author saying this
 * element is not in the document right now. No layout rule is entitled to
 * overrule that. Anything that needs to animate on its way out has to do so
 * BEFORE the attribute goes on -- see .bubble-cons.leaving in page/hub.css.
 *
 * tools/invariants.pl asserts this rule is still here.
 * ------------------------------------------------------------------------- */
[hidden] { display: none !important; }

/* --- Back link --------------------------------------------------------- */

/* One object in one corner, whichever kind of page you are on.

   There were two: a bordered pill on the bare pages -- games, explainers,
   drills -- and a plain 11px text link on the framed ones -- the section
   indexes, the personnel file, privacy, the mailbox. Same position, same job,
   two different things to recognise, so moving between levels felt like moving
   between sites. The pill wins because it reads as a control rather than as
   the first line of the page, which is what the note in bare.css was already
   arguing about when it was only talking about overlap.

   bare.css still owns where its copy SITS -- flex-item shrinking and the
   margins that keep it off a centred panel. What it no longer owns is what it
   looks like. */
.back,
.rl-back {
  display: inline-block;
  font-size: 10.5px;
  letter-spacing: .04em;
  color: var(--line);
  text-decoration: none;
  border: 1px solid var(--line-dim);
  border-radius: 4px;
  padding: 5px 10px;
}
.back:hover,
.rl-back:hover { background: rgba(94, 200, 216, .14); border-color: var(--line); }

/* In flow above the mast, so it needs the gap the mast does not give it. */
.wrap > .back { margin-bottom: 14px; }

/* --- Footer ------------------------------------------------------------
 *
 * Not the page footer any more -- page_foot() stopped rendering one when the
 * pinned bar took over the affiliation notice and the privacy route. This is
 * still live for the pages that build their own .foot row inside the content
 * (the roundabout, the drills), which inherit everything but display and
 * margin from here. Do not delete it without checking those.
 */

.foot {
  border-top: 1px solid var(--line-dim);
  padding-top: 16px;
  margin-top: 36px;
  font-size: 10.5px;
  color: var(--ink-dim);
  line-height: 1.75;
}
.foot b { color: var(--ink); }
.foot a { color: var(--line); }

/* Shown when localStorage throws — private windows, hardened browsers. The
   store degrades to memory mode; this is how the user finds out. */
.storagetag { font-size: 9.5px; color: var(--bad); margin-top: 8px; min-height: 12px; }

/* Sync indicator for signed-in users. Unobtrusive by design: a failed write
   retries on its own, and a modal for something the user cannot act on is
   noise. */
.synctag { font-size: 9.5px; color: var(--ink-dim); }
.synctag.offline { color: var(--bad); }

/* --- Accessibility ----------------------------------------------------- */

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 10;
  background: var(--panel-2); color: var(--ink);
  padding: 10px 16px; border: 1px solid var(--line);
}
.skip-link:focus { left: 8px; top: 8px; }

/* The original files relied entirely on the UA focus ring, which is invisible
   against this palette on several elements. */
:focus-visible { outline: 2px solid var(--line); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Room for the pinned bar on full-width pages. See the note in bare.css for
   why the bare pages reserve it in that file instead. */
/* 52px: the bar is 39px closed plus a little air. It grows to ~121px when the
   small print unfolds, and that overlap is deliberate — unfolding is something
   you did on purpose, it is transient, and reserving room for the open state
   would waste 70px on every page for the 99% of the time it is shut. */
body { padding-bottom: 52px; }
