/* Buy The World — the sheet and the album leaf.
   Squares are stamps: printed on gummed paper, punched with perforations, sold
   at a face value, mounted on dark album card. The rail is a sheet; each panel
   is a pane separated by gutters; status lives in the selvedge marginalia the
   way a printer's registration marks and plate numbers do. */

:root {
  /* Album card — warm near-black, the leaf a collection is mounted on. */
  --leaf:        #16120e;
  --leaf-2:      #1e1813;
  --leaf-3:      #272019;

  /* Gummed paper — the stamp face itself. */
  --gum:         #f3ecdd;
  --gum-2:       #e6dcc7;
  --gum-ink:     #17130d;

  /* Ink on the leaf. */
  --text:        #ece4d5;
  --text-dim:    #b3a692;
  --text-faint:  #7d7263;

  /* Signal: carmine, the classic definitive ink. Carries every primary action. */
  --carmine:     #d0405a;
  --carmine-lit: #e65b74;
  --carmine-ink: #2a0a11;
  --carmine-dim: #4a1a24;

  /* Information: ultramarine, the airmail overprint. */
  --marine:      #5b8fd4;
  --marine-dim:  #23334c;

  /* Brand, unchanged: the globe's own language. */
  --amber:       #e8a13c;
  --amber-dim:   #4a3717;
  --land:        #7cb56d;

  --rule:        #33291f;
  --rule-lit:    #4a3c2c;

  --perf:        7px;    /* perforation hole diameter */
  --perf-gap:    12px;   /* pitch between holes */
  --r:           2px;

  --shadow-leaf: 0 1px 2px rgba(0, 0, 0, .5), 0 10px 28px -14px rgba(0, 0, 0, .9);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, .5), 0 18px 40px -18px rgba(0, 0, 0, .95);

  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Every display rule below would otherwise outrank the hidden attribute, and a
   panel that hides itself by setting .hidden would stay on screen. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--leaf);
  color: var(--text);
  font-family: "Familjen Grotesk", "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

button, input, select, textarea { font: inherit; }

a { color: var(--marine); text-underline-offset: 2px; }
a:hover { color: #82abe0; }

.mono {
  font-family: "Azeret Mono", ui-monospace, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Perforation: punched out of the panel edge, not drawn on it. Two masks —
   one keeps the panel body, the other bites the holes out along an edge. */
.perf-top,
.perf-bottom { position: relative; }

.perf-top::before,
.perf-bottom::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: var(--perf);
  background: var(--leaf);
  -webkit-mask-image: radial-gradient(circle at var(--perf-gap) 50%,
                #000 calc(var(--perf) / 2), transparent calc(var(--perf) / 2 + .5px));
  mask-image: radial-gradient(circle at var(--perf-gap) 50%,
                #000 calc(var(--perf) / 2), transparent calc(var(--perf) / 2 + .5px));
  -webkit-mask-size: calc(var(--perf-gap) * 2) 100%;
  mask-size: calc(var(--perf-gap) * 2) 100%;
  -webkit-mask-repeat: repeat-x;
  mask-repeat: repeat-x;
  pointer-events: none;
}
.perf-top::before { top: calc(var(--perf) / -2); }
.perf-bottom::after { bottom: calc(var(--perf) / -2); }

/* ---------------------------------------------------------------- layout */

/* The stage and the sheet are the two named areas; the wordmark and the account
   links are laid into the stage's own area rather than positioned absolutely
   inside it. That is what makes the stacked layout possible further down - a
   grid item can be moved to a row of its own, and an absolutely positioned
   overlay cannot. It is also what stops the wordmark outgrowing the stage: on a
   phone the plate stood 370px tall in a 260px stage and hung over the sheet. */
.app {
  display: grid;
  grid-template-columns: 1fr 372px;
  grid-template-areas: "stage sheet";
  height: 100dvh;
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

.stage { grid-area: stage; position: relative; background: #0d1a24; min-width: 0; }
#map { position: absolute; inset: 0; }

/* Outside the globe the map's canvas is transparent, so the stage's night blue
   is what space is made of. The stars are painted under the map and brought up
   by globe.js as the globe pulls back - close in, there is no space to see. */
#stars {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
}

/* MapLibre ships white chrome; bring it onto the leaf. */
.maplibregl-ctrl-attrib {
  font-family: "Azeret Mono", monospace !important;
  font-size: 9.5px !important;
  background: color-mix(in srgb, var(--leaf) 86%, transparent) !important;
  color: var(--text-faint) !important;
  border-radius: var(--r) 0 0 0 !important;
  padding: 3px 7px !important;
}
.maplibregl-ctrl-attrib a { color: var(--text-dim) !important; }
.maplibregl-ctrl-attrib-button { filter: invert(1) opacity(.55); }

.maplibregl-ctrl-group {
  background: color-mix(in srgb, var(--leaf) 88%, transparent) !important;
  border: 1px solid var(--rule) !important;
  border-radius: var(--r) !important;
  box-shadow: var(--shadow-leaf) !important;
  overflow: hidden;
}
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--rule) !important; }
.maplibregl-ctrl-group button { background: transparent !important; width: 30px !important; height: 30px !important; }
.maplibregl-ctrl-group button:hover { background: var(--leaf-3) !important; }
.maplibregl-ctrl-group button:focus-visible { outline: 2px solid var(--marine) !important; outline-offset: -2px; }
.maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) opacity(.62); }
.maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon { filter: invert(1) opacity(.92); }

