/* style.css — dark translucent game-HUD look */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
  background: #000;
  font-family: system-ui, "Hiragino Sans", "Noto Sans JP", sans-serif;
  color: #f1f1f1;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* ---------------------------------------------------------------- desktop/touch toggles */
.touch-only { display: none; }
body.touch .desktop-only { display: none; }
body.touch .touch-only { display: block; }

#game-canvas {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh; /* fallback for browsers without dvh support */
  height: 100dvh; /* §fix: tracks the real visible viewport through browser-chrome/fullscreen/orientation changes (main.js mirrors this via renderer.setSize) */
  display: block;
  cursor: crosshair;
}
/* §3: starving (hunger at 0) — a subtle grey/desaturated look on the canvas. */
body.starving #game-canvas {
  filter: saturate(0.45) brightness(0.9);
}
/* §co-op 段階2: ダウン中/観戦中 — a heavier grey desaturation than starving,
   toggled by hud.js's showDown()/showDead()/hideDown(). */
body.downed #game-canvas {
  filter: saturate(0.2) brightness(0.7);
}

.hidden { display: none !important; }

/* ---------------------------------------------------------------- icons (iOS Safari robustness) */
/* Every inline SVG icon carries this class: no width/height ATTRIBUTES on the
   <svg> itself (Safari can fall back to an odd intrinsic box, or clip inside
   a fixed-size wrapper, when an attribute and a differently-sized wrapper
   disagree) — sizing is CSS-only. 1.1em is the default for an icon sitting
   inline with text; anything living in a fixed-size slot (hotbar, market
   cards, HUD rows, touch buttons, …) gets an explicit px override below,
   scoped to its container so it always wins over this default regardless of
   source order. */
.icon {
  width: 1.1em;
  height: 1.1em;
  display: inline-block;
  vertical-align: -0.15em;
  flex: none;
}

/* ---------------------------------------------------------------- panels */
/* Panels (translucent navy card + subtle border/inner top highlight) are
   reserved for surfaces that group real content: the hotbar, the market
   modal, the fight gauge, the title panel, and the pause/game-over/clear
   overlays (each rolls its own version of this look below, scoped to its own
   selector). Everything else in the HUD — the status row, mission line,
   HP/hunger, ammo, enemy counter — sits directly on the 3D scene as plain
   text/bars with a text-shadow for legibility instead of a background card;
   see the "unboxed HUD text" rule further down. */

/* ---------------------------------------------------------------- loading */
#loading-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(ellipse at center, #16324a 0%, #060a12 100%);
  z-index: 60;
}
.loading-panel {
  width: min(360px, 80vw);
  text-align: center;
}
.loading-title {
  font-size: 18px;
  font-weight: 700;
  margin-bottom: 18px;
  color: #f1f1f1;
  letter-spacing: 0.05em;
}
.loading-bar-outer {
  width: 100%;
  height: 10px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 999px;
  overflow: hidden;
}
#loading-bar-inner {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #ffb84d, #ff7a59);
  transition: width 0.2s ease;
}
#loading-percent {
  margin-top: 10px;
  font-size: 13px;
  color: #9fb0c9;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- title */
/* §2: transparent except the glass panel — the 3D lake/dock/stall scene
   (driven by main.js's animate() while !state.gameStarted) shows through. */
#title-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  z-index: 50;
}
.title-panel {
  max-width: 460px;
  width: 90%;
  max-height: 92vh;
  overflow-y: auto;
  padding: 34px 38px;
  background: rgba(12, 22, 40, 0.74);
  border: 1px solid rgba(160, 200, 255, 0.18);
  border-radius: 16px;
  text-align: center;
  backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 24px 70px rgba(0, 0, 0, 0.55);
}
body.touch .title-panel { backdrop-filter: none; }
.title-heading {
  margin: 0 0 10px;
  font-size: 27px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: #e8f0ff;
  text-shadow: 0 0 24px rgba(95, 211, 255, 0.35), 0 2px 8px rgba(0, 0, 0, 0.6);
}
/* §rename: the game's former title, kept on as a tagline directly under the
   new h1 — smaller than the heading but still prominent (accent color),
   sitting above the plain descriptive .subtitle line. */
.title-tagline {
  margin: 0 0 10px;
  color: #ffb84d;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.subtitle {
  margin: 0 0 18px;
  color: #9fb3cc;
  font-size: 13px;
  line-height: 1.6;
}

.title-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
  color: #5fd3ff;
}
.divider-line {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(160, 200, 255, 0.35), transparent);
}
.divider-wave { flex: none; opacity: 0.8; width: 28px; height: 12px; }

.title-flow {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 10px;
  margin-bottom: 18px;
}
.flow-card {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.flow-vignette {
  width: 100%;
  height: auto;
  border-radius: 10px;
  border: 1px solid rgba(160, 200, 255, 0.18);
}
.flow-label {
  font-weight: 700;
  font-size: 13px;
  color: #e8f0ff;
}
.flow-label-sub {
  display: block;
  font-weight: 500;
  font-size: 10.5px;
  color: #9fb3cc;
  margin-top: 1px;
}

.title-controls {
  text-align: left;
  margin-bottom: 20px;
}
.title-controls summary {
  cursor: pointer;
  list-style: none;
  font-size: 12.5px;
  font-weight: 700;
  color: #9fb3cc;
  padding: 6px 2px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.title-controls summary::-webkit-details-marker { display: none; }
.title-controls summary::before {
  content: '';
  width: 6px;
  height: 6px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
  transition: transform 0.15s ease;
}
.title-controls[open] summary::before { transform: rotate(45deg); }
.title-controls ul {
  margin: 6px 0 0;
  padding-left: 18px;
  font-size: 12.5px;
  line-height: 1.85;
  color: #d8e0ec;
  text-align: left;
}

#title-start-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 14px 44px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
  cursor: pointer;
  box-shadow: 0 10px 28px rgba(255, 154, 60, 0.45);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
#title-start-btn:hover { transform: translateY(-2px); box-shadow: 0 14px 34px rgba(255, 154, 60, 0.55); }
#title-start-btn:active { transform: translateY(0); }
#title-start-btn svg { width: 16px; height: 16px; }

/* §save: "つづきから" — same shape/size family as #title-start-btn but a
   secondary (outline, no fill) treatment so はじめる stays the clear default
   action. Shown only when save.hasSave() (see hud.setContinueVisible()). */
#title-continue-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 11px 36px;
  margin-top: 10px;
  border: 1px solid rgba(255, 184, 77, 0.5);
  border-radius: 999px;
  background: transparent;
  color: #ffd27a;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
#title-continue-btn:hover { transform: translateY(-2px); background: rgba(255, 184, 77, 0.12); border-color: rgba(255, 184, 77, 0.8); }
#title-continue-btn:active { transform: translateY(0); }
#title-continue-btn svg { width: 14px; height: 14px; }

/* ---------------------------------------------------------------- 協力プレイ (src/lobby.js) */
/* Same secondary-button family as #title-continue-btn (outline, no fill) but
   a cool accent instead of the warm gold — reads as "a different kind of
   action" from はじめる/つづきから while still belonging to the same panel. */
#title-coop-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 11px 36px;
  margin-top: 10px;
  border: 1px solid rgba(95, 211, 255, 0.4);
  border-radius: 999px;
  background: transparent;
  color: #5fd3ff;
  cursor: pointer;
  transition: transform 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
#title-coop-btn:hover { transform: translateY(-2px); background: rgba(95, 211, 255, 0.12); border-color: rgba(95, 211, 255, 0.75); }
#title-coop-btn:active { transform: translateY(0); }
#title-coop-btn svg { width: 14px; height: 14px; }

/* .title-panel.coop-open hides every OTHER direct child (heading/tagline/
   flow cards/start buttons, and anything install.js/settings.js insert
   dynamically as siblings of #title-start-btn) so #coop-panel reads as a
   full takeover of the panel without needing its own absolute positioning
   or touching any other module's markup/classes. */
.title-panel.coop-open > *:not(#coop-panel) { display: none; }

#coop-panel { text-align: left; }
#coop-back-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 14px;
  padding: 4px 2px;
  border: none;
  background: transparent;
  color: #9fb3cc;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
#coop-back-btn:hover { color: #e8f0ff; }
#coop-back-btn svg { width: 15px; height: 15px; }

#coop-heading {
  margin: 0 0 6px;
  font-size: 19px;
  font-weight: 800;
  color: #e8f0ff;
}
#coop-intro {
  margin: 0 0 16px;
  font-size: 12.5px;
  line-height: 1.6;
  color: #9fb3cc;
}

.coop-field { margin-bottom: 16px; }
.coop-field label {
  display: block;
  margin-bottom: 6px;
  font-size: 12px;
  font-weight: 700;
  color: #9fb3cc;
}
#coop-name-input,
#coop-code-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 14px;
  border: 1px solid rgba(160, 200, 255, 0.25);
  border-radius: 10px;
  background: rgba(6, 12, 22, 0.55);
  color: #e8f0ff;
  font-size: 14px;
  font-family: inherit;
}
#coop-name-input:focus,
#coop-code-input:focus {
  outline: none;
  border-color: rgba(95, 211, 255, 0.7);
}
#coop-code-input {
  text-transform: uppercase;
  letter-spacing: 0.2em;
  text-align: center;
  font-weight: 700;
}

#coop-choice-row { display: flex; flex-direction: column; gap: 12px; margin-bottom: 4px; }
#coop-create-btn {
  padding: 12px 20px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}
#coop-join-group { display: flex; gap: 8px; }
#coop-join-group #coop-code-input { flex: 1; min-width: 0; }
#coop-join-btn {
  flex: none;
  padding: 10px 20px;
  border: 1px solid rgba(95, 211, 255, 0.5);
  border-radius: 999px;
  background: rgba(95, 211, 255, 0.14);
  color: #e8f0ff;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
}
#coop-create-btn:disabled,
#coop-join-btn:disabled { opacity: 0.5; cursor: default; }

#coop-status {
  min-height: 1.4em;
  margin-top: 12px;
  font-size: 12.5px;
  font-weight: 600;
  color: #ffd27a;
}

#coop-result { text-align: center; }
#coop-code-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 4px 0 16px;
  padding: 16px;
  border: 1px solid rgba(160, 200, 255, 0.2);
  border-radius: 12px;
  background: rgba(6, 12, 22, 0.5);
}
#coop-code-label { font-size: 12px; color: #9fb3cc; font-weight: 700; }
#coop-code-value {
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 0.28em;
  color: #5fd3ff;
  text-shadow: 0 0 20px rgba(95, 211, 255, 0.4);
}
#coop-share-row { display: flex; gap: 8px; justify-content: center; margin-bottom: 12px; }
#coop-copy-btn,
#coop-share-btn {
  padding: 9px 18px;
  border: 1px solid rgba(160, 200, 255, 0.28);
  border-radius: 999px;
  background: rgba(95, 211, 255, 0.14);
  color: #e8f0ff;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
