/* Buy The World — the orbit console.
   The visitor is looking down at a planet at night from low orbit. The ground
   is space; every panel is a pane of glass with an instrument on it; the light
   comes from the planet and from the instruments themselves. Cyan is the
   interface acting, violet is a mode being held open, magenta is time running
   out, and amber - the one colour the project has always had - is a square
   somebody has claimed. */

:root {
  /* Space. Blue-black, never grey-black: a grey ground turns every neon muddy. */
  --void:        #04060c;
  --space:       #070b16;
  --panel:       #0b1020;
  --panel-2:     #0f1628;
  --panel-3:     #151d34;
  --glass:       rgba(9, 13, 26, .74);

  /* Hairlines. Tinted from the ground, drawn light rather than dark. */
  --line:        rgba(148, 166, 224, .14);
  --line-lit:    rgba(148, 166, 224, .30);

  /* Type on space. */
  --text:        #e8edff;
  --text-dim:    #9ba7c9;
  --text-faint:  #6b78a0;
  --dimmer:      var(--text-faint);

  /* Cyan: the interface acting. Primary actions, links, focus, the selection. */
  --cyan:        #22e5ff;
  --cyan-lit:    #8df1ff;
  --cyan-ink:    #03151c;
  --cyan-dim:    rgba(34, 229, 255, .14);
  --cyan-line:   rgba(34, 229, 255, .42);

  /* Violet: a mode being held open. Marking, and the basket on the map. */
  --violet:      #a970ff;
  --violet-lit:  #cdb0ff;
  --violet-dim:  rgba(169, 112, 255, .16);
  --violet-line: rgba(169, 112, 255, .45);

  /* Magenta: time. The clock, and only the clock. */
  --magenta:     #ff4fd8;
  --magenta-lit: #ff8ae6;
  --magenta-dim: rgba(255, 79, 216, .16);

  /* Brand, fixed: a claimed square on the map is amber, and so is its outline
     wherever the interface repeats it. */
  --amber:       #ffb02e;
  --amber-dim:   rgba(255, 176, 46, .16);

  /* The planet's own colours, for the legend and nothing else. */
  --land:        #23a271;
  --grid-swatch: rgba(34, 229, 255, .55);

  --r:           14px;   /* panels */
  --r-s:         9px;    /* controls */
  --r-xs:        6px;    /* fields, chips */

  --font-display: "Syne", "Space Grotesk", system-ui, sans-serif;
  --font-ui:      "Space Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --shadow:      0 1px 2px rgba(0, 0, 0, .5), 0 22px 60px -24px rgba(0, 0, 0, .95);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, .5), 0 30px 70px -26px rgba(0, 0, 0, .95);
  --glow-cyan:   0 0 0 1px rgba(34, 229, 255, .35), 0 0 26px rgba(34, 229, 255, .28);
  --glow-violet: 0 0 0 1px rgba(169, 112, 255, .4), 0 0 24px rgba(169, 112, 255, .3);
  --edge:        inset 0 1px 0 rgba(255, 255, 255, .05);

  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(--void);
  color: var(--text);
  font-family: var(--font-ui);
  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(--cyan); text-underline-offset: 2px; }
a:hover { color: var(--cyan-lit); }

::selection { background: rgba(34, 229, 255, .35); color: #fff; }

* { scrollbar-width: thin; scrollbar-color: var(--line-lit) transparent; }
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--line-lit); border-radius: 8px; }
::-webkit-scrollbar-track { background: transparent; }

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* The eyebrow: tracked mono caps, the label an instrument carries. Every
   section heading and every disclosure is one of these. */
.eyebrow,
.pane > h2,
.roll-title,
.mode,
.unfold,
.clockbar .lede,
.launching .lede,
.leafpage h2,
.leafpage .back {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .17em;
  text-transform: uppercase;
}

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

/* The stage and the sheet are the two named areas; the plate and the roll 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. */
.app {
  display: grid;
  grid-template-columns: 1fr 384px;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "brand sheet"
    "stage sheet";
  height: 100dvh;
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* The bar. One row across the top at every width, holding the three things that
   are about the site rather than about a square: whose it is, how long it has
   left, and the way into an account. A real grid row rather than a third
   overlay floating in the stage: a row cannot collide with anything. */
.topbar {
  grid-area: brand;
  position: relative;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 12px 20px 11px;
  background: linear-gradient(180deg, var(--panel), var(--space));
  border-bottom: 1px solid var(--line);
  min-width: 0;
  z-index: 4;
}
/* The one line of light on the chrome: a hairline that runs cyan into violet
   along the bottom of the bar, so the bar reads as an instrument rather than a
   header. */
.topbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(90deg, transparent 0%, var(--cyan) 22%, var(--violet) 58%, transparent 100%);
  opacity: .55;
  pointer-events: none;
}
.topbar h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.01em;
  line-height: 1.05;
  white-space: nowrap;
  color: var(--text);
  background: linear-gradient(90deg, #ffffff 0%, var(--cyan-lit) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* The links go to the far end, so the clock ends up beside the wordmark rather
   than adrift in the middle. */
.topbar .ledger { margin-left: auto; }

/* The countdown, in the one place on the page that is always in view. Short
   units because a bar has no room for a sentence - the long form is behind the
   plate's fold, and the aria-label on the element carries it besides.
   Magenta, and magenta is nothing else on this page: time is its own colour. */
.clockbar {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 9px;
  min-width: 0;
}
.clockbar .tick { white-space: nowrap; }
/* The label the figures answer to, and it drops out when the clock has run out
   - "this site will live for: no time left" is not a sentence. */
.clockbar .lede {
  color: var(--text-faint);
  white-space: nowrap;
  font-size: 9.5px;
  letter-spacing: .15em;
}
.clockbar.out .lede { display: none; }
.clockbar b {
  font-family: var(--font-mono);
  font-size: 17px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--magenta);
  letter-spacing: -.01em;
  text-shadow: 0 0 14px rgba(255, 79, 216, .55);
}
.clockbar i {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 11px;
  color: var(--text-faint);
  margin-left: 1px;
}
.clockbar.last-day b { color: var(--magenta-lit); }
.clockbar.out b, .clockbar.out { color: var(--magenta); font-size: 13px; }

