:root {
  color-scheme: dark;
  --bg: #14110e;
  --panel: #1a1612;
  --raise: #251f19;
  --raise-2: #30281f;
  --line: #3b3229;
  --text: #f2e9d8;
  --dim: #a79c8a;
  --accent: #f0b43c;
  --accent-ink: #281b04;
  --serif: 'Fraunces', 'Iowan Old Style', Georgia, serif;
  --sans: 'Schibsted Grotesk', 'Helvetica Neue', Arial, sans-serif;
  --mono: 'DM Mono', ui-monospace, Menlo, monospace;
  /* The display face for words in the world's own script. The engine sets it from the world. */
  --script: sans-serif;
  /* How far Arai's own screens keep from the edges of the window. The globe and
     the page of maps share these, so the name of the game does not move between them. */
  --edge-top: clamp(22px, 6vh, 64px);
  --edge-left: clamp(22px, 6vw, 84px);
  --edge-right: clamp(22px, 6vw, 84px);
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 16px/1.4 var(--sans);
  -webkit-font-smoothing: antialiased;
}

button { font: inherit; color: inherit; }
/* A finger held on the street walks the player there. A phone must not take it
   for a long press on a picture, which offers to save or share it: so no picture
   in the game answers a long press, and the ones on the street are not touched
   at all (the street under them is). */
body { -webkit-touch-callout: none; }
#street, #street * { -webkit-user-select: none; user-select: none; }
#street img { pointer-events: none; -webkit-user-drag: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
[hidden] { display: none !important; }

/* Nothing ends on a line with a word or two in it. Everything written in the
   game is split into lines of about the same length, wherever it is: a browser
   asked only to look after the ending of a paragraph still leaves two short
   words by themselves. (A browser evens out the first handful of lines of
   anything, and nothing here runs longer.) */
body { text-wrap: balance; }

/* The picture has the whole window, and everything else is laid over it (see
   "the box", at the end). A phone held sideways puts the talking beside it. */
#app {
  position: relative;
  height: 100vh;
  height: 100dvh;
  display: grid;
  grid-template: minmax(0, 1fr) / minmax(0, 1fr);
  overflow: hidden;
}

/* The street */

#street {
  position: relative;
  overflow: hidden;
  background: linear-gradient(#0f151a 0%, #16212a 44%, #33302c 76%, #6a4a31 100%);
  cursor: pointer;
  touch-action: none;
  user-select: none;
}

/* Each map brings its own sky. Talat is early morning. */
#street[data-map='talat'] { background: linear-gradient(#bcdcec 0%, #d8ecef 46%, #f2e7cc 78%, #e8d4ab 100%); }
/* The beach is the last of the day: a sky going from blue to gold over the sea. */
#street[data-map='beach'] { background: linear-gradient(#3f6f9a 0%, #7fa6b8 26%, #f2c98a 42%, #ffb36a 47%, #2f7fa3 47.2%, #2f7fa3 72%, #ecd9a8 78%, #e6cf98 100%); }
#street[data-map='beach'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.8), rgba(10, 9, 8, 0.5) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='beach'] :is(#deadline, .hud-label, #carry) { color: #e6dccb; }
/* The morning of the boat: a pale clear sky over flat sea. */
#street[data-map='snorkel'] { background: linear-gradient(#6fb6e0 0%, #b7ddef 40%, #dff1f2 46.6%, #2f8fa8 46.8%, #2f8fa8 72%, #f1e4bd 78%, #e8d9ae 100%); }
#street[data-map='snorkel'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.8), rgba(10, 9, 8, 0.5) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='snorkel'] :is(#deadline, .hud-label, #carry) { color: #e6dccb; }
/* The pier: a clear afternoon over the sea, and a sandy road. */
#street[data-map='pier'] { background: linear-gradient(#4f9fd6 0%, #a6d3ea 42%, #d8ecef 50%, #2f8fa8 50.2%, #2f8fa8 72%, #d8c9a6 78%, #cdbd96 100%); }
#street[data-map='pier'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.8), rgba(10, 9, 8, 0.5) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='pier'] :is(#deadline, .hud-label, #carry) { color: #e6dccb; }
/* The mall is indoors: white ceiling, glass, pale tile. */
#street[data-map='mall'] { background: linear-gradient(#eef2f4 0%, #dfe6ea 18%, #dfe6ea 78%, #e9eef0 100%); }
#street[data-map='mall'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.86), rgba(10, 9, 8, 0.6) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='mall'] :is(#deadline, .hud-label, #carry) { color: #dde3e6; }
/* The classroom: a cream wall over floorboards. */
#street[data-map='class'] { background: linear-gradient(#e3d8c0 0%, #efe6d3 12%, #efe6d3 62%, #b9d3c5 64%, #b9d3c5 78%, #b98f5e 79%, #a37c4e 100%); }
#street[data-map='class'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.86), rgba(10, 9, 8, 0.6) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='class'] :is(#deadline, .hud-label, #carry) { color: #ddd5c4; }
/* Soi Ari, the test street from OpenStreetMap: a hazy late afternoon. */
#street[data-map='ari'] { background: linear-gradient(#9fc4dc 0%, #d4e3e8 50%, #ece2cc 79%, #4d4f52 79.5%, #4d4f52 100%); }
#street[data-map='ari'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.86), rgba(10, 9, 8, 0.6) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='ari'] :is(#deadline, .hud-label, #carry) { color: #ddd5c4; }
/* In daylight the top bar needs a deeper shade behind it to stay readable. */
#street[data-map='talat'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.86), rgba(10, 9, 8, 0.6) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='talat'] :is(#deadline, .hud-label, #carry) { color: #ddd5c4; }

#far, #world { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
/* The engine sizes the world, and the backdrop painted for it, to the map. */
.layer { position: absolute; left: 0; top: 0; }
.layer svg { display: block; }
#front { pointer-events: none; }

.sign { font: 400 11px var(--script); }
.hand { font: 400 15px 'Sriracha', 'Thonburi', cursive; }
.neon { font: 400 22px var(--script); }

.backdrop { display: block; }
/* What is round a map's corner hangs off the left end of its backdrop. */
.backdrop.aside { position: absolute; top: 0; max-width: none; }
/* The light of a screen somebody left on. It wavers. */
.flicker { position: absolute; background: #a9c6ff; mix-blend-mode: screen; opacity: 0.1; pointer-events: none; animation: flicker 2.9s steps(1) infinite; }
@keyframes flicker { 0%, 100% { opacity: 0.08; } 7% { opacity: 0.24; } 11% { opacity: 0.05; } 15% { opacity: 0.2; } 49% { opacity: 0.12; } 53% { opacity: 0.28; } 57% { opacity: 0.1; } 82% { opacity: 0.18; } }
.sprite img { display: block; }
.crisp .backdrop, .crisp .sprite img { image-rendering: pixelated; }

#closeup { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
#closeup:not(.indoors)::before {
  content: '';
  position: absolute;
  inset: 0 0 0 45%;
  background: linear-gradient(to right, rgba(12, 10, 8, 0), rgba(12, 10, 8, 0.62));
}
#interior { position: absolute; max-width: none; image-rendering: pixelated; }
#figureClip { position: absolute; overflow: hidden; }
#figureClip img { display: block; width: auto; max-width: none; image-rendering: pixelated; }
/* Something held up in a close-up: a picture on a card, say. */
#figureClip .held { position: absolute; transform: translate(-50%, -50%); line-height: 1; white-space: nowrap; }
/* The same picture small, in a line of words. */
.pip { display: inline-block; height: 1.7em; width: auto; margin: -0.35em 0.1em -0.35em 0; vertical-align: middle; image-rendering: pixelated; }

.actor { position: absolute; left: 0; top: 0; pointer-events: none; }
/* A little dust where the player comes down from a hop: two specks, one each way. */
.puff { position: absolute; left: 0; top: 0; pointer-events: none; }
.puff::before, .puff::after { content: ''; position: absolute; left: -2px; top: -4px; width: 3px; height: 3px; background: rgba(255, 255, 255, 0.6); animation: puff 0.32s steps(5, jump-none) both; }
.puff::after { --way: -1; }
@keyframes puff { to { transform: translate(calc(var(--way, 1) * 16px), -7px); opacity: 0; } }
.actor svg { display: block; overflow: visible; }
.leg { transform-box: fill-box; transform-origin: 50% 0; }
/* A figure drawn in code, on the move. Only the figure: the whole game is
   "walking" too, between conversations, and everything else drawn in code (a
   floor, the icons in the top bar) must keep still. */
.actor.walking .leg.a { animation: stride 0.38s ease-in-out infinite alternate; }
.actor.walking .leg.b { animation: stride 0.38s ease-in-out infinite alternate-reverse; }
.actor.walking svg { animation: bob 0.38s ease-in-out infinite; }
.tail { transform-box: fill-box; transform-origin: 100% 100%; }
.happy .tail { animation: wag 0.28s ease-in-out infinite alternate; }

.smoke { opacity: 0; transform-box: fill-box; animation: smoke 5.2s linear infinite; }
.coals { animation: coals 1.7s ease-in-out infinite alternate; }
.beacon { animation: blink 2.6s steps(2, jump-none) infinite; }
.train { animation: train 52s linear infinite; }

@keyframes stride { from { transform: rotate(-16deg); } to { transform: rotate(16deg); } }
@keyframes bob { 50% { transform: translateY(-2px); } }
@keyframes wag { from { transform: rotate(-14deg); } to { transform: rotate(18deg); } }
@keyframes smoke {
  0% { opacity: 0; transform: translate(0, 0) scale(0.6); }
  18% { opacity: 0.15; }
  100% { opacity: 0; transform: translate(30px, -96px) scale(2.3); }
}
@keyframes coals { from { fill: #c95a2a; } to { fill: #f08a3a; } }
@keyframes blink { 50% { opacity: 0.15; } }
@keyframes train { from { transform: translateX(-320px); } 45%, to { transform: translateX(2200px); } }

/* What can be done at a spot on the street: the same dark label with an amber
   line round it that marks a country on the globe, and a pixel pointer under it. */
.prompt {
  position: absolute;
  left: 0;
  top: 0;
  background: rgba(12, 16, 24, 0.92);
  color: #f2e9d8;
  font: 600 13px/1 var(--sans);
  padding: 8px 12px;
  border: 1px solid #f0b43c;
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 6px 14px rgba(8, 6, 4, 0.45);
  transition: background 0.15s ease, color 0.15s ease;
}
.prompt:hover { background: #f0b43c; color: #281b04; }
/* The pointer, with a darker one behind it so it shows against a lit window. */
.prompt::before, .prompt::after {
  content: '';
  position: absolute;
  left: 50%;
  -webkit-mask: var(--px-pointer) 50% 50% / 100% 100% no-repeat;
  mask: var(--px-pointer) 50% 50% / 100% 100% no-repeat;
  animation: hover 1s steps(2, jump-none) infinite;
}
.prompt::before { top: calc(100% + 1px); width: 22px; height: 12px; margin-left: -11px; background: rgba(12, 16, 24, 0.92); }
.prompt::after { top: calc(100% + 3px); width: 14px; height: 8px; margin-left: -7px; background: #f0b43c; }
.prompt kbd {
  font: 600 11px/1 var(--sans);
  border: 1px solid color-mix(in srgb, currentColor 40%, transparent);
  border-radius: 4px;
  padding: 2px 5px;
  margin-left: 8px;
}
@media (pointer: coarse) { .prompt kbd { display: none; } }

/* Clock, Confidence, pockets */

#hud {
  position: absolute;
  inset: 0 0 auto 0;
  display: flex;
  align-items: flex-start;
  gap: 34px;
  padding: 14px 22px 40px;
  background: linear-gradient(rgba(10, 9, 8, 0.78), rgba(10, 9, 8, 0));
  pointer-events: none;
}
#clock { display: block; font: 600 36px/1 var(--serif); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
#clock.late { color: var(--accent); }
#deadline, .hud-label, #carry { font-size: 13px; color: var(--dim); }
#deadline { display: block; margin-top: 5px; white-space: nowrap; }
.hud-time, .hud-conf { flex: none; }
.hud-conf { padding-top: 3px; }
.hud-label { display: block; margin-bottom: 8px; }
.hud-label b { color: var(--text); font-weight: 600; margin-left: 4px; }
#confDelta { font-style: normal; font-weight: 600; color: var(--accent); margin-left: 6px; opacity: 0; transition: opacity 0.9s ease 0.9s; }
#confDelta.show { opacity: 1; transition: none; }
#ticks { display: flex; gap: 3px; }
#ticks i { width: 5px; height: 15px; border-radius: 1.5px; background: rgba(242, 233, 216, 0.2); transition: background 0.3s ease; }
#ticks i.on { background: var(--accent); }
#ticks i.gate { margin-left: 5px; }
.hud-carry { margin-left: auto; text-align: right; }
#cash { display: block; font: 600 24px/1 var(--serif); font-variant-numeric: tabular-nums; margin-top: 5px; }
#carry { display: block; margin-top: 7px; max-width: 36ch; }

/* Conversation */

#panel {
  position: relative;
  min-height: 0;
  background: var(--panel);
  color: var(--text);
}
/* One column: what was said, and under it what there is to say or do next. It
   scrolls as one. During a visit it is the box over the picture (see "the box",
   at the end), or on a phone held sideways a column beside it, where a short one
   sits at the bottom. */
#stream {
  position: relative;
  height: 100%;
  overflow: hidden auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
  scroll-behavior: smooth;
}
/* Where the talking meets the street, and where a sheet meets the picture over
   it, one runs into the other through a pattern of dots, like the pictures on the
   cards for the maps. */
#panel::before, .sheet::before {
  content: '';
  position: absolute;
  inset: auto 0 100% 0;
  height: 36px;
  background: var(--panel);
  -webkit-mask: var(--dither) 0 100% / 12px 36px repeat-x;
  mask: var(--dither) 0 100% / 12px 36px repeat-x;
  pointer-events: none;
}