#coop-stage-note {
  margin: 0 0 12px;
  font-size: 11px;
  color: #7f93ad;
}
#coop-players-preview {
  min-height: 1.2em;
  margin-bottom: 16px;
  font-size: 12px;
  color: #d8e0ec;
}
#coop-start-row { display: flex; flex-direction: column; gap: 10px; }
#coop-start-btn {
  padding: 12px 20px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}
#coop-continue-btn {
  padding: 10px 20px;
  border: 1px solid rgba(255, 184, 77, 0.5);
  border-radius: 999px;
  background: transparent;
  color: #ffd27a;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
}

/* ---------------------------------------------------------------- PWA install prompt (src/install.js) */
/* Sits directly under #title-start-btn, inside .title-panel — title-screen
   only, per install.js's own MutationObserver on #title-screen's `hidden`
   class. Namespaced under .install-tip-* so it can't collide with anything
   else in the title panel. */
.install-tip {
  position: relative;
  margin-top: 16px;
  padding: 14px 26px 12px 16px;
  background: rgba(20, 34, 56, 0.65);
  border: 1px solid rgba(160, 200, 255, 0.18);
  border-radius: 12px;
  text-align: left;
}
.install-tip-close {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: #9fb3cc;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.install-tip-close:hover { color: #e8f0ff; background: rgba(255, 255, 255, 0.1); }
.install-tip-heading {
  margin: 0 20px 8px 0;
  font-size: 13px;
  font-weight: 700;
  color: #e8f0ff;
}
.install-tip-step {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
  font-size: 12.5px;
  color: #d8e0ec;
  line-height: 1.4;
}
.install-tip-icon {
  flex: none;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: rgba(95, 211, 255, 0.14);
  color: #5fd3ff;
}
.install-tip-icon .icon { width: 14px; height: 14px; }
.install-tip-note {
  margin: 6px 0 0;
  font-size: 11px;
  color: #7f93ad;
}
.install-tip-btn {
  display: block;
  width: 100%;
  margin-top: 16px;
  padding: 12px 20px;
  border: 1px solid rgba(160, 200, 255, 0.28);
  border-radius: 999px;
  background: rgba(95, 211, 255, 0.14);
  color: #e8f0ff;
  font-size: 13.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.15s ease;
}
.install-tip-btn:hover { background: rgba(95, 211, 255, 0.22); transform: translateY(-1px); }
.install-tip-btn:active { transform: translateY(0); }

/* ---------------------------------------------------------------- HUD */
#hud {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  font-variant-numeric: tabular-nums;
}

/* §1: one compact panel row — phase icon, day, time, phase pill, coin, money —
   then the mission card underneath (see #mission-panel below). */
#hud-topleft {
  position: absolute;
  top: 16px;
  left: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 300px;
}
/* §restyle: no background card — plain text/icons directly on the scene,
   legible via text-shadow (see the "unboxed HUD text" rule below) instead of
   a translucent panel. The phase pill (#hud-phase) keeps its own small solid
   badge since it's a status indicator, not a card. */
#hud-status-panel {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
}
/* §save: tiny fading "セーブしました" — anchored just to the right of the
   status row (money/time), out of flex flow so it never shifts layout,
   deliberately not part of the #toast-container stack (see hud.js). */
#save-indicator {
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: 12px;
  transform: translateY(-50%);
  white-space: nowrap;
  font-size: 11px;
  font-weight: 700;
  color: #9fe6b8;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.5s ease;
}
#save-indicator.show { opacity: 1; transition: opacity 0.2s ease; }
.hud-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #ffd27a;
  flex: none;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .75)) drop-shadow(0 0 4px rgba(0, 0, 0, .45));
}
.hud-icon svg { width: 14px; height: 14px; }
.hud-coin-icon { color: #ffd27a; }
#hud-day {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #9fb3cc;
}
.hud-status-dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(159, 179, 204, 0.6);
  flex: none;
}
#hud-time {
  font-size: 18px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #e8f0ff;
  line-height: 1;
}
#hud-phase {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 999px;
  color: #10203a;
  min-width: 24px;
  text-align: center;
  overflow: visible;
}
#hud-phase.phase-morning { background: #ffb84d; }
#hud-phase.phase-day { background: #7cc4ff; }
#hud-phase.phase-night { background: #9d8dff; }
#hud-money {
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #ffd27a;
}

/* §restyle: legible text-shadow for every HUD element that no longer sits on
   a background card — bright sky and dark night both keep readable contrast. */
#hud-day, #hud-time, #hud-money,
#mission-title, #mission-progress,
.hud-bar-text,
#ammo-text,
#hud-enemy-counter,
#prompt {
  text-shadow: 0 1px 2px rgba(0, 0, 0, .75), 0 0 6px rgba(0, 0, 0, .45);
}

/* §3(restyle)/§1: "敵 N" — plain text + skull icon, no pill. Sits under the
   touch pause button (top-right corner) so the two never collide; on desktop
   (no pause button) it simply sits at the corner. */
#hud-enemy-counter {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  font-size: 13px;
  color: #ffbdbd;
  pointer-events: auto;
}
.enemy-skull-icon {
  color: #ff6a6a;
  flex: none;
  display: inline-flex;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .75)) drop-shadow(0 0 4px rgba(0, 0, 0, .45));
}
.enemy-skull-icon svg { width: 12px; height: 12px; }
body.touch #hud-enemy-counter {
  top: calc(60px + env(safe-area-inset-top));
  right: calc(16px + env(safe-area-inset-right));
}

/* §co-op(段階1): "● 3人 — ホスト: A, B, C", sitting just under the enemy
   counter/touch-pause-button corner (see src/lobby.js's
   refreshInGamePlayersList()) — hidden whenever net isn't connected. */
#coop-players-hud {
  position: absolute;
  top: 40px;
  right: 16px;
  max-width: 260px;
  font-size: 11.5px;
  font-weight: 600;
  color: #cfe6ff;
  text-align: right;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .75), 0 0 6px rgba(0, 0, 0, .45);
  pointer-events: none;
}
/* §fix: verified via getBoundingClientRect() that the top-right corner is
   fully booked on touch (enemy counter, then #give-touch-btn's slot right
   below it) — this text summary moves to the left column instead, paired
   with #coop-players-list below it (see that rule's own comment). */
body.touch #coop-players-hud {
  top: calc(84px + env(safe-area-inset-top));
  left: calc(16px + env(safe-area-inset-left));
  right: auto;
  max-width: 190px;
  text-align: left;
  /* §fix: with 4 players this line is long enough to wrap to 2-3 lines at
     this width, which pushed into #coop-players-list below it (verified via
     getBoundingClientRect()) — keep it a single deterministic-height line
     instead so the two never fight over the same space. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* §co-op 段階2 prep: rich players list (color dot / name / ホスト / ダウン
   tags) — see hud.js's setPlayersList(). A grouped-content panel (navy
   translucent, radius 8), unlike the plain-text #coop-players-hud above. */
#coop-players-list {
  position: absolute;
  top: 64px;
  right: 16px;
  max-width: 200px;
  margin: 0;
  padding: 6px;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: rgba(12, 22, 40, 0.7);
  border: 1px solid rgba(160, 200, 255, 0.16);
  border-radius: 8px;
  pointer-events: none;
}
/* §fix: the touch button cluster (give/market/eat/bandage/jump/primary) plus
   the enemy counter already book the top-right corner at 844x390 (see
   #coop-players-hud's own comment above, which moved here for the same
   reason) — this list sits in the same left column, stacked below it. */
body.touch #coop-players-list {
  top: calc(112px + env(safe-area-inset-top));
  left: calc(16px + env(safe-area-inset-left));
  right: auto;
  max-width: 190px;
}
.coop-player-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: #e8f0ff;
}
.coop-player-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
}
.coop-player-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.coop-player-self { color: #5fd3ff; }
.coop-player-tag {
  flex: none;
  font-size: 9.5px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
}
.coop-player-tag-host { background: rgba(95, 211, 255, 0.22); color: #5fd3ff; }
.coop-player-tag-down { background: rgba(255, 90, 90, 0.22); color: #ff9a9a; }

/* ---------------------------------------------------------------- §5 mission panel/banner/boss bar */
/* §restyle: no card — plain text with a 2px gold left accent line, sitting
   directly on the scene (see the "unboxed HUD text" rule above for the
   text-shadow). The progress bar keeps no track background of its own; only
   the thin 2px fill is visible once there's progress to show. */
#mission-panel {
  padding: 1px 0 1px 10px;
  border-left: 2px solid #ffd27a;
}
#mission-title {
  font-size: 13px;
  font-weight: 700;
  color: #e8f0ff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#mission-progress {
  margin-top: 2px;
  font-size: 11.5px;
  font-weight: 600;
  color: #9fb3cc;
  font-variant-numeric: tabular-nums;
}
#mission-bar-outer {
  margin-top: 6px;
  width: 100%;
  height: 2px;
  border-radius: 1px;
  overflow: hidden;
}
#mission-bar-inner {
  height: 100%;
  width: 0%;
  border-radius: 1px;
  background: linear-gradient(90deg, #ffb84d, #ffd27a);
  transition: width 0.3s ease;
}

/* §11.8: 依頼パネル — 旧ミッションパネルの後継、同じ位置/見た目(#mission-panel
   と同じ左の金の縦線+影付きテキスト)。3行固定、空文字の行は非表示、達成
   (先頭が✓)の行は緑寄りに少し暗く。see hud.js's setRequestPanel(). */
#request-panel {
  padding: 1px 0 1px 10px;
  border-left: 2px solid #ffd27a;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.request-line {
  font-size: 13px;
  font-weight: 700;
  color: #e8f0ff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .75), 0 0 6px rgba(0, 0, 0, .45);
}
.request-line:nth-child(3) { font-size: 11.5px; font-weight: 600; color: #9fb3cc; }
.request-line:empty { display: none; }
.request-line-done { color: #7fdba0 !important; opacity: 0.8; }

#mission-banner {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%) translateY(-140%);
  padding: 12px 26px;
  background: linear-gradient(90deg, rgba(60, 46, 10, 0.95), rgba(15, 18, 26, 0.95));
  border: 1px solid rgba(255, 226, 122, 0.5);
  border-radius: 8px;
  font-size: 16px;
  font-weight: 800;
  color: #ffe27a;
  white-space: nowrap;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
  transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2), opacity 0.35s ease;
  opacity: 0;
  pointer-events: none;
  z-index: 15;
}
#mission-banner.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}