/* Space. The map's canvas is transparent everywhere the globe is not, so this
   is what the visitor sees around the planet: a faint nebula in the two inks,
   and the stars painted on the canvas above it. */
.stage {
  grid-area: stage;
  position: relative;
  min-width: 0;
  background:
    radial-gradient(ellipse 60% 50% at 22% 30%, rgba(120, 70, 255, .13), transparent 70%),
    radial-gradient(ellipse 55% 45% at 80% 75%, rgba(34, 229, 255, .08), transparent 70%),
    var(--void);
}
#map { position: absolute; inset: 0; }

/* The stars sit under the map and are 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;
}

/* The atmosphere: a ring of light sitting just outside the globe's edge, drawn
   under the map so the globe itself covers all of it but the rim. Its box is
   set by globe.js, which measures where that edge actually is. Cyan at the
   limb running out into violet, which is the light this whole page is lit by. */
#halo {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(closest-side circle at 50% 50%,
              rgba(34, 229, 255, 0) 0 72%,
              rgba(34, 229, 255, .34) 76.5%,
              rgba(120, 140, 255, .16) 84%,
              rgba(169, 112, 255, .06) 92%,
              rgba(169, 112, 255, 0) 100%);
}

/* MapLibre ships white chrome; bring it into orbit. */
.maplibregl-ctrl-attrib {
  font-family: var(--font-mono) !important;
  font-size: 9.5px !important;
  background: var(--glass) !important;
  color: var(--text-faint) !important;
  border-radius: var(--r-xs) 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: var(--glass) !important;
  backdrop-filter: blur(12px) saturate(140%);
  border: 1px solid var(--line-lit) !important;
  border-radius: var(--r-s) !important;
  box-shadow: var(--shadow), var(--edge) !important;
  overflow: hidden;
}
.maplibregl-ctrl-group button + button { border-top: 1px solid var(--line) !important; }
.maplibregl-ctrl-group button { background: transparent !important; width: 32px !important; height: 32px !important; }
.maplibregl-ctrl-group button:hover { background: var(--cyan-dim) !important; }
.maplibregl-ctrl-group button:focus-visible { outline: 2px solid var(--cyan) !important; outline-offset: -2px; }
.maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1) opacity(.7); }
.maplibregl-ctrl-group button:hover .maplibregl-ctrl-icon { filter: invert(1) opacity(1); }

/* Marking, offered beside the zoom pair - where a hand already is while
   somebody is looking around. Deliberately quiet: an icon the size of a zoom
   button, and a number only once something is marked. Violet when the mode is
   held open, which is this interface's ink for exactly that. */
.maplibregl-ctrl-group button.mark-ctrl {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: auto !important;
  min-width: 32px;
  padding: 0 7px;
  color: var(--text-dim);
}
.mark-ctrl svg { width: 15px; height: 15px; flex: none; }
.mark-ctrl:hover { color: var(--text); }
.mark-ctrl.on {
  color: var(--violet-lit);
  background: var(--violet-dim) !important;
  box-shadow: inset 0 0 0 1px var(--violet-line);
}
.mark-ctrl .n {
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.mark-ctrl .n:empty { display: none; }

/* ---------------------------------------------------------- opening soon */
/* The page somebody early gets. Space, the wordmark, and the countdown set in
   the same magenta as the clock in the bar - it is the same kind of fact, and
   this is the first thing anybody will ever have seen of this site. */
.launching {
  max-width: 34rem;
  margin: 0 auto;
  padding: clamp(48px, 14vh, 120px) 22px 60px;
  text-align: left;
}
.launching h1 {
  margin: 0 0 30px;
  font-family: var(--font-display);
  font-size: clamp(30px, 7vw, 46px);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -.02em;
  color: var(--text);
}
.launching .lede {
  margin: 0 0 10px;
  color: var(--text-faint);
}
.launching .dial {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 14px;
  row-gap: 5px;
}
.launching .dial .tick { white-space: nowrap; }
.launching .dial b {
  font-family: var(--font-mono);
  font-size: clamp(30px, 9vw, 46px);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--magenta);
  letter-spacing: -.02em;
  text-shadow: 0 0 22px rgba(255, 79, 216, .5);
}
.launching .dial i {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 11px;
  color: var(--text-faint);
  margin-left: 5px;
}
.launching .dial.out b { color: var(--magenta-lit); }
.launching .blurb {
  margin: 26px 0 0;
  font-size: 15px;
  line-height: 1.62;
  color: var(--text-dim);
}
.launching .notice { margin-top: 18px; font-size: 12.5px; color: var(--text-faint); }
.launching .notice a { color: var(--cyan); }

/* ------------------------------------------------------------ the welcome */
/* The one modal on the site, shown once to somebody who has never been here.
   A pane of glass over the planet, lit from its top edge. */