/* The colours of the talking belong to the place. Each map names its look, and
   the conversation, the choices, and the sheet on its start and end screens take
   it: night for a street after dark, paper for a market in the morning, sand
   for a beach at the end of the day, cool for a mall with the air-conditioning on.
   Another kind of place is another block here. The street and
   the top bar keep the night colours above, and Arai's own screens keep theirs. */
:is(#panel, .sheet)[data-theme='night'] {
  --panel: #0c1b25; --raise: #142b39; --raise-2: #1c394a; --line: #2a4658;
  --text: #eaf0ee; --dim: #8fa8b1; --accent: #f5b83f; --accent-ink: #251a02;
}
:is(#panel, .sheet)[data-theme='sand'] {
  --panel: #f3dfb2; --raise: #faedcd; --raise-2: #fff7e2; --line: #dcc48f;
  --text: #2c2315; --dim: #77664a; --accent: #c5501f; --accent-ink: #fff5ea;
  color-scheme: light;
}
:is(#panel, .sheet)[data-theme='cool'] {
  --panel: #e6edf0; --raise: #f2f6f8; --raise-2: #ffffff; --line: #c3d0d7;
  --text: #16232b; --dim: #586b76; --accent: #0e7c86; --accent-ink: #f0fbfb;
  color-scheme: light;
}
:is(#panel, .sheet)[data-theme='paper'] {
  --panel: #efe6d3; --raise: #f8f1e1; --raise-2: #fffaf0; --line: #d3c8ae;
  --text: #2a2118; --dim: #6d6252; --accent: #b5402f; --accent-ink: #fff6ee;
  color-scheme: light;
}

#feed, #tray { flex: none; width: 100%; max-width: 760px; margin: 0 auto; padding: 20px 24px 16px; }
#feed { display: flex; flex-direction: column; gap: 14px; margin-top: auto; }
#tray { display: flex; flex-direction: column; padding-top: 16px; padding-bottom: 0; border-top: 1px solid var(--line); }
#tray:empty { border-top-color: transparent; }
#tray > :last-child { margin-bottom: 26px; }

.note, .cue { font: italic 400 17px/1.45 var(--serif); margin: 0; max-width: 44ch; }
.cue { color: var(--dim); font-size: 16px; }
.turn { display: flex; flex-direction: column; gap: 7px; align-items: flex-start; }
.turn.mine { align-items: flex-end; }
.gloss { font: 500 14px/1.4 var(--sans); margin: 0; max-width: 46ch; }
.gloss.meaning { color: var(--accent); }
/* What a hint or a meaning said, once it has been paid for, under its picture. */
.gloss:is(.hint, .meaning) { position: relative; padding-left: 20px; }
.gloss:is(.hint, .meaning)::before {
  content: '';
  position: absolute;
  left: 0;
  top: 3px;
  width: 10px;
  height: 14px;
  background: currentColor;
  -webkit-mask: var(--px-bulb) 50% 50% / contain no-repeat;
  mask: var(--px-bulb) 50% 50% / contain no-repeat;
}
.gloss.meaning::before { width: 12px; -webkit-mask-image: var(--px-note); mask-image: var(--px-note); }
/* Help on offer for a line, under it: a hint, the meaning. */
.aids { display: flex; flex: none; }
/* Whoever spoke, and beside them the one button for help with what they said.
   What they did, and anything written in under it, go below. */
.turn:not(.mine) { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 7px 10px; }
.turn:not(.mine) > :is(.cue, .gloss, .pieces) { order: 1; flex: 0 0 100%; max-width: none; }
/* A phrase taught in a lesson: the player's own saying of it, what it means,
   and when it is said. */
.taught { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; padding: 12px 14px; background: var(--raise); border: 1px solid var(--line); border-left: 3px solid var(--accent); border-radius: 12px; }
.taught .means { margin: 0; font: 600 20px/1.25 var(--serif); color: var(--text); }
.taught .use { flex: 0 0 100%; margin: 2px 0 0; font: 400 15px/1.45 var(--sans); color: var(--text); max-width: 62ch; }
/* A long line in pieces: small bubbles, each a breath of it. */
.pieces { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.pieces > .who { margin-right: 2px; }
.bubble.piece { min-height: 0; padding: 4px 10px; border-radius: 12px; }
.bubble.piece .bars { height: 20px; min-width: 24px; }
/* One of the player's own sounds, pointed out inside a line. */
.gloss:is(.caught, .kept) { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; color: var(--dim); }
.bubble.small { min-height: 0; padding: 3px 10px 3px 8px; gap: 7px; font-size: 13px; }
.bubble.small .bars { height: 18px; min-width: 22px; }
.bubble.small .bars i { width: 2px; }
/* The help there is for a line, listed over the button once it is pressed: what
   each is, and what it costs. */
.helps { position: absolute; z-index: 4; display: flex; flex-direction: column; gap: 6px; width: max-content; max-width: min(340px, 100%); padding: 10px; background: var(--panel); border: 2px solid var(--line); border-radius: 14px; box-shadow: 0 0 0 2px rgba(8, 6, 4, 0.6), 0 12px 26px rgba(8, 6, 4, 0.5); }
.helps .btn { justify-content: flex-start; width: 100%; min-height: 44px; color: var(--text); }
.helps .btn .cost { margin-left: auto; }

.bubble {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 15px 8px 13px;
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 17px 17px 17px 5px;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
/* A long voice note is as wide as there is room for and no wider: its bars
   narrow to fit, and neither half of the talking ever scrolls sideways. */
.bubble { max-width: 100%; min-width: 0; }
.bubble .who { flex: none; white-space: nowrap; }
.bubble .bars i { flex: 0 1 3px; min-width: 1px; }
.bubble:hover { background: var(--raise-2); border-color: color-mix(in srgb, var(--accent) 60%, var(--line)); }
/* The triangle at its head says it plays. */
.bubble .px { color: var(--dim); transition: color 0.15s ease; }
.bubble:hover .px, .bubble.mine .px { color: var(--accent); }
.bubble.mine { background: transparent; border-color: color-mix(in srgb, var(--accent) 45%, transparent); border-radius: 17px 17px 5px 17px; }
.who { font-size: 13px; font-weight: 600; color: var(--dim); }
.bars { display: inline-flex; align-items: center; gap: 2px; height: 28px; min-width: 30px; }
.bars i { width: 3px; border-radius: 2px; background: color-mix(in srgb, currentColor 34%, transparent); }
.bars i.on { background: var(--text); }
.mine .bars i.on, .chip .bars i.on { background: var(--accent); }

/* Choices */

.group { margin-bottom: 20px; }
.tray-h { display: flex; align-items: baseline; gap: 9px; font: 600 13px/1.3 var(--sans); color: var(--dim); margin: 0 0 10px; }
.tray-h::before { content: ''; flex: none; width: 6px; height: 6px; background: var(--accent); transform: translateY(-1px); }
.chips, .actions, .notes { display: flex; flex-wrap: wrap; gap: 8px; }

.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  max-width: 330px;
  padding: 8px 13px 8px 11px;
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 12px;
  font: 500 15px/1.25 var(--sans);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.chip:hover { background: var(--raise-2); border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); }
.chip.armed { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--raise-2)); }
/* The one that is picked has a frame at its corners, like a map that is picked. */
.chip.armed::after {
  --mark: linear-gradient(var(--accent) 0 0);
  content: '';
  position: absolute;
  inset: -5px;
  background:
    var(--mark) 0 0 / 9px 2px, var(--mark) 0 0 / 2px 9px,
    var(--mark) 100% 0 / 9px 2px, var(--mark) 100% 0 / 2px 9px,
    var(--mark) 0 100% / 9px 2px, var(--mark) 0 100% / 2px 9px,
    var(--mark) 100% 100% / 9px 2px, var(--mark) 100% 100% / 2px 9px;
  background-repeat: no-repeat;
  pointer-events: none;
}
.chip .bars { height: 22px; flex: none; }
.chip .bars i { width: 2.5px; }
/* What the player remembers of a phrase they cannot place: the start of it, on
   one line. All of it shows beside "Say it" once the phrase is picked. */
.chip .memo { display: block; max-width: 22ch; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: italic 400 14px/1.3 var(--serif); color: var(--dim); }
.confirm .recalled { flex: 1 1 24ch; max-width: 46ch; font: italic 400 14px/1.35 var(--serif); }
.chip.locked { opacity: 0.55; }
/* A phrase with nothing written on it: the sound alone, to be told by ear. */
.chip.bare { min-height: 44px; padding: 8px 16px; }
.chip.bare .bars { min-width: 46px; justify-content: center; }

.btn.more { flex: none; }
/* The phrases there are to say, and after them on the same line what can be
   done with the one that is picked. */