#boss-bar {
  position: absolute;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  width: min(480px, 70vw);
  text-align: center;
}
#boss-bar-name {
  font-size: 13px;
  font-weight: 800;
  color: #ffbdbd;
  margin-bottom: 4px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}
#boss-bar-outer {
  width: 100%;
  height: 16px;
  background: rgba(15, 18, 26, 0.75);
  border: 1px solid rgba(255, 100, 100, 0.4);
  border-radius: 8px;
  overflow: hidden;
}
#boss-bar-inner {
  height: 100%;
  width: 100%;
  background: linear-gradient(90deg, #aa2222, #ff5f5f);
  transition: width 0.2s ease;
}

/* §restyle: no panel behind HP/hunger — just the icon + an 8px bar + text,
   directly on the scene. */
#hud-bottom-left {
  position: absolute;
  bottom: 20px;
  left: 16px;
  width: 210px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.hud-bar-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.hud-bar-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .75)) drop-shadow(0 0 4px rgba(0, 0, 0, .45));
}
.hud-bar-icon svg { width: 14px; height: 14px; }
.hud-icon-hp { color: #ff5a5a; }
.hud-icon-hunger { color: #ffb454; }
.hud-bar-outer {
  position: relative;
  flex: 1;
  height: 8px;
  background: rgba(6, 10, 20, 0.6);
  border-radius: 4px;
  overflow: hidden;
}
.hud-bar-inner {
  height: 100%;
  width: 100%;
  border-radius: 4px;
  transition: width 0.2s ease;
}
#hp-bar-inner { background: linear-gradient(90deg, #ff5a5a, #ff8a5a); }
#hunger-bar-inner { background: linear-gradient(90deg, #ffb84d, #ffd27a); }
.hud-bar-text {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  font-size: 9px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #e8f0ff;
  pointer-events: none;
}
#hunger-bar-outer.hunger-low #hunger-bar-inner {
  background: linear-gradient(90deg, #ff8a5a, #ff5a5a);
  animation: hunger-pulse 0.6s ease-in-out infinite alternate;
}
@keyframes hunger-pulse {
  from { opacity: 1; }
  to { opacity: 0.5; }
}

/* §restyle: no panel — small red pip icons (up to 6) + a count, sitting
   directly on the scene. Shown only while a gun is the selected slot
   (hud.updateAmmo toggles .hidden). Sits to the right of the hotbar on
   desktop; touch places it above the action buttons (see the touch media
   rules further down). */
#ammo-panel {
  position: absolute;
  bottom: 20px;
  right: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
#ammo-icons {
  display: flex;
  gap: 3px;
}
.ammo-pip {
  width: 6px;
  height: 14px;
  border-radius: 3px;
  background: #ff5a5a;
  box-shadow: 0 0 4px rgba(255, 90, 90, 0.5);
}
.ammo-pip.ammo-pip-empty {
  background: rgba(255, 255, 255, 0.12);
  box-shadow: none;
}
#ammo-text {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #e8f0ff;
  white-space: nowrap;
}

/* §restyle: ONE bar with a subtle background — the only "card" in the HUD's
   bottom row. Slots inside are square-ish (radius 6) and nearly transparent
   so they read as compartments of the one bar rather than separate cards. */
#hotbar {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  padding: 6px;
  background: rgba(12, 22, 40, 0.6);
  border: 1px solid rgba(160, 200, 255, 0.16);
  border-radius: 10px;
  backdrop-filter: blur(6px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
body.touch #hotbar { backdrop-filter: none; }
.hotbar-slot {
  width: 52px;
  height: 52px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(160, 200, 255, 0.14);
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  font-size: 10px;
  color: #e8f0ff;
  /* #hud has pointer-events:none; opt this element back in so tapping
     (touch) or clicking (mouse) a slot can select it. */
  pointer-events: auto;
  cursor: pointer;
}
body.touch .hotbar-slot { width: 46px; height: 46px; }
.hotbar-slot .slot-key {
  position: absolute;
  top: 2px;
  left: 5px;
  font-size: 9px;
  color: #8fa0b8;
}
/* §4: touch has dedicated buttons for everything a hotbar slot does, so the
   desktop keyboard-shortcut numbers (1-8, 9, 0) are just clutter there — hide
   them and let the label use the full slot. Desktop keeps the numbers. */
body.touch .hotbar-slot .slot-key { display: none; }
.hotbar-slot .slot-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #e8f0ff;
}
.hotbar-slot .slot-icon svg { width: 22px; height: 22px; }
.hotbar-slot .slot-label {
  font-weight: 700;
  font-size: 9px;
  text-align: center;
  padding: 0 2px;
  line-height: 1.2;
}
.hotbar-slot .slot-count {
  font-size: 9px;
  font-weight: 700;
  color: #ffd27a;
  font-variant-numeric: tabular-nums;
}
.hotbar-slot.active {
  border-color: #5fd3ff;
  box-shadow: 0 0 0 3px rgba(95, 211, 255, 0.25);
}
.hotbar-slot.disabled {
  opacity: 0.35;
}

/* §4: separator + the two consumable slots (9 食べる / 0 包帯) appended to
   the hotbar's right end. Clicking/tapping one uses the item immediately —
   it never becomes the "active" slot. */
.hotbar-separator {
  align-self: stretch;
  width: 2px;
  margin: 4px 2px;
  background: rgba(160, 200, 255, 0.14);
}
.hotbar-slot-consumable .slot-label {
  font-size: 9px;
}

#crosshair {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 18px;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
}

/* §restyle: plain text near the crosshair, no pill — legible via the shared
   text-shadow rule (see the "unboxed HUD text" group above). */
#prompt {
  position: absolute;
  top: calc(50% + 30px);
  left: 50%;
  transform: translateX(-50%);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  color: #f1f1f1;
}

/* ---------------------------------------------------------------- §8-5: hit marker */
#hitmarker {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  pointer-events: none;
  opacity: 0;
  z-index: 12;
}
#hitmarker::before,
#hitmarker::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 3px;
  background: #ffffff;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
}
#hitmarker::before { transform: translate(-50%, -50%) rotate(45deg); }
#hitmarker::after { transform: translate(-50%, -50%) rotate(-45deg); }
#hitmarker.kill::before,
#hitmarker.kill::after { background: #ff3b3b; }
#hitmarker.show { animation: hitmarker-pop 0.12s ease-out; }
@keyframes hitmarker-pop {
  0% { opacity: 1; transform: scale(0.6); }
  40% { opacity: 1; transform: scale(1.2); }
  100% { opacity: 0; transform: scale(1); }
}

/* ---------------------------------------------------------------- §8-5: floating damage numbers */
#dmg-number-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 16;
  overflow: hidden;
}
.dmg-number {
  position: absolute;
  font-weight: 800;
  font-size: 16px;
  color: #ff6a5a;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
  opacity: 0;
  will-change: transform, opacity;
  transition: top 0.05s linear, left 0.05s linear;
}
.dmg-number-big {
  font-size: 24px;
  color: #ffe27a;
}

/* ---------------------------------------------------------------- §8-5: player damage direction arcs */
.dmg-arc {
  position: fixed;
  pointer-events: none;
  z-index: 19;
  opacity: 0;
}
.dmg-arc-top,
.dmg-arc-bottom { left: 0; right: 0; height: 150px; }
.dmg-arc-left,
.dmg-arc-right { top: 0; bottom: 0; width: 150px; }
.dmg-arc-top {
  top: 0;
  background: radial-gradient(ellipse at 50% 0%, rgba(255, 40, 40, 0.6), rgba(255, 40, 40, 0) 70%);
}
.dmg-arc-bottom {
  bottom: 0;
  background: radial-gradient(ellipse at 50% 100%, rgba(255, 40, 40, 0.6), rgba(255, 40, 40, 0) 70%);
}
.dmg-arc-left {
  left: 0;
  background: radial-gradient(ellipse at 0% 50%, rgba(255, 40, 40, 0.6), rgba(255, 40, 40, 0) 70%);
}
.dmg-arc-right {
  right: 0;
  background: radial-gradient(ellipse at 100% 50%, rgba(255, 40, 40, 0.6), rgba(255, 40, 40, 0) 70%);
}
.dmg-arc.show { animation: dmg-arc-fade 0.6s ease-out; }
@keyframes dmg-arc-fade {
  0% { opacity: 1; }
  100% { opacity: 0; }
}

/* ---------------------------------------------------------------- §8-5: low HP pulsing vignette */
#lowhp-vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 19;
  opacity: 0;
  background: radial-gradient(ellipse at center, rgba(180, 0, 0, 0) 52%, rgba(180, 0, 0, 0.55) 100%);
}
#lowhp-vignette.active {
  animation: lowhp-pulse 1.4s ease-in-out infinite;
}
@keyframes lowhp-pulse {
  0%, 100% { opacity: 0.25; }
  50% { opacity: 0.65; }
}

/* ---------------------------------------------------------------- §8-6: phase banner */
#phase-banner {
  position: absolute;
  top: 32%;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 26px 0;
  pointer-events: none;
  z-index: 25;
  background: linear-gradient(90deg, rgba(6, 8, 14, 0) 0%, rgba(6, 8, 14, 0.78) 22%, rgba(6, 8, 14, 0.78) 78%, rgba(6, 8, 14, 0) 100%);
  opacity: 0;
  transform: translateY(-18px);
  transition: opacity 0.5s ease, transform 0.5s ease;
}
#phase-banner.show {
  opacity: 1;
  transform: translateY(0);
}
#phase-banner-text {
  font-size: 42px;
  font-weight: 800;
  letter-spacing: 0.1em;
  color: #ffe8c2;
  text-shadow: 0 4px 20px rgba(0, 0, 0, 0.75);
}

/* §3: a bold amber badge above the crosshair with a soft pulse (no more
   bare floating glyph). */