.welcome {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px);
  overflow-y: auto;
  overscroll-behavior: contain;
  margin: auto;
  padding: 28px 32px 26px;
  border: 1px solid var(--line-lit);
  border-radius: var(--r);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  color: var(--text-dim);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .7), var(--edge), 0 0 0 1px rgba(34, 229, 255, .06);
}
.welcome::backdrop {
  background: rgba(3, 5, 10, .66);
  backdrop-filter: blur(4px);
}
.welcome h2 {
  margin: 0 34px 6px 0;
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--text);
}
.welcome p { font-size: 14px; line-height: 1.64; margin: 12px 0 0; }
.welcome .thesis { color: var(--text); }
.welcome .whatitis b { color: var(--text); font-weight: 600; }
.welcome .acts { margin-top: 20px; }
.welcome .unfold { margin-top: 16px; }
.welcome .unfold + .acts { margin-top: 14px; }
.welcome .notice { font-size: 11.5px; color: var(--text-faint); margin-top: 12px; }

/* The cross. Its own form so it submits the dialog closed with no script, and
   in the corner at a size a thumb can hit. */
.welcome-shut { float: right; margin: -8px -12px 0 0; }
.welcome .x {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--r-s);
  background: none;
  color: var(--text-faint);
  cursor: pointer;
}
.welcome .x svg { width: 15px; height: 15px; }
.welcome .x:hover { color: var(--text); background: var(--panel-3); }
.welcome .x:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* A dialog that is open without showModal - no <dialog> support - is a plain
   block in the flow rather than a centred overlay. Put it back over the page.
   Keyed on a class the script adds, not on `:not(:modal)`: a browser old
   enough to lack <dialog> lacks `:modal` too. */
.welcome.plain[open] {
  position: fixed;
  inset: 20px auto auto 50%;
  transform: translateX(-50%);
  z-index: 20;
}

@media (prefers-reduced-motion: no-preference) {
  .welcome[open] { animation: settle .34s cubic-bezier(.16, 1, .3, 1); }
}

@media (max-width: 560px) {
  .welcome { padding: 20px 18px 18px; }
  .welcome h2 { font-size: 24px; }
  .welcome p { font-size: 13.5px; }
}

/* -------------------------------------------------------------- the plate */

/* The controls over the map: the two ways in, and the fold. A pane of glass in
   the stage's top-left corner. */
.plate {
  grid-area: stage;
  align-self: start;
  justify-self: start;
  z-index: 3;
  margin: 18px 0 0 20px;
  /* Against the stage row, not the viewport: the bar sits above it. */
  max-height: calc(100% - 36px);
  /* A column so the fold can be the part that gives. */
  display: flex;
  flex-direction: column;
  min-height: 0;
  pointer-events: none;
  max-width: min(44ch, 60%);
  background: var(--glass);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--line-lit);
  border-radius: var(--r);
  padding: 14px 16px 14px;
  box-shadow: var(--shadow), var(--edge);
}

/* The plate is click-through so the globe can be dragged behind it, and every
   descendant inherits that. Only the parts meant to be pressed get their
   presses back. Anything interactive added to the plate has to be named here,
   or it will look right and do nothing - tests/test_plate.py pins the set. */
.plate .find,
.plate .find-list,
.plate .acts,
.plate .more,
.plate .unfold { pointer-events: auto; }

/* The mark control sits directly under the search: the two ways in, together. */
.plate .plate-acts { margin-top: 8px; }

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

/* What the person reading has bought the map. */
.plate .contributed {
  margin: 11px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-dim);
}
.plate .contributed b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

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

.ledger {
  display: flex;
  gap: 6px;
  align-items: center;
  flex: none;
}

/* The links, and the one button among them - the switch to the other look -
   dressed the same, because it lives in the same row for the same reason. */
.ledger form { display: contents; }
.ledger button { font: inherit; cursor: pointer; }
.ledger a,
.ledger button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  text-decoration: none;
  background: var(--panel-3);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 12.5px;
  font-weight: 500;
  transition: border-color .14s ease, background .14s ease, box-shadow .14s ease;
}
.ledger a:hover,
.ledger button:hover {
  border-color: var(--cyan-line);
  background: var(--cyan-dim);
  color: var(--cyan-lit);
  box-shadow: 0 0 18px rgba(34, 229, 255, .16);
}
.ledger a:focus-visible,
.ledger button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.ledger .who {
  color: var(--text-faint);
  padding: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  background: none;
  border: 0;
}

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

.sheet {
  grid-area: sheet;
  background: var(--panel);
  border-left: 1px solid var(--line);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* One square or several. Two tabs sharing a rule with the pane below. Cyan on
   the selected one, and a line of light under it: it decides what a click does. */
.modes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid var(--line);
  background: var(--space);
}
.mode {
  appearance: none;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  padding: 14px 10px 12px;
  color: var(--text-faint);
  cursor: pointer;
  transition: color .14s ease, background .14s ease;
}
.mode + .mode { border-left: 1px solid var(--line); }
.mode:hover { color: var(--text-dim); }
.mode[aria-selected="true"] {
  color: var(--cyan-lit);
  border-bottom-color: var(--cyan);
  background: linear-gradient(180deg, transparent, var(--cyan-dim));
  box-shadow: inset 0 -12px 24px -18px rgba(34, 229, 255, .8);
}
.mode:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }
.mode .val { color: var(--text-dim); letter-spacing: .06em; }
.mode[aria-selected="true"] .val { color: var(--cyan-lit); }

/* The two screens carry no chrome of their own - the panes inside them already
   have it, and a border here would double every rule on the sheet. */
