:root {
  --bg: #f4f6f9;
  --fg: #2c3542;
  --muted: #7b8698;
  --line: #cdd5e0;
  --btn-bg: #55637a;
  --btn-fg: #f2f5f9;
  --sheet-bg: #ffffff;

  /* 지도. 땅 → 길 → 건물 순으로 밝기를 낮춰, 색을 보지 않고 명암만으로도 층이
     갈리게 했다. 노선과 경고색만 채도를 가진다. */
  --ground: #dfe5ee;
  --road: #ffffff;
  --alley: #eff2f7;
  --road-edge: #ccd5e2;
  --water: #a8c6e2;
  --hill: #cbd7c4;
  --hill-2: #bdcbb5;
  /* 건물 색은 종류가 아니라 층수가 정한다. 자란 정도가 화면에서 읽혀야 한다. */
  --lv1: #c2cde0;
  --lv2: #aab8d0;
  --lv3: #92a2c0;
  --lv4: #7789ab;
  --metro: #3f6fd8;
  --metro-soft: #8fa9e4;
  --reach: #cfdcf3;
  /* 노선 색. 다섯을 돌려 쓴다 — 여섯 번째 노선까지 가는 판이 아직 없고, 색이
     늘수록 서로 구별되지 않는다. */
  --line1: #3f6fd8;
  --line2: #c0453f;
  --line3: #2f8f5b;
  --line4: #b5761f;
  --line5: #7a4fb5;
  --under: #d9534f;
  --slow: #c9862b;
  --demand: #d1892b;
  /* 밀린 곳의 색. 못 짓는다는 뜻의 --under와 갈라 둔다 — 하나는 "안 된다"이고
     이쪽은 "되는데 모자란다"라, 같은 붉은색이면 둘이 섞여 읽힌다. */
  --jam: #e0553c;
  --on-jam: #ffffff;
  --station-fill: #ffffff;
  --station-ring: #3c465a;
  /* 노선이 비싼 땅을 지나는 토막에 덧칠하는 색. 그 땅의 색을 진하게 한 것이라
     "여기가 강 밑이구나"가 지도와 이어져 읽힌다. */
  --cut-building: #d9534f;
  --cut-hill: #6f8a5f;
  --cut-water: #1f6fb0;

  --pad-x: clamp(10px, 4vmin, 28px);
  --app-max: 440px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #171b21;
    --fg: #dfe5ee;
    --muted: #8892a3;
    --line: #333c49;
    --btn-bg: #4a5568;
    --sheet-bg: #212832;

    --ground: #171c24;
    --road: #3f4a59;
    --alley: #2f3845;
    --road-edge: #2c3441;
    --water: #1d3247;
    --hill: #26302a;
    --hill-2: #2d3931;
    --lv1: #2d3645;
    --lv2: #3b4757;
    --lv3: #4b586a;
    --lv4: #5d6b7e;
    --metro: #6f9bf0;
    --metro-soft: #3a4c70;
    --reach: #26344b;
    --line1: #6f9bf0;
    --line2: #e07a74;
    --line3: #57b485;
    --line4: #d8a13a;
    --line5: #a487e0;
    --under: #e4736f;
    --slow: #d8a13a;
    --demand: #e0a84a;
    --jam: #ef6a4f;
    --on-jam: #1a0f0c;
    --station-fill: #12161c;
    --station-ring: #c3cbd8;
    --cut-building: #e4736f;
    --cut-hill: #8fb07a;
    --cut-water: #5aa9e6;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }

/* display를 지정한 클래스는 `[hidden]`의 display:none을 이긴다. 판을 확정한 뒤에도
   지난 구간의 숫자가 그대로 떠 있던 것이 이 때문이었다. */
[hidden] { display: none !important; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  display: flex;
  justify-content: center;
  padding: clamp(10px, 3vmin, 24px) var(--pad-x);
}

.app {
  width: min(100%, var(--app-max));
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 2vmin, 14px);
}

/* 헤더 배치는 모든 게임이 같다 — 왼쪽 위에 목록과 도움말, 가운데 이름, 오른쪽에 소리. */
.title-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
}