#bite-indicator {
  position: absolute;
  top: calc(50% - 78px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 40px;
  padding: 6px 16px;
  border-radius: 8px;
  background: linear-gradient(180deg, #ffb84d, #ff9a3c);
  border: 1px solid rgba(255, 255, 255, 0.35);
  text-align: center;
  font-size: 22px;
  font-weight: 900;
  color: #2a1404;
  box-shadow: 0 0 20px rgba(255, 154, 60, 0.7), 0 4px 14px rgba(0, 0, 0, 0.4);
  animation: bite-pop 0.5s ease infinite alternate;
}
@keyframes bite-pop {
  from { transform: translateX(-50%) scale(1); }
  to { transform: translateX(-50%) scale(1.1); }
}

/* ---------------------------------------------------------------- §2.2 fight mini-game */
/* §3: a tall rounded navy panel on the RIGHT edge, vertically centered —
   holds the vertical track+zone+fish, then a horizontal progress bar with a
   tiny caption, then the (existing, fishing.js-controlled) instruction label. */
#fight-ui {
  position: absolute;
  top: 50%;
  right: 28px;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 16px 14px;
  background: rgba(12, 22, 40, 0.74);
  border: 1px solid rgba(160, 200, 255, 0.14);
  border-radius: 8px;
  backdrop-filter: blur(6px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  pointer-events: none;
}
body.touch #fight-ui { backdrop-filter: none; }
#fight-track {
  position: relative;
  width: 44px;
  height: 220px;
  background: rgba(6, 10, 20, 0.55);
  border: 1px solid rgba(160, 200, 255, 0.25);
  border-radius: 10px;
}
#fight-zone {
  position: absolute;
  left: 2px;
  right: 2px;
  border-radius: 6px;
  background: rgba(125, 220, 107, 0.4);
  border: 1px solid rgba(125, 220, 107, 0.55);
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
#fight-zone.fight-zone-inside {
  background: rgba(125, 220, 107, 0.7);
  border-color: #c8ffb8;
  box-shadow: 0 0 12px rgba(125, 220, 107, 0.6);
}
#fight-fish {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  color: #fff;
  filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.7));
}
#fight-fish svg { width: 20px; height: 20px; }
#fight-track.fight-shake { animation: fight-track-shake 0.15s linear infinite; }
@keyframes fight-track-shake {
  0% { transform: translate(0, 0); }
  25% { transform: translate(-1.5px, 1px); }
  50% { transform: translate(1.5px, -1px); }
  75% { transform: translate(-1px, -1.5px); }
  100% { transform: translate(1px, 1.5px); }
}
#fight-progress-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
#fight-progress-caption {
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #9fb3cc;
}
#fight-progress-outer {
  width: 96px;
  height: 8px;
  background: rgba(6, 10, 20, 0.6);
  border: 1px solid rgba(160, 200, 255, 0.2);
  border-radius: 5px;
  overflow: hidden;
}
#fight-progress-inner {
  height: 100%;
  width: 30%;
  background: linear-gradient(90deg, #4fae63, #7ddc6b);
}
#fight-label {
  font-size: 11px;
  font-weight: 700;
  color: #e8f0ff;
  background: rgba(6, 10, 20, 0.6);
  padding: 3px 8px;
  border-radius: 6px;
}

/* ---------------------------------------------------------------- §2.3 catch presentation */
#catch-card {
  position: absolute;
  top: calc(50% - 160px);
  left: 50%;
  min-width: 240px;
  padding: 18px 30px;
  background: rgba(12, 22, 40, 0.9);
  border: 1px solid rgba(160, 200, 255, 0.22);
  border-radius: 8px;
  text-align: center;
  opacity: 0;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 18px 50px rgba(0, 0, 0, 0.5);
}
#catch-card.anim-in { animation: catch-card-in 0.35s ease-out forwards; }
#catch-card.anim-out { animation: catch-card-out 0.4s ease-in forwards; }
@keyframes catch-card-in {
  from { opacity: 0; transform: translateX(-50%) translateY(-28px) scale(0.9); }
  to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
@keyframes catch-card-out {
  from { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
  to { opacity: 0; transform: translateX(-50%) translateY(-16px) scale(0.92); }
}
#catch-card.tier-rare {
  border-color: #ffd27a;
  box-shadow: 0 0 24px rgba(255, 210, 122, 0.45), 0 18px 50px rgba(0, 0, 0, 0.5);
}
#catch-card.tier-legendary {
  border-color: #ffe27a;
  background: linear-gradient(160deg, rgba(60, 46, 10, 0.95), rgba(15, 18, 26, 0.92));
  box-shadow: 0 0 40px rgba(255, 226, 122, 0.6), 0 18px 50px rgba(0, 0, 0, 0.5);
}
/* Badge (NEW! / 自己ベスト) as a small pill in the top-right corner. */
.catch-card-badge {
  position: absolute;
  top: -10px;
  right: 14px;
  padding: 3px 11px;
  border-radius: 999px;
  background: linear-gradient(90deg, #ff9a3c, #ff5f5f);
  color: #250a02;
  font-weight: 800;
  font-size: 11px;
}
/* Hierarchy: name (24px) > size (18px) > price (gold) > stars. */
.catch-card-name { font-size: 24px; font-weight: 800; color: #e8f0ff; margin-bottom: 5px; }
.catch-card-size { font-size: 18px; font-weight: 600; color: #dfe6f0; margin-bottom: 4px; }
.catch-card-price { font-size: 16px; font-weight: 700; color: #ffd27a; margin-bottom: 6px; }
.catch-card-stars { font-size: 16px; color: #ffe27a; letter-spacing: 2px; }
.catch-card-sparkles { position: absolute; inset: 0; pointer-events: none; overflow: visible; }
.sparkle {
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 16px;
  color: #ffe27a;
  transform: translate(-50%, -50%);
  animation: sparkle-out 0.7s ease-out forwards;
  --dx: 0px;
  --dy: 0px;
}
@keyframes sparkle-out {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(0.4); }
  100% { opacity: 0; transform: translate(calc(-50% + var(--dx)), calc(-50% + var(--dy))) scale(1.1); }
}

/* ---------------------------------------------------------------- full-screen flash */
#white-flash {
  position: fixed;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  z-index: 60;
}
#white-flash.show { animation: white-flash-anim 0.25s ease-out; }
@keyframes white-flash-anim {
  0% { opacity: 0.9; }
  100% { opacity: 0; }
}

#toast-container {
  position: absolute;
  top: 90px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: max-content;
  max-width: 70vw;
}
.toast {
  padding: 8px 18px;
  background: rgba(15, 18, 26, 0.82);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.toast.show { opacity: 1; transform: translateY(0); }
.toast-big { font-size: 20px; color: #ffd27a; }

/* Aggregated kill-drop money popup (hud.toastMoney) — small and gold,
   floating just above the hotbar, separate from the main toast stack. */
#money-toast {
  position: absolute;
  bottom: 90px;
  left: 50%;
  transform: translateX(-50%) translateY(-6px);
  font-size: 13px;
  font-weight: 700;
  color: #ffd27a;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
#money-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* §1: damage feedback — edge-only radial (center stays fully clear so the
   crosshair is never obscured); hud.js caps the JS-driven opacity at 0.35
   (see flashDamage/tickVignette). */
#vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 20;
  opacity: 0;
  background: radial-gradient(ellipse at center, rgba(220, 30, 30, 0) 55%, rgba(220, 30, 30, 0.9) 100%);
}

/* ---------------------------------------------------------------- §co-op 段階2: ダウン/蘇生 */
#down-overlay {
  position: fixed;
  inset: 0;
  z-index: 25;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-align: center;
  pointer-events: none;
}
#down-overlay-title {
  font-size: 18px;
  font-weight: 800;
  color: #ffb0b0;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.8);
}
#down-overlay-timer {
  font-size: 40px;
  font-weight: 800;
  color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85);
}
#down-overlay-spectate {
  margin-top: 4px;
  padding: 6px 16px;
  border-radius: 999px;
  background: rgba(15, 18, 26, 0.6);
  border: 1px solid rgba(255, 255, 255, 0.25);
  font-size: 12.5px;
  font-weight: 700;
  color: #cfe0f5;
  pointer-events: auto;
  cursor: pointer;
}
#down-overlay-spectate.hidden { display: none; }

/* §co-op 段階2: circular 蘇生 progress ring (see hud.js's showReviveRing/
   hideReviveRing) — SVG circle stroke-dashoffset, r=42 in index.html. */
#revive-ring {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 26;
  width: 120px;
  height: 120px;
  pointer-events: none;
  text-align: center;
}
#revive-ring svg {
  width: 120px;
  height: 120px;
  transform: rotate(-90deg);
}
.revive-ring-bg {
  fill: none;
  stroke: rgba(255, 255, 255, 0.18);
  stroke-width: 8;
}
#revive-ring-progress {
  fill: none;
  stroke: #5fd3ff;
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.05s linear;
}
#revive-ring-label {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 8px;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 700;
  color: #e8f0ff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}

/* §11.3: 汎用進捗リング(焼き台の10秒など) — #revive-ring と同じ見た目/構造
   だが独立した要素(蘇生と焼くが同時に起きても取り合わない)。circle.revive-
   ring-bg は共用。see hud.js's showProgressRing/hideProgressRing. */
#progress-ring {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 26;
  width: 120px;
  height: 120px;
  pointer-events: none;
  text-align: center;
}
#progress-ring svg {
  width: 120px;
  height: 120px;
  transform: rotate(-90deg);
}
#progress-ring-progress {
  fill: none;
  stroke: #ffb84d;
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dashoffset 0.05s linear;
}
#progress-ring-label {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 8px;
  white-space: nowrap;
  font-size: 13px;
  font-weight: 700;
  color: #e8f0ff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
}

/* ---------------------------------------------------------------- overlays */
#pause-overlay, #gameover-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 6, 10, 0.65);
  z-index: 40;
  cursor: pointer;
}
.overlay-panel {
  padding: 28px 40px;
  background: rgba(15, 18, 26, 0.88);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  text-align: center;
  font-size: 18px;
  font-weight: 700;
}
#gameover-screen .overlay-panel h1 {
  margin: 0 0 12px;
  color: #ff8a8a;
}
#gameover-screen .overlay-panel p {
  margin: 6px 0;
  font-size: 15px;
  font-weight: 500;
  color: #dfe6f0;
}
#gameover-reload {
  margin-top: 16px;
  font-size: 16px;
  font-weight: 700;
  padding: 10px 30px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffb84d, #ff7a59);
  color: #201004;
  cursor: pointer;
}

/* ---------------------------------------------------------------- §5: pause-overlay / clear-overlay achievement log */
#pause-title { margin-bottom: 4px; }
#clear-mission-list-wrap {
  margin-top: 14px;
  text-align: left;
  max-height: 160px;
  overflow-y: auto;
}
.mission-log-title {
  font-size: 12px;
  font-weight: 800;
  color: #8fa0b8;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
#clear-mission-list {
  margin: 0;
  padding: 0;
  list-style: none;
}
#clear-mission-list li {
  font-size: 13px;
  font-weight: 500;
  color: #dfe6f0;
  padding: 3px 0;
}
#clear-mission-list:empty::after {
  content: 'まだありません';
  display: block;
  font-size: 12px;
  color: #6a7a90;
}