#screenOne, #screenMany { display: contents; }

.pane { padding: 18px 20px 20px; border-bottom: 1px solid var(--line); }
.pane:last-child { border-bottom: 0; }

.pane > h2 {
  margin: 0 0 14px;
  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 square */

/* The selected square, as an instrument reading: a dark pane with a bracket of
   light in two corners, the way a target is drawn on a console. */
.stamp {
  position: relative;
  background: linear-gradient(180deg, var(--panel-3), var(--panel-2));
  color: var(--text);
  border: 1px solid var(--line-lit);
  border-radius: var(--r);
  padding: 16px 17px 17px;
  box-shadow: var(--shadow), var(--edge);
}
.stamp::before,
.stamp::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--cyan);
  opacity: .8;
  pointer-events: none;
}
.stamp::before { top: -1px; left: -1px; border-right: 0; border-bottom: 0; border-radius: var(--r) 0 0 0; }
.stamp::after { bottom: -1px; right: -1px; border-left: 0; border-top: 0; border-radius: 0 0 var(--r) 0; }

.stamp .denom {
  float: right;
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 800;
  line-height: 1;
  color: var(--cyan);
  margin: -2px 0 0 12px;
  text-shadow: 0 0 16px rgba(34, 229, 255, .45);
}

.stamp .catalogue {
  font-family: var(--font-mono);
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.1;
  word-break: break-all;
  color: var(--text);
}
.stamp .catalogue.empty { font-size: 14px; color: var(--text-faint); letter-spacing: 0; }

.stamp .inscription {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .05em;
  color: var(--text-faint);
  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: var(--text-faint); }
.fact .v {
  font-family: var(--font-mono);
  font-size: 12px;
  text-align: right;
  color: var(--text);
}
.fact .v.off { color: var(--text-faint); }

/* The image well. Empty, it shows the grid the square is cut from. */
.vignette {
  margin-top: 14px;
  width: 100%;
  aspect-ratio: 1;
  background:
    repeating-linear-gradient(0deg, transparent 0 23px, rgba(34, 229, 255, .07) 23px 24px),
    repeating-linear-gradient(90deg, transparent 0 23px, rgba(34, 229, 255, .07) 23px 24px),
    var(--space);
  border-radius: var(--r-s);
  display: grid;
  place-items: center;
  text-align: center;
  padding: 18px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--text-faint);
  box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden;
}
.vignette.filled {
  color: transparent;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* --------------------------------------------------------------- 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(--panel-3);
  color: var(--text);
  border: 1px solid var(--line-lit);
  border-radius: var(--r-s);
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background .14s ease, border-color .14s ease, color .14s ease, box-shadow .14s ease, transform .14s ease;
}
.btn:hover:not(:disabled) {
  background: var(--cyan-dim);
  border-color: var(--cyan-line);
  color: var(--cyan-lit);
}
.btn:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn[hidden] { display: none; }
.btn svg { width: 14px; height: 14px; flex: none; }

/* The primary action is the one lit thing in its row. */
.btn.primary {
  background: linear-gradient(180deg, #6df0ff, #12d2ec);
  border-color: transparent;
  color: var(--cyan-ink);
  font-weight: 700;
  box-shadow: 0 0 0 1px rgba(34, 229, 255, .3), 0 0 22px rgba(34, 229, 255, .28), 0 8px 20px -12px rgba(34, 229, 255, .8);
}
.btn.primary:hover:not(:disabled) {
  background: linear-gradient(180deg, #8df5ff, #22e5ff);
  color: var(--cyan-ink);
  border-color: transparent;
  box-shadow: 0 0 0 1px rgba(34, 229, 255, .5), 0 0 30px rgba(34, 229, 255, .42), 0 10px 24px -12px rgba(34, 229, 255, .9);
  transform: translateY(-1px);
}
.btn.primary:disabled {
  background: var(--panel-3);
  border-color: var(--line);
  color: var(--text-faint);
  box-shadow: none;
  opacity: 1;
}

/* A mode held open. */
.btn.on {
  background: var(--violet-dim);
  border-color: var(--violet-line);
  color: var(--violet-lit);
  box-shadow: 0 0 18px rgba(169, 112, 255, .18);
}
.btn.on:hover:not(:disabled) { background: rgba(169, 112, 255, .24); border-color: var(--violet); color: #fff; }
.btn.slim { flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn.primary:hover:not(:disabled) { transition: none; transform: none; }
}

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

.field { display: grid; gap: 5px; margin-top: 12px; }
.field label { font-size: 11.5px; color: var(--text-dim); }
.field input,
.field select,
.field textarea,
.card form input {
  width: 100%;
  background: var(--void);
  border: 1px solid var(--line-lit);
  border-radius: var(--r-xs);
  color: var(--text);
  padding: 9px 11px;
  font-size: 13px;
  transition: border-color .14s ease, box-shadow .14s ease;
}
.field input::placeholder,
.card form input::placeholder { color: var(--text-faint); }
.field input:focus,
.field select:focus,
.field textarea:focus,
.card form input:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px var(--cyan-dim);
}
.field textarea { resize: vertical; min-height: 62px; }
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-dim) 50%),
                    linear-gradient(135deg, var(--text-dim) 50%, transparent 50%);
  background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 30px;
}
.onleaf label { color: var(--text-dim); }

.consent {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  margin-top: 12px;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
}
.consent b { color: var(--text); }
.consent input { margin-top: 2px; accent-color: var(--cyan); flex: none; }
.consent a { color: var(--cyan); }

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

