/* The TerraWorld website, after the website mockups of 2026-11-01. Every value reads a token from
   tokens.css or counts art pixels of --u, one art pixel at two times, so the art keeps whole pixels.
   A media query cannot read a token, so its widths are the one place a size is written out.
   The art and the lettering are the mockup generator's, synced into assets/mockups/. Its stylesheet,
   mockups.css, loads after this one, so the page's own class names never repeat one of its names. */

:root {
  --u: var(--unit-screen);
  --letter: calc(3 * var(--u) / 2);
  /* One content width for the header's band, the text and every mockup's window: a game screen at two
     times, the founder's ask that they all line up. The page adds its side padding around it. */
  --content-width: calc(17 * 32 * var(--u));
  --site-width: calc(var(--content-width) + 2 * var(--space-screen-24));
  --measure: calc(320 * var(--u));
  --focus-ring: calc(var(--border-screen-1) + var(--border-screen-2)) solid var(--color-focus);
}

*, *::before, *::after { box-sizing: border-box; }

/* The browser's own controls and scrollbars follow the theme, pinned or not. */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

body {
  margin: 0;
  font: var(--type-screen-body);
  color: var(--color-ink);
  background-color: var(--color-page);
  background-image: url("/assets/mockups/grain.png");
  background-size: calc(64 * var(--u));
  image-rendering: pixelated;
}

/* The grain is vellum, so a dark page goes without it; the art itself never changes. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) body { background-image: none; }
}
@media screen {
  :root[data-theme="dark"] body { background-image: none; }
}

a { color: var(--color-link); }
a:focus-visible { outline: var(--focus-ring); outline-offset: var(--border-screen-2); }

.visually-hidden {
  position: absolute;
  width: var(--border-screen-1);
  height: var(--border-screen-1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  top: calc(-32 * var(--u));
  left: var(--space-screen-16);
  z-index: 2;
  padding: var(--space-screen-12) var(--space-screen-16);
  background: var(--color-surface);
  color: var(--color-ink);
}
.skip:focus { top: var(--space-screen-16); }

/* Pixel lettering: the generator's drawings as masks, painted in the text's colour. Each letter
   pixel is three screen pixels, two on a phone; an initial's is two. */
.lettering {
  display: inline-block;
  vertical-align: bottom;
  background-color: currentColor;
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: 100% 100%;
}
.wordmark { width: calc(59 * var(--letter)); height: calc(7 * var(--letter)); mask-image: url("/assets/mockups/wordmark.svg"); }

/* The header: the village band, with the mark and the links on framed plaques over it. */
.masthead {
  position: relative;
  width: calc(100% - 2 * var(--space-screen-24));
  max-width: var(--content-width);
  margin-inline: auto;
}
.masthead-band {
  height: calc(160 * var(--u));
  background: url("/assets/mockups/village-band.png") center / calc(600 * var(--u)) auto;
}
.masthead-plaques {
  position: absolute;
  inset: 0 0 auto 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-screen-16);
  padding: var(--space-screen-12) var(--space-screen-16);
}
.plaque {
  color: var(--color-frame-ink);
  border: calc(4 * var(--u)) solid transparent;
  border-image: url("/assets/mockups/frame.png") 6 / calc(6 * var(--u)) / calc(2 * var(--u)) stretch;
  background-color: var(--color-frame-panel);
  background-image: url("/assets/mockups/grain.png");
  background-size: calc(64 * var(--u));
  background-clip: padding-box;
  background-origin: padding-box;
}
.plaque a { color: var(--color-frame-ink); text-decoration: none; }
.plaque a:hover { background-color: var(--color-frame-lip); }
.plaque a:focus-visible { outline-color: var(--color-frame-focus); }
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-screen-12);
  padding: var(--space-screen-4) var(--space-screen-12);
}
.mark-2x { width: calc(16 * var(--u)); height: calc(16 * var(--u)); }
.site-nav { padding: 0 var(--space-screen-12); }
.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--space-screen-24);
  margin: 0;
  padding: 0;
  list-style: none;
}
.site-nav a {
  display: inline-flex;
  align-items: baseline;
  line-height: calc(22 * var(--u));
  padding: 0 var(--space-screen-4);
}
/* The initial's own empty column of two screen pixels is the founder's steer, one art pixel. */
.nav-initial {
  display: inline-block;
  width: calc(5 * var(--u));
  height: calc(7 * var(--u));
  margin-right: var(--u);
  background-color: var(--color-rubric);
  mask: no-repeat center / 100% 100%;
}
.nav-initial-t { mask-image: url("/assets/mockups/initial-t.svg"); }
.nav-initial-p { mask-image: url("/assets/mockups/initial-p.svg"); }
.nav-initial-f { mask-image: url("/assets/mockups/initial-f.svg"); }