/* ---------------------------------------------------------------- §11.8: pause-overlay「住人」タブ */
#pause-tabs {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-top: 10px;
}
.pause-tab-btn {
  padding: 5px 14px;
  border: 1px solid rgba(160, 200, 255, 0.25);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: #9fb3cc;
  font-size: 11.5px;
  font-weight: 700;
  cursor: pointer;
}
.pause-tab-btn.active { background: rgba(255, 210, 122, 0.18); border-color: #ffd27a; color: #ffd27a; }
.pause-tab-btn:hover { color: #e8f0ff; }

#pause-residents-wrap {
  margin-top: 14px;
  text-align: left;
  max-height: 160px;
  overflow-y: auto;
}
#pause-residents-list { margin: 0; padding: 0; list-style: none; }
#pause-residents-list li {
  font-size: 13px;
  font-weight: 500;
  color: #dfe6f0;
  padding: 5px 0;
  border-bottom: 1px solid rgba(160, 200, 255, 0.08);
}
#pause-residents-list li:last-child { border-bottom: none; }
.resident-row-name { font-weight: 700; color: #e8f0ff; }
.resident-row-title { font-size: 11px; color: #ffd27a; margin-left: 4px; }
.resident-row-step { display: block; font-size: 11.5px; color: #9fb3cc; margin-top: 2px; }
#pause-residents-list:empty::after {
  content: 'まだ誰にも会っていません';
  display: block;
  font-size: 12px;
  color: #6a7a90;
}

/* ---------------------------------------------------------------- §5.1: game-clear overlay */
#clear-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 10, 6, 0.7);
  z-index: 45;
}
#clear-overlay .overlay-panel {
  max-width: 420px;
  max-height: 88vh;
  overflow-y: auto;
}
#clear-overlay .overlay-panel h1 {
  margin: 0 0 6px;
  background: linear-gradient(90deg, #ffd27a, #6fd88a);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.clear-subtitle {
  color: #ffd27a !important;
  font-weight: 700;
}
#clear-overlay .overlay-panel p {
  margin: 6px 0;
  font-size: 15px;
  font-weight: 500;
  color: #dfe6f0;
}
.clear-overlay-buttons {
  margin-top: 18px;
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* ---------------------------------------------------------------- §co-op 段階2: 手渡しパネル */
/* (src/hud.js showGivePanel/hideGivePanel) — desktop: a small floating panel
   centered on screen; touch: a bottom sheet (see body.touch override below). */
#give-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(360px, 92vw);
  max-height: 80vh;
  overflow-y: auto;
  padding: 16px 18px;
  background: rgba(12, 22, 40, 0.92);
  border: 1px solid rgba(160, 200, 255, 0.2);
  border-radius: 8px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  z-index: 42;
  pointer-events: auto;
  color: #e8f0ff;
}
#give-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
#give-panel-title {
  font-size: 15px;
  font-weight: 800;
  color: #e8f0ff;
}
#give-panel-close {
  border: none;
  background: transparent;
  color: #9fb3cc;
  cursor: pointer;
  padding: 4px;
  line-height: 0;
  flex: none;
}
#give-panel-close:hover { color: #e8f0ff; }
#give-panel-close svg { width: 16px; height: 16px; }

.give-section + .give-section {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(160, 200, 255, 0.12);
}
.give-section-heading {
  font-size: 11px;
  font-weight: 800;
  color: #8fa0b8;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 8px;
}
.give-weapon-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.give-weapon-chip {
  padding: 8px 14px;
  border: 1px solid rgba(95, 211, 255, 0.4);
  border-radius: 999px;
  background: rgba(95, 211, 255, 0.12);
  color: #e8f0ff;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
}
.give-weapon-chip:hover { background: rgba(95, 211, 255, 0.22); border-color: #5fd3ff; }

.give-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 0;
  flex-wrap: wrap;
}
.give-row-label {
  font-size: 12.5px;
  font-weight: 600;
  color: #cfe0f5;
  flex: 1;
  min-width: 90px;
}
.give-row-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
}
.give-row-btn {
  padding: 6px 14px;
  border: none;
  border-radius: 999px;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
  font-weight: 700;
  font-size: 12px;
  cursor: pointer;
  flex: none;
}
.give-row-btn:hover { filter: brightness(1.08); }

.give-stepper { display: flex; align-items: center; gap: 4px; }
.give-stepper-btn {
  width: 24px;
  height: 24px;
  border: 1px solid rgba(160, 200, 255, 0.3);
  border-radius: 6px;
  background: rgba(160, 200, 255, 0.12);
  color: #e8f0ff;
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.give-stepper-btn:disabled { opacity: 0.35; cursor: default; }
.give-stepper-value {
  min-width: 26px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 13px;
}
.give-stepper-quick { display: flex; gap: 4px; margin-left: 4px; }
.give-quick-btn {
  padding: 3px 8px;
  border: 1px solid rgba(160, 200, 255, 0.25);
  border-radius: 999px;
  background: rgba(6, 12, 22, 0.5);
  color: #9fb3cc;
  font-size: 10.5px;
  font-weight: 700;
  cursor: pointer;
}
.give-quick-btn:hover { color: #e8f0ff; border-color: rgba(95, 211, 255, 0.6); }

.give-money-wrap { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.give-money-input {
  width: 68px;
  padding: 5px 8px;
  border: 1px solid rgba(160, 200, 255, 0.25);
  border-radius: 6px;
  background: rgba(6, 12, 22, 0.55);
  color: #e8f0ff;
  font-size: 12.5px;
  font-family: inherit;
  text-align: right;
}
.give-money-quick { display: flex; gap: 4px; }

.give-empty {
  padding: 20px 0;
  text-align: center;
  font-size: 12.5px;
  color: #7f93ad;
}

body.touch #give-panel {
  top: auto;
  left: 0;
  right: 0;
  bottom: 0;
  transform: none;
  width: 100%;
  max-height: 70vh;
  border-radius: 8px 8px 0 0;
  padding: 14px 16px calc(14px + env(safe-area-inset-bottom));
}

/* ---------------------------------------------------------------- §11.3/§11.4: 住人/注文箱ダイアログ */
/* Navy glass card, centered — used for both resident talk() and the order
   box's openBox(); works identically with mouse and touch (plain <button>s
   inside), Escape closes (hud.js), and is never shown while the market
   modal is open (also hud.js). */
#resident-dialog {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 10, 20, 0.45);
  z-index: 43;
  pointer-events: auto;
}
#resident-dialog-panel {
  width: min(400px, 92vw);
  max-height: 82vh;
  overflow-y: auto;
  padding: 18px 20px;
  background: rgba(12, 22, 40, 0.92);
  border: 1px solid rgba(160, 200, 255, 0.2);
  border-radius: 10px;
  backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 20px 60px rgba(0, 0, 0, 0.5);
  color: #e8f0ff;
}
body.touch #resident-dialog-panel { backdrop-filter: none; }
#resident-dialog-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
#resident-dialog-heading { display: flex; flex-direction: column; gap: 2px; }
#resident-dialog-name { font-size: 17px; font-weight: 800; color: #e8f0ff; }
#resident-dialog-title { font-size: 11.5px; font-weight: 700; color: #ffd27a; }
#resident-dialog-close {
  border: none;
  background: transparent;
  color: #9fb3cc;
  cursor: pointer;
  padding: 4px;
  line-height: 0;
  flex: none;
}
#resident-dialog-close:hover { color: #e8f0ff; }
#resident-dialog-close svg { width: 16px; height: 16px; }
#resident-dialog-text {
  font-size: 13.5px;
  line-height: 1.6;
  color: #cfe0f5;
  white-space: pre-line;
  margin-bottom: 12px;
}
#resident-dialog-needs {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#resident-dialog-needs li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12.5px;
  font-weight: 600;
  color: #dfe6f0;
  padding: 6px 10px;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 6px;
}
#resident-dialog-needs li.need-met { color: #9fe6b8; }
#resident-dialog-needs .need-count { font-variant-numeric: tabular-nums; color: #9fb3cc; flex: none; }
#resident-dialog-needs li.need-met .need-count { color: #7fdba0; }
#resident-dialog-buttons { display: flex; flex-direction: column; gap: 8px; }
.resident-dialog-btn {
  padding: 10px 16px;
  border: none;
  border-radius: 999px;
  font-weight: 700;
  font-size: 13.5px;
  cursor: pointer;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
}
.resident-dialog-btn:disabled { opacity: 0.4; cursor: default; filter: grayscale(0.3); }
.resident-dialog-btn.secondary { background: rgba(255, 255, 255, 0.1); color: #e8f0ff; }
.resident-dialog-btn:not(:disabled):hover { filter: brightness(1.08); }

body.touch #resident-dialog-panel {
  width: min(340px, 90vw);
  max-height: 84vh;
  padding: 14px 16px;
}
.clear-overlay-buttons button {
  font-size: 15px;
  font-weight: 700;
  padding: 10px 22px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
}
#clear-continue-btn {
  background: linear-gradient(90deg, #6fd88a, #3fae63);
  color: #06210f;
}
#clear-reload-btn {
  background: rgba(255, 255, 255, 0.1);
  color: #f1f1f1;
}

/* ---------------------------------------------------------------- market */
/* §4: three-region layout — a left category rail, a center item-card grid,
   and a right detail panel with the action button. Kept translucent so the
   stall/merchant show at the edges. */
#market-modal {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(6, 10, 20, 0.45);
  z-index: 30;
}
#market-panel {
  width: min(880px, 94vw);
  max-height: 92vh;
  display: flex;
  flex-direction: column;
  background: rgba(12, 22, 40, 0.86);
  border: 1px solid rgba(160, 200, 255, 0.18);
  border-radius: 10px;
  overflow: hidden;
  backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 24px 70px rgba(0, 0, 0, 0.6);
}
body.touch #market-panel { backdrop-filter: none; }
#market-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: rgba(255, 255, 255, 0.03);
  border-bottom: 1px solid rgba(160, 200, 255, 0.14);
}
#market-title { font-weight: 800; font-size: 17px; color: #e8f0ff; margin-right: auto; }
#market-wallet { font-weight: 700; color: #ffd27a; font-variant-numeric: tabular-nums; }
#market-close {
  border: none;
  background: rgba(255, 255, 255, 0.08);
  color: #e8f0ff;
  padding: 6px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
}
#market-close:hover { background: rgba(255, 255, 255, 0.16); }