.notice {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
  margin: 13px 0 0;
}
.notice b { color: var(--text); font-weight: 500; }
.notice.error { color: var(--magenta-lit); }
.stamp #testNote {
  background: var(--cyan-dim);
  border: 1px solid var(--cyan-line);
  border-radius: var(--r-xs);
  padding: 9px 11px;
  color: var(--text-dim);
}
.stamp #testNote b { color: var(--cyan-lit); font-weight: 600; }
.stamp #testNote .mono { color: var(--text); font-size: .95em; }

/* ------------------------------------------------- why it is not live yet */
/* A callout on the pane, with a caret punched through its bottom edge at the
   one control it names. Violet: it is about a state being held, not an action. */
.hint {
  position: relative;
  margin-top: 13px;
  padding: 10px 12px;
  border: 1px solid var(--violet-line);
  border-radius: var(--r-xs);
  background: var(--violet-dim);
}
.hint .ask {
  margin: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--violet-lit);
}
.hint .why {
  margin: 5px 0 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-dim);
}
.hint .why b { color: var(--text); font-weight: 600; }
.hint::before,
.hint::after {
  content: "";
  position: absolute;
  left: 17px;
  width: 0;
  height: 0;
  border: 7px solid transparent;
  border-bottom: 0;
}
.hint::before { bottom: -7px; border-top-color: var(--violet-line); }
.hint::after { bottom: -6px; border-top-color: #1b1a36; }
.hint + .acts { margin-top: 10px; }

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

.byline {
  margin-top: 13px;
  padding: 11px 12px;
  background: var(--space);
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  font-size: 12.5px;
}
.byline .who {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--amber);
  margin-bottom: 5px;
}
.byline .cap { color: var(--text-dim); line-height: 1.5; }
.byline a { display: inline-block; margin-top: 7px; font-size: 12px; word-break: break-all; color: var(--cyan); }

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

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 11px; }
.chip {
  font-family: var(--font-mono);
  font-size: 11.5px;
  background: var(--panel-3);
  border: 1px solid var(--line-lit);
  border-radius: 999px;
  color: var(--text-dim);
  padding: 5px 11px;
  cursor: pointer;
  transition: border-color .14s ease, color .14s ease, box-shadow .14s ease;
}
.chip:hover { border-color: var(--amber); color: var(--amber); box-shadow: 0 0 14px rgba(255, 176, 46, .2); }
.chip:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

/* ------------------------------------------------- the newest squares, rolling */

/* A grid item laid into the stage's area, exactly as the plate is - never
   `position: absolute` against the stage. The plate takes the top of that area
   and this takes the bottom, so on any screen wide enough to show both they
   cannot meet. */
.roll {
  grid-area: stage;
  align-self: end;
  justify-self: start;
  z-index: 2;
  margin: 0 0 18px 20px;
  width: min(320px, 42%);
  /* Click-through, like the plate: the globe has to be draggable across it.
     Only the rows take a press - see `.rollrow`. */
  pointer-events: none;
  background: var(--glass);
  backdrop-filter: blur(16px) saturate(140%);
  border: 1px solid var(--line-lit);
  border-radius: var(--r);
  padding: 11px 12px 11px;
  box-shadow: var(--shadow), var(--edge);
}

.roll-title {
  margin: 0 0 8px 7px;
  color: var(--text-faint);
  display: flex;
  align-items: center;
  gap: 7px;
}
/* A live dot, because the list is one. */
.roll-title::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 8px var(--amber);
}

/* What the roll happens behind. */
.roll-clip { overflow: hidden; }
.roll-list { display: flex; flex-direction: column; }

/* One square at a time on a phone, and the two of them share a cell so the
   change is a change rather than a gap. */
.roll.one .roll-list { display: grid; }
.roll.one .roll-list > * { grid-area: 1 / 1; }

.rollrow {
  /* The one thing in here that takes a press. */
  pointer-events: auto;
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  text-align: left;
  background: transparent;
  border: 0;
  border-left: 2px solid transparent;
  border-radius: 0 var(--r-xs) var(--r-xs) 0;
  padding: 6px 7px;
  cursor: pointer;
  font: inherit;
  color: inherit;
  transition: background-color .14s ease, border-color .14s ease;
}
.rollrow:hover { background: rgba(255, 176, 46, .08); border-left-color: var(--amber); }
.rollrow:focus-visible { outline: 2px solid var(--cyan); outline-offset: -2px; }

/* The face, at 32px. Square, because a square is what was bought. */
.rollface {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 5px;
  background: var(--panel-3) center / cover no-repeat;
  box-shadow: inset 0 0 0 1px var(--line-lit);
}
/* Bought, nothing printed on it: the dashed amber outline the map draws for
   the same cell, so the two say the same thing in the same colour. */
.rollface.blank {
  background: transparent;
  border: 1.5px dashed var(--amber);
  box-shadow: none;
}

.rolltext { min-width: 0; display: grid; gap: 1px; flex: 1 1 auto; }