.to-say { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.to-say > .chips { flex: 0 1 auto; min-width: 0; }
.confirm { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.confirm:empty { display: none; }
.confirm .why { font-size: 14px; color: var(--dim); }

/* Buttons. Everything pressed in the game is the shape of the pills on Arai's own
   screens: round at the ends with a hairline round it. Amber is the one thing to
   do next, and it carries a pixel arrow. The quieter ones are an outline. A
   picture on a button is cut out of the button's own colour, so it follows the
   colours of the place. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: 44px;
  padding: 8px 18px;
  background: var(--raise);
  border: 1px solid var(--line);
  border-radius: 22px;
  color: var(--text);
  font: 600 15px/1.2 var(--sans);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.06s ease;
}
.btn:hover:not(:disabled) { background: var(--raise-2); border-color: color-mix(in srgb, var(--accent) 70%, var(--line)); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn::before, .btn::after {
  flex: none;
  width: 10px;
  height: 14px;
  background: currentColor;
  /* A page that has not been given the pictures shows none, not a block of colour. */
  -webkit-mask: var(--px, linear-gradient(#0000 0 0)) 50% 50% / contain no-repeat;
  mask: var(--px, linear-gradient(#0000 0 0)) 50% 50% / contain no-repeat;
}
.btn.primary { padding-right: 16px; background: var(--accent); border-color: var(--accent); color: var(--accent-ink); box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.17); }
.btn.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 86%, white); border-color: color-mix(in srgb, var(--accent) 86%, white); }
.btn.primary:active:not(:disabled) { box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.17); transform: translateY(2px); }
.btn.primary::after { content: ''; --px: var(--px-go); }
.btn.quiet, .btn.back { background: none; color: var(--dim); }
.btn.quiet { min-height: 36px; padding: 6px 14px; font-size: 14px; }
.btn:is(.quiet, .back):hover:not(:disabled) { background: none; border-color: var(--accent); color: var(--text); }
.btn.back { padding-left: 14px; }
.btn.back::before { content: ''; width: 8px; --px: var(--px-back); }
.btn.again::before { content: ''; --px: var(--px-unknown); }
.btn.hint::before { content: ''; --px: var(--px-bulb); }
.btn.meaning::before { content: ''; width: 12px; --px: var(--px-note); }
.btn.more::before { content: ''; height: 10px; --px: var(--px-plus); }
.btn.inpieces::before { content: ''; width: 12px; --px: var(--px-pieces); }
.btn.notebook::before { content: ''; width: 16px; height: 18px; --px: var(--px-book); color: var(--accent); background: var(--accent); }
.btn:disabled { opacity: 0.4; cursor: default; }
/* What it costs, or how many: a small count at the end of a button. */
.cost { flex: none; padding: 4px 7px 3px; background: color-mix(in srgb, currentColor 13%, transparent); border-radius: 999px; font: 600 12px/1 var(--sans); font-variant-numeric: tabular-nums; white-space: nowrap; }
.find .cost { margin-left: 8px; }

/* What to do with the phrase that is picked. It stays at the bottom while the
   choices scroll under it. The shadows at its sides hide the frame of a picked
   phrase passing behind. */
#tray.busy { pointer-events: none; opacity: 0.55; }
.keys { font-size: 14px; color: var(--dim); max-width: 46ch; margin: 0; }
.keys.first { margin-bottom: 18px; color: var(--text); }
/* A word about how something works, said once: over the box, in the dark label
   with an amber line that the signs on the street are. */
.tip { position: absolute; z-index: 4; left: 0; bottom: calc(100% + 8px); max-width: min(46ch, 100%); margin: 0; padding: 10px 14px; background: rgba(12, 16, 24, 0.96); border: 1px solid #f0b43c; border-radius: 12px; box-shadow: 0 10px 24px rgba(8, 6, 4, 0.5); color: #f2e9d8; font: 500 14px/1.4 var(--sans); pointer-events: none; }
/* Holding up fingers, before it is picked: two of them, small. */
.digits { display: inline-flex; align-items: flex-end; gap: 3px; }
.digits i { width: 4px; height: 15px; border-radius: 2px; background: currentColor; }
.digits i:last-child { height: 12px; }

.fingers .btn { align-items: flex-end; gap: 4px; height: 46px; min-height: 0; padding: 0 14px 11px; border-radius: 14px; }
.fingers i { width: 5px; height: 20px; border-radius: 3px; background: var(--text); }
/* How many are picked is marked the way a picked phrase is: the frame at its corners. */
.fingers .btn { position: relative; }
.fingers .btn.armed { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 9%, var(--raise-2)); }
.fingers .btn.armed::after {
  --mark: linear-gradient(var(--accent) 0 0);
  content: '';
  position: absolute;
  inset: -5px;
  width: auto;
  height: auto;
  -webkit-mask: none;
  mask: none;
  background:
    var(--mark) 0 0 / 9px 2px, var(--mark) 0 0 / 2px 9px,
    var(--mark) 100% 0 / 9px 2px, var(--mark) 100% 0 / 2px 9px,
    var(--mark) 0 100% / 9px 2px, var(--mark) 0 100% / 2px 9px,
    var(--mark) 100% 100% / 9px 2px, var(--mark) 100% 100% / 2px 9px;
  background-repeat: no-repeat;
  pointer-events: none;
}
.to-say > .fingers { flex: none; }
.to-say[hidden] { display: none; }
.actions + .to-say { margin-top: 10px; }

/* Over the money: the price as it was said, to play again, and the till where there is one. */
.heard { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; margin-bottom: 16px; }
.till {
  display: inline-block;
  padding: 9px 14px 8px;
  background: #0b110c;
  border-radius: 6px;
  color: #a5e6a0;
  font: 500 24px/1 var(--mono);
}
/* Not looked at yet. */
.till.dark { color: #2f4a2e; }
.cash {
  position: relative;
  min-width: 66px;
  height: 40px;
  border: 0;
  border-radius: 5px;
  color: #fbf6ea;
  font: 600 17px/1 var(--serif);
  cursor: pointer;
}
/* Notes are oblong and coins are round. Each one's colour comes from the world. */
.cash.coin { min-width: 40px; border-radius: 50%; }
.cash:disabled { opacity: 0.25; cursor: default; }
.cash .n {
  position: absolute;
  right: -7px;
  top: -7px;
  min-width: 20px;
  padding: 3px 5px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--dim);
  font: 600 11px/1 var(--sans);
}
.shelf .chip.armed .price { color: var(--accent); }
.price { color: var(--dim); font-variant-numeric: tabular-nums; margin-left: 4px; }

/* Start and end of the evening */

/* The street stays in view with the title over it. Everything else sits on a sheet
   that stands exactly where the panel is, in the panel's colours. */
#overlay {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
#app:has(#overlay:not([hidden])) :is(#hud, #prompts) { visibility: hidden; }
.marquee {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 14px;
  min-height: 150px;
  padding: 22px clamp(22px, 6vw, 84px) clamp(34px, 4vw, 48px);
  background: linear-gradient(rgba(10, 9, 8, 0.25), rgba(10, 9, 8, 0.78));
  text-shadow: 0 2px 22px rgba(6, 5, 4, 0.7);
}
/* Over the verdict at the end of a visit: which map this was. */
.marquee .eyebrow { display: flex; align-items: center; gap: 10px; margin: 0; font: 600 12px/1.3 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; }
.marquee .eyebrow::before { content: ''; flex: none; width: 6px; height: 6px; background: var(--accent); }
.marquee .tag { text-shadow: none; }
.sheet {
  position: relative;
  flex: none;
  min-height: 46vh;
  min-height: calc(46dvh + 1px);
  padding: 22px clamp(22px, 6vw, 84px) max(26px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--panel);
  color: var(--text);
}
.col { flex: none; max-width: 640px; }
.sheet-h { font: 600 13px/1.3 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--dim); margin: 0 0 12px; }
.title { font: 600 clamp(72px, 13vw, 136px)/0.86 var(--serif); letter-spacing: -0.035em; margin: 0; }
.title span { font: 400 0.36em/1 var(--script); letter-spacing: 0; color: var(--accent); margin-left: 0.35em; }

/* Arai's own screen inside a world: the maps there and the settings, laid over the
   same sky as the globe, with nothing of any map behind them. The maps' cards and
   the settings board are in the player's colours. */
/* The page of maps is one screen, like a game's menu: nothing on it is further
   down. Where the player is and who they are go along the top, and the maps are
   one row under them that slides sideways. The row is what gives when the
   window is short: its pictures get shorter, down to a strip (the engine says
   how low the row can go, in --maps-min, from how much the cards say). Only a
   window too small for even that scrolls. */
.hub {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: grid;
  grid-template: "lead" auto "setup" auto "places" minmax(var(--maps-min, 280px), auto) "kit" auto / minmax(0, 1fr);
  align-content: start;
  gap: clamp(10px, 2.6vh, 30px) clamp(32px, 5vw, 72px);
  padding: var(--edge-top) var(--edge-right) max(clamp(12px, 3vh, 30px), env(safe-area-inset-bottom)) var(--edge-left);
  color: var(--text);
  color-scheme: dark;
  scrollbar-width: thin;
  scrollbar-color: #2a2f3a transparent;
  transition: opacity 0.25s ease;
}
/* Coming in from the globe, the page waits for the Earth to fall away. Going back
   out, it gets out of the way at once. */
.hub.arriving { animation: arrive 0.6s ease-out 0.4s both; }
.hub.leaving { opacity: 0; pointer-events: none; }
@keyframes arrive { from { opacity: 0; transform: translateY(10px); } }
/* Arai's own look, which the globe set: night sky, panels of dark glass with a
   hairline round them, amber for whatever can be done next, and pixel art for
   every picture. It is the same wherever the player is: the colours of the
   talking change with the place, and these do not. */