#market-body {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* -- left rail: category icon buttons -- */
#market-rail {
  flex: none;
  width: 128px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 8px;
  border-right: 1px solid rgba(160, 200, 255, 0.12);
  overflow-y: auto;
}
.market-cat-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid transparent;
  background: transparent;
  color: #9fb3cc;
  padding: 9px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-weight: 700;
  font-size: 12px;
  text-align: left;
}
.market-cat-btn svg { flex: none; width: 18px; height: 18px; }
.market-cat-btn:hover { background: rgba(255, 255, 255, 0.05); }
.market-cat-btn.active {
  color: #5fd3ff;
  border-color: #5fd3ff;
  background: rgba(95, 211, 255, 0.1);
  box-shadow: 0 0 0 3px rgba(95, 211, 255, 0.15);
}
.market-cat-label-short { display: none; }

/* -- center: item card grid -- */
#market-grid {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
  gap: 8px;
  padding: 14px;
  overflow-y: auto;
  align-content: start;
}
.market-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 8px 8px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(160, 200, 255, 0.14);
  border-radius: 6px;
  cursor: pointer;
  text-align: center;
  color: #e8f0ff;
}
.market-card:hover { border-color: rgba(95, 211, 255, 0.4); }
.market-card.selected {
  border-color: #5fd3ff;
  box-shadow: 0 0 0 3px rgba(95, 211, 255, 0.25);
  background: rgba(95, 211, 255, 0.08);
}
.market-card.unaffordable { opacity: 0.55; }
.market-card.owned-full { opacity: 0.65; }
.market-card.bounce { animation: market-card-bounce 250ms ease; }
@keyframes market-card-bounce {
  0% { transform: scale(1); }
  35% { transform: scale(1.08); }
  65% { transform: scale(0.97); }
  100% { transform: scale(1); }
}
.market-card-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  color: #dfe6f0;
}
.market-card-icon svg { width: 30px; height: 30px; }
.market-card-name {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
}
.market-card-price {
  font-size: 12px;
  font-weight: 700;
  color: #ffd27a;
  font-variant-numeric: tabular-nums;
}
.market-card.unaffordable .market-card-price { color: #ff5a5a; }
.market-card-state {
  font-size: 10.5px;
  color: #9fb3cc;
}
.market-card-check {
  position: absolute;
  top: 6px;
  right: 6px;
  color: #7ddc6b;
  display: flex;
}
.market-card-check svg { width: 14px; height: 14px; }
.market-card-tier {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  border-radius: 0 0 6px 6px;
}
.market-empty {
  grid-column: 1 / -1;
  font-size: 13px;
  color: #6a7a90;
  padding: 20px 4px;
  text-align: center;
}

/* -- right: detail panel -- */
#market-detail {
  flex: none;
  width: 240px;
  display: flex;
  flex-direction: column;
  padding: 16px;
  border-left: 1px solid rgba(160, 200, 255, 0.12);
  overflow-y: auto;
}
.market-detail-empty {
  margin: auto;
  font-size: 12.5px;
  color: #6a7a90;
  text-align: center;
}
.market-detail-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin: 0 auto 10px;
  color: #e8f0ff;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(160, 200, 255, 0.16);
  border-radius: 8px;
}
.market-detail-icon svg { width: 20px; height: 20px; }
.market-detail-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.market-detail-headtext { flex: 1; min-width: 0; }
.market-detail-name { font-size: 17px; font-weight: 800; color: #e8f0ff; text-align: center; }
.market-detail-price {
  margin-top: 4px;
  font-size: 15px;
  font-weight: 700;
  color: #ffd27a;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.market-detail-price.unaffordable { color: #ff5a5a; }
.market-detail-expand-btn {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  color: #9fb3cc;
  cursor: pointer;
}
.market-detail-expand-btn svg { width: 16px; height: 16px; transition: transform 160ms ease; }
.market-detail-expand-btn.expanded svg { transform: rotate(180deg); }
.market-detail-desc {
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.6;
  color: #9fb3cc;
}
.market-detail-state {
  margin-top: 8px;
  font-size: 12px;
  color: #7ddc6b;
  font-weight: 600;
  text-align: center;
}
.market-detail-sheet { display: block; }
.market-stat-bars { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.market-stat-row { display: flex; align-items: center; gap: 8px; }
.market-stat-label { flex: none; width: 52px; font-size: 10.5px; color: #9fb3cc; }
.market-stat-track {
  flex: 1;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}
.market-stat-fill {
  height: 100%;
  border-radius: 3px;
  background: linear-gradient(90deg, #5fd3ff, #7ddc6b);
}

/* -- quantity stepper: fish sales, ammo, materials, bandages only (§1) -- */
.market-qty-row {
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.market-qty-btn {
  flex: none;
  width: 28px;
  height: 28px;
  border: 1px solid rgba(160, 200, 255, 0.2);
  background: rgba(255, 255, 255, 0.06);
  color: #e8f0ff;
  border-radius: 6px;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.market-qty-btn:hover { background: rgba(255, 255, 255, 0.12); }
.market-qty-value {
  min-width: 28px;
  text-align: center;
  font-size: 15px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: #e8f0ff;
}
.market-qty-max-btn {
  flex: none;
  height: 28px;
  padding: 0 10px;
  border: 1px solid rgba(95, 211, 255, 0.3);
  background: rgba(95, 211, 255, 0.1);
  color: #5fd3ff;
  border-radius: 6px;
  font-size: 10.5px;
  font-weight: 700;
  cursor: pointer;
}
.market-qty-max-btn:hover { background: rgba(95, 211, 255, 0.18); }
.market-qty-total {
  margin-top: 6px;
  font-size: 12px;
  color: #9fb3cc;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.market-qty-total.unaffordable { color: #ff5a5a; }

.market-detail-action {
  margin-top: auto;
  padding-top: 14px;
}
.market-action-btn {
  width: 100%;
  border: none;
  padding: 12px;
  border-radius: 8px;
  background: linear-gradient(90deg, #ffb84d, #ff9a3c);
  color: #201004;
  font-weight: 800;
  font-size: 14px;
  cursor: pointer;
  transition: transform 120ms ease, filter 120ms ease;
}
.market-action-btn:hover:not(:disabled) { filter: brightness(1.08); }
.market-action-btn:active:not(:disabled) { transform: scale(0.97); filter: brightness(0.95); }
.market-action-btn:disabled {
  background: rgba(255, 255, 255, 0.08);
  color: #6a7a90;
  cursor: not-allowed;
}

/* §a11y: cyan focus-visible ring for every keyboard-reachable market control. */
.market-card:focus-visible,
.market-cat-btn:focus-visible,
.market-action-btn:focus-visible,
.market-qty-btn:focus-visible,
.market-qty-max-btn:focus-visible,
.market-detail-head:focus-visible,
.market-detail-expand-btn:focus-visible,
#market-close:focus-visible {
  outline: 2px solid #5fd3ff;
  outline-offset: 2px;
}

/* ---------------------------------------------------------------- touch: on-screen controls */
#touch-controls {
  display: none;
  position: fixed;
  inset: 0;
  /* Below #hud (10): #hud is pointer-events:none everywhere except the
     hotbar slots (which opt back in), so at most pixels a touch here
     correctly "falls through" hud to the zones/buttons below — except
     right over a hotbar slot, where the slot (being in front) wins the
     hit test instead of the joystick/look zone. Still above the game
     canvas itself. */
  z-index: 9;
  pointer-events: none; /* zones/buttons opt back in individually */
}
body.touch #touch-controls { display: block; }

#touch-joystick-zone,
#touch-look-zone {
  position: fixed;
  top: 64px;
  bottom: 0;
  touch-action: none;
  pointer-events: auto;
}
#touch-joystick-zone { left: 0; width: 45%; }
#touch-look-zone { left: 45%; width: 55%; }

.touch-joy-base,
.touch-joy-knob {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  touch-action: none;
}
.touch-joy-base {
  width: 110px;
  height: 110px;
  margin-left: -55px;
  margin-top: -55px;
  background: rgba(20, 24, 34, 0.35);
  border: 2px solid rgba(255, 255, 255, 0.3);
}
.touch-joy-knob {
  width: 54px;
  height: 54px;
  margin-left: -27px;
  margin-top: -27px;
  background: rgba(255, 255, 255, 0.4);
  border: 2px solid rgba(255, 255, 255, 0.55);
}

.touch-btn,
.touch-pill {
  appearance: none;
  -webkit-appearance: none;
  position: fixed;
  /* Only needs to beat the joystick/look zones (which paint above it
     otherwise, purely by later DOM order) — this is a local stacking
     context inside #touch-controls, not compared against #hud. */
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 18, 26, 0.62);
  border: 2px solid rgba(255, 255, 255, 0.28);
  color: #fff;
  font-weight: 800;
  font-family: inherit;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: auto;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}
.touch-btn {
  border-radius: 50%;
  text-align: center;
  line-height: 1.15;
  padding: 0;
}
.touch-btn:active { background: rgba(255, 255, 255, 0.22); }

#touch-primary-btn {
  width: 72px;
  height: 72px;
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
  font-size: 14px;
}
#touch-primary-btn.pulse-red {
  background: rgba(200, 30, 30, 0.6);
  border-color: #ff9a9a;
  animation: touch-pulse 0.4s ease infinite alternate;
}
@keyframes touch-pulse {
  from { transform: scale(1); }
  to { transform: scale(1.12); }
}
#touch-secondary-btn {
  width: 56px;
  height: 56px;
  right: calc(24px + env(safe-area-inset-right));
  bottom: calc(102px + env(safe-area-inset-bottom));
  font-size: 12px;
}
#touch-jump-btn {
  width: 56px;
  height: 56px;
  right: calc(100px + env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
  font-size: 11px;
}

/* §4: consumable buttons — stacked directly above the jump button (same
   right offset) so the cluster stays a narrow column and never reaches
   toward the bottom-center hotbar, even on a short landscape phone. */
.touch-item-btn {
  font-size: 11px;
}
.touch-item-btn svg { width: 18px; height: 18px; }
.touch-item-badge {
  position: absolute;
  bottom: 4px;
  right: 6px;
  min-width: 14px;
  padding: 0 3px;
  font-size: 10px;
  font-weight: 700;
  line-height: 1.4;
  color: #ffd27a;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 8px;
}
.touch-item-btn.disabled {
  opacity: 0.4;
  filter: grayscale(0.6);
}
#touch-eat-btn {
  width: 56px;
  height: 56px;
  right: calc(100px + env(safe-area-inset-right));
  bottom: calc(80px + env(safe-area-inset-bottom));
}
#touch-bandage-btn {
  width: 56px;
  height: 56px;
  right: calc(100px + env(safe-area-inset-right));
  bottom: calc(144px + env(safe-area-inset-bottom));
}