/* ---------------------------------------------------------- the wordmark */

.plate {
  grid-area: stage;
  align-self: start;
  justify-self: start;
  z-index: 3;
  margin: 20px 0 0 22px;
  max-height: calc(100dvh - 40px);
  pointer-events: none;
  max-width: min(44ch, 60%);
  background: color-mix(in srgb, var(--leaf) 88%, transparent);
  backdrop-filter: blur(7px);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 13px 17px 14px;
  box-shadow: var(--shadow-leaf);
}

.plate h1 {
  margin: 0;
  font-family: "Bodoni Moda", Georgia, serif;
  font-size: 25px;
  font-weight: 600;
  letter-spacing: .005em;
  line-height: 1.05;
}

.plate p {
  margin: 7px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
  max-width: 40ch;
}

/* How much of the world is spoken for, on the plate. The figure is leaf ink,
   not amber: amber is the map's own word for a claimed square and is never
   borrowed for UI chrome. The bar underneath is the exception that was already
   here, and it is the one thing on the plate that IS the claims. */
.plate .claimed { margin-top: 13px; }

.plate .claimed-line {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-dim);
}
.plate .claimed-line b {
  font-family: "Bodoni Moda", Georgia, serif;
  font-size: 21px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: .005em;
  margin-right: 3px;
  font-variant-numeric: tabular-nums;
}
.plate .claimed .gauge { margin-top: 9px; }
.plate .claimed-count {
  margin: 6px 0 0;
  font-size: 11.5px;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

/* What the person reading has bought the map. Sits under the share of the
   world claimed, because it is the same number told about them. */
.plate .contributed {
  margin: 11px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-dim);
}
.plate .contributed b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* The selvedge strip: a printer's colour bar, doubling as the live counter. */
.selvedge {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 11px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-family: "Azeret Mono", monospace;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* A sheet printed for reference rather than for postage is overprinted
   SPECIMEN. Shown only while Stripe is in test mode. */
.specimen {
  border: 1px solid var(--carmine);
  color: var(--carmine);
  border-radius: 1px;
  padding: 1px 5px;
  letter-spacing: .18em;
  font-size: 9px;
}

.bars { display: flex; gap: 3px; }
.bars i {
  width: 9px;
  height: 9px;
  border-radius: 1px;
  display: block;
}
.bars i:nth-child(1) { background: var(--carmine); }
.bars i:nth-child(2) { background: var(--marine); }
.bars i:nth-child(3) { background: var(--amber); }
.bars i:nth-child(4) { background: var(--land); }

/* -------------------------------------------------------------- top bar */

.ledger {
  grid-area: stage;
  align-self: start;
  justify-self: end;
  z-index: 4;
  margin: 20px 22px 0 0;
  display: flex;
  gap: 6px;
  align-items: center;
}

.ledger a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  text-decoration: none;
  background: color-mix(in srgb, var(--leaf) 88%, transparent);
  backdrop-filter: blur(7px);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: 7px 12px;
  font-size: 12.5px;
  transition: border-color .14s ease, background .14s ease;
}
.ledger a:hover { border-color: var(--rule-lit); background: var(--leaf-2); color: var(--text); }
.ledger .who {
  color: var(--text-faint);
  padding: 7px 2px 7px 8px;
  font-family: "Azeret Mono", monospace;
  font-size: 11px;
}