.rolltop { display: flex; align-items: baseline; gap: 8px; }
.rolltop b {
  font-weight: 500;
  font-size: 12.5px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Two lines and always two: the caption when there is one and where the
   square is when there is not. */
.rollsecond {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--text-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rollsecond.said {
  font-family: inherit;
  font-size: 11.5px;
  color: var(--text-dim);
}

/* The phone's change: the one standing fades out at once and the next rises in
   behind it, overlapping through the middle. */
.roll.one .rollrow {
  transition: opacity 680ms ease 140ms,
              transform 680ms cubic-bezier(.16, 1, .3, 1) 140ms;
}
.roll.one .rollrow.coming { opacity: 0; transform: translateY(9px); }
.roll.one .rollrow.going {
  opacity: 0;
  transform: translateY(-7px);
  transition: opacity 420ms ease, transform 420ms ease;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .roll-list { transition: none !important; }
  .roll.one .rollrow,
  .roll.one .rollrow.going { transition: none; }
}

/* ------------------------------------------------------------- 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: 2px; flex: none; }
.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(--violet) 0 2px, transparent 2px 4px);
  background-color: var(--violet-dim);
}

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

.boot-dim { color: var(--text-faint); }
#boot {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  background: var(--void);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-dim);
  letter-spacing: .12em;
  text-transform: uppercase;
  text-align: center;
  padding: 32px;
  line-height: 2;
}
@media (prefers-reduced-motion: no-preference) {
  #boot { animation: bootpulse 1.6s ease-in-out infinite; }
}
@keyframes bootpulse {
  0%, 100% { color: var(--text-faint); }
  50% { color: var(--cyan-lit); text-shadow: 0 0 18px rgba(34, 229, 255, .5); }
}

/* One authored moment: the panes arrive as if switched on. */
@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; }
  .roll { animation: settle .6s cubic-bezier(.16, 1, .3, 1) backwards .18s; }
}

@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: var(--font-display);
  font-size: 36px;
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.05;
  margin: 0 0 12px;
  text-wrap: balance;
  color: var(--text);
}
.leafpage h2 {
  color: var(--cyan);
  margin: 36px 0 10px;
  font-size: 11px;
  letter-spacing: .16em;
}
.leafpage p, .leafpage li { color: var(--text-dim); font-size: 15px; line-height: 1.68; }
.leafpage li::marker { color: var(--text-faint); }
.leafpage .lede { color: var(--text); font-size: 16.5px; }
.leafpage .back {
  display: inline-block;
  margin-bottom: 8px;
  text-decoration: none;
  color: var(--text-faint);
  font-size: 11px;
  letter-spacing: .1em;
}
.leafpage .back:hover { color: var(--cyan); }
.leafpage code {
  font-family: var(--font-mono);
  font-size: .86em;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: .1em .35em;
}
.leafpage .pane {
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: var(--panel);
}

/* Links on the long pages. Cyan, underlined, so a link in a paragraph is never
   mistaken for emphasis. */
.leafpage a:not(.btn):not(.back):not(.mounted):not(.story-card) {
  color: var(--cyan);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.leafpage a:not(.btn):not(.back):not(.mounted):not(.story-card):hover { text-decoration-thickness: 2px; color: var(--cyan-lit); }
.leafpage p > .btn { display: inline-flex; flex: none; }

/* The collection: a grid of squares somebody holds, each one a small pane. */
.collection { display: grid; grid-template-columns: repeat(auto-fill, minmax(154px, 1fr)); gap: 14px; margin-top: 26px; }
.mounted {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  overflow: hidden;
  text-decoration: none;
  display: block;
  box-shadow: var(--shadow);
  transition: transform .16s cubic-bezier(.16, 1, .3, 1), box-shadow .16s ease, border-color .16s ease;
}
.mounted:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift), var(--glow-cyan); border-color: var(--cyan-line); }
.mounted .img {
  aspect-ratio: 1;
  background: var(--panel-3) center / cover no-repeat;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.mounted .meta { padding: 9px 11px 11px; }
.mounted .meta b {
  display: block;
  font-family: var(--font-mono);
  color: var(--text);
  font-size: 13px;
  letter-spacing: -.01em;
}
.mounted .meta span { font-size: 11.5px; color: var(--text-faint); }

/* A public reading destination for the work already on the map. */
.stories-page { max-width: 1080px; }
.story-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin: 28px 0 30px;
}
.story-card {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-s);
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform .16s cubic-bezier(.16, 1, .3, 1), box-shadow .16s ease, border-color .16s ease;
}
.story-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift), var(--glow-cyan); border-color: var(--cyan-line); }
.story-card__link {
  color: var(--text);
  display: flex;
  flex: 1;
  flex-direction: column;
  text-decoration: none;
}
.story-card img { aspect-ratio: 1; background: var(--panel-3); display: block; object-fit: cover; width: 100%; }
.story-card__copy { color: var(--text-dim); flex: 1; font-size: 14px; line-height: 1.5; padding: 12px 13px 7px; }
.story-card__actions {
  align-items: stretch;
  border-top: 1px solid var(--line);
  display: flex;
}
.story-card__action {
  color: var(--cyan);
  flex: 1;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: .06em;
  padding: 10px 13px;
  text-decoration: none;
  text-transform: uppercase;
}
.story-card__share {
  appearance: none;
  background: transparent;
  border: 0;
  border-left: 1px solid var(--line);
  color: var(--cyan);
  cursor: pointer;
  font: 10px/1 var(--font-mono);
  letter-spacing: .06em;
  padding: 10px 13px;
  text-transform: uppercase;
}
.story-card__share:hover, .story-card__share:focus-visible { background: var(--panel-3); }
.story-empty { max-width: 50ch; margin: 28px 0; }