.touch-pill {
  border-radius: 999px;
  padding: 0 16px;
  height: 56px;
  min-height: 56px;
  font-size: 12px;
  white-space: nowrap;
}

/* §1(restyle): the pause button is deliberately tiny and unobtrusive — a
   30px translucent circle with a thin "‖" glyph, sitting at the extreme
   top-right corner. The button box itself stays 44px (accessible hit area);
   the visible circle/glyph are centered pseudo-elements inside it, and the
   whole thing dims to ~35% opacity except while actively pressed. */
#touch-pause-btn {
  appearance: none;
  -webkit-appearance: none;
  position: fixed;
  top: env(safe-area-inset-top);
  right: env(safe-area-inset-right);
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: transparent;
  box-shadow: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  pointer-events: auto;
  z-index: 3; /* above the enemy counter/mission panel in this stacking context */
  opacity: 0.35;
  transition: opacity 0.1s ease;
}
#touch-pause-btn.pressed { opacity: 1; }
#touch-pause-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 30px;
  height: 30px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(15, 18, 26, 0.65);
}
#touch-pause-btn::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2px;
  height: 10px;
  background: #fff;
  transform: translate(-5px, -50%);
  box-shadow: 6px 0 0 #fff;
}

#touch-interact-btn {
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(172px + env(safe-area-inset-bottom));
}

/* §co-op 段階2: 「渡す」pill — same column as touch-interact-btn, one slot
   above it (hidden unless a giveable target is in range, see hud.js's
   setGiveButtonVisible()). */
#give-touch-btn {
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(236px + env(safe-area-inset-bottom));
}

/* §co-op 段階2: 蘇生 — same size/family as #touch-primary-btn (hidden unless
   a downed teammate is in range, see hud.js's setReviveButtonVisible()).
   §fix: this used to sit at #touch-jump-btn's exact slot (right:100,
   bottom:16), reasoned as "mutually exclusive since movement is disabled
   while downed" — but that's backwards: the person who sees and presses
   this button is the REVIVER, who is very much alive and needs jump to
   reach/reposition near the downed teammate (only the downed player loses
   movement). Moved one slot further left along the same bottom row instead,
   clear of jump/eat/bandage's right:100 column — verified via
   getBoundingClientRect() at 844x390 with ?touch=1 that it overlaps none of
   #touch-jump-btn / #touch-eat-btn / #give-touch-btn / #touch-bandage-btn /
   #touch-interact-btn with both #revive-touch-btn and #give-touch-btn visible
   together. */
#revive-touch-btn {
  width: 72px;
  height: 72px;
  right: calc(172px + env(safe-area-inset-right));
  bottom: calc(16px + env(safe-area-inset-bottom));
  font-size: 13px;
}

/* ---------------------------------------------------------------- touch: rotate overlay */
#rotate-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(4, 6, 10, 0.95);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  color: #f1f1f1;
  font-size: 16px;
  font-weight: 700;
  pointer-events: auto;
}
.rotate-icon {
  width: 40px;
  height: 40px;
  font-size: 48px;
  animation: rotate-wiggle 1.6s ease-in-out infinite;
}
@keyframes rotate-wiggle {
  0%, 100% { transform: rotate(0deg); }
  50% { transform: rotate(90deg); }
}
@media (orientation: portrait) {
  body.touch #rotate-overlay { display: flex; }
}

/* ---------------------------------------------------------------- touch: market modal */
body.touch #market-panel { max-height: 92vh; }
body.touch #market-body {
  -webkit-overflow-scrolling: touch;
}
body.touch .market-action-btn,
body.touch #market-close,
body.touch .market-cat-btn,
body.touch .market-detail-head,
body.touch .market-detail-expand-btn,
body.touch .market-qty-btn,
body.touch .market-qty-max-btn {
  min-height: 44px;
}
body.touch .market-qty-btn,
body.touch .market-qty-max-btn,
body.touch .market-detail-expand-btn {
  min-width: 44px;
}

/* §13 fix: on a phone the market panel doesn't cover the full screen, so the
   hotbar/joystick/action buttons/enemy+ammo HUD underneath were both visually
   distracting and, along the panel's edges, literally tappable through the
   gaps. body.market-open is toggled by market.js's openModal()/close(); kept
   scoped to body.touch so desktop (where the modal already sits over
   everything and there's no on-screen chrome to begin with) is untouched. */
body.touch.market-open #hotbar,
body.touch.market-open #touch-controls,
body.touch.market-open #ammo-panel,
body.touch.market-open #hud-enemy-counter {
  display: none;
}

/* §5/§10 width breakpoint (desktop AND touch: any narrow WINDOW) reuses the
   §4 phone-landscape layout below — both need the rail-as-top-row /
   grid-then-detail-bar structure so #market-grid never gets squeezed under
   ~300px wide. This leg is width-only and applies regardless of touch.
   §10 fix: the max-height leg used to be combined into this same query
   (`(max-height: 480px), (max-width: 700px)`), which meant a merely SHORT
   desktop browser window — no touch device involved — also got dropped into
   this mobile layout. A short window is normal on desktop (a resized
   browser); it should never look like a phone. Real touch phones in
   landscape (e.g. 844×390) are exactly the case that DOES need this layout
   from height alone, so that leg is re-scoped under body.touch (set by
   touch.js) further below, right after this one — same rule bodies, kept
   next to each other for exactly that reason; there's no way to merge them
   into one block without either losing the touch gate on the height leg or
   duplicating every declaration line-by-line with a `body.touch` prefix, so
   nesting is used instead to factor that prefix out once. */
@media (max-width: 700px) {
  #market-panel { max-height: 94vh; }
  #market-header { padding: 10px 12px; }
  #market-title { font-size: 15px; }
  #market-body { flex-direction: column; }
  #market-rail {
    width: auto;
    flex-direction: row;
    gap: 6px;
    padding: 8px 10px;
    border-right: none;
    border-bottom: 1px solid rgba(160, 200, 255, 0.12);
    overflow-x: auto;
    overflow-y: visible;
  }
  .market-cat-btn { flex: 1 1 0; padding: 8px; justify-content: center; }
  .market-cat-label-full { display: none; }
  .market-cat-label-short { display: inline; }
  #market-grid {
    grid-template-columns: repeat(3, 1fr);
    padding: 10px;
    /* §12 fix: was 12px — less than the 20px mask fade band below, so the
       last row (and its tier-color bar) always looked faded/half-cut even
       scrolled all the way to the end. Matching it to the fade height means
       the fade only ever covers empty padding, never real card content, once
       scrolled to the bottom. */
    padding-bottom: 20px;
    gap: 6px;
    min-height: 0;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent 100%);
  }
  /* The bottom bar wraps onto a 2nd line for the collapsible sheet instead of
     overlaying it absolutely: .market-detail-sheet below gets flex-basis:100%
     + a high `order`, so it drops to its own full-width line beneath the
     always-visible name/price/qty/action line, growing #market-detail
     downward when expanded. #market-grid (flex:1 + min-height:0 above)
     simply shrinks to make room and keeps scrolling internally — no absolute
     positioning or z-index stacking involved. */
  #market-detail {
    width: auto;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-left: none;
    border-top: 1px solid rgba(160, 200, 255, 0.12);
  }
  .market-detail-icon { display: none; }
  .market-detail-head { flex: 1 1 auto; min-width: 0; }
  .market-detail-headtext { min-width: 0; }
  .market-detail-name {
    min-width: 0;
    font-size: 13px;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .market-detail-price { margin-top: 0; font-size: 13px; text-align: left; }
  .market-detail-state { display: none; }
  .market-detail-expand-btn { display: inline-flex; }
  .market-detail-sheet {
    order: 1;
    flex: 0 0 100%;
    width: 100%;
    display: none;
    max-height: 35vh;
    overflow-y: auto;
  }
  .market-detail-sheet.expanded {
    display: block;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid rgba(160, 200, 255, 0.14);
  }
  /* §11 fix: was white-space:nowrap + ellipsis, which truncated the
     description to a single clipped line even once the user explicitly
     expanded the sheet to read it. Wrap instead, capped at 3 lines. */
  .market-detail-sheet .market-detail-desc {
    margin-top: 0;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    white-space: normal;
    overflow: hidden;
  }
  .market-qty-row { margin-top: 0; flex: none; }
  .market-qty-total { display: none; }
  .market-detail-action { margin-top: 0; padding-top: 0; flex: none; width: 120px; }
  .market-detail-empty { margin: 0; }
  body.touch .market-card-icon svg { width: 26px; height: 26px; }
}

/* §10 fix: the touch-only counterpart of the block above — identical rule
   bodies, reached instead by a short WINDOW HEIGHT, but only ever on an
   actual touch device (body.touch). See the long comment above for why this
   couldn't stay merged into one media query. */
body.touch {
  @media (max-height: 480px) {
    #market-panel { max-height: 94vh; }
    #market-header { padding: 10px 12px; }
    #market-title { font-size: 15px; }
    #market-body { flex-direction: column; }
    #market-rail {
      width: auto;
      flex-direction: row;
      gap: 6px;
      padding: 8px 10px;
      border-right: none;
      border-bottom: 1px solid rgba(160, 200, 255, 0.12);
      overflow-x: auto;
      overflow-y: visible;
    }
    .market-cat-btn { flex: 1 1 0; padding: 8px; justify-content: center; }
    .market-cat-label-full { display: none; }
    .market-cat-label-short { display: inline; }
    #market-grid {
      grid-template-columns: repeat(3, 1fr);
      padding: 10px;
      padding-bottom: 20px; /* §12 fix, see the twin rule above */
      gap: 6px;
      min-height: 0;
      -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent 100%);
      mask-image: linear-gradient(to bottom, #000 calc(100% - 20px), transparent 100%);
    }
    #market-detail {
      width: auto;
      flex-direction: row;
      flex-wrap: wrap;
      align-items: center;
      gap: 10px;
      padding: 8px 12px;
      border-left: none;
      border-top: 1px solid rgba(160, 200, 255, 0.12);
    }
    .market-detail-icon { display: none; }
    .market-detail-head { flex: 1 1 auto; min-width: 0; }
    .market-detail-headtext { min-width: 0; }
    .market-detail-name {
      min-width: 0;
      font-size: 13px;
      text-align: left;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .market-detail-price { margin-top: 0; font-size: 13px; text-align: left; }
    .market-detail-state { display: none; }
    .market-detail-expand-btn { display: inline-flex; }
    .market-detail-sheet {
      order: 1;
      flex: 0 0 100%;
      width: 100%;
      display: none;
      max-height: 35vh;
      overflow-y: auto;
    }
    .market-detail-sheet.expanded {
      display: block;
      margin-top: 8px;
      padding-top: 8px;
      border-top: 1px solid rgba(160, 200, 255, 0.14);
    }
    .market-detail-sheet .market-detail-desc {
      margin-top: 0;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 3;
      line-clamp: 3;
      white-space: normal;
      overflow: hidden;
    }
    .market-qty-row { margin-top: 0; flex: none; }
    .market-qty-total { display: none; }
    .market-detail-action { margin-top: 0; padding-top: 0; flex: none; width: 120px; }
    .market-detail-empty { margin: 0; }
    .market-card-icon svg { width: 26px; height: 26px; }
  }
}

