/* Phone first: one column, readable at 375px, the same on a desktop window. Light and dark follow the system. */

:root {
  --bg: #f3f1ec;
  --surface: #ffffff;
  --text: #1c1d1f;
  --muted: #5d6166;
  --line: #dcd8cf;
  --accent: #1d6b57;
  --on-accent: #ffffff;
  --accent-soft: #e1efe9;
  --warn: #a13a12;
  --track: #e6e2d9;
  --english: #2d6ab0;
  --coding: #7550a8;
  --energy: #b86f00;
  --sky-top: #9fcdea;
  --sky-bottom: #e2f1f8;
  --radius: 14px;
  --talk-bg: #fff8ea;
  --talk-border: #cdb089;
  --talk-text: #3b2f25;
  --talk-muted: #76603f;
  --keyword-bg: #f6ead2;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #15171a;
    --surface: #1f2226;
    --text: #eceae5;
    --muted: #a3a7ad;
    --line: #34383e;
    --accent: #5cc0a2;
    --on-accent: #0d1f19;
    --accent-soft: #1d3a31;
    --warn: #ff9b6e;
    --track: #33373d;
    --english: #6aa7ee;
    --coding: #b18ef0;
    --energy: #f0ad45;
    --sky-top: #5f8fb2;
    --sky-bottom: #a9c6d6;
    --talk-bg: #2b241d;
    --talk-border: #6b5a44;
    --talk-text: #f1e6d2;
    --talk-muted: #c2ab8a;
    --keyword-bg: #3a3027;
  }
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 system-ui, -apple-system, "Apple SD Gothic Neo", "Noto Sans KR", "Malgun Gothic", sans-serif;
  word-break: keep-all;
  overflow-wrap: anywhere;
}

#app {
  max-width: 480px;
  margin: 0 auto;
  padding: 16px 16px 40px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

h1,
h2,
p,
ul,
dl,
dd {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

h2 {
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 6px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
}

/* Title */

.title {
  position: relative;
  padding: 12px 0 0;
}

.brand {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--accent);
}

.title h1 {
  font-size: 26px;
  line-height: 1.25;
}

.run {
  color: var(--muted);
  font-size: 14px;
}

/* The brand's line, with the update news and the sound switch at its end; on a narrow screen they wrap under it. */
.title-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  min-height: 36px;
}