/* The opening: the headline on the left, the line and the button on the right. */
main { max-width: var(--site-width); margin-inline: auto; }
.intro {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--space-screen-32);
  align-items: start;
  padding: var(--space-screen-40) var(--space-screen-24) var(--space-screen-32);
}
.page-title { margin: 0; font: var(--type-screen-h1); line-height: 0; }
.page-title .lettering { width: calc(137 * var(--letter)); height: calc(9 * var(--letter)); mask-image: url("/assets/mockups/headline.svg"); }
.lead { font: var(--type-screen-lead); margin: 0 0 var(--space-screen-20); }

/* A button: the action colour, its corners notched by a pixel all round. */
.button {
  display: inline-flex;
  align-items: center;
  min-height: calc(22 * var(--u));
  padding: 0 var(--space-screen-24);
  background: var(--color-action);
  color: var(--color-on-action);
  font-weight: var(--font-weight-bold);
  text-decoration: none;
  box-shadow:
    0 calc(-1 * var(--u)) 0 var(--color-action),
    0 var(--u) 0 var(--color-action),
    calc(-1 * var(--u)) 0 0 var(--color-action),
    var(--u) 0 0 var(--color-action);
}
.button:focus-visible { outline-offset: calc(2 * var(--u)); }

/* A part of the page: a heading over a rail of the frame's wood, and reading text kept narrow. */
.part { padding: 0 var(--space-screen-24) var(--space-screen-48); }
.part h2 { font: var(--type-screen-h2); margin: 0; padding-top: var(--space-screen-32); }
.part h2::after {
  content: "";
  display: block;
  height: calc(3 * var(--u));
  margin: var(--space-screen-8) 0 var(--space-screen-24);
  background: var(--color-frame-outline);
  box-shadow: inset 0 calc(3 * var(--u) / 2) 0 var(--color-frame-wood);
}
/* The page's own text only, by its place: a rule on every paragraph or list would reach into the mockups. */
.part > p, .part > ul, .game-step > p { max-width: var(--measure); margin: 0 0 var(--space-screen-16); }
.part > ul { padding-left: var(--space-screen-24); }

/* The game, as five numbered steps, each with its mockup under it. */
.game-steps { margin: 0; padding: 0; list-style: none; counter-reset: step; }
.game-step { counter-increment: step; padding-bottom: var(--space-screen-40); }
.game-step > h3 { font: var(--type-screen-h3); margin: 0 0 var(--space-screen-8); }
.game-step > h3::before { content: counter(step) ". "; color: var(--color-ink-muted); }

/* A mockup: never scaled, so a narrow screen scrolls it inside its own box. Until its script runs,
   the host holds the still frame, in a light and a dark twin. */
.shot { margin: var(--space-screen-16) 0 0; }

/* A mockup's window, a modern desktop window at the founder's ask: rounded corners, a plain bar with three
   coloured dots and the mockup's name, a soft shadow, and the screen meeting its edges with no space above
   or below. Two things depart from the design system on purpose: its corners are notched, never rounded,
   and the dots take three of its ramp colours directly, the red, the gold and the green, where a style
   should read a token of its own. The bar stays put while a narrow screen scrolls inside the body. */