/* ---------------------------------------------------------------- touch: fight UI */
body.touch #fight-track { height: 140px; }
body.touch #catch-card { padding: 12px 20px; }
/* Keep the name > size > price hierarchy intact at the smaller touch scale
   (a flat 17px name here used to sit BELOW the 18px size line). */
body.touch .catch-card-name { font-size: 19px; }
body.touch .catch-card-size { font-size: 15px; }
body.touch .catch-card-price { font-size: 14px; }

/* §3: on touch (844x390), the fight panel sits right-of-center, clear of the
   bottom-right action-button column (primary/secondary/jump/eat/bandage,
   left edge ~688px at 844 width) — a large `right` offset plus the tight
   #fight-label caps in index.html (the label, not the track, is what drives
   this panel's width) keep its right edge well clear of that column. An
   explicit max-width caps the panel itself (belt-and-suspenders alongside
   the label's own max-width) so it can never grow past this budget even if
   the label's text metrics vary. Verified via getBoundingClientRect() against
   every touch button at 844x390: no overlap. */
body.touch #fight-ui { top: 46%; right: 176px; padding: 10px 8px; gap: 6px; max-width: 150px; }
body.touch #fight-progress-outer { width: 76px; }

/* §1: ammo panel sits above the action-button cluster on touch instead of
   beside the (touch-sized, narrower) hotbar. */
body.touch #ammo-panel {
  left: auto;
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(244px + env(safe-area-inset-bottom));
}

/* ---------------------------------------------------------------- small landscape screens */
/* Title / game-over panels: keep them fully reachable on a ~390px-tall
   landscape phone screen regardless of touch/desktop. */
@media (max-height: 480px) {
  .title-panel,
  #gameover-screen .overlay-panel {
    max-height: 92vh;
    overflow-y: auto;
    padding: 16px 20px;
  }
  .title-heading { font-size: 19px; }
  .title-tagline { font-size: 12.5px; margin-bottom: 6px; }
  .subtitle { font-size: 11.5px; margin-bottom: 12px; }
  .title-divider { margin-bottom: 12px; }
  .title-flow { margin-bottom: 10px; gap: 6px; }
  .flow-label { font-size: 11px; }
  .flow-label-sub { display: none; } /* §2: small screens hide card descriptions, keep the 3 icons */
  .title-controls { margin-bottom: 12px; }
  .title-controls ul { font-size: 10.5px; line-height: 1.6; }
  #title-start-btn { padding: 10px 32px; font-size: 15px; }
  .install-tip { margin-top: 10px; padding: 10px 22px 8px 12px; }
  .install-tip-heading { font-size: 12px; margin-bottom: 6px; }
  .install-tip-step { font-size: 11px; gap: 6px; margin-bottom: 4px; }
  .install-tip-icon { width: 18px; height: 18px; }
  .install-tip-icon .icon { width: 12px; height: 12px; }
  .install-tip-btn { margin-top: 10px; padding: 9px 16px; font-size: 12.5px; }

  /* §bugfix: install.js toggles `.has-install-ui` on .title-panel whenever
     the iOS tip card or the Android install button is actually mounted. On
     a short landscape phone (the primary target: 844x390) that content used
     to land ~118px below the fold with no scroll hint, so on THIS bucket
     only — and only while the install UI is present — drop the 朝/昼/夜 flow
     cards (the least essential content: a decorative day-cycle preview) to
     reclaim enough height that the card/button fits without scrolling at
     all in the common case. install.js also scrollIntoView()s it once on
     insertion as a belt-and-suspenders for any remaining edge case (e.g. an
     even shorter screen, or large text/zoom) where it still doesn't fit —
     the panel's own `overflow-y: auto` (above) stays as the ultimate
     fallback either way. */
  .title-panel.has-install-ui .title-flow { display: none; }
  .title-panel.has-install-ui .title-divider { margin-bottom: 8px; }

  #coop-heading { font-size: 16px; }
  #coop-intro { font-size: 11.5px; margin-bottom: 12px; }
  #coop-code-value { font-size: 24px; }
}

/* Compact HUD for a short landscape phone screen. Clock/topleft/mission/money
   sizing applies on both desktop and touch (item 3: "desktop uses the same
   style"); touch-only rules (hotbar/joystick/toasts/etc.) stay scoped. */
@media (max-height: 480px) {
  #hud-status-panel { gap: 5px; }
  #hud-time { font-size: 15px; }
  #hud-day { font-size: 10.5px; }
  #hud-phase { font-size: 10px; padding: 1px 7px; min-width: 22px; }
  #hud-money { font-size: 12px; }
  body.touch #hud-bottom-left { width: 150px; bottom: 12px; left: 12px; gap: 6px; }
  body.touch .hud-bar-text { font-size: 8px; }
  body.touch .hotbar-slot { width: 42px; height: 42px; font-size: 9px; }
  body.touch .hotbar-slot .slot-label { font-size: 9px; }
  body.touch .hotbar-slot .slot-key { font-size: 8px; }
  body.touch #hotbar { bottom: 10px; gap: 4px; }
  body.touch #ammo-panel { bottom: calc(210px + env(safe-area-inset-bottom)); }
  body.touch .toast { font-size: 12px; padding: 6px 12px; }
  body.touch .toast-big { font-size: 16px; }
  body.touch #money-toast { bottom: 62px; font-size: 12px; }
  body.touch #touch-joystick-zone,
  body.touch #touch-look-zone { top: 40px; }
  body.touch #hud-enemy-counter { top: calc(48px + env(safe-area-inset-top)); }
  body.touch #fight-ui { top: 44%; padding: 10px 8px; gap: 6px; }
  #fight-track { height: 150px; }
  #fight-progress-outer { width: 76px; }

  /* §5: compact mission HUD / boss bar / clear overlay on a short landscape screen.
     top-left's own height shrinks in compact mode, but the default gap
     already clears it with margin to spare — no separate override needed,
     just the narrower max-width. */
  #hud-topleft { max-width: 230px; gap: 6px; }
  #mission-panel { max-width: 210px; padding: 1px 0 1px 8px; }
  #mission-title { font-size: 11px; }
  #mission-progress { font-size: 10px; }
  #mission-bar-outer { margin-top: 4px; }
  /* §11.8: request panel stays inside the same 230px column as mission-panel
     above it, and its 3rd (resident) line never grows past 2 lines even
     with a long "灯台守ゲン: ..." string — keeps it clear of the touch
     hotbar/joystick which live along the bottom edge, not up here. */
  #request-panel { max-width: 210px; padding: 1px 0 1px 8px; }
  .request-line { font-size: 11px; }
  .request-line:nth-child(3) { font-size: 10px; }
  #mission-banner { font-size: 12px; padding: 7px 16px; top: 10px; }
  #phase-banner { top: 22%; padding: 14px 0; }
  #phase-banner-text { font-size: 24px; letter-spacing: 0.06em; }
  .dmg-arc-top, .dmg-arc-bottom { height: 90px; }
  .dmg-arc-left, .dmg-arc-right { width: 90px; }
  #boss-bar { top: 10px; width: min(320px, 80vw); }
  #boss-bar-name { font-size: 11px; }
  #boss-bar-outer { height: 11px; }
  #clear-overlay .overlay-panel { padding: 16px 20px; max-height: 92vh; }
  #clear-overlay .overlay-panel h1 { font-size: 20px; }
  #clear-overlay .overlay-panel p { font-size: 12px; margin: 4px 0; }
  #pause-residents-wrap,
  #clear-mission-list-wrap { max-height: 90px; margin-top: 8px; }
  .clear-overlay-buttons button { font-size: 13px; padding: 8px 16px; }

  /* §co-op 段階2: keep the down/revive/give UI clear of the shorter HUD at
     844x390 — smaller timer/ring, tighter players list, shorter give-panel. */
  #coop-players-list { font-size: 10.5px; }
  body.touch #coop-players-hud { max-width: 160px; font-size: 10.5px; }
  body.touch #coop-players-list { max-width: 160px; }
  #down-overlay-title { font-size: 14px; }
  #down-overlay-timer { font-size: 30px; }
  #down-overlay-spectate { font-size: 11px; padding: 5px 12px; }
  #revive-ring, #revive-ring svg { width: 84px; height: 84px; }
  #revive-ring-label { font-size: 11px; }
  #progress-ring, #progress-ring svg { width: 84px; height: 84px; }
  #progress-ring-label { font-size: 11px; }
  #give-panel { max-height: 88vh; padding: 12px 14px; }
  body.touch #give-panel { max-height: 82vh; }

  /* §11.3/§11.4: keep the dialog/order-box card and the pause「住人」tab
     readable and non-overlapping at 844x390 (verified layout target). */
  #resident-dialog-panel { max-height: 88vh; padding: 12px 14px; }
  #resident-dialog-name { font-size: 15px; }
  #resident-dialog-text { font-size: 12.5px; margin-bottom: 8px; }
  #resident-dialog-needs li { font-size: 11.5px; padding: 5px 8px; }
  .resident-dialog-btn { font-size: 12px; padding: 8px 14px; }
  #pause-residents-wrap { max-height: 90px; margin-top: 8px; }
}

/* prompt pill: fully hidden when there is no text */
#prompt[hidden] { display: none !important; }

/* market modal: allow vertical scrolling on touch even though body has touch-action:none */
#market-modal, #market-panel, #market-body { touch-action: pan-y; }

/* touch primary button while waiting for a bite */
#touch-primary-btn.dim { opacity: 0.55; font-size: 14px; }