/* ------------------------------------------------------------- the sheet */

.sheet {
  grid-area: sheet;
  background: var(--leaf-2);
  border-left: 1px solid var(--rule);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--rule-lit) transparent;
}

/* Panes are separated by gutters, the way panes on a sheet are. */
.pane { padding: 18px 20px 20px; border-bottom: 1px solid var(--rule); }
.pane:last-child { border-bottom: 0; }

.pane > h2 {
  margin: 0 0 14px;
  font-family: "Azeret Mono", monospace;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--text-faint);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
}
.pane > h2 .val { color: var(--text-dim); letter-spacing: .06em; }

/* --------------------------------------------------------- the stamp itself */

.stamp {
  background: var(--gum);
  color: var(--gum-ink);
  border-radius: var(--r);
  padding: 15px 16px 16px;
  box-shadow: var(--shadow-leaf);
  --perf: 8px;
  --perf-gap: 11px;
}

.stamp .denom {
  float: right;
  font-family: "Bodoni Moda", Georgia, serif;
  font-size: 26px;
  font-weight: 600;
  line-height: 1;
  color: var(--carmine);
  margin: -2px 0 0 12px;
}

.stamp .catalogue {
  font-family: "Azeret Mono", monospace;
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.1;
  word-break: break-all;
}
.stamp .catalogue.empty { font-size: 14px; color: #6d6455; letter-spacing: 0; }

.stamp .inscription {
  font-family: "Azeret Mono", monospace;
  font-size: 10.5px;
  letter-spacing: .05em;
  color: #6d6455;
  margin-top: 4px;
  word-break: break-all;
}

.facts { display: grid; gap: 6px; margin-top: 13px; }
.fact { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.fact .k { font-size: 12px; color: #6d6455; }
.fact .v {
  font-family: "Azeret Mono", monospace;
  font-size: 12px;
  text-align: right;
  color: var(--gum-ink);
}
.fact .v.off { color: #9a8f7c; }

/* The image sits in the stamp's vignette, perforated on both edges. */
.vignette {
  margin-top: 14px;
  width: 100%;
  aspect-ratio: 1;
  background: var(--gum-2) center / cover no-repeat;
  border-radius: 1px;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 18px;
  font-family: "Azeret Mono", monospace;
  font-size: 10px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #8a7f6c;
  box-shadow: inset 0 0 0 1px rgba(23, 19, 13, .1);
}
.vignette.filled { color: transparent; }

/* --------------------------------------------------------------- controls */

.acts { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 13px; }
.acts:not(:has(> *:not([hidden]))) { display: none; }

.btn {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  background: var(--leaf-3);
  color: var(--text);
  border: 1px solid var(--rule-lit);
  border-radius: var(--r);
  padding: 9px 13px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.btn:hover:not(:disabled) { background: #33291f; border-color: #5c4b37; }
.btn:focus-visible { outline: 2px solid var(--marine); outline-offset: 2px; }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn[hidden] { display: none; }
.btn svg { width: 14px; height: 14px; flex: none; }

.btn.primary {
  background: var(--carmine);
  border-color: var(--carmine);
  color: #fff;
  font-weight: 600;
}
.btn.primary:hover:not(:disabled) { background: var(--carmine-lit); border-color: var(--carmine-lit); }
.btn.primary:disabled { background: var(--carmine-dim); border-color: var(--carmine-dim); color: #a88790; opacity: 1; }

.btn.on { background: var(--marine-dim); border-color: var(--marine); color: #bcd4f2; }
.btn.slim { flex: 0 0 auto; }

/* On the gum, buttons are printed rather than lit. */
.stamp .btn { background: transparent; border-color: rgba(23, 19, 13, .28); color: var(--gum-ink); }
.stamp .btn:hover:not(:disabled) { background: rgba(23, 19, 13, .07); border-color: rgba(23, 19, 13, .5); }
.stamp .btn.primary { background: var(--carmine); border-color: var(--carmine); color: #fff; }
.stamp .btn.primary:hover:not(:disabled) { background: #b83450; border-color: #b83450; }
.stamp .btn.primary:disabled { background: #d9b3bb; border-color: #d9b3bb; color: #7d5a62; }

/* ----------------------------------------------------------------- fields */

.field { display: grid; gap: 5px; margin-top: 12px; }
.field label { font-size: 11.5px; color: #6d6455; }
.field input,
.field select,
.field textarea {
  width: 100%;
  background: rgba(23, 19, 13, .05);
  border: 1px solid rgba(23, 19, 13, .22);
  border-radius: var(--r);
  color: var(--gum-ink);
  padding: 8px 10px;
  font-size: 13px;
}
.field input::placeholder { color: #9a8f7c; }
.field input:focus,
.field select:focus,
.field textarea:focus { outline: none; border-color: var(--carmine); }
.field textarea { resize: vertical; min-height: 62px; }

/* Fields on the leaf rather than on the gum. */
.pane > .field input,
.pane > .field select,
.pane > .field textarea,
.onleaf input, .onleaf select, .onleaf textarea {
  background: var(--leaf);
  border-color: var(--rule-lit);
  color: var(--text);
}
.onleaf label { color: var(--text-faint); }

.consent {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  margin-top: 12px;
  font-size: 11.5px;
  line-height: 1.5;
  color: #6d6455;
}
.consent input { margin-top: 2px; accent-color: var(--carmine); flex: none; }
.consent a { color: #8a5a66; }

/* ------------------------------------------------------------- the notice */

.notice {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 13px 0 0;
}
.stamp .notice { color: #6d6455; }
.stamp #testNote {
  background: rgba(208, 64, 90, .07);
  border: 1px solid rgba(208, 64, 90, .28);
  border-radius: var(--r);
  padding: 9px 11px;
  color: #7d3a47;
}
.stamp #testNote b { color: var(--carmine); font-weight: 600; }
.stamp #testNote .mono { color: #4a4237; font-size: .95em; }
.notice b { color: var(--text); font-weight: 500; }

/* ------------------------------------------------------- owner's caption */

.byline {
  margin-top: 13px;
  padding: 11px 12px;
  background: rgba(23, 19, 13, .05);
  border: 1px solid rgba(23, 19, 13, .14);
  border-radius: var(--r);
  font-size: 12.5px;
}
.byline .who {
  display: block;
  font-family: "Azeret Mono", monospace;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--carmine);
  margin-bottom: 5px;
}
.byline .cap { color: #4a4237; line-height: 1.5; }
.byline a { display: inline-block; margin-top: 7px; font-size: 12px; word-break: break-all; color: #2f5fb0; }

/* ------------------------------------------------------------ the counter */

.gauge {
  height: 3px;
  background: var(--leaf);
  border-radius: 2px;
  overflow: hidden;
  margin-top: 12px;
}
.gauge i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--amber);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s cubic-bezier(.16, 1, .3, 1);
}
@media (prefers-reduced-motion: reduce) { .gauge i { transition: none; } }

/* ------------------------------------------------------------------ chips */

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.chip {
  font-family: "Azeret Mono", monospace;
  font-size: 11.5px;
  background: var(--leaf);
  border: 1px solid var(--rule-lit);
  border-radius: var(--r);
  color: var(--text-dim);
  padding: 5px 9px;
  cursor: pointer;
  transition: border-color .14s ease, color .14s ease;
}
.chip:hover { border-color: var(--amber); color: var(--amber); }
.chip:focus-visible { outline: 2px solid var(--marine); outline-offset: 2px; }

/* ------------------------------------------------------------- the legend */

.legend { display: grid; gap: 9px; }
.key { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--text-dim); }
.key .sw { width: 16px; height: 10px; border-radius: 1px; flex: none; }
/* Bought and blank: the outline the map draws, at legend size. */
.key .sw.ring {
  background: transparent;
  border: 1.5px dashed var(--amber);
  box-sizing: border-box;
}
.key .sw.hatch {
  background-image: repeating-linear-gradient(45deg,
    var(--marine) 0 2px, transparent 2px 4px);
  background-color: var(--marine-dim);
}

/* --------------------------------------------------------------- the boot */

#boot {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  background: var(--leaf);
  font-family: "Azeret Mono", monospace;
  font-size: 12px;
  color: var(--text-dim);
  letter-spacing: .09em;
  text-align: center;
  padding: 32px;
  line-height: 2;
}

/* One authored moment: the sheet arrives as if laid onto the leaf. */
@media (prefers-reduced-motion: no-preference) {
  .sheet > .pane {
    animation: settle .5s cubic-bezier(.16, 1, .3, 1) backwards;
  }
  .sheet > .pane:nth-child(1) { animation-delay: .02s; }
  .sheet > .pane:nth-child(2) { animation-delay: .06s; }
  .sheet > .pane:nth-child(3) { animation-delay: .1s; }
  .sheet > .pane:nth-child(4) { animation-delay: .14s; }
  .sheet > .pane:nth-child(5) { animation-delay: .18s; }
  .plate { animation: settle .6s cubic-bezier(.16, 1, .3, 1) backwards .1s; }
}

@keyframes settle {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------ plain pages */

.leafpage {
  max-width: 72ch;
  margin: 0 auto;
  padding: 52px 26px 96px;
  height: 100dvh;
  overflow-y: auto;
}
.leafpage h1 {
  font-family: "Bodoni Moda", Georgia, serif;
  font-size: 34px;
  font-weight: 600;
  letter-spacing: -.005em;
  margin: 0 0 10px;
  text-wrap: balance;
}
.leafpage h2 {
  font-family: "Azeret Mono", monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--carmine);
  margin: 36px 0 10px;
}
.leafpage p, .leafpage li { color: var(--text-dim); font-size: 15px; line-height: 1.68; }
.leafpage .lede { color: var(--text); font-size: 16.5px; }
.leafpage .back {
  font-family: "Azeret Mono", monospace;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text-faint);
}
.leafpage .back:hover { color: var(--text); }
.leafpage code {
  font-family: "Azeret Mono", monospace;
  font-size: .86em;
  background: var(--leaf-2);
  border: 1px solid var(--rule);
  border-radius: var(--r);
  padding: .1em .35em;
}

.collection { display: grid; grid-template-columns: repeat(auto-fill, minmax(154px, 1fr)); gap: 14px; margin-top: 26px; }
.mounted {
  background: var(--gum);
  border-radius: var(--r);
  overflow: hidden;
  text-decoration: none;
  display: block;
  box-shadow: var(--shadow-leaf);
  transition: transform .16s cubic-bezier(.16, 1, .3, 1), box-shadow .16s ease;
}
.mounted:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.mounted .img {
  aspect-ratio: 1;
  background: var(--gum-2) center / cover no-repeat;
  display: grid;
  place-items: center;
  font-family: "Azeret Mono", monospace;
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #8a7f6c;
}
.mounted .meta { padding: 9px 11px 11px; }
.mounted .meta b {
  display: block;
  font-family: "Azeret Mono", monospace;
  color: var(--gum-ink);
  font-size: 13px;
  letter-spacing: -.01em;
}
.mounted .meta span { font-size: 11.5px; color: #6d6455; }

.card {
  max-width: 400px;
  margin: 0 auto;
  background: var(--gum);
  color: var(--gum-ink);
  border-radius: var(--r);
  padding: 30px 28px;
  box-shadow: var(--shadow-leaf);
  --perf: 8px;
  --perf-gap: 11px;
}
.card h1 { font-size: 24px; margin: 0 0 14px; color: var(--gum-ink); }
.card p { color: #4a4237; font-size: 13.5px; }
.card a { color: #2f5fb0; }
.card label { display: block; font-size: 12px; color: #6d6455; margin-top: 12px; }
.card form input {
  width: 100%;
  background: rgba(23, 19, 13, .05);
  border: 1px solid rgba(23, 19, 13, .22);
  border-radius: var(--r);
  color: var(--gum-ink);
  padding: 9px 11px;
  font-size: 14px;
  margin: 5px 0 4px;
}
.card form input:focus { outline: none; border-color: var(--carmine); }
.card .errorlist { list-style: none; padding: 0; margin: 8px 0 0; color: #a32b3f; font-size: 12.5px; }
.card .btn { width: 100%; margin-top: 18px; }

.flash {
  background: rgba(23, 19, 13, .05);
  border: 1px solid rgba(23, 19, 13, .16);
  border-radius: var(--r);
  padding: 10px 12px;
  font-size: 13px;
  margin-bottom: 16px;
  color: #4a4237;
}

/* --------------------------------------------------------------- narrow */

/* ---------------------------------------------------------------- stacked

   Below 940px, and in any window too short to hold a floating masthead over a
   map, the whole layout stops being an app shell and becomes one scrolling
   document: a bar, the globe, the argument, then the sheet.

   The overlay was the whole bug. A masthead pinned over the stage is fine at
   1440px, where it covers a third of a 900px-tall map. On a 375x812 phone the
   stage was 373px and the plate 370px, so it covered the globe entirely and
   still hung 10px over the sheet; at 320px it overflowed by 153px and buried
   the top of the selected-square stamp, and in landscape by 233px. The account
   links sat in the same 14px-top row as the wordmark on a higher z-index, so
   "My squares" printed straight across "Buy The World" and clipped it mid-word.

   Both come from the same mistake - two absolutely positioned overlays sharing
   a corner they only fit in when the corner is big. Placed in the grid they
   cannot collide and cannot overflow, because the rows size to them. */
@media (max-width: 940px), (max-height: 620px) {
  /* One scroller, not three. Two nested scroll areas plus the map's own gesture
     handling is what makes a phone feel like it is fighting back. */
  body { overflow: auto; }
  html, body { height: auto; }

  .app {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "brand    nav"
      "stage    stage"
      "argument argument"
      "sheet    sheet";
    height: auto;
    min-height: 100dvh;
  }

  /* The plate stops being a panel and hands its two halves to the grid: the
     wordmark into the bar, the argument into the flow under the map. */
  .plate {
    display: contents;
  }
  .plate > h1 {
    grid-area: brand;
    pointer-events: auto;
    display: flex;
    align-items: flex-end;
    /* DESIGN.md puts a 24px floor under Bodoni. It used to drop to 20px here. */
    font-size: clamp(24px, 6.6vw, 27px);
    text-wrap: balance;
    padding: calc(13px + env(safe-area-inset-top)) 6px 11px 16px;
    border-bottom: 1px solid var(--rule);
  }
  .plate > .argument {
    grid-area: argument;
    pointer-events: auto;
    padding: 15px 16px 17px;
    border-top: 1px solid var(--rule);
    background: var(--leaf);
  }

  /* The bar's two halves stretch to the same height, so their bottom borders
     meet as one rule across the screen. Narrow enough and the wordmark wraps to
     two lines and the row grows with it - nothing overlaps at any width. */
  .ledger {
    grid-area: nav;
    margin: 0;
    align-self: stretch;
    justify-self: end;
    align-items: center;
    padding: calc(6px + env(safe-area-inset-top)) 16px 6px 6px;
    border-bottom: 1px solid var(--rule);
  }
  .ledger .who { display: none; }

  /* The map is the interface, so it gets a real amount of the screen and a
     floor in pixels - 58dvh of a landscape phone is 220px, which is not a
     globe you can turn. */
  .stage { height: clamp(300px, 58dvh, 620px); }

  .plate > .argument .thesis { font-size: .89rem; line-height: 1.5; margin-bottom: .5rem; }

  .sheet {
    border-left: 0;
    border-top: 1px solid var(--rule);
    max-height: none;
    overflow: visible;
    padding-bottom: env(safe-area-inset-bottom);
  }

  .leafpage { height: auto; overflow: visible; padding: 34px 18px calc(72px + env(safe-area-inset-bottom)); }
  .leafpage h1 { font-size: 27px; }
  .leafpage .lede { font-size: 15.5px; }
}

@media (prefers-reduced-motion: no-preference) and (max-width: 940px),
       (prefers-reduced-motion: no-preference) and (max-height: 620px) {
  .plate > h1 { animation: settle .5s cubic-bezier(.16, 1, .3, 1) backwards; }
  .plate > .argument { animation: settle .5s cubic-bezier(.16, 1, .3, 1) .08s backwards; }
}

@media (max-width: 560px) {
  /* Two columns of thumbnails, not one wide one and a gap. */
  .collection { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .mounted .meta { padding: 7px 9px 9px; }
  .mounted .meta b { font-size: 12px; }
  .mounted .meta span { font-size: 10.5px; }
  .leafpage h1 { font-size: 24px; }
  .prefs .consent { padding: 6px 0; }
  .prefs .btn, .leafpage .btn { width: 100%; text-align: center; }

  /* A primary action takes the row. The slim pair - Share and Report - splits
     it, because one full-width button each for two afterthoughts pushes the
     buy action off the screen. */
  .acts .btn { width: 100%; }
  .acts .btn.slim { width: auto; flex: 1 1 calc(50% - 4px); }
}

@media (max-width: 420px) {
  .plate > .argument { padding: 13px 14px 15px; }
  .plate > .argument .thesis { font-size: .84rem; line-height: 1.45; }
  .plate > h1 { padding-left: 14px; }
  .ledger { padding-right: 14px; gap: 4px; }
  .ledger a { padding-left: 10px; padding-right: 10px; }
  .pane { padding: 16px 14px 18px; }
  /* Two columns all the way down. One column of square tiles puts a single
     thumbnail across half the screen, and a collection you have to scroll
     through one at a time is not a collection you can look at. */
  .collection { gap: 8px; }
}

/* ------------------------------------------------------------------ touch

   Screen size is not input method: a touch laptop needs these and a 900px
   browser window on a desktop does not. Keyed on the pointer, not the width. */
@media (pointer: coarse) {
  /* Under 16px, iOS Safari zooms the whole page the moment a field is focused,
     and the layout the visitor was reading jumps sideways under their thumb. */
  .field input, .field select, .field textarea,
  .card form input { font-size: 16px; }

  .btn { min-height: 44px; }
  .chip { min-height: 44px; display: inline-flex; align-items: center; }
  .ledger a { min-height: 44px; }
  .maplibregl-ctrl-group button { width: 44px !important; height: 44px !important; }

  /* The footer's three legal links are navigation on their own line, not words
     in a sentence. Padding an inline box grows the hit area without moving the
     line it sits on. Deliberately not applied to .notice links generally: the
     terms link inside a consent label would then swallow taps meant to tick
     the box it sits in. */
  .notice.legal a { padding: 11px 3px; }

  /* A 13px-tall link is the only way back to the globe from every paper page. */
  .leafpage .back { display: inline-block; padding: 11px 0; }
  .consent { padding: 4px 0; }
  .consent input[type="checkbox"] { width: 22px; height: 22px; }
}


/* The masthead now argues before it instructs. The thesis carries the weight;
   the how-to steps back so it does not read as another line of the same voice. */
.plate .thesis {
  font-size: .93rem;
  line-height: 1.55;
  color: var(--text);
  margin-bottom: .55rem;
}
.plate .howto,
.plate .howto-touch {
  font-size: .82rem;
  color: var(--text-faint);
  margin-top: 0;
}
/* "Scroll to come closer" is not an instruction a thumb can follow. */
.plate .howto-touch { display: none; }
@media (pointer: coarse) {
  .plate .howto { display: none; }
  .plate .howto-touch { display: block; }
}


/* Notification switches on the collection page. The consent label style already
   exists for the checkout box; this only gives the stack some room. */
.prefs { margin-top: 16px; }
.prefs .consent { display: flex; gap: 10px; margin-bottom: 10px; align-items: flex-start; }
.prefs .flash, .leafpage .flash { color: var(--moss, #4a6141); }
.prefs .flash.error, .leafpage .flash.error { color: var(--carmine); }


/* A <pre> is the one element that will push a phone page sideways on its own.
   The form has to stay monospaced to read as a form, so it scrolls in its own
   box instead of taking the document with it. */


/* Links on the paper pages had no colour of their own, so they came out as
   browser blue on a cream sheet - the one colour nothing else here uses. */
.leafpage a:not(.btn):not(.back) {
  color: var(--carmine);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.leafpage a:not(.btn):not(.back):hover { text-decoration-thickness: 2px; }


/* The one revision, said in the panel rather than only in an error after the
   fact. It is the whole shape of what somebody is buying, so it reads as part
   of the form and not as a warning bolted on. */
.metanote {
  margin: 6px 0 2px;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--ink-3, #6b6257);
}
.metanote:empty { display: none; }


/* The clock. Carmine because it is the definitive mark and this is the most
   definitive thing on the page - not amber, which belongs to the globe. The bar
   drains rather than fills, so it reads as something being used up. */
.doom {
  height: 6px;
  background: var(--carmine-dim);
  overflow: hidden;
  margin: 2px 0 10px;
}
.doom i {
  display: block;
  height: 100%;
  background: var(--carmine);
  transform-origin: left center;
  transform: scaleX(1);
  transition: transform .6s ease-out;
}
.doom i.low { background: var(--carmine-lit); }
#clockDays { font-variant-numeric: tabular-nums; }
#clockDays.out { color: var(--carmine-lit); }


/* ---------- the clock ----------
   The second thing you read, after the thesis. A sentence rather than a digital
   dial: the units cascade down as the time runs out, so it gets more urgent on
   its own without anything changing colour.

   Carmine for the figures because it is the definitive ink and this is the most
   definitive thing on the page. Never amber - that belongs to the globe. */
.doomsday {
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid var(--rule);
}
.doomsday .lede-clock {
  margin: 0 0 6px;
  font-family: var(--mono, "Azeret Mono", ui-monospace, monospace);
  font-size: 10px;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.doomsday .dial {
  margin: 0;
  font-size: 0;                 /* collapses whitespace between the units */
  line-height: 1;
}
.doomsday .dial .n {
  font-family: var(--mono, "Azeret Mono", ui-monospace, monospace);
  font-size: 40px;
  line-height: 1.02;
  font-variant-numeric: tabular-nums;
  color: var(--carmine-lit);
  letter-spacing: -.02em;
}
.doomsday .dial .u {
  font-family: var(--ui, "Familjen Grotesk", sans-serif);
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin: 0 14px 0 5px;
  vertical-align: 6px;
}
.doomsday .dial .u:last-child { margin-right: 0; }
.doomsday .bought {
  margin: 9px 0 0;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--text-dim);
}
.doomsday .bought b { color: var(--text); font-weight: 600; }
/* Under a day left, the figures stop being a fact and start being a warning. */
.doomsday.last-day .dial .n { color: var(--carmine); }
.doomsday.out .dial .n { font-size: 27px; color: var(--carmine); }

@media (max-width: 940px) {
  .doomsday .dial .n { font-size: 32px; }
  .doomsday .dial .u { font-size: 11px; margin-right: 11px; }
}
@media (max-width: 560px) {
  .doomsday { margin-top: 11px; padding-top: 10px; }
  .doomsday .dial .n { font-size: 27px; }
  .doomsday .dial .u { font-size: 10px; margin: 0 9px 0 4px; vertical-align: 4px; }
  .doomsday .bought { font-size: .74rem; }
}