/* The card: sign in, the invite gate, an error page. One pane, centred. */
.card {
  position: relative;
  max-width: 420px;
  margin: 0 auto;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  color: var(--text);
  border: 1px solid var(--line-lit);
  border-radius: var(--r);
  padding: 32px 30px;
  box-shadow: var(--shadow), var(--edge);
}
.card::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 24px;
  right: 24px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  opacity: .7;
}
.card h1 { font-family: var(--font-display); font-size: 24px; font-weight: 800; letter-spacing: -.02em; margin: 0 0 14px; color: var(--text); }
.card p { color: var(--text-dim); font-size: 13.5px; }
.card a { color: var(--cyan); }
.card label { display: block; font-size: 12px; color: var(--text-dim); margin-top: 12px; }
.card form input { font-size: 14px; margin: 5px 0 4px; }
.card .errorlist { list-style: none; padding: 0; margin: 8px 0 0; color: var(--magenta-lit); font-size: 12.5px; }
.card .btn { width: 100%; margin-top: 18px; }

.flash {
  background: var(--cyan-dim);
  border: 1px solid var(--cyan-line);
  border-radius: var(--r-xs);
  padding: 10px 12px;
  font-size: 13px;
  margin-bottom: 16px;
  color: var(--text);
}
.flash.error, .leafpage .flash.error { background: var(--magenta-dim); border-color: rgba(255, 79, 216, .4); color: var(--magenta-lit); }
.prefs .flash, .leafpage .flash { color: var(--cyan-lit); }

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

   Below 940px, and in any window too short to hold a floating panel over a
   map, the whole layout stops being an app shell and becomes one scrolling
   document: a bar, the globe, the plate, then the sheet. Placed in the grid
   the panels cannot collide and cannot overflow, because the rows size to
   them. */
@media (max-width: 940px), (max-height: 620px) {
  /* One scroller, not three. */
  body { overflow: auto; }
  html, body { height: auto; }

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

  /* The bar is already a row; it only has to be allowed to wrap. Below 560px
     the clock stacks; see that block. */
  .topbar {
    flex-wrap: wrap;
    align-items: center;
    column-gap: 12px;
    row-gap: 6px;
    padding: calc(11px + env(safe-area-inset-top)) 16px 11px;
  }
  .topbar h1 {
    font-size: clamp(20px, 6vw, 24px);
    white-space: normal;
    text-wrap: balance;
  }

  /* The plate stops being an overlay and joins the flow under the map. */
  .plate {
    grid-area: argument;
    align-self: stretch;
    justify-self: stretch;
    pointer-events: auto;
    max-width: none;
    max-height: none;
    margin: 0;
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
    background: var(--panel);
    backdrop-filter: none;
    box-shadow: none;
    padding: 15px 16px 17px;
  }

  /* No column to put a list in, so it stops being one: one square at a time
     at the top of the map, stretched across it. */
  .roll {
    align-self: start;
    justify-self: stretch;
    width: auto;
    margin: 10px 12px 0;
    padding: 8px 10px 9px;
  }
  .roll-title { margin: 0 0 5px 7px; font-size: 9px; }

  /* The name is the first thing to go beside a wrapping wordmark. */
  .ledger .who { display: none; }

  /* The map is the interface, so it gets a real amount of the screen and a
     floor in pixels. */
  .stage { height: clamp(300px, 58dvh, 620px); }

  .sheet {
    border-left: 0;
    border-top: 1px solid var(--line);
    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: 28px; }
  .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) {
  .topbar { animation: settle .5s cubic-bezier(.16, 1, .3, 1) backwards; }
  .plate { animation: settle .5s cubic-bezier(.16, 1, .3, 1) .08s backwards; }
}

/* The clock drops under the wordmark and the links once three abreast no
   longer fit. */
@media (max-width: 760px) {
  .topbar .clockbar { order: 3; width: 100%; }
}

@media (max-width: 560px) {
  .collection { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .story-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .story-card__copy { font-size: 12.5px; padding: 9px 10px 5px; }
  .story-card__action, .story-card__share { font-size: 9px; padding: 9px 10px; }
  .mounted .meta { padding: 7px 9px 9px; }
  .mounted .meta b { font-size: 12px; }
  .mounted .meta span { font-size: 10.5px; }
  .leafpage h1 { font-size: 25px; }
  .prefs .consent { padding: 6px 0; }
  .prefs .btn, .leafpage .btn { width: 100%; text-align: center; }

  /* A primary action takes the row. The slim pair splits it. */
  .acts .btn { width: 100%; }
  .acts .btn.slim { width: auto; flex: 1 1 calc(50% - 4px); }
}

@media (max-width: 420px) {
  .plate { padding: 13px 14px 15px; }
  .topbar { padding-left: 14px; padding-right: 14px; }
  .ledger { gap: 4px; }
  .ledger a { padding-left: 10px; padding-right: 10px; }
  .pane { padding: 16px 14px 18px; }
  .collection { gap: 8px; }
}

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

   Screen size is not input method: keyed on the pointer, not the width. */
@media (pointer: coarse) {
  /* Under 16px, iOS Safari zooms the whole page the moment a field is focused. */
  .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, .ledger button { min-height: 44px; }
  .maplibregl-ctrl-group button { width: 44px !important; height: 44px !important; }

  .notice.legal a { padding: 11px 3px; }
  .leafpage .back { display: inline-block; padding: 11px 0; }
  .consent { padding: 4px 0; }
  .consent input[type="checkbox"] { width: 22px; height: 22px; }
}

/* ---------- finding a place ----------------------------------------------
   The search box on the plate: the first thing a visitor who came to buy
   somewhere in particular needs. */
.find {
  display: flex;
  gap: 6px;
  margin: 0 0 .5rem;
}
.find input {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--void);
  border: 1px solid var(--line-lit);
  color: var(--text);
  font: inherit;
  font-size: .84rem;
  padding: 8px 11px;
  border-radius: var(--r-s);
  /* Safari draws a search field as a rounded capsule with its own inset
     shadow and ignores most of the above without this. */
  -webkit-appearance: none;
  appearance: none;
  transition: border-color .14s ease, box-shadow .14s ease;
}
.find input::placeholder { color: var(--text-faint); }
.find input:focus {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px var(--cyan-dim), 0 0 18px rgba(34, 229, 255, .2);
}
.find input::-webkit-search-cancel-button { filter: invert(1) opacity(.45); }