/* Every window is the text column's width, a game screen's at two times at full size, the founder's ask.
   On a narrower screen the window stays as wide as the text and its screen scrolls sideways inside it,
   keeping its whole pixels. */
.window {
  width: 100%;
  margin-inline: auto;
  overflow: hidden;
  border-radius: calc(5 * var(--u));
  background: var(--color-surface);
  box-shadow: 0 0 0 var(--border-screen-1) var(--color-rule), var(--shadow-sheet);
}
.window-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: var(--space-screen-8) var(--space-screen-12);
  border-bottom: var(--border-screen-1) solid var(--color-rule);
  background: var(--color-surface);
  color: var(--color-ink-muted);
  font: var(--type-screen-label);
}
.window-dots {
  width: calc(6 * var(--u));
  height: calc(6 * var(--u));
  border-radius: 50%;
  background: var(--color-ramp-red-3);
  box-shadow: calc(10 * var(--u)) 0 0 var(--color-ramp-sand-4), calc(20 * var(--u)) 0 0 var(--color-ramp-grass-4);
}
.window-title { grid-column: 2; }
.window-body { overflow-x: auto; scrollbar-width: thin; line-height: 0; }
.window-body .mockup { line-height: normal; }
.shot figcaption { text-align: center; }/* Only the still frames: a rule on every image would reach into the mockups' own art. */
.shot .frame { display: block; max-width: none; background-color: var(--color-desk); }
.shot .frame-dark { display: none; }
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .shot .frame-light { display: none; }
  :root:not([data-theme="light"]) .shot .frame-dark { display: block; }
}
@media screen {
  :root[data-theme="dark"] .shot .frame-light { display: none; }
  :root[data-theme="dark"] .shot .frame-dark { display: block; }
}

.site-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-screen-12);
  max-width: var(--site-width);
  margin: 0 auto;
  padding: var(--space-screen-24);
  border-top: var(--border-screen-1) solid var(--color-rule);
  font: var(--type-screen-small);
  color: var(--color-ink-muted);
}
.site-foot p { margin: 0; }

/* The theme switch, on the footer's right: a framed plaque as the header's are, the same in both themes,
   its three choices in one row. The chosen one takes the design system's ring for what is chosen, gold
   inside brown, as a picked card does. */
.theme-switch { display: flex; gap: var(--space-screen-4); margin: 0 0 0 auto; padding: 0 var(--space-screen-4); min-inline-size: 0; }
.theme-switch[hidden] { display: none; }
.theme-switch label { display: inline-flex; }
.theme-switch input { position: absolute; opacity: 0; width: var(--border-screen-1); height: var(--border-screen-1); }
.theme-switch span {
  display: inline-flex;
  align-items: center;
  min-height: calc(22 * var(--u));
  padding: 0 var(--space-screen-12);
  color: var(--color-frame-ink);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}
.theme-switch span:hover { background-color: var(--color-frame-lip); }
.theme-switch input:checked + span {
  background-color: var(--color-frame-lip);
  box-shadow: inset 0 0 0 var(--u) var(--color-frame-focus), inset 0 0 0 calc(2 * var(--u)) var(--color-frame-focus-halo);
}
.theme-switch input:focus-visible + span { outline: var(--focus-ring); outline-color: var(--color-frame-focus); outline-offset: var(--border-screen-2); }

@media (max-width: 760px) {
  .masthead { width: calc(100% - 2 * var(--space-screen-16)); }
  .masthead-plaques { flex-direction: column; align-items: flex-start; gap: var(--space-screen-8); }
  .site-nav ul { display: grid; grid-template-columns: auto auto; column-gap: var(--space-screen-16); }
  .intro { grid-template-columns: 1fr; padding-inline: var(--space-screen-16); }
  .part { padding-inline: var(--space-screen-16); }
  .page-title .lettering { width: calc(137 * var(--u)); height: calc(9 * var(--u)); }
}