.hub, #atlas {
  --hair: #2a2f3a; --hair-2: #3d4556; --glass: rgba(12, 16, 24, 0.9); --glass-2: rgba(12, 16, 24, 0.78);
  --text: #f2e9d8; --dim: #a79c8a; --line: var(--hair); --accent: #f0b43c; --accent-ink: #281b04;
  --panel: var(--glass); --raise: rgba(255, 255, 255, 0.05); --raise-2: rgba(255, 255, 255, 0.09);
}
/* A pill: something small to press, often with a pixel picture at its head. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  padding: 0 16px;
  background: var(--glass-2);
  border: 1px solid var(--hair);
  border-radius: 999px;
  color: var(--text);
  font: 600 14px/1 var(--sans);
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.pill:hover { border-color: var(--accent); }
.pill[aria-pressed='true'] { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, var(--glass-2)); }
.pill .px { flex: none; color: var(--accent); }
.pill .cost { margin-left: 0; color: var(--dim); }
.px { display: block; flex: none; }
/* Small headings: on the sky over a group of cards, and over a thing to choose. */
.hub .sheet-h { display: flex; align-items: center; gap: 10px; color: var(--dim); }
.hub .sheet-h::before { content: ''; width: 6px; height: 6px; background: var(--accent); }
.board .label { font: 600 12px/1.3 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); margin: 0 0 4px; }
.board .label:not(:first-child) { margin-top: 24px; }
.hub-main, .hub-side { display: contents; }
.lead { grid-area: lead; min-width: 0; }
.setup { grid-area: setup; min-width: 0; }
.places { grid-area: places; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* The page is headed with the place, which is longer than the game's name, so it
   is set smaller, with the same thing in the place's own language on a line of
   its own under it. The heading keeps clear of the way back out, in the corner. */
.lead .name { display: grid; justify-items: start; gap: clamp(2px, 0.5vw, 6px); }
.hub .title { padding-right: 204px; font-size: clamp(40px, min(7.2vw, 11.5vh), 96px); line-height: 0.96; text-wrap: balance; }
.hub .say { margin-left: -10px; font-size: clamp(18px, min(5.4vw, 4.6vh), 38px); white-space: nowrap; }
.hub .tagline { margin-top: clamp(6px, 1.6vh, 14px); }
.hub .small { font-size: 14px; color: var(--dim); max-width: 52ch; margin: 0 0 12px; }

/* The way back out to the globe: a small Earth, turning. */
.to-world { position: absolute; right: var(--edge-right); top: var(--edge-top); padding: 0 15px 0 4px; }
/* On a place's page it has how to play beside it, behind a question mark. */
.hub-ways { position: absolute; right: var(--edge-right); top: var(--edge-top); display: flex; gap: 10px; }
.hub-ways .to-world { position: static; }
.pill.howto { justify-content: center; width: 44px; padding: 0; }
.pill.howto .px { color: var(--text); }
.pill.howto:hover .px { color: var(--accent); }
/* The same way back, from a country on the globe to the whole of it. */
.to-world canvas { display: block; border-radius: 50%; image-rendering: pixelated; }

/* A heading with a word beside it in the world's own script. On the page of maps
   that word is a sound you can tap, like every phrase in the game. */
.name { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 0.06em; }
.say {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-left: clamp(8px, 1.4vw, 18px);
  padding: 6px 10px;
  background: none;
  border: 0;
  border-radius: 10px;
  color: var(--accent);
  font: 400 clamp(26px, 4.7vw, 49px)/1 var(--script);
  cursor: pointer;
}
.say:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.say .bars { height: 26px; min-width: 0; color: var(--text); }
.say .bars i.on { background: var(--accent); }
.tagline { font: italic 400 clamp(16px, 2vw, 21px)/1.35 var(--serif); margin: 14px 0 0; max-width: 30em; }

/* A map: a picture of the place with when it happens pinned over it, fading
   through a pattern of dots into what is said about it, and the way in. */
.maps-h { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 32px; margin-bottom: 10px; }
.maps-h .sheet-h { margin: 0; }
.slide { display: flex; gap: 6px; margin-left: auto; }
.slide[hidden] { display: none; }
/* One row, as wide as it needs to be, sliding under a fade at the window's edge.
   The cards share two rows of a grid, the picture and the words, so every
   picture is the same height whatever is written under it. */
.map-row {
  flex: 0 1 clamp(250px, 46vh, 430px);
  min-height: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: auto;
  justify-content: start;
  grid-template-rows: minmax(var(--art-min, 56px), 1fr) auto;
  gap: 0 16px;
  /* Room round the cards for the frame that marks the one picked, which stands
     7 points out from a card: the row clips whatever goes past its edges. */
  margin: -8px calc(-1 * var(--edge-right)) -8px -8px;
  padding: 8px var(--edge-right) 8px 8px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to left, transparent, #000 calc(var(--edge-right) * 0.8));
  mask-image: linear-gradient(to left, transparent, #000 calc(var(--edge-right) * 0.8));
}
.map-row::-webkit-scrollbar { display: none; }
.map-row > .map { grid-row: 1 / -1; display: grid; grid-template-rows: subgrid; width: clamp(284px, 22vw, 340px); scroll-margin-inline: 8px; }
.map-row > .map > .map-art { height: auto; min-height: 0; }
.map { position: relative; display: flex; flex-direction: column; background: var(--glass); border: 1px solid var(--hair); border-radius: 16px; backdrop-filter: blur(6px); transition: border-color 0.2s ease; }
.map-art { position: relative; height: clamp(120px, 21vh, 184px); overflow: hidden; border-radius: 15px 15px 0 0; background: #0b0f17 50% 50% / cover no-repeat; }
.map-art::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 36px;
  background: rgb(12, 16, 24);
  -webkit-mask: var(--dither) 0 100% / 12px 36px repeat-x;
  mask: var(--dither) 0 100% / 12px 36px repeat-x;
}
.map-body { flex: 1; display: grid; gap: 8px; justify-items: start; align-content: start; padding: 4px 18px 18px; }
.map h3 { font: 600 30px/1 var(--serif); letter-spacing: -0.02em; margin: 0; }
.map h3 span { font: 400 0.55em/1 var(--script); letter-spacing: 0; color: var(--accent); margin-left: 0.45em; }
.map-what { font: 400 16px/1.45 var(--serif); margin: 0; }
.map-history { font: 500 13px/1.4 var(--sans); color: var(--dim); margin: 0; }
/* A map that is open is pressed anywhere: its name is the button, stretched over
   the whole card, with an arrow beside it to say the card goes somewhere. */
.map.open { cursor: pointer; transition: border-color 0.2s ease, transform 0.08s ease; }
.map.open:active { transform: translateY(1px); }
.map-name { display: flex; align-items: center; justify-content: space-between; gap: 12px; justify-self: stretch; }
.enter { padding: 0; background: none; border: 0; color: inherit; font: inherit; letter-spacing: inherit; text-align: left; cursor: pointer; }
.enter::after { content: ''; position: absolute; inset: 0; z-index: 2; border-radius: 16px; }
.enter:focus-visible { outline: none; } /* the frame round the card shows where the keys are */
.map-name .cue { flex: none; color: var(--accent); opacity: 0.6; transition: opacity 0.15s ease, transform 0.15s ease; }
.map.open:is(:hover, :focus-within) .cue { opacity: 1; transform: translateX(4px); }
/* It answers the pointer, and the keys, with a frame round it, the way a game
   marks what is picked. */
.map::after {
  --mark: linear-gradient(var(--accent) 0 0);
  content: '';
  position: absolute;
  inset: -3px;
  background:
    var(--mark) 0 0 / 14px 2px, var(--mark) 0 0 / 2px 14px,
    var(--mark) 100% 0 / 14px 2px, var(--mark) 100% 0 / 2px 14px,
    var(--mark) 0 100% / 14px 2px, var(--mark) 0 100% / 2px 14px,
    var(--mark) 100% 100% / 14px 2px, var(--mark) 100% 100% / 2px 14px;
  background-repeat: no-repeat;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, inset 0.15s ease;
}
.map.open:is(:hover, :focus-within, .lit) { border-color: var(--hair-2); }
.map.open:is(:hover, :focus-within, .lit)::after { inset: -7px; opacity: 1; }

/* When a map happens, or that it is new: pinned over its picture on its card,
   and over its name on its start screen. */
.map-art .tag { position: absolute; left: 10px; top: 10px; z-index: 1; }
:is(.map-art, .marquee) .tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 11px 6px 8px;
  background: rgba(7, 9, 13, 0.84);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  color: var(--text);
  font: 600 12px/1 var(--sans);
}
:is(.map-art, .marquee) .tag b { font-weight: 600; font-variant-numeric: tabular-nums; }
:is(.map-art, .marquee) .tag span { color: var(--dim); font-weight: 500; }
:is(.map-art, .marquee) .tag .px { color: var(--accent); }
.map-art .tag.new { left: auto; right: 10px; padding: 7px 11px; background: var(--accent); border-color: var(--accent); color: var(--accent-ink); letter-spacing: 0.06em; text-transform: uppercase; }

/* Built but not open to this player yet: the picture goes dark and drained, with a padlock on it. */
/* A game that has been found: what it gave, on the dark of its screen. */
.map.game .map-art { background-color: #111b3f; background-size: auto 66%; image-rendering: pixelated; }
/* One not found yet: the shape of what it gives, empty, where that will go. */
.map.game .gap { position: absolute; inset: 0; background: #243170; -webkit-mask: 50% 50% / auto 66% no-repeat; mask: 50% 50% / auto 66% no-repeat; image-rendering: pixelated; }
.map.game.shut .map-art { background-color: #111b3f; }
.map.game.shut .map-body { align-content: center; }
.map.shut .map-art { background-color: #1a2233; background-blend-mode: luminosity; }
.map.shut .map-art::before { content: ''; position: absolute; inset: 0; background: rgba(7, 9, 13, 0.58); }
.bolt { position: absolute; inset: 0 0 18px; display: grid; place-items: center; color: var(--text); filter: drop-shadow(0 2px 0 rgba(7, 9, 13, 0.9)); }
.map.shut .tag { opacity: 0.75; }
.map.shut h3, .map.shut .map-what { color: var(--dim); }
.map.shut h3 span { color: inherit; }
.map.shut .map-history { color: var(--text); font-weight: 600; }
/* Not built yet: an empty place, waiting. */
.map.locked { flex-direction: row; align-items: center; gap: 16px; min-height: 96px; padding: 16px 18px; background: none; border-style: dashed; border-color: var(--hair-2); backdrop-filter: none; }
.slot { display: grid; place-items: center; width: 44px; height: 44px; flex: none; border: 1px solid var(--hair-2); border-radius: 10px; color: var(--dim); }
.map.locked .map-body { flex: 1; gap: 4px; padding: 0; }
/* The place that is not built yet is a narrower slot at the end of the row. */
.map-row > .map.locked { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 12px; width: 200px; }
.map-row > .map.locked .map-body { flex: none; }
.map.locked h3 { font: 600 15px/1.3 var(--sans); letter-spacing: 0; color: var(--dim); }
.map.locked .map-what { font: 400 14px/1.4 var(--sans); color: var(--dim); }
/* A text message: pictures and amounts, no words. */
.sms { display: inline-flex; flex-wrap: wrap; gap: 6px 16px; padding: 9px 15px; background: var(--raise); border: 1px solid var(--line); border-radius: 17px 17px 17px 5px; font: 600 17px/1.3 var(--sans); font-style: normal; white-space: nowrap; }
.pocket-note { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 14px 0 0; font-size: 14px; color: var(--dim); }
.pocket-note .sms { color: var(--text); }

/* What came clear on the way home, at the end of a visit. */
.dawned { display: grid; gap: 8px; justify-items: start; margin-top: 22px; }
.dawned .tray-h, .dawned .gloss, .dawned .small { margin: 0; }
.dawned .gloss { font-size: 16px; }
.opened { display: inline-flex; align-items: center; gap: 10px; margin: 0 0 14px; padding: 8px 14px 8px 8px; background: color-mix(in srgb, var(--accent) 10%, transparent); border: 1px solid var(--accent); border-radius: 999px; font: 600 15px/1.3 var(--sans); }
.opened::before { content: 'New'; flex: none; padding: 5px 9px 4px; background: var(--accent); border-radius: 999px; color: var(--accent-ink); font: 600 11px/1 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; }

/* Who the player is: the characters stand straight on the sky, with nothing
   round them. Whoever is chosen is in the light, with a pointer over their head
   and a pool of the same light at their feet. The rest wait in the dark. Each
   one's voice is under them. */
/* The characters, and beside them (under them, where there is no room beside) what the chosen one is wearing. */
.board { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px; }
.kit .board { display: block; flex: 0 0 100%; }
.cast { position: relative; display: flex; gap: clamp(4px, 3vw, 28px); margin-left: -8px; padding: 30px 0 0; }
.who-card { position: relative; z-index: 1; display: grid; justify-items: center; }
.who-card.chosen::before { content: ''; position: absolute; inset: -30px -22px 40px; background: radial-gradient(50% 60% at 50% 44%, rgba(240, 180, 60, 0.18), rgba(240, 180, 60, 0) 72%); pointer-events: none; }
.who-card .figure::before { content: ''; position: absolute; left: 50%; bottom: -7px; width: 86px; height: 16px; margin-left: -43px; border-radius: 50%; background: radial-gradient(closest-side, rgba(240, 180, 60, 0.55), rgba(240, 180, 60, 0)); opacity: 0; transition: opacity 0.2s ease; }
.who-card.chosen .figure::before { opacity: 1; }
.who-card .who { position: relative; display: grid; justify-items: center; padding: 0 8px; background: none; border: 0; border-radius: 10px; color: var(--dim); cursor: pointer; }
.who-card .figure { position: relative; display: block; width: 92px; min-height: 120px; }
.who-card .figure img { position: absolute; left: 50%; bottom: 0; display: block; max-width: none; image-rendering: pixelated; font-size: 13px; filter: brightness(0.42) saturate(0.4); transition: filter 0.2s ease; }
.who-card .who:hover .figure img { filter: brightness(0.8) saturate(0.85); }
.who-card.chosen .figure img { filter: none; }
.who-card .who .bars { height: 32px; min-width: 0; margin-top: 8px; }
.who-card .who .bars i.on { background: var(--accent); }
.who-card.chosen .bars { color: var(--text); }
.who-card .pointer { position: absolute; left: 50%; top: -24px; margin-left: -7px; color: var(--accent); visibility: hidden; }
.who-card.chosen .pointer { visibility: visible; animation: hover 1s steps(2, jump-none) infinite; }
@keyframes hover { 50% { transform: translateY(3px); } }
/* What the chosen one is wearing, with a square for each thing they could wear. */
.outfit { display: flex; align-items: center; gap: 10px; }
.outfit[hidden] { display: none; }
.hub .arrow { display: grid; place-items: center; width: 44px; height: 44px; flex: none; background: var(--glass-2); border: 1px solid var(--hair); border-radius: 50%; color: var(--text); cursor: pointer; transition: border-color 0.15s ease, color 0.15s ease; }
.hub .arrow:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.hub .arrow:disabled { opacity: 0.35; cursor: default; }
.slide .arrow { width: 32px; height: 32px; }
.wearing { display: grid; justify-items: center; gap: 7px; min-width: 7em; }
.wear { font: 600 15px/1 var(--sans); }
.pips { display: flex; gap: 5px; }
.pips i { width: 6px; height: 6px; background: var(--hair-2); }
.pips i.on { background: var(--accent); }

/* A row of pills to pick one of: which recorded cast to hear, where there is more than one. */
.looks { display: flex; flex-wrap: wrap; gap: 8px; }
/* What the player carries between maps, and the way to put it all down. */
.kit { grid-area: kit; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; }
.kit:not(:has(> :not([hidden]))) { display: none; }
.kit .small { margin: 0; }
/* A short or a narrow window: the smaller figures (the engine swaps the pictures
   for them), with less room round them. */
@media (max-width: 1180px), (max-height: 720px) {
  .hub .sheet-h { margin-bottom: 8px; }
  .cast { gap: 4px; padding-top: 22px; }
  .who-card .figure { width: 62px; min-height: 80px; }
  .who-card .figure::before { bottom: -5px; width: 60px; height: 12px; margin-left: -30px; }
  .who-card.chosen::before { inset: -22px -14px 30px; }
  .who-card .pointer { top: -19px; }
  .who-card .who .bars { height: 26px; margin-top: 6px; }
  .outfit { gap: 6px; }
  .outfit .arrow { width: 38px; height: 38px; }
  .wearing { min-width: 5.8em; }
}
@media (max-width: 760px) {
  .kit .pill .cost { display: none; }
  .kit .btn.quiet { min-height: 36px; padding: 0 6px; font-size: 13px; }
}
/* A phone held upright: the characters and what the chosen one wears share a
   line, what the player carries is one line, and a card says the same in less
   room, so that there is height left for its picture. */
@media (max-width: 560px) {
  .hub { --art-min: 84px; }
  .board { gap: 10px 12px; }
  .cast { margin-left: -2px; }
  .who-card .who { padding: 0 2px; }
  .outfit { gap: 4px; }
  .outfit .arrow { width: 32px; height: 32px; }
  .wear { font-size: 14px; }
  .wearing { min-width: 92px; }
  .kit { gap: 6px; }
  .kit .pill { padding: 0 10px; }
  .kit .btn.quiet { padding: 0 2px; font-size: 12.5px; }
  .map-row .map:not(.locked) .map-body { gap: 6px; padding-bottom: 14px; }
  .map-row .map:not(.locked) h3 { font-size: 27px; }
  .map-row .map:not(.locked) .map-what { font-size: 15px; line-height: 1.4; }
}
/* A short phone gives up the line under the name, and the name's second line,
   before it gives up a map's picture. */
@media (max-width: 760px) and (max-height: 700px) {
  .hub { --art-min: 72px; row-gap: 10px; }
  .hub .title { font-size: 32px; }
  .hub .tagline { display: none; }
}
/* The narrowest phones: the name and the line of what the player carries each still fit on one line. */
@media (max-width: 370px) {
  .kit .pill { padding: 0 8px; }
  .kit .btn.quiet { font-size: 12px; }
}
@media (max-width: 370px) and (max-height: 700px) {
  .hub .title { font-size: 29px; }
}
/* A wide window with height to spare: who the player is stands beside the name
   of the place, which keeps one line for as long as it can, and the maps have
   the full width under both. "Your character" is on a line with the way back to
   the world, so nobody stands under that. */
@media (min-width: 900px) and (min-height: 681px) {
  .hub { grid-template: "lead setup" auto "places places" minmax(var(--maps-min, 280px), auto) "kit kit" auto / minmax(0, auto) minmax(216px, 1fr); }
  .hub .title { padding-right: 0; }
  .setup > .sheet-h { min-height: 44px; margin-bottom: 4px; }
}
/* A window that is wide and short, down to a phone on its side: the place and
   its maps on the left, the full height of the window, and who the player is
   down the right with what they carry at the foot of it. */
@media (max-height: 680px) and (min-width: 600px) {
  .hub { display: flex; align-items: stretch; column-gap: 24px; }
  .hub-main { display: flex; flex-direction: column; flex: 1 1 0; min-width: 0; gap: clamp(6px, 2vh, 14px); }
  .hub-side { display: flex; flex-direction: column; justify-content: space-between; flex: 0 0 236px; gap: 10px; }
  .hub .places { flex: 1 1 auto; min-height: var(--maps-min, 240px); }
  .hub .title { padding-right: 0; font-size: clamp(34px, 9vh, 56px); }
  .setup > .sheet-h { min-height: 44px; margin-bottom: 4px; }
  /* The row stops at its own column here: the fade is at the edge of that. */
  .hub .map-row { flex: 1 1 0; max-height: 430px; margin-right: 0; padding-right: 30px; -webkit-mask-image: linear-gradient(to left, transparent, #000 30px); mask-image: linear-gradient(to left, transparent, #000 30px); }
  .kit .pill .cost { display: none; }
  .kit .btn.quiet { min-height: 36px; padding: 0 6px; font-size: 13px; }
}
/* Beside a narrow column the way back to the world is only the small Earth. */
@media (max-width: 1180px), (max-height: 680px) {
  .hub .to-world { padding: 3px; }
  .hub .to-world span { display: none; }
}
.headline { font: 600 clamp(34px, 5vw, 52px)/1.04 var(--serif); letter-spacing: -0.02em; margin: 0; max-width: 18em; }
.lede { font: 400 20px/1.5 var(--serif); margin: 0 0 14px; max-width: 34em; }
.sheet .small { font-size: 14px; color: var(--dim); max-width: 52ch; margin: 0 0 12px; }
.sheet .picked { margin-top: 26px; }
.sheet .actions { margin: 22px 0 18px; align-items: center; gap: 10px; }
.voice { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; }
.voice + .small { margin-top: 22px; }
.voice .btn[aria-pressed='true'] { border-color: var(--accent); background: var(--raise-2); }
.recap { margin: 0 0 6px; padding: 0; list-style: none; }
.recap li { position: relative; font: 400 18px/1.45 var(--serif); padding: 9px 0 9px 20px; border-top: 1px solid var(--line); }
.recap li::before { content: ''; position: absolute; left: 2px; top: 19px; width: 6px; height: 6px; background: var(--accent); }
.recap li:last-child { border-bottom: 1px solid var(--line); }
.sounds { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0; }

@media (min-width: 900px) and (min-height: 541px) {
  .sheet { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 clamp(32px, 5vw, 72px); align-content: start; }
  .sheet .col > :first-child { margin-top: 0; }
}

/* The globe: the first thing a player sees. The sky and the Earth fill the window.
   The name of the game, a name beside each light, and the card for a place that
   has been picked float over them and let touches through to the Earth, except
   where there is something to press. Behind the page of maps only the sky is left. */

#atlas {
  --line: #2a2f3a;
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: radial-gradient(120% 90% at 50% 60%, #101826 0%, #0a0e16 45%, #07090d 100%);
  color: var(--text);
  user-select: none;
}
#atlas > * { transition: opacity 0.5s ease-out; }
#atlas.receded > :not(.sky) { opacity: 0; transition: opacity 0.7s ease-in; }
.sky { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; pointer-events: none; }
.earth { position: absolute; left: 0; top: 0; display: block; image-rendering: pixelated; touch-action: none; cursor: grab; }
.pins { position: absolute; left: 0; top: 0; pointer-events: none; }

/* The name of the game sits exactly where it does on the page of maps. */
.mark {
  position: absolute;
  inset: 0 0 auto 0;
  padding: var(--edge-top) var(--edge-right) 44px var(--edge-left);
  background: linear-gradient(rgba(7, 9, 13, 0.62), rgba(7, 9, 13, 0));
  text-shadow: 0 2px 22px rgba(7, 9, 13, 0.85);
  pointer-events: none;
}
.mark .word { margin-left: clamp(8px, 1.4vw, 18px); padding: 6px 10px; color: var(--accent); font: 400 clamp(26px, 4.7vw, 49px)/1 var(--script); }
.mark .say { text-shadow: inherit; pointer-events: auto; }
.mark .tagline { transition: opacity 0.3s ease; }
.at-place .mark .tagline { opacity: 0; }
.resume { position: absolute; right: var(--edge-right); top: var(--edge-top); text-shadow: none; pointer-events: auto; }
.at-place .resume { display: none; }

#atlas .place {
  position: absolute;
  left: 0;
  top: 0;
  padding: 6px 10px 6px 9px;
  background: rgba(12, 16, 24, 0.86);
  border: 1px solid var(--accent);
  border-radius: 8px;
  color: var(--text);
  font: 600 14px/1 var(--sans);
  white-space: nowrap;
  cursor: pointer;
  pointer-events: auto;
}
#atlas .place::before { content: ''; position: absolute; left: -9px; bottom: -9px; width: 12px; height: 2px; background: var(--accent); transform: rotate(-40deg); transform-origin: 100% 50%; }
#atlas .place:is(:hover, .lit) { background: var(--accent); color: var(--accent-ink); }
.at-place .place { display: none; }
/* Inside a country its places have the names, each beside its own light. One
   that would lie over another is put on the other side of its light. A place
   that cannot be gone to yet has a quieter name. */
.at-place .place.spot { display: block; }
#atlas .place.west::before { left: auto; right: -9px; transform: rotate(40deg); transform-origin: 0 50%; }
#atlas .place.shut { border-color: var(--hair-2); color: var(--dim); }
#atlas .place.shut::before { background: var(--hair-2); }
#atlas .place.shut:is(:hover, .lit) { background: rgba(12, 16, 24, 0.86); color: var(--text); }

/* The places in the country that has been picked, one card each: beside the
   Earth on a wide window, under it on a tall one. A card is pressed anywhere,
   like a map's on the page of maps, and is lit with its light on the Earth. */
.place-card {
  position: absolute;
  right: clamp(16px, 7vw, 110px);
  top: 52%;
  transform: translateY(-50%);
  width: min(380px, 40vw);
  display: grid;
  gap: 12px;
}
.place-card[hidden] { display: none; }
/* The cards themselves. Stacked, they are laid out by the list they are in. */
.place-card .stack { display: contents; }
/* Under the Earth with no room to stack (the atlas says when), they are one row
   that slides, the width of the window, with the next card showing at the edge. */
.place-card.sliding { inset: auto 0 max(4px, env(safe-area-inset-bottom)) 0; max-width: none; margin: 0; gap: 8px; }
.place-card.sliding .where { padding-left: 14px; }
.place-card.sliding .stack {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(80vw, 320px);
  justify-content: start;
  gap: 10px;
  padding: 8px 14px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to left, transparent, #000 30px);
  mask-image: linear-gradient(to left, transparent, #000 30px);
}
.place-card.sliding .stack::-webkit-scrollbar { display: none; }
.place-card .where { display: flex; align-items: center; gap: 10px; font: 600 12px/1.3 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--dim); margin: 0; text-shadow: 0 1px 10px rgba(7, 9, 13, 0.9); }
.place-card .where::before { content: ''; flex: none; width: 6px; height: 6px; background: var(--accent); }
/* A card with no picture at its head. */
.map.plain .map-body { padding-top: 16px; }
/* Beside the Earth with no room for them (a phone held sideways): a place
   that can be gone to is its name and the way in, and nothing else. */
.place-card.tight { gap: 8px; }
.place-card.tight .map.open .map-what { display: none; }
.place-card.tight .map.plain.open .map-body { padding: 12px 16px; }
.place-card.tight .map.open h3 { font-size: 24px; }
.map.plain.locked { background: rgba(12, 16, 24, 0.72); backdrop-filter: blur(6px); }
.map.plain.locked h3 { font: 600 22px/1.1 var(--serif); letter-spacing: -0.01em; }
.map.plain.locked h3 span { color: inherit; opacity: 0.85; }
.map.plain.locked.lit { border-color: var(--text); }

#atlas .hint { position: absolute; inset: auto 0 0 0; margin: 0; padding: 6px var(--edge-right) max(18px, env(safe-area-inset-bottom)) var(--edge-left); text-align: center; font-size: 14px; color: var(--dim); text-shadow: 0 1px 10px rgba(7, 9, 13, 0.9); pointer-events: none; }
.at-place .hint { visibility: hidden; }
/* Who made it, quietly, in the corner opposite the name. */
#atlas .credit { position: absolute; right: var(--edge-right); bottom: max(18px, env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 10px; margin: 0; font-size: 13px; color: var(--dim); opacity: 0.75; pointer-events: none; }
#atlas .credit a { display: inline-flex; align-items: center; min-height: 24px; color: inherit; text-decoration: none; pointer-events: auto; }
#atlas .credit a:hover { color: var(--text); }
#atlas .credit:hover { opacity: 1; }
.at-place .credit { visibility: hidden; }

/* The notebook: a pad from the player's pocket. Always paper, whatever the panel is. */

#notebook {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: grid;
  justify-items: center;
  align-items: start;
  padding: clamp(14px, 4vh, 48px) 14px;
  background: rgba(10, 8, 6, 0.74);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.pad {
  --ink: #2b241b;
  --faint: #7a6d59;
  --rule: #d9cdb1;
  --pen: #a8392b;
  position: relative;
  width: min(100%, 620px);
  padding: 44px clamp(18px, 5vw, 38px) 26px;
  background:
    radial-gradient(circle at 50% 14px, #14110e 0 5px, transparent 5.5px) 0 0 / 34px 28px repeat-x,
    radial-gradient(circle, rgba(43, 36, 27, 0.13) 1px, transparent 1.4px) 0 6px / 18px 18px,
    #f1e8d4;
  border-radius: 4px 4px 10px 10px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  color: var(--ink);
  color-scheme: light;
}
.pad h2 { font: 600 34px/1 var(--serif); letter-spacing: -0.02em; margin: 0 0 4px; }
.pad h3 { font: 600 13px/1.3 var(--sans); letter-spacing: 0.06em; text-transform: uppercase; color: var(--faint); margin: 26px 0 0; padding-bottom: 8px; border-bottom: 1.5px solid var(--ink); }
.pad .shut { position: absolute; right: clamp(14px, 4vw, 30px); top: 38px; padding: 9px 15px; background: none; border: 1.5px solid var(--ink); border-radius: 999px; font: 600 14px/1 var(--sans); cursor: pointer; }
.pad .shut:hover { background: var(--ink); color: #f1e8d4; }
.pad :focus-visible { outline-color: var(--pen); }
.entry { display: grid; grid-template-columns: 132px minmax(0, 1fr); gap: 4px 18px; align-items: start; padding: 13px 0; border-bottom: 1px solid var(--rule); }
.ink { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-height: 44px; padding: 7px 10px; background: rgba(43, 36, 27, 0.06); border: 1px solid var(--rule); border-radius: 9px; cursor: pointer; }
.ink:hover { background: rgba(43, 36, 27, 0.11); }
.ink .who { font-size: 12px; color: var(--faint); text-align: left; }
.ink .bars { height: 24px; max-width: 100%; overflow: hidden; }
.ink .bars i { width: 2.5px; flex: none; }
.ink .bars i.on { background: var(--pen); }
.entry p { margin: 0; }
.entry .text { display: grid; gap: 3px; justify-items: start; padding-top: 2px; }
.entry .means { font: 400 20px/1.25 'Sriracha', var(--serif); }
.entry .means.unsure { font: italic 400 16px/1.35 var(--serif); color: var(--faint); }
.entry .memo { font: italic 400 15px/1.35 var(--serif); color: var(--faint); }
.entry .count { font: 500 12px/1.3 var(--sans); color: var(--faint); }
.find { margin-top: 6px; padding: 6px 6px 6px 12px; text-align: left; background: none; border: 1px solid color-mix(in srgb, var(--pen) 45%, transparent); border-radius: 999px; color: var(--pen); font: 600 14px/1.2 var(--sans); cursor: pointer; }
.find:hover:not(:disabled) { border-color: var(--pen); background: color-mix(in srgb, var(--pen) 8%, transparent); }
.find:disabled { opacity: 0.45; cursor: default; }
/* What has been found and kept, stuck in under the heading. */
.stuck { display: flex; flex-wrap: wrap; gap: 8px 14px; margin: 14px 0 -8px; }
.stuck > * { transform: rotate(-6deg); }
.stuck > :nth-child(even) { transform: rotate(4deg); }
.stuck img { display: block; image-rendering: pixelated; filter: drop-shadow(0 2px 0 rgba(43, 36, 27, 0.22)); }
/* One that came out of a game is the way back into it. */
.stuck .sticker { padding: 0; background: none; border: 0; border-radius: 50%; cursor: pointer; transition: transform 0.12s ease; }
.stuck .sticker:is(:hover, :focus-visible) { transform: rotate(0deg) scale(1.08); }
/* On a phone a row of them is four, so that seven are two rows and not three. */
@media (max-width: 560px) {
  .stuck { gap: 6px 10px; }
  .stuck img { width: 58px; height: auto; }
}
.foot-note { margin: 18px 0 0; font: italic 400 14px/1.4 var(--serif); color: var(--faint); max-width: 48ch; }

/* Smaller screens. Three shapes:
   wide and tall (desktop, tablet): street above, conversation and choices side by side.
   narrow (phone held upright):     street above, conversation, then choices.
   short and wide (phone on its side): street on the left, everything else on the right. */

#prompts { position: absolute; inset: 0; pointer-events: none; }
#prompts .prompt { pointer-events: auto; }
body { touch-action: manipulation; }
#hud { padding-left: max(22px, env(safe-area-inset-left)); padding-right: max(22px, env(safe-area-inset-right)); padding-top: max(14px, env(safe-area-inset-top)); }
#feed, #tray { padding-left: max(24px, env(safe-area-inset-left)); padding-right: max(24px, env(safe-area-inset-right)); }

@media (pointer: coarse) {
  .prompt { font-size: 15px; padding: 12px 14px; }
  .btn.quiet { min-height: 44px; }
  .btn.quiet.earlier { min-height: 38px; }
  .chip { min-height: 44px; }
  .bubble { min-height: 44px; }
  .cash { height: 46px; min-width: 70px; }
  .cash.coin { min-width: 46px; }
  #atlas .place { padding: 11px 13px 11px 12px; }
}

@media (max-width: 760px) {
  .heard { margin-bottom: 12px; }
  .group { margin-bottom: 14px; }
  .chip { padding: 7px 11px 7px 9px; font-size: 14px; }
  .chip .memo { font-size: 13px; }
  .hud-carry { min-width: 0; }
  #feed { gap: 10px; }
  #feed, #tray { padding: 12px 16px; }
  #tray { padding-bottom: 0; }
  #hud { gap: 14px; padding: max(10px, env(safe-area-inset-top)) 14px 30px; }
  #clock { font-size: 26px; }
  #cash { font-size: 20px; margin-top: 3px; }
  #ticks { gap: 2px; }
  #ticks i { width: 4px; height: 12px; }
  #ticks i.gate { margin-left: 4px; }
  #carry { max-width: 20ch; font-size: 12px; }
  .hud-label { font-size: 12px; margin-bottom: 6px; }
  .note { font-size: 16px; }
  .cue { font-size: 15px; }
  .sheet { min-height: 64vh; min-height: calc(64dvh + 1px); padding-top: 18px; }
  .sheet .actions .btn { flex: 1 1 auto; }
  :root { --edge-top: max(22px, env(safe-area-inset-top)); }
  .map-body { padding: 4px 16px 16px; }
  .lede { font-size: 17px; }
  .entry { grid-template-columns: 104px minmax(0, 1fr); gap: 4px 12px; }
  .entry .means { font-size: 18px; }
  .pad h2 { font-size: 28px; }
}

/* On a tall or narrow window the card for a place goes under the Earth, and the
   way back in goes under the name of the game. */
@media (max-width: 820px), (orientation: portrait) {
  .place-card { inset: auto 12px max(12px, env(safe-area-inset-bottom)) 12px; transform: none; width: auto; max-width: 460px; margin: 0 auto; gap: 10px; }
  .place-card .map h3 { font-size: 26px; }
  .place-card .map.locked h3 { font-size: 20px; }
  .place-card .map-what { font-size: 15px; }
  .place-card .map.locked { min-height: 0; padding: 12px 16px; }
}
@media (max-width: 760px) {
  /* No room beside the line about dragging, so who made it goes under that. */
  #atlas .credit { left: 0; right: 0; bottom: max(10px, env(safe-area-inset-bottom)); justify-content: center; }
  #atlas .hint { padding-bottom: calc(max(10px, env(safe-area-inset-bottom)) + 30px); }
}
@media (max-width: 560px) {
  .resume { position: static; margin-top: 14px; }
  .to-world { padding: 3px; }
  .to-world span { display: none; }
  /* The way back out is only a small Earth here, so the heading can run closer
     to it and the question mark beside it. */
  .hub .title { padding-right: 106px; }
}

@media (max-height: 540px) and (min-width: 600px) {
  #app { grid-template-rows: minmax(0, 1fr); grid-template-columns: minmax(0, 54fr) minmax(0, 46fr); }
  #panel { border-top: 0; border-left: 1px solid var(--line); }
  #feed { gap: 8px; }
  #feed, #tray { padding: 10px max(14px, env(safe-area-inset-right)) 10px 14px; }
  #tray { padding-bottom: 0; }
  #hud { gap: 12px; padding: 8px 12px 26px max(12px, env(safe-area-inset-left)); }
  #clock { font-size: 24px; }
  #deadline, .hud-label, #carry { font-size: 11px; }
  .hud-label { margin-bottom: 5px; }
  #cash { font-size: 18px; margin-top: 2px; }
  #ticks { gap: 2px; }
  #ticks i { width: 3px; height: 10px; }
  #ticks i.gate { margin-left: 3px; }
  #carry { max-width: 18ch; }
  .group { margin-bottom: 10px; }
  .tray-h { margin-bottom: 7px; }
  .chip { padding: 6px 10px 6px 8px; font-size: 14px; }
  .chip .memo { font-size: 13px; }
  .note, .cue { font-size: 15px; }
  .btn { min-height: 40px; padding: 6px 14px; }
  .btn.quiet { min-height: 40px; }
  #panel::before, .sheet::before { content: none; }
  #overlay { flex-direction: row; overflow: hidden; }
  .marquee { flex: 0 0 54%; min-height: 0; padding: 14px 16px 16px max(16px, env(safe-area-inset-left)); }
  .sheet { flex: 1 1 0; min-width: 0; min-height: 0; overflow-y: auto; scrollbar-width: thin; padding: 14px max(16px, env(safe-area-inset-right)) 16px 16px; border-top: 0; border-left: 1px solid var(--line); }
  .sheet.pin .actions { position: sticky; bottom: -16px; z-index: 1; flex-wrap: nowrap; gap: 8px; margin: 12px 0 10px; padding: 10px 0 max(16px, env(safe-area-inset-bottom)); background: var(--panel); border-top: 1px solid var(--line); }
  .sheet.pin .actions .btn { flex: none; padding: 6px 12px; font-size: 14px; }
  .sheet.pin .actions .btn.back { flex: 0 1 auto; }
  :root { --edge-top: 16px; --edge-left: max(18px, env(safe-area-inset-left)); --edge-right: max(18px, env(safe-area-inset-right)); }
  .hub { padding-bottom: 18px; }
  .mark .word { font-size: 24px; }
  .place-card { inset: 50% var(--edge-right) auto auto; transform: translateY(-50%); width: min(320px, 44vw); max-width: none; margin: 0; gap: 8px; }
  .place-card .map h3 { font-size: 24px; }
  .place-card .map-what { font-size: 14px; }
  .place-card .map.plain .map-body { padding: 10px 14px 12px; }
  .place-card .map.locked { min-height: 0; padding: 8px 12px; }
  /* A phone on its side has the least height of all: less of everything on the page of maps. */
  .hub { --art-min: 40px; gap: 6px 24px; padding-bottom: max(10px, env(safe-area-inset-bottom)); }
  .hub .title { font-size: 34px; }
  .hub .tagline { display: none; }
  .hub .maps-h { margin-bottom: 6px; }
  .hub .cast { padding-top: 18px; }
  .hub .who-card .pointer { top: -17px; }
  .hub .who-card .who .bars { height: 22px; }
  .hub .outfit .arrow { width: 34px; height: 34px; }
  .hub .kit { gap: 2px 12px; }
  .hub .kit .pill { min-height: 38px; }
  .hub .kit .btn.quiet { min-height: 30px; }
  .map-row .map:not(.locked) .map-body { gap: 5px; padding: 2px 14px 12px; }
  .map-row .map:not(.locked) h3 { font-size: 24px; }
  .map-row .map:not(.locked) .map-what { font-size: 14px; line-height: 1.35; }
  .map-row .map-history { font-size: 12px; }
  .say { font-size: 24px; }
  .say .bars { height: 20px; }
  .tagline { font-size: 15px; margin-top: 8px; }
  .title { font-size: 64px; }
  .lede { font-size: 16px; }
  .headline { font-size: 30px; }
  #notebook { padding: 10px max(14px, env(safe-area-inset-left)); }
  .pad { width: min(100%, 760px); }
}
/* The shortest phone on its side, with the browser's own bar over it. */
@media (max-height: 360px) and (min-width: 600px) {
  :root { --edge-top: 10px; }
  .hub { padding-bottom: max(8px, env(safe-area-inset-bottom)); }
  .hub .board { gap: 6px 22px; }
  .hub .cast { padding-top: 16px; }
  .hub .kit { gap: 0 12px; }
}

/* ---------- the box ----------
   How a map is laid out during a visit. The picture has the whole window.
   Walking about, what is in the player's pocket sits along its bottom edge. When
   somebody speaks, a box comes up over the bottom of the picture and holds only
   the latest of it: who spoke, what they did, the help for that line, and what
   there is to say back. Everything before that is marked `.past` by the engine
   and left out, until `Earlier` opens the box into the whole conversation. The
   box is as tall as what is in it: low while somebody speaks, and it opens over
   the picture for the player's turn. The picture does not move for it. A phone
   held sideways has no height to spare for a box
   over the picture, so there it keeps the picture beside the talking, and the
   talking still holds only the latest.
   A map's start and end screens are made the same way: the whole picture, the
   name of the map or the verdict written over it, and the words and buttons in
   a sheet over it, at the side on a wide screen and across the bottom of a tall
   one (where the engine lifts the street to stand on it). */
.btn.earlier { position: absolute; z-index: 2; top: 8px; right: 10px; min-height: 32px; padding: 3px 12px; font-size: 13px; background: var(--panel); }
#app.walking .earlier { display: none; }
#panel:not(.recall) #feed > .past { display: none; }
/* Room at the head of the box for the way back, beside whoever is speaking. */
#panel:not(.recall):has(.earlier:not([hidden])) #feed > .turn > .bubble { max-width: calc(100% - 84px); }
/* In a box there is one side: whoever is speaking starts at its top left. */
#panel:not(.recall) .turn.mine { align-items: flex-start; }
/* The price is already there to play, over the money: once is enough. */
#panel:not(.recall) .heard > .bubble { display: none; }
#panel:not(.recall) .heard:not(:has(.till)) { display: none; }

@media not all and (max-height: 540px) and (min-width: 600px) {
  /* The box is only there while a visit is under way (the engine sets one or the other). */
  #app:not(.walking, .talking) #panel { display: none; }
  #app:is(.walking, .talking) #panel {
    position: absolute;
    z-index: 1;
    left: 0;
    right: 0;
    bottom: max(14px, env(safe-area-inset-bottom));
    display: flex;
    flex-direction: column;
    width: min(920px, 100% - 28px);
    max-height: min(60%, 560px);
    margin: 0 auto;
    background: none;
    border: 0;
  }
  #app:is(.walking, .talking) #panel.recall { max-height: min(84%, 820px); }
  #app:is(.walking, .talking) #panel::before { content: none; }
  /* The box itself: the colours of the place, with a line round it. */
  #app:is(.walking, .talking) #stream { height: auto; min-height: 0; flex: 0 1 auto; background: var(--panel); border: 2px solid var(--line); border-radius: 16px; box-shadow: 0 0 0 2px rgba(8, 6, 4, 0.6), 0 16px 34px rgba(8, 6, 4, 0.5); }
  #app:is(.walking, .talking) #feed, #app:is(.walking, .talking) #tray { max-width: none; padding: 16px 20px 12px; }
  #app:is(.walking, .talking) #feed { margin-top: 0; gap: 10px; }
  #app:is(.walking, .talking) #feed:not(:has(> :not(.past))) { padding-top: 0; padding-bottom: 0; }
  #app:is(.walking, .talking) #panel.recall #feed:has(> *) { padding-top: 16px; padding-bottom: 12px; }
  #app:is(.walking, .talking) #tray { padding-top: 14px; padding-bottom: 0; }
  #app.talking #tray > :last-child { margin-bottom: 16px; }
  #app.talking .group { margin-bottom: 14px; }
  #app.talking .tray-h { margin-bottom: 8px; }

  /* Walking about: no box. What is in the player's pocket, and how to get about
     until they have finished a visit, along the bottom of the picture over a
     shade like the top bar's. The street under it still answers a press. */
  #app.walking #panel {
    --panel: transparent; --raise: rgba(16, 20, 28, 0.88); --raise-2: rgba(30, 36, 46, 0.94); --line: rgba(242, 233, 216, 0.3);
    --text: #f2e9d8; --dim: #d9cfbd; --accent: #f0b43c; --accent-ink: #281b04;
    color-scheme: dark;
    bottom: 0;
    width: auto;
    max-height: none;
    background: linear-gradient(rgba(10, 9, 8, 0), rgba(10, 9, 8, 0.5) 45%, rgba(10, 9, 8, 0.78));
    pointer-events: none;
  }
  #app.walking #panel::before { content: none; }
  #app.walking #panel :is(.btn, .note) { pointer-events: auto; }
  #app.walking #stream { overflow: visible; background: none; border: 0; border-radius: 0; box-shadow: none; }
  /* Something told as the player walks off, or on the way: it shows for a while
     under the top bar, where it covers nobody. */
  #app.walking #feed { position: fixed; top: calc(max(14px, env(safe-area-inset-top)) + 78px); left: 0; right: 0; width: auto; margin: 0; padding: 0 16px; align-items: center; }
  #app.walking #feed > :is(:not(.note), .read) { display: none; }
  #app.walking #feed > .note { padding: 8px 14px; background: rgba(12, 16, 24, 0.92); border: 1px solid rgba(240, 180, 60, 0.7); border-radius: 12px; color: #f2e9d8; font-size: 16px; text-align: center; animation: told 0.6s ease 7s forwards; }
  #app.walking #tray { align-items: flex-start; gap: 8px; border-top: 0; padding: 30px max(22px, env(safe-area-inset-right)) max(14px, env(safe-area-inset-bottom)) max(22px, env(safe-area-inset-left)); }
  #app.walking #tray > * { margin: 0; }
  #app.walking .group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
  #app.walking .tray-h, #app.walking .keys:not(.first) { display: none; }
  #app.walking .keys { font-size: 14px; color: #e6dccb; text-shadow: 0 1px 2px rgba(8, 6, 4, 0.8); }
  #app.walking .pocket-note { margin: 0; }
}
@keyframes told { to { opacity: 0; visibility: hidden; } }
/* A wide box uses its width to stay low: the help for a line sits beside the
   line, and the things to do sit beside the things to say. */
@media (min-width: 900px) and (min-height: 541px) {
  #app.talking #tray { flex-flow: row nowrap; align-items: flex-start; column-gap: 40px; }
  /* Neither pushes the other off the line. The things to say give way first and
     wrap inside themselves; the things to do keep their width, up to a point. */
  #app.talking #tray > .group { flex: 0 1 auto; min-width: 0; }
  #app.talking #tray > .group ~ .group { flex: none; max-width: 45%; }
  #app.talking #tray > .group:only-child { flex: 1 1 100%; }
}
@media (max-width: 760px) and (min-height: 541px), (max-width: 599px) {
  #app:is(.walking, .talking) #panel { bottom: max(8px, env(safe-area-inset-bottom)); width: calc(100% - 16px); max-height: 62%; }
  #app:is(.walking, .talking) #feed, #app:is(.walking, .talking) #tray { padding: 12px 14px 10px; }
  #app:is(.walking, .talking) #tray { padding-top: 12px; padding-bottom: 0; }
  #app.talking #tray > :last-child { margin-bottom: 12px; }
  #app.walking #panel { bottom: 0; width: auto; max-height: none; }
  #app.walking #feed { top: calc(max(10px, env(safe-area-inset-top)) + 66px); padding: 0 12px; }
  #app.walking #feed > .note { font-size: 15px; }
  /* What is in the player's pocket is one row here, however much there is: it
     slides sideways, and stays under the feet of whoever is on the street. */
  #app.walking #tray { padding: 22px 0 max(10px, env(safe-area-inset-bottom)); }
  #app.walking #tray > .keys { padding: 0 14px; }
  #app.walking .group { flex-wrap: nowrap; max-width: 100%; padding: 0 14px; overflow-x: auto; scrollbar-width: none; pointer-events: auto; }
  #app.walking .group > * { flex: none; flex-wrap: nowrap; white-space: nowrap; }
  #app.walking .group .btn { flex: none; min-height: 40px; padding: 6px 14px; white-space: nowrap; }
  #app.walking .btn.notebook .cost { display: none; }
}

/* A map's start and end screens (see the top of this section). */
@media not all and (max-height: 540px) and (min-width: 600px) {
  #overlay { overflow: hidden; }
  .marquee { background: linear-gradient(rgba(10, 9, 8, 0) 38%, rgba(10, 9, 8, 0.74)); }
  .sheet {
    display: flex;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--line) transparent;
    border: 2px solid var(--line);
    box-shadow: 0 0 0 2px rgba(8, 6, 4, 0.6), 0 16px 34px rgba(8, 6, 4, 0.5);
  }
  .sheet::before { content: none; }
  @media (orientation: landscape) {
    .marquee { flex: 1 1 auto; min-height: 0; padding-right: calc(max(380px, 34%) + 60px); }
    .sheet { position: absolute; right: 24px; bottom: 24px; width: max(380px, 34%); max-height: calc(100% - 48px); padding: 24px 26px 8px; border-radius: 16px; }
  }
  @media (orientation: portrait) {
    #overlay { justify-content: flex-end; }
    .marquee { flex: none; min-height: 0; padding: 44px 16px 14px; background: linear-gradient(rgba(10, 9, 8, 0), rgba(10, 9, 8, 0.74) 62%); }
    .sheet { max-height: 62%; padding: 16px 16px max(10px, env(safe-area-inset-bottom)); border-width: 2px 0 0; border-radius: 18px 18px 0 0; box-shadow: none; }
  }
}

/* The way out of a visit: a small arrow in the corner of the top bar, and under
   it, once pressed, a word to make sure. Both are the dark label with an amber
   line that the signs on the street are. */
.leave { flex: none; display: grid; place-items: center; width: 30px; height: 30px; margin: 2px -16px 0 0; padding: 0; background: rgba(12, 16, 24, 0.55); border: 1px solid rgba(242, 233, 216, 0.24); border-radius: 50%; color: #a79c8a; cursor: pointer; pointer-events: auto; transition: border-color 0.15s ease, color 0.15s ease; }
.leave:hover { border-color: #f0b43c; color: #f2e9d8; }
.leaving { position: absolute; z-index: 3; top: calc(max(14px, env(safe-area-inset-top)) + 40px); left: max(22px, env(safe-area-inset-left)); max-width: min(320px, 100% - 28px); padding: 14px 16px; background: rgba(12, 16, 24, 0.96); border: 1px solid #f0b43c; border-radius: 14px; box-shadow: 0 10px 24px rgba(8, 6, 4, 0.5); color: #f2e9d8; cursor: default; }
.leaving p { margin: 0 0 12px; font: 500 15px/1.4 var(--sans); }
@media (max-width: 760px), (max-height: 540px) {
  .leave { width: 28px; height: 28px; margin: 0 -2px 0 0; }
  .leaving { left: max(12px, env(safe-area-inset-left)); }
}
/* The way to how to play is the same button at the other end of the bar, and
   what it asks comes up under it. On a phone the bar is full, and it goes under
   the arrow, with what it asks under that. */
.hud-ways { display: contents; }
.leave.howto { order: 1; margin: 2px 0 0; }
.leaving.far { left: auto; right: max(22px, env(safe-area-inset-right)); }
@media (max-width: 760px), (max-height: 540px) {
  .hud-ways { flex: none; display: flex; flex-direction: column; gap: 8px; }
  .leave.howto { order: 0; margin: 0; }
  .leaving.far { left: max(12px, env(safe-area-inset-left)); right: auto; top: calc(max(14px, env(safe-area-inset-top)) + 76px); }
}

/* Before a first visit, a start screen offers how to play: quietly, under the way in. */
.sheet .howto-first { align-self: flex-start; min-height: 36px; margin: -6px 0 0; padding-top: 4px; padding-bottom: 4px; }
.howto-first .px { color: var(--accent); }

/* How to play: a word about one thing on screen, in the dark label with an amber
   line that the signs and the tips are, and round the thing, the frame at its
   corners that marks a picked phrase. Over everything but the notebook. */
.guide {
  --raise: rgba(255, 255, 255, 0.06); --raise-2: rgba(255, 255, 255, 0.11); --line: #3d4556;
  --text: #f2e9d8; --dim: #a79c8a; --accent: #f0b43c; --accent-ink: #281b04;
  position: fixed;
  z-index: 4;
  left: 0;
  top: 0;
  width: max-content;
  max-width: min(330px, calc(100vw - 20px));
  padding: 13px 14px 12px 16px;
  background: rgba(12, 16, 24, 0.96);
  border: 1px solid #f0b43c;
  border-radius: 14px;
  box-shadow: 0 10px 24px rgba(8, 6, 4, 0.5);
  color: var(--text);
  cursor: default;
}
.guide-says { margin: 0; font: 500 15px/1.4 var(--sans); }
.guide .actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.guide .btn { min-height: 36px; padding: 6px 14px; font-size: 14px; }
.guide .btn.quiet { margin-right: auto; padding: 6px 2px; background: none; border-color: transparent; color: var(--dim); }
.guide .btn.quiet:hover { background: none; border-color: transparent; color: var(--text); }
/* With nothing to press but the way out of it, that is small and to one side. */
.guide:not(.reading) .actions { margin-top: 6px; }
.guide:not(.reading) .btn.quiet { min-height: 28px; padding: 2px; font-size: 13px; }
.guide-frame {
  --mark: linear-gradient(#f0b43c 0 0);
  position: fixed;
  z-index: 4;
  left: 0;
  top: 0;
  pointer-events: none;
  background:
    var(--mark) 0 0 / 12px 2px, var(--mark) 0 0 / 2px 12px,
    var(--mark) 100% 0 / 12px 2px, var(--mark) 100% 0 / 2px 12px,
    var(--mark) 0 100% / 12px 2px, var(--mark) 0 100% / 2px 12px,
    var(--mark) 100% 100% / 12px 2px, var(--mark) 100% 100% / 2px 12px;
  background-repeat: no-repeat;
}
@media (pointer: coarse) {
  .guide .btn { min-height: 44px; }
  .guide:not(.reading) .btn.quiet { min-height: 36px; }
}
/* A short window has little room to spare for it. */
@media (max-height: 600px) {
  .guide { padding: 10px 12px 9px 14px; }
  .guide-says { font-size: 14px; }
  .guide .actions { margin-top: 6px; }
}

/* The tutorial's floor is nowhere: white, with a grid on it. */
#street[data-map='tutorial'] { background: #f7f6f2; }
#street[data-map='tutorial'] #hud { background: linear-gradient(rgba(10, 9, 8, 0.86), rgba(10, 9, 8, 0.6) 55%, rgba(10, 9, 8, 0)); }
#street[data-map='tutorial'] :is(#deadline, .hud-label, #carry) { color: #dde3e6; }
/* And over white, the shade under the pocket needs to be as deep as the top bar's. */
#app.walking:has(#street[data-map='tutorial']) #panel { background: linear-gradient(rgba(10, 9, 8, 0), rgba(10, 9, 8, 0.62) 40%, rgba(10, 9, 8, 0.86)); }
/* And it is in one colour, the teal of its talk box: the words and the frame
   round what they are about, the top bar, the sign on the door and the pocket.
   Elsewhere those are the amber of the signs. */
#street[data-map='tutorial'], #app.touring .guide, #app.walking:has(#street[data-map='tutorial']) #panel { --accent: #0e7c86; --accent-ink: #f0fbfb; }
#app.touring .guide { border-color: var(--accent); }
#app.touring .guide-frame { --mark: linear-gradient(#0e7c86 0 0); }
#street[data-map='tutorial'] .prompt { border-color: var(--accent); }
#street[data-map='tutorial'] .prompt:hover { background: var(--accent); color: var(--accent-ink); }
#street[data-map='tutorial'] .prompt::after { background: var(--accent); }
#street[data-map='tutorial'] .leave:hover { border-color: var(--accent); }

/* On a narrow screen, things of one kind are one row that slides sideways under
   a finger, where they would otherwise stack: the help for a line, the phrases
   there are to say, and the things to do beside them. The row runs out to the
   edges of the box and fades at the right one, so that whatever is cut off there
   says there is more. Where there is only a list of things to do, it stays a
   list: every one of them shows. */
@media (max-width: 760px), (max-height: 540px) {
  #app.talking :is(.chips, #tray:has(.chips) .actions:not(.fingers)) {
    flex-wrap: nowrap;
    align-self: stretch;
    margin: -6px -14px;
    padding: 6px 34px 6px 14px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
    -webkit-mask-image: linear-gradient(to left, transparent, #000 30px);
    mask-image: linear-gradient(to left, transparent, #000 30px);
  }
  #app.talking :is(.chips, #tray:has(.chips) .actions:not(.fingers)) > * { flex: none; }
  /* In a row that slides, a phrase is one line however long it is called. */
  #app.talking .chips > .chip { max-width: none; }
  #app.talking .chips > .chip .label { white-space: nowrap; }
  #app.talking #tray:has(.chips) .actions:not(.fingers) > .btn { white-space: nowrap; }
  /* The phrases slide, and what to do with the picked one stays put at the end of
     their line, the row fading under it, or under them if it has more to offer
     than fits there. */
  #app.talking .to-say > .chips { flex: 1 1 150px; }
  #app.talking .to-say > .chips:has(+ .confirm:not(:empty)) { margin-right: 0; }
  #app.talking .to-say > .confirm { flex: none; max-width: 100%; }
  /* The way to the rest of the phrases is a plus and how many. */
  .btn.more > .words { display: none; }
  .btn.more { min-width: 44px; padding: 6px 10px; }
  /* The button for help is its picture alone. */
  .btn.help { width: 44px; min-height: 44px; padding: 0; border-radius: 50%; }
  .btn.help > span { display: none; }
  #panel:not(.recall):has(.earlier:not([hidden])) #feed > .turn > .bubble { max-width: calc(100% - 138px); }
}
@media (pointer: coarse) {
  #app.talking :is(.chips, .actions) { scrollbar-width: none; }
  #app.talking :is(.chips, .actions)::-webkit-scrollbar { display: none; }
}

/* ---------- what is on the box ----------
   The box and the sheets on a map's start and end screens are paper, and on
   them there is ink and little else. No card inside the card, no pill round a
   voice, no ruled lines. Who is speaking is their name in the serif, and what
   they said is a play mark and its shape. Things to press are a thin line and
   words, with rounded corners, and the one way on is the filled pill. Help and
   the way back are plain words. The things there are to say, the frame at the
   corners of the one that is picked, and "Say it" beside them, are as they were
   (further up): numbered tokens with a pointer over the picked one were tried
   and were a different game's. All of it is kept to the box while somebody is
   talking and to those sheets: the row along the bottom while walking, the
   menus and the notebook have their own looks. The colours are the place's. */
:is(#panel, .sheet) {
  --ink: color-mix(in srgb, var(--text) 86%, var(--panel));
  --ink-mid: color-mix(in srgb, var(--text) 58%, var(--panel));
  --ink-faint: color-mix(in srgb, var(--text) 22%, transparent);
  --paper: linear-gradient(color-mix(in srgb, var(--panel) 93%, white), var(--panel) 46%, color-mix(in srgb, var(--panel) 95%, var(--text)));
}
#app.talking #stream, .sheet, #app.talking #panel .helps { background: var(--paper); }
#app.talking #feed, #app.talking #tray { padding-left: max(26px, env(safe-area-inset-left)); padding-right: max(26px, env(safe-area-inset-right)); }
/* Room, and no lines. One beat (some narration, a voice, a text that has come)
   stands clear of the one before it. What belongs to a voice keeps close under
   it: what was going on, the voice in pieces, the player's own sound in it, a
   hint. A text keeps close to the line that says it came. Where what was said
   meets what there is to say there is a wider gap, and the heading over the
   choices. A phone has less height to give, so everything there is a step in. */
#app.talking #feed { padding-top: 24px; padding-bottom: 10px; gap: 18px; }
#app.talking #feed > .turn:not(.mine) { row-gap: 10px; }
#app.talking #feed > .note:not(.past) + .note:has(> .sms) { margin-top: -8px; }
#app.talking #tray { border-top: 0; padding-top: 14px; }
#app.talking #tray > :last-child { margin-bottom: 22px; }
#app.talking #tray .group { margin-bottom: 18px; }
#app.talking #tray .tray-h { margin-bottom: 10px; }
@media (max-width: 760px), (max-height: 540px) {
  #app.talking #feed, #app.talking #tray { padding-left: max(18px, env(safe-area-inset-left)); padding-right: max(18px, env(safe-area-inset-right)); }
  #app.talking #feed { padding-top: 20px; padding-bottom: 8px; gap: 14px; }
  #app.talking #feed > .turn:not(.mine) { row-gap: 8px; }
  #app.talking #feed > .note:not(.past) + .note:has(> .sms) { margin-top: -5px; }
  #app.talking #tray { padding-top: 12px; }
  #app.talking #tray > :last-child { margin-bottom: 18px; }
  #app.talking #tray .group { margin-bottom: 16px; }
  #app.talking #tray .tray-h { margin-bottom: 8px; }
}

/* A voice: a play mark, the name, and its shape. */
:is(#app.talking #panel, .sheet) .bubble { background: none; border: 0; border-radius: 0; padding: 2px 0; gap: 9px; }
:is(#app.talking #panel, .sheet) .bubble:hover { background: none; }
:is(#app.talking #panel, .sheet) .bubble .who { font: 600 15px/1.2 var(--serif); color: var(--ink); }
:is(#app.talking #panel, .sheet) .bubble.mine .who { color: var(--accent); }
:is(#app.talking #panel, .sheet) .bubble .px { color: var(--ink); }
:is(#app.talking #panel, .sheet) .bubble:hover .px { color: var(--accent); }
:is(#app.talking #panel, .sheet) .bubble .bars i { width: 2px; border-radius: 0; background: var(--ink-mid); }
:is(#app.talking #panel, .sheet) .bubble .bars i.on { background: var(--ink); }
:is(#app.talking #panel, .sheet) .bubble.mine .bars i.on { background: var(--accent); }
:is(#app.talking #panel, .sheet) .bubble.piece { padding: 1px 8px; border-radius: 8px; background: color-mix(in srgb, var(--text) 6%, transparent); }
:is(#app.talking #panel, .sheet) .bubble.small { padding: 0 6px 0 4px; }

/* Narration is the italic serif, in ink. Help and the way back are words. */
:is(#app.talking #panel, .sheet) :is(.note, .cue) { color: var(--ink); }
:is(#app.talking #panel, .sheet) .cue { color: var(--ink-mid); }
#app.talking #panel :is(.btn.help, .btn.earlier) { background: none; border: 0; min-height: 0; padding: 6px 8px; border-radius: 10px; color: var(--ink-mid); font: 600 13px/1 var(--sans); }
#app.talking #panel :is(.btn.help, .btn.earlier):hover:not(:disabled) { background: color-mix(in srgb, var(--text) 7%, transparent); color: var(--ink); }
#app.talking #panel .btn.help { width: auto; }
#app.talking #panel .btn.help > span { display: inline; }
#app.talking #panel .btn.earlier { top: 12px; right: 14px; }

/* A phrase taught: its meaning as a heading, then the two voices to set against
   each other, then when it is said. */
:is(#app.talking #panel, .sheet) .taught { background: none; border: 0; border-radius: 0; padding: 2px 0 0; gap: 2px 22px; }
:is(#app.talking #panel, .sheet) .taught .means { order: -1; flex: 0 0 100%; font: 600 22px/1.2 var(--serif); }
:is(#app.talking #panel, .sheet) .taught .use { margin-top: 4px; font-size: 15px; color: var(--ink); }

/* The heading over the choices: plain words, no mark before them. */
:is(#app.talking #panel, .sheet) .tray-h { gap: 0; font: 600 13px/1.3 var(--sans); color: var(--ink-mid); }
:is(#app.talking #panel, .sheet) .tray-h::before { content: none; }

/* Things to press: a thin line and words, with rounded corners. The one way on
   is the filled pill, untouched. */
:is(#app.talking #panel, .sheet) .btn:where(:not(.primary)) { min-height: 40px; border-radius: 12px; background: none; border: 1px solid var(--ink-faint); color: var(--ink); font-weight: 600; }
:is(#app.talking #panel, .sheet) .btn:where(:not(.primary)):hover:not(:disabled) { background: color-mix(in srgb, var(--text) 7%, transparent); border-color: var(--text); }
:is(#app.talking #panel, .sheet) .btn.quiet { border-color: transparent; color: var(--ink-mid); }
:is(#app.talking #panel, .sheet) .cost { border-radius: 6px; background: color-mix(in srgb, var(--text) 8%, transparent); font: 500 11px/1 var(--mono); }
#app.talking #panel .helps .btn { border-color: transparent; padding: 6px 10px; }
/* A way on that stands alone sits in the bottom right corner. */
#app.talking #tray > .group:only-child .actions:not(.fingers):has(> .btn:only-child) { justify-content: flex-end; }
#app.talking #tray > .group:last-child .actions:not(.fingers):has(> .btn.primary:first-child) { justify-content: flex-end; }

/* ---------- a machine's screen ---------- */
/* A game inside the game (src/catch.js) has the whole window while it is up: its
   screen, as big as whole pixels allow, and under it the one or two things there
   are to press. Nothing in it scrolls. */
.arcade {
  position: fixed;
  inset: 0;
  z-index: 6;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  gap: 12px;
  padding: max(16px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(14px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  background: #070a16;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.arcade .tube { position: relative; display: grid; place-items: center; min-width: 0; min-height: 0; }
.arcade canvas { display: block; image-rendering: pixelated; border-radius: 6px; box-shadow: 0 0 0 6px #12172e; }
.arcade .deck { display: flex; justify-content: center; align-items: center; gap: 10px; min-height: 46px; }
/* What the machine gives, up in front of its screen to be taken. */
.arcade .prize { position: absolute; left: 50%; top: 50%; width: min(46vmin, 219px); height: auto; image-rendering: pixelated; transform: translate(-50%, -50%) rotate(-6deg); filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.4)); animation: prize 0.36s steps(6) both; }
@keyframes prize { from { transform: translate(-50%, 30%) rotate(10deg); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .smoke, .coals, .beacon, .train, .actor.walking svg, .actor.walking .leg, .happy .tail, .hub.arriving, .prompt::before, .prompt::after, .flicker, .arcade .prize { animation: none; }
  .puff { display: none; }
  #atlas > *, .mark .tagline, .hub { transition: none; }
  #stream { scroll-behavior: auto; }
  #app.walking #feed > .note { animation: none; }
}