/* The disclosure. A tracked mono caps line rather than a button, because it is
   not an action. */
.unfold {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  margin: 11px 0 0;
  padding: 8px 0 0;
  border: 0;
  border-top: 1px solid var(--line);
  background: none;
  color: var(--text-faint);
  text-align: left;
  cursor: pointer;
  transition: color .14s ease;
}
.unfold:hover { color: var(--cyan); }
.unfold:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  color: var(--cyan);
}
.unfold svg {
  width: 13px;
  height: 13px;
  flex: none;
  transition: transform .14s ease;
}
.unfold[aria-expanded="true"] svg { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) {
  .unfold svg { transition: none; }
}

/* The fold is what shrinks, so the two controls and the disclosure stay put
   and only the prose scrolls. */
.plate .argument {
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.plate .more {
  min-height: 0;
  overflow-y: auto;
  /* The map is behind this. Scrolling to the end must not start turning the
     globe. */
  overscroll-behavior: contain;
}
.plate .more > :first-child { margin-top: 9px; }

/* The way back to the welcome. A line rather than a button, because it opens
   something to read rather than doing anything to the map. */
.plate .again { margin-top: 12px; }
.plate .again button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 12px;
  color: var(--cyan);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.plate .again button:hover { color: var(--cyan-lit); }
.plate .again button:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }

.find-note {
  font-size: .78rem;
  color: var(--text-faint);
  margin: -.25rem 0 .5rem;
}
.find-note:empty { display: none; }
.find-list {
  list-style: none;
  margin: -.25rem 0 .6rem;
  padding: 0;
  background: var(--panel-2);
  border: 1px solid var(--line-lit);
  border-radius: var(--r-s);
  /* Eight results at most, and a phone in landscape has no room for eight. */
  max-height: 232px;
  overflow-y: auto;
  overflow-x: hidden;
}
.find-list li {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1px 10px;
  padding: 8px 10px;
  cursor: pointer;
  border-top: 1px solid var(--line);
}
.find-list li:first-child { border-top: 0; }
.find-list li:hover,
.find-list li[aria-selected="true"] { background: var(--cyan-dim); }
.find-list li b {
  font-weight: 500;
  font-size: .82rem;
  color: var(--text);
}
.find-list li .where {
  grid-column: 1;
  font-size: .74rem;
  color: var(--text-faint);
}
.find-list li .cell {
  grid-row: 1 / span 2;
  grid-column: 2;
  align-self: center;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .04em;
  color: var(--cyan);
  white-space: nowrap;
}
/* A label that exists for a screen reader and not for the eye. */
.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.plate .howto,
.plate .howto-price {
  font-size: .82rem;
  color: var(--text-faint);
  margin-top: 0;
}
/* The price breakdown is the one line here a visitor is owed rather than
   offered, so it is not faded as far. */
.plate .howto-price {
  color: var(--text-dim);
  margin-top: .45rem;
  margin-bottom: .55rem;
}

/* Notification switches on the collection page. */
.prefs { margin-top: 16px; }
.prefs .consent { display: flex; gap: 10px; margin-bottom: 10px; align-items: flex-start; }

/* ---------- giving it away -----------------------------------------------
   The gift inputs sit inside the square's pane and inherit .field. What they
   need of their own is a rule separating them from the square's facts: this is
   the one block on the panel that is about a person rather than a place. */
#giftBox {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
#giftBox .field:first-child { margin-top: 0; }

/* Handing over a square that already exists. Same treatment, and deliberately
   not the same block. */
#giveBox {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
#giveBox .field:first-child { margin-top: 0; }

.metanote {
  margin: 6px 0 2px;
  font-size: .78rem;
  line-height: 1.45;
  color: var(--text-faint);
}
.metanote:empty { display: none; }

/* The case for a gift, above the three fields that take one. Prose weight, not
   footnote weight: it is the argument. The rule down the left is the only mark
   on it. */
.gift-lede {
  margin: 2px 0 14px;
  padding: 1px 0 1px 12px;
  border-left: 2px solid var(--cyan-line);
  font-size: .86rem;
  line-height: 1.55;
  color: var(--text-dim);
}
.gift-lede b { color: var(--text); font-weight: 600; }

/* The clock in the sheet. Magenta, and the bar drains rather than fills, so it
   reads as something being used up. */
.doom {
  height: 6px;
  background: var(--panel-3);
  border-radius: 3px;
  overflow: hidden;
  margin: 2px 0 10px;
  box-shadow: inset 0 0 0 1px var(--line);
}
.doom i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--violet), var(--magenta));
  border-radius: 3px;
  transform-origin: left center;
  transform: scaleX(1);
  transition: transform .6s ease-out;
  box-shadow: 0 0 12px rgba(255, 79, 216, .55);
}
.doom i.low { background: var(--magenta); }
#clockDays { font-variant-numeric: tabular-nums; color: var(--magenta); }
#clockDays.out { color: var(--magenta-lit); }
@media (prefers-reduced-motion: reduce) { .doom i { transition: none; } }