.title-controls {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

/* The title, with the game's version small after it. */
.title-name {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 8px;
}

.patch-current {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* The arrival story on the intro, kept small so how to play starts on a phone's first screen */

.story {
  padding: 10px 14px;
  font-size: 15px;
  line-height: 1.45;
}

.story .goal {
  font-weight: 700;
  color: var(--accent);
}

/* Room pick */

.lead {
  font-weight: 600;
}

.formula {
  color: var(--muted);
  font-size: 14px;
}

.why {
  font-size: 14px;
}

.formula + .why {
  margin-top: 4px;
}

.board {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  font-size: 14px;
}

.board dt {
  color: var(--muted);
}

.rooms {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.rooms h2 {
  margin: 4px 0 0;
}

button {
  font: inherit;
  color: inherit;
  min-height: 44px;
  border-radius: 12px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

button:disabled {
  cursor: default;
}

button:focus-visible,
input:focus-visible,
a:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.room {
  display: grid;
  grid-template-columns: 3.4em 1fr;
  grid-template-areas:
    "number rent"
    "number clues";
  align-items: center;
  column-gap: 14px;
  width: 100%;
  padding: 10px 14px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
}

.room[aria-pressed="true"] {
  border: 2px solid var(--accent);
  background: var(--accent-soft);
  padding: 9px 13px;
}

.room:disabled:not([aria-pressed="true"]) {
  opacity: 0.6;
}

.room-number {
  grid-area: number;
  font-weight: 700;
  color: var(--accent);
}

.room-rent {
  grid-area: rent;
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.room-clues {
  grid-area: clues;
  font-size: 14px;
  color: var(--muted);
}

/* The rooms on the whole map: where the map and its pins sit and their size are set in code. It is a picture that
   looks the same in both themes, as the small map does, and so are its pins. */
.room-map canvas {
  border-radius: var(--radius);
  box-shadow: 0 0 0 1px rgba(122, 82, 51, 0.35), 0 1px 3px rgba(59, 47, 37, 0.3);
}

.room-pin {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border-radius: 50%;
  border: 2px solid #1d6b57;
  background: #fffaee;
  color: #1d6b57;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
  /* A thin dark ring outside the green one keeps the pin's edge clear of the water and the parks it may sit on. */
  box-shadow: 0 0 0 1px #3b2f25, 0 1px 4px rgba(59, 47, 37, 0.45);
}

.room-pin[aria-pressed="true"] {
  border: 3px solid #fffaee;
  background: #1d6b57;
  color: #ffffff;
  box-shadow: 0 0 0 2px #1d6b57, 0 0 0 3px #3b2f25, 0 2px 6px rgba(59, 47, 37, 0.5);
}

.room-pin:disabled:not([aria-pressed="true"]) {
  opacity: 0.6;
}

.room-map-hint {
  font-size: 14px;
  color: var(--muted);
}

/* The picked room under the map, laid out as the list's rooms were. */
.room-card {
  display: grid;
  grid-template-columns: 3.4em 1fr;
  grid-template-areas:
    "number rent"
    "number clues";
  align-items: center;
  column-gap: 14px;
  border: 2px solid var(--accent);
  background: var(--accent-soft);
  padding: 9px 13px;
}

.guess {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.guess label {
  font-weight: 600;
}

.guess-rule {
  margin-top: -4px;
  font-size: 14px;
  color: var(--muted);
}

.guess-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.dollar {
  font-size: 20px;
  font-weight: 700;
  color: var(--muted);
}

.guess input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 8px 12px;
  font: inherit;
  font-size: 20px;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
}

.hint {
  min-height: 1.5em;
  font-size: 14px;
  color: var(--warn);
}

.primary {
  width: 100%;
  min-height: 52px;
  font-weight: 700;
  color: var(--on-accent);
  background: var(--accent);
  border: none;
}

.primary:disabled {
  background: var(--track);
  color: var(--muted);
}

/* An outlined button, and a link drawn like one. */
.secondary {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  font-weight: 700;
  color: var(--accent);
  background: var(--surface);
  border: 2px solid var(--accent);
  border-radius: 12px;
  text-decoration: none;
}

/* Reveal */

.reveal .label {
  font-size: 14px;
  color: var(--muted);
}

.total {
  font-size: 34px;
  font-weight: 800;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.breakdown {
  color: var(--muted);
  font-size: 14px;
  margin-bottom: 10px;
}

.points li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}

/* What the guess wins or loses as the month starts, large, with why under it. */
.guess-money {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 8px 0 0;
  border-top: 1px solid var(--line);
  font-weight: 700;
}

.guess-money-amount {
  font-size: 24px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.guess-money-reward .guess-money-amount {
  color: var(--accent);
}

.guess-money-penalty .guess-money-amount {
  color: var(--warn);
}

.guess-why {
  margin-bottom: 8px;
  font-size: 14px;
  color: var(--muted);
}

.left {
  font-weight: 600;
}

.month-cost {
  margin: -2px 0 8px;
  font-size: 14px;
}

.start .notes {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 12px;
  font-size: 15px;
}

/* The intro, the page's first screen. Its way in (시작하기, or 이어하기 and 새로 시작) stays in sight at the foot of the
   screen however long the rest is, on a small phone and on one turned on its side. */
.intro {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.how-to-lines {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 14px;
}

.how-to-lines li {
  position: relative;
  padding-left: 1.1em;
}

.how-to-lines li::before {
  content: "";
  position: absolute;
  top: 0.65em;
  left: 0.2em;
  width: 6px;
  height: 6px;
  background: var(--accent);
  border-radius: 50%;
}

.guess-pays {
  font-size: 14px;
}

.guess-rule-line {
  margin: 4px 0 2px;
  font-size: 15px;
  font-weight: 700;
  color: var(--accent);
}

.guess-examples {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.intro-start {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin: 0 -16px;
  padding: 10px 16px max(10px, env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--line);
}

/* The card that offers the month kept from an earlier visit, at the top of the intro */
.kept-from {
  font-size: 20px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.kept-note {
  margin: 4px 0 12px;
  font-size: 14px;
  color: var(--muted);
}

/* On the intro the kept month's buttons are in the bar at the foot, so the card ends at the note. */
.kept .kept-note {
  margin-bottom: 0;
}

.kept-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* On another run's start card: starting it drops the kept month. */
.start .replaces {
  margin: -4px 0 12px;
  font-size: 14px;
  color: var(--warn);
}

/* The month */

/* The 3D town. Its shape (aspect-ratio) comes from TownCamera, so the picture and the names over it line up. */
.town {
  position: relative;
  overflow: hidden;
  background: linear-gradient(var(--sky-top), var(--sky-bottom));
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.town canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* The names sit on the picture, which looks the same in both themes, so their colours stay fixed. */
.town-label {
  position: absolute;
  transform: translate(-50%, -100%);
  padding: 0 6px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.6;
  white-space: nowrap;
  color: #1c1d1f;
  background: rgba(255, 255, 255, 0.88);
  border-radius: 6px;
  pointer-events: none;
}

/* On the narrowest phones the names get smaller, so neighbours do not cover each other. */
@media (max-width: 359px) {
  .town-label {
    padding: 0 4px;
    font-size: 11px;
  }
}

.town-label.here {
  color: #ffffff;
  background: #1d6b57;
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 12px;
  margin: -16px -16px 0;
  padding: 10px 16px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.figure {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.figure-label {
  font-size: 12px;
  color: var(--muted);
}

.figure-value {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* The day's weather, a word after the date. */
.weather {
  margin-left: 0.3em;
  font-size: 0.75em;
  font-weight: 600;
  color: var(--muted);
}

.log ul {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 15px;
}

.stats {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.meter {
  display: grid;
  grid-template-columns: 3em 1fr 3.5em;
  align-items: center;
  gap: 10px;
}

.meter-label {
  font-weight: 600;
}

.meter-bar {
  height: 10px;
  border-radius: 5px;
  background: var(--track);
  overflow: hidden;
}

.meter-fill {
  display: block;
  height: 100%;
  border-radius: 5px;
}

.english .meter-fill {
  background: var(--english);
}

.coding .meter-fill {
  background: var(--coding);
}

.energy .meter-fill {
  background: var(--energy);
}

.meter-value {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.interview {
  border-color: var(--accent);
}

.chance {
  font-weight: 700;
  color: var(--accent);
}

.actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.actions h2 {
  margin: 4px 0 0;
}

/* When nothing but sleep is left today: go home to sleep. */
.actions .bedtime {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--warn);
}

.action {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "name effect"
    "why why";
  align-items: center;
  column-gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 8px 14px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
}

.action:not(:disabled):active {
  background: var(--accent-soft);
}

.action:disabled {
  background: transparent;
  border-style: dashed;
}

.action:disabled .action-name,
.action:disabled .action-effect {
  color: var(--muted);
}

.action-name {
  grid-area: name;
  font-weight: 700;
}

.action-effect {
  grid-area: effect;
  font-size: 14px;
  color: var(--muted);
  text-align: right;
}

.action-why {
  grid-area: why;
  font-size: 14px;
  color: var(--warn);
}

/* Ending */

.ending {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ending-offer {
  border: 2px solid var(--accent);
}

.ending-line {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.4;
}

.figures {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.ending-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* Today's result */

.result {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.result h2 {
  margin: 0;
}

.result-line {
  padding: 10px 12px;
  font-size: 15px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  /* One tap selects the whole line, for when the copy button is refused. */
  -webkit-user-select: all;
  user-select: all;
}

.result-status {
  font-size: 14px;
  color: var(--muted);
}

/* The town to walk in. It fills the screen (set in code, with the finger kept for the town); the day's figures
   sit over its top and a talk with a place's person over its bottom. */

html:has(.walk-town) {
  overflow: hidden;
  overscroll-behavior: none;
}

.walk-town {
  background: #bfe3f5;
  -webkit-user-select: none;
  user-select: none;
}

/* Each building's name floats over the picture, which looks the same in both themes, so its colours stay fixed.
   The name is a button: a tap on it talks to the place's person. */
.place-name {
  min-height: 32px;
  padding: 4px 12px;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.5;
  white-space: nowrap;
  color: #3b2f25;
  background: rgba(255, 250, 238, 0.92);
  border: 1px solid rgba(122, 82, 51, 0.35);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(59, 47, 37, 0.25);
  will-change: transform;
}

/* The name is easy to hit: its tap area reaches past the pill on every side, to 48 points tall. */
.place-name::after {
  content: "";
  position: absolute;
  inset: -8px;
}

/* The bike shop's name, in the warm colour of its walls, so it reads apart from the five places. */
.place-name.shop-name {
  background: rgba(249, 230, 176, 0.95);
}

.place-name.here {
  color: #ffffff;
  background: #1d6b57;
  border-color: #1d6b57;
}

/* A name whose building is behind the camera or lost in the haze hides; the town also takes it out of the Tab order
   and hides it from screen readers until it shows again. */
.place-name.behind {
  opacity: 0;
  pointer-events: none;
}

/* A name that would sit under the top card or the day's log hides there, so it never peeks out from under them. */
.place-name.under {
  opacity: 0;
  pointer-events: none;
}

/* The small map of the whole town, in the top right corner just under the top card and the day's log. Where it sits
   and its size are set in code; it is a picture that looks the same in both themes, as the town does. A tap shows it
   larger, about four fifths of the screen wide. */
.minimap {
  background: #6fb3d9;
  border: 1px solid rgba(122, 82, 51, 0.35);
  border-radius: 10px;
  box-shadow: 0 1px 3px rgba(59, 47, 37, 0.3);
  cursor: pointer;
}

.minimap.large {
  border-radius: 14px;
}

.over-town {
  position: fixed;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: max(8px, env(safe-area-inset-top)) 8px max(8px, env(safe-area-inset-bottom));
  /* Fingers pass through to the town, except on the talk. */
  pointer-events: none;
  /* The cards over the town are laid out by the town's size: the chooser's list by the room on a small phone. */
  container-type: size;
}

.over-town > * {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
}

.hud {
  padding: 8px 12px;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.hud-figures {
  display: grid;
  grid-template-columns: repeat(4, auto);
  justify-content: space-between;
  gap: 8px;
}

.hud .figure-label {
  font-size: 11px;
}

.hud .figure-value {
  font-size: 15px;
}

.hud-stats {
  margin-top: 2px;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.hud-note {
  font-size: 13px;
  color: var(--muted);
}

/* The time of day, first on the line of the day's figures. */
.hud-time {
  font-weight: 700;
}

/* At night, or with nothing left to do: go home to sleep. */
.hud-note.hud-bedtime {
  font-weight: 600;
  color: var(--warn);
}

/* Where a tap from afar sent the character: the tap's answer, so it reads over the notes round it. */
.hud-note.hud-going {
  font-weight: 600;
  color: var(--text);
}

/* The day's skills on the left, the sound switch and the "?" on the right. */
.hud-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 2px;
}

.hud-line .hud-stats {
  margin-top: 0;
}

/* Each skill stays whole when the line wraps on a narrow phone. */
.hud-stats span {
  white-space: nowrap;
}

.hud-controls {
  display: flex;
  flex: none;
  gap: 6px;
  pointer-events: auto;
}

/* What the player owns, to get on, or what they ride and 내리기. Under the skills, in the top card. */
.hud-ride {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  pointer-events: auto;
}

.hud-riding {
  font-size: 13px;
  font-weight: 700;
  color: var(--accent);
}

.hud-ride-button {
  position: relative;
  min-height: 30px;
  padding: 2px 12px;
  font-size: 13px;
  font-weight: 700;
  color: var(--on-accent);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
}

.hud-ride-button::after {
  content: "";
  position: absolute;
  inset: -7px -2px;
}

/* Why a shared one could not be rented. */
.hud-ride-note {
  font-size: 13px;
  color: var(--warn);
}

.hud .sound-switch,
.guide-open {
  position: relative;
  min-height: 30px;
  font-size: 12px;
}

/* Small to look at, easier to hit: each tap area reaches a little past the button. */
.hud .sound-switch::after,
.guide-open::after {
  content: "";
  position: absolute;
  inset: -7px -2px;
}

.guide-open {
  width: 30px;
  padding: 0;
  font-weight: 700;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 50%;
}

/* The log gives up its lower lines before a talk is pushed off a small screen: the talk always stays whole. */
.over-town .log {
  min-height: 0;
  overflow: hidden;
  padding: 8px 12px;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
}

.over-town .log h2 {
  margin-bottom: 2px;
  font-size: 12px;
}

.over-town .log ul {
  font-size: 13px;
}

/* A talk with a place's person, as in a storybook: the person's face and name, their line, and the answers. */
.talk {
  margin-top: auto;
  padding: 12px 14px 14px;
  color: var(--talk-text);
  background: var(--talk-bg);
  border: 2px solid var(--talk-border);
  border-radius: 18px;
  box-shadow: 0 6px 18px rgba(59, 47, 37, 0.25);
  pointer-events: auto;
  /* Two fingers on the talk do nothing, so a pinch there never zooms the page. */
  touch-action: none;
}

.talk:focus {
  outline: none;
}

.talk:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* How to get about, at the bottom on the first day, where the talks open later. */
.town-hint {
  margin-top: auto;
  padding: 8px 12px;
  font-size: 13px;
  color: var(--text);
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

@media (prefers-reduced-motion: no-preference) {
  .talk {
    animation: talk-up 180ms ease-out;
  }
}

@keyframes talk-up {
  from {
    transform: translateY(16px);
    opacity: 0;
  }
}

.talk-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.talk-name {
  display: flex;
  flex-direction: column;
  line-height: 1.3;
}

.talk-name strong {
  font-size: 17px;
}

.talk-role {
  font-size: 13px;
  color: var(--talk-muted);
}

/* A face drawn with boxes, as the town is: hair over skin, two eyes, on the colour of the person's clothes. */
.face {
  display: grid;
  place-items: end center;
  flex: none;
  width: 44px;
  height: 44px;
  overflow: hidden;
  border: 2px solid var(--talk-border);
  border-radius: 12px;
}

.face-skin {
  position: relative;
  width: 30px;
  height: 30px;
  margin-bottom: 2px;
  border-radius: 6px;
}

.face-hair {
  position: absolute;
  inset: -2px -2px auto;
  height: 11px;
  border-radius: 6px 6px 2px 2px;
}

.face-eyes {
  position: absolute;
  top: 15px;
  left: 8px;
  width: 4px;
  height: 6px;
  background: #2a2220;
  border-radius: 2px;
  box-shadow: 10px 0 #2a2220;
}

.talk-line {
  min-height: 3em;
  margin: 10px 0 12px;
  font-size: 16px;
  line-height: 1.5;
  cursor: pointer;
}

.keywords {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.keyword {
  min-height: 44px;
  padding: 6px 12px;
  font-weight: 700;
  color: var(--talk-text);
  background: var(--keyword-bg);
  border: 1px solid var(--talk-border);
  border-radius: 999px;
}

.keyword.spend {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "name effect"
    "why why";
  align-items: center;
  column-gap: 12px;
  text-align: left;
  border-radius: 14px;
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

.keyword.spend .action-effect {
  color: inherit;
  opacity: 0.85;
}

/* At the bike shop, a button for each thing to buy, with its price, or why not. */
.keyword.buy {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "name effect"
    "why why";
  align-items: center;
  column-gap: 12px;
  text-align: left;
  border-radius: 14px;
}

.keyword.buy .action-effect {
  color: inherit;
}

.keyword.buy:disabled {
  color: var(--talk-muted);
  background: transparent;
  border-style: dashed;
}

.keyword.spend:disabled {
  color: var(--talk-muted);
  background: transparent;
  border-style: dashed;
  border-color: var(--talk-border);
}

.keyword.spend:disabled .action-effect {
  color: var(--talk-muted);
}

/*
 * Where to go on the SkyTrain, a bus, the water bus or a taxi: a button for each place, its fare beside it or why
 * not. A long list scrolls inside the card, so 그만 always stays on a small screen.
 */
.chooser .talk-line {
  min-height: 0;
  margin: 4px 0 10px;
  font-size: 14px;
  cursor: default;
}

.chooser-list {
  max-height: 34cqh;
  margin-bottom: 8px;
  overflow-y: auto;
  touch-action: pan-y;
}

.keyword.go {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "name effect"
    "why why";
  align-items: center;
  column-gap: 8px;
  text-align: left;
  border-radius: 14px;
}

.keyword.go .action-name,
.keyword.go .action-effect {
  white-space: nowrap;
}

.keyword.go .action-effect {
  color: inherit;
}

/* On a narrow phone, one place to a row, so no name or fare is broken across two lines, and the rows a little lower. */
@container (max-width: 359px) {
  .chooser-list {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .keyword.go {
    min-height: 40px;
  }
}

/* On a short screen, or a phone turned on its side, the list takes less of it, so the card leaves the small map be. */
@container (max-height: 640px) {
  .chooser-list {
    max-height: 18cqh;
  }
}

.chooser-empty {
  margin: 0 0 10px;
  font-size: 14px;
  color: var(--talk-muted);
}

.keyword.go .action-why {
  font-size: 12px;
}

.keyword.go:disabled {
  color: var(--talk-muted);
  background: transparent;
  border-style: dashed;
}

/* 택시 부르기, quieter than getting on what the player owns. */
.hud-ride-button.hud-taxi {
  color: var(--accent);
  background: var(--surface);
}

.ending-word {
  font-weight: 600;
  color: var(--accent);
}

/* The sound switch: a small pill that says what a tap does, filled while the sound is on. */
.sound-switch {
  min-height: 36px;
  padding: 2px 12px;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 999px;
}

.sound-switch.on {
  color: var(--on-accent);
  background: var(--accent);
}

.topbar .sound-switch {
  position: absolute;
  top: 10px;
  right: 16px;
}

/* The card on how to play, over the town from its "?". The town waits under a soft shade. On a short
   screen (a phone on its side, or large text) the card is never taller than the screen: it scrolls instead, and the
   shade can scroll too, with "safe" centring so nothing is pushed off the top. */
.guide {
  position: fixed;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  place-items: safe center;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: rgba(28, 29, 31, 0.35);
}

.guide-card {
  width: 100%;
  max-width: 400px;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 18px 18px 16px;
  color: var(--talk-text);
  background: var(--talk-bg);
  border: 2px solid var(--talk-border);
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(59, 47, 37, 0.3);
}

.guide-title {
  margin-bottom: 10px;
  font-size: 18px;
  font-weight: 700;
  color: var(--talk-text);
}

.guide-lines {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.guide-lines li {
  position: relative;
  padding-left: 1.1em;
}

.guide-lines li::before {
  content: "";
  position: absolute;
  top: 0.65em;
  left: 0.2em;
  width: 6px;
  height: 6px;
  background: var(--talk-border);
  border-radius: 50%;
}

.guide-goal {
  margin: 12px 0 14px;
  padding: 8px 12px;
  font-weight: 700;
  background: var(--keyword-bg);
  border-radius: 12px;
}

/* The map's credit, small at the card's foot and at the intro's, its licence's name a link. */
.guide-credit,
.intro-credit {
  margin-top: 12px;
  font-size: 11px;
  line-height: 1.4;
  opacity: 0.75;
}

.intro-credit {
  margin-top: 0;
  color: var(--muted);
}

.guide-credit a,
.intro-credit a {
  color: inherit;
  text-decoration: underline;
}

/* The Burnaby line sits right under the Vancouver one, as one credit. */
.guide-credit + .burnaby-credit,
.intro-credit + .burnaby-credit {
  margin-top: 2px;
}

@media (prefers-reduced-motion: no-preference) {
  .guide-card {
    animation: talk-up 180ms ease-out;
  }
}

/* The update news: a pill by the sound switch, in its look, and at the button screen's foot. */
.patch-open {
  position: relative;
  min-height: 36px;
  padding: 2px 12px;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--accent);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 999px;
}

.patch-foot {
  display: flex;
  justify-content: center;
  padding-top: 4px;
}

/* At the guide's foot, a link next to the map's credit. */
.patch-guide-foot {
  margin-top: 12px;
}

.patch-guide-foot + .guide-credit {
  margin-top: 4px;
}

.patch-link {
  position: relative;
  min-height: 32px;
  padding: 0 2px;
  font-size: 13px;
  font-weight: 700;
  color: var(--talk-text);
  background: none;
  border: none;
  border-radius: 6px;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* While there is news the player has not opened, a small dot on the button's corner. */
.patch-open.patch-news::after,
.patch-link.patch-news::after {
  content: "";
  position: absolute;
  top: -3px;
  right: -3px;
  width: 10px;
  height: 10px;
  background: var(--warn);
  border: 2px solid var(--bg);
  border-radius: 50%;
}

/* The link is small to look at; its tap area reaches past it, to 48 points tall. The dot keeps ::after. */
.patch-link::before {
  content: "";
  position: absolute;
  inset: -8px -6px;
}

.patch-link.patch-news::after {
  top: 4px;
  right: -12px;
  border-color: var(--talk-bg);
}

/* The update news over the page, over the guide too when opened from its foot. The list of updates scrolls inside
   the card, so its title and 닫기 stay in sight on a short or turned phone. */
.patch-cover {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  justify-content: safe center;
  overscroll-behavior: contain;
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right))
    max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
  background: rgba(28, 29, 31, 0.45);
}

.patch-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 440px;
  max-height: 100%;
  min-height: 0;
  padding: 16px 16px 14px;
  color: var(--talk-text);
  background: var(--talk-bg);
  border: 2px solid var(--talk-border);
  border-radius: 18px;
  box-shadow: 0 8px 24px rgba(59, 47, 37, 0.3);
}

.patch-card:focus {
  outline: none;
}

.patch-title {
  flex: none;
  margin-bottom: 6px;
  font-size: 18px;
  font-weight: 700;
  color: var(--talk-text);
}

.patch-list {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0 -6px;
  padding: 0 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.patch-entry {
  padding: 4px 0 8px;
  border-top: 1px solid color-mix(in srgb, var(--talk-border) 50%, transparent);
}

.patch-entry:first-child {
  border-top: none;
}

/* A version's line: its number and date, then its headline; a tap opens or folds what changed. */
.patch-summary {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 8px;
  padding: 6px 28px 6px 0;
  list-style: none;
  cursor: pointer;
  border-radius: 8px;
}

.patch-summary::-webkit-details-marker {
  display: none;
}

.patch-summary::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 8px;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--talk-muted);
  border-bottom: 2px solid var(--talk-muted);
  transform: translateY(-75%) rotate(45deg);
}

.patch-entry[open] > .patch-summary::after {
  transform: translateY(-25%) rotate(-135deg);
}

.patch-summary:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 0;
}

.patch-version {
  font-weight: 800;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.patch-date {
  font-size: 13px;
  color: var(--talk-muted);
}

.patch-headline {
  flex-basis: 100%;
  font-weight: 700;
}

.patch-section {
  display: inline-block;
  margin: 8px 0 4px;
  padding: 1px 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--talk-text);
  background: var(--keyword-bg);
  border: 1px solid var(--talk-border);
  border-radius: 999px;
}

.patch-lines {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 15px;
  line-height: 1.45;
}

.patch-lines li {
  position: relative;
  padding-left: 1.1em;
}

.patch-lines li::before {
  content: "";
  position: absolute;
  top: 0.6em;
  left: 0.2em;
  width: 5px;
  height: 5px;
  background: var(--talk-border);
  border-radius: 50%;
}

.patch-close {
  flex: none;
  margin-top: 12px;
}

@media (prefers-reduced-motion: no-preference) {
  .patch-card {
    animation: talk-up 180ms ease-out;
  }
}

/* Read by a screen reader, not shown. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