.title-row h1 { text-align: center; }
.title-row .head-nav { justify-self: start; }
.head-nav { display: flex; align-items: center; gap: 14px; }
.title-row .head-actions { justify-self: end; }

h1 {
  margin: 0;
  font-size: clamp(22px, 5.6vmin, 32px);
  font-weight: 800;
  letter-spacing: -0.02em;
}

.head-actions { display: flex; align-items: baseline; gap: 14px; }

.toggle {
  border: 0; background: none; padding: 0;
  color: inherit; font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; opacity: 0.6;
}
.toggle:hover { opacity: 1; }
.toggle.sound { font-size: 12px; }
.toggle.sound[aria-pressed="false"] { opacity: 0.38; text-decoration: line-through; }

.back {
  color: inherit; opacity: 0.6; text-decoration: none;
  font-size: 14px; font-weight: 600;
}
.back:hover { opacity: 1; }

.picker-row { display: flex; align-items: center; gap: 10px; }
.picker { display: flex; gap: 4px; }

.pick {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
}

.pick[aria-pressed="true"] {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}

.budget, .clock { font-size: 12px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.budget b { color: var(--fg); }
.clock { margin-inline-start: auto; }
/* 시계가 멈춰 있다는 것을 숫자 자체로 알린다. 일시정지 단추만으로는 판을 보다가
   "왜 안 움직이지"를 묻게 된다 — 편집 중에도 시간은 멈춘다. */
.clock.held { opacity: 0.4; }
.picker-row { flex-wrap: wrap; }
.picker-row .toggle { margin-inline-start: 0; }

.flow {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 14px;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.flow > span { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.flow b { color: var(--fg); font-weight: 700; }
.dot.caught { background: var(--metro); }
.dot.waiting { background: var(--demand); }
.dot.missed { background: var(--jam); }
/* 못 탄 사람은 "잘 돌고 있다"의 반대라 색으로도 갈라 둔다. 이 줄에서 유일하게
   눈에 띄어야 하는 숫자다. */
.flow .jam b { color: var(--jam); }

.btn.warn { background: var(--under); }

/* 도구 고르개는 판 바로 아래에 둔다. 판 안은 touch-action: none이라 click이 나지
   않으므로 단추를 그 안에 둘 수 없고, 헤더까지 올리면 지금 무슨 모드인지가 눈이
   가는 곳에서 멀어진다. */
.modes, .tools { justify-content: center; flex-wrap: wrap; }
.modes .pick { padding: 6px 16px; font-size: 13px; }
.tools .pick { font-size: 12px; }

/* 노선 관리. 지도를 보면서 만져야 해서 시트가 아니라 판 아래 패널이다. */
.linepanel {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 9px 10px 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.linepanel .picker { flex-wrap: wrap; }
.linerow, .patternrow { display: flex; align-items: center; gap: 6px; }
.linerow .picker { flex: 1; min-width: 0; }
.pick.drop { border-color: var(--under); color: var(--under); }
.patternrow .picker { flex: 1; min-width: 0; }
.pick.add { border-style: dashed; }
.pick:disabled { opacity: 0.35; cursor: default; }

/* 정차역 줄. 역이 많아지면 옆으로 넘긴다 — 줄바꿈으로 두면 노선의 순서가
   끊겨 보여 "이 역 다음에 저 역"이라는 것이 읽히지 않는다. */
.stops {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 2px;
}

.stop {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: 2px solid var(--line);
  background: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.stop[aria-pressed="true"] {
  background: var(--metro);
  border-color: var(--metro);
  color: var(--btn-fg);
}

.stop:disabled { cursor: default; opacity: 0.85; }

.trainrow { display: flex; align-items: center; gap: 7px; }
/* 이름과 숫자는 접히면 안 된다 — "정방향"이 두 줄로 갈리면 줄이 세 줄이 되고,
   "(선로 한계)"가 갈리면 그 말이 눈에 안 들어온다. 좁으면 접히는 것은 줄 전체다. */
.trainrow { flex-wrap: wrap; row-gap: 2px; }
.trainlabel {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}
.trainrow .plan, .trainrow .crowd { white-space: nowrap; }
.trainrow b { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; min-width: 1.2em; text-align: center; }

.step {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: none;
  color: inherit;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.step:disabled { opacity: 0.3; cursor: default; }
.step .ico { width: 15px; height: 15px; display: block; }

.crowd {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.crowd.over { color: var(--under); }

.plan {
  margin-inline-start: auto;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.pick .ico { width: 13px; height: 13px; vertical-align: -2px; }
.picker-row .toggle { margin-inline-start: auto; }

/* 지도는 화면 한 장에 다 들어온다. 확대·팬이 없는 것은 게으름이 아니라 결정이다 —
   shared/base.js가 손가락 둘 이상의 touchmove를 문서 전체에서 취소하므로, 자체
   핀치 줌을 짜도 이벤트가 오지 않는다. 자세한 사정은 CLAUDE.md에 있다. */
.map-wrap {
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  background: var(--ground);
}

.map {
  display: block;
  width: 100%;
  /* 한 화면에 보이는 창(citygen.js의 VIEW)과 같은 비율로 못 박아 여백(레터박스)이
     생기지 않게 한다. 도시 전체가 아니라 창의 비율이다. 여백이 생기면
     손가락 좌표를 지도 좌표로 옮기는 계산이 한 겹 더 필요해진다. */
  aspect-ratio: 2400 / 2700;
  /* 끌어서 조작하는 판이라 none. 그래서 이 안에는 click으로 도는 조작을 두지 않는다 —
     확정·취소 단추가 판 밖에 있는 이유가 이것이다. */
  touch-action: none;
}

.status {
  margin: 0;
  min-height: 1.3em;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  text-align: center;
}
.status.warn { color: var(--under); }

.readout {
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.stats { margin: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
.stats div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.stats dt { font-size: 11px; color: var(--muted); font-weight: 600; }
.stats dd {
  margin: 0;
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* 땅의 갈래를 길이 비율 그대로 한 줄에 눕힌다. 숫자 셋을 읽는 것보다 빠르다. */
.mix { display: flex; height: 7px; border-radius: 999px; overflow: hidden; background: var(--line); }
.mix span { display: block; min-width: 0; }
.mix-road { background: var(--metro-soft); }
.mix-empty { background: var(--muted); }
.mix-building { background: var(--cut-building); }
.mix-hill { background: var(--cut-hill); }
.mix-water { background: var(--cut-water); }

.mix-legend {
  margin: 0;
  display: flex;
  gap: 5px 12px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex-wrap: wrap;
}
.mix-legend span { display: inline-flex; align-items: center; gap: 4px; }
.mix-legend b { color: var(--fg); font-weight: 700; }
.dot { width: 7px; height: 7px; border-radius: 2px; display: inline-block; }
.dot.road { background: var(--metro-soft); }
.dot.empty { background: var(--muted); }
.dot.building { background: var(--cut-building); }
.dot.hill { background: var(--cut-hill); }
.dot.water { background: var(--cut-water); }

.actions { display: flex; gap: 8px; }

.btn {
  flex: 1;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 0;
  border-radius: 8px;
  padding: 11px 16px;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
}
.btn.ghost { background: none; color: var(--fg); border: 1px solid var(--line); flex: 0 1 auto; }
.btn:disabled { opacity: 0.4; cursor: default; }

.sheet-title { margin: 0; font-size: 19px; font-weight: 800; }
.sheet-note { margin: 0; font-size: 14px; color: var(--muted); }
.sheet-actions { display: flex; gap: 8px; }

.help-list {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 14px;
  line-height: 1.55;
}

/* 열차 패널. 판 위의 열차를 눌렀을 때만 뜬다. */
.trainhead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.trainhead b { font-size: 14px; }
.trainhead span { font-size: 12px; color: var(--muted); }
.trainhead .drop { margin-left: auto; }

/* 재차 인원을 막대로도 보여 준다 — 숫자만으로는 "얼마나 찼나"가 안 잡힌다. */
.fillbar {
  height: 12px;
  border-radius: 999px;
  background: var(--reach);
  overflow: hidden;
}
.fillbar i { display: block; height: 100%; background: var(--metro); transition: width 0.2s linear; }
.fillbar.over i { background: var(--jam); }
