/* ---- Phone HUD ----
   The world stays the picture. One family of translucent round controls at the edges,
   labelled only where the action changes with the situation.
   Left: who you are, a slim menu rail, and a pad that appears under the thumb.
   Right: where you are, then attack and jump with abilities in an arc around them and up to
   three things to do here, the first nearest the thumb. No backdrop blur over the 3D canvas. */
body.touch-mode .game-viewport {
  --gl: max(14px, env(safe-area-inset-left));
  --gr: max(14px, env(safe-area-inset-right));
  --gt: max(10px, env(safe-area-inset-top));
  --gb: max(18px, env(safe-area-inset-bottom));
  --map: 84px;
  --plate: 232px;
  --plate-height: 54px;
  --attack: 78px;
  --jump: 60px;
  --skill: 50px;
  --prompt: 46px;
  --hud-ink: #fff8e8;
  --hud-dim: #ddd3ba;
  --hud-glass: #0b1510a8;
  --hud-solid: #0b1510e3;
  --hud-edge: #fff0cf42;
  --hud-ember: #efbb6c;
  --hud-ember-ink: #2a1a06;
  --hud-shadow: 0 3px 14px #0005;
}
#touch-controls {
  position: absolute;
  inset: 0;
  pointer-events: none;
  color: var(--hud-ink);
}
#touch-controls[hidden],
#touch-controls [hidden] {
  display: none !important;
}
#touch-controls button {
  pointer-events: auto;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  position: relative;
  display: grid;
  place-items: center;
  margin: 0;
  padding: 0;
  border: 1.5px solid var(--hud-edge);
  border-radius: 50%;
  color: var(--hud-ink);
  background: var(--hud-glass);
  box-shadow:
    var(--hud-shadow),
    inset 0 1px #ffffff12;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.25;
  text-shadow: 0 1px 2px #000b;
  transition:
    transform 0.1s ease-out,
    background-color 0.12s,
    border-color 0.12s,
    opacity 0.18s;
}
#touch-controls button .icon {
  width: 24px;
  height: 24px;
  stroke-width: 1.7;
  pointer-events: none;
}
#touch-controls button:is(.is-pressed, :active):not(:disabled) {
  transform: scale(0.92);
  background-color: #f6e0b452;
  border-color: #fff4dcb0;
}
#touch-controls button:disabled {
  opacity: 0.34;
  box-shadow: none;
}

/* Menus: a slim rail under the status plate. */
.touch-toolbar {
  position: absolute;
  left: var(--gl);
  top: calc(var(--gt) + var(--plate-height) + 12px);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
#touch-controls .touch-toolbar button {
  width: 44px;
  height: 44px;
}
#touch-controls .touch-toolbar .icon {
  width: 20px;
  height: 20px;
}
#touch-controls .touch-toolbar [data-unread='true']::after {
  content: '';
  position: absolute;
  top: 1px;
  right: 1px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--hud-ember);
  box-shadow: 0 0 0 2px #0b1510;
}
.touch-chat-peek {
  position: absolute;
  margin: 0;
  max-width: min(250px, calc(100vw - var(--gl) - var(--gr) - 70px));
  padding: 7px 12px;
  border: 1px solid var(--hud-edge);
  border-radius: 14px;
  background: var(--hud-solid);
  box-shadow: var(--hud-shadow);
  color: var(--hud-ink);
  font-size: 13px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  pointer-events: none;
  animation: touch-fade 0.2s ease-out;
}
.touch-chat-peek[data-side='beside'] {
  transform: translateY(-50%);
}
.touch-chat-peek b {
  margin-right: 6px;
  color: var(--hud-ember);
}

/* Left thumb: the pad rests in the corner and moves to wherever the thumb lands. */
.touch-move {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 50%;
  height: 40%;
  pointer-events: auto;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}
.touch-move[data-disabled='true'] {
  pointer-events: none;
}
.touch-stick {
  position: absolute;
  left: var(--gl);
  bottom: var(--gb);
  width: 124px;
  height: 124px;
  border: 1.5px solid #fff3d873;
  border-radius: 50%;
  background: radial-gradient(circle, #0b151026 0 55%, #0b15106b 56% 100%);
  box-shadow: var(--hud-shadow);
  opacity: 0.55;
  pointer-events: none;
  transition:
    transform 0.2s ease-out,
    opacity 0.2s,
    border-color 0.15s,
    box-shadow 0.15s;
}
.touch-move[data-disabled='true'] .touch-stick {
  opacity: 0.2;
}
.touch-stick::before {
  content: '';
  position: absolute;
  inset: 14px;
  border: 1px solid #fff3d830;
  border-radius: 50%;
}
.touch-stick.is-active {
  opacity: 1;
  transition:
    opacity 0.08s,
    border-color 0.15s,
    box-shadow 0.15s;
}
/* Pushed far enough to run, the pad glows. */
.touch-stick[data-gait='run'] {
  border-color: var(--hud-ember);
  box-shadow:
    var(--hud-shadow),
    0 0 18px #efbb6c70;
}
.touch-stick[data-gait='run']::before {
  border-color: #efbb6c80;
}
.touch-stick-knob {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 54px;
  height: 54px;
  margin: -27px 0 0 -27px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #fffaf0, #e9dcbf 60%, #cdbd9a);
  box-shadow:
    0 4px 12px #0007,
    inset 0 -2px 4px #0002;
  opacity: 0.92;
}
.touch-stick:not(.is-active) .touch-stick-knob {
  transition: transform 0.15s ease-out;
}

/* Right thumb: things to do here, stacked upward just above the highest ability. */
.touch-prompts {
  position: absolute;
  right: var(--gr);
  bottom: calc(var(--gb) + var(--attack) + 14px);
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 8px;
  width: min(248px, 66vw);
}
#touch-controls .touch-prompt {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 9px;
  max-width: 100%;
  min-width: 0;
  min-height: var(--prompt);
  padding: 4px 16px 4px 4px;
  border-radius: calc(var(--prompt) / 2);
  font-size: 14px;
  text-align: left;
  animation: touch-slide 0.18s ease-out;
}
.touch-prompt-icon,
.touch-skill-icon,
.touch-attack-icon {
  display: grid;
  place-items: center;
  flex: none;
  pointer-events: none;
}
.touch-prompt-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #ffffff17;
}
#touch-controls .touch-prompt .icon {
  width: 20px;
  height: 20px;
}
/* A long target name wraps to a second line rather than losing its end. */
.touch-prompt-label {
  min-width: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  line-height: 1.25;
}
/* The bottom prompt is the one to reach for. */
#touch-controls .touch-prompt:first-child {
  border-color: #efbb6cb8;
  background: #2b1d0bd6;
}
#touch-controls .touch-prompt:first-child .touch-prompt-icon {
  background: var(--hud-ember);
  color: var(--hud-ember-ink);
}

/* Attack in the corner, jump beside it, abilities on an arc above. */
.touch-pad {
  position: absolute;
  right: var(--gr);
  bottom: var(--gb);
  width: 0;
  height: 0;
}
#touch-controls .touch-pad > button {
  position: absolute;
}
#touch-controls .touch-attack {
  right: 0;
  bottom: 0;
  width: var(--attack);
  height: var(--attack);
  border-color: #ffd9c670;
  background: radial-gradient(circle at 50% 35%, #713626d6, #3b1a12db);
}
#touch-controls .touch-attack .icon {
  width: 34px;
  height: 34px;
  stroke-width: 1.6;
}
/* The recharge sweeps away clockwise, so a resting attack shows when it returns. */
.touch-attack::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(#050a07b3 calc(var(--cooldown, 0) * 1turn), #0000 0);
  pointer-events: none;
}
#touch-controls .touch-attack[data-cooling='true']:disabled {
  opacity: 1;
}
#touch-controls .touch-jump {
  right: calc(var(--attack) / 2 + 96px - var(--jump) / 2);
  bottom: calc(var(--attack) / 2 - 6px - var(--jump) / 2);
  width: var(--jump);
  height: var(--jump);
}
#touch-controls .touch-jump .icon {
  width: 26px;
  height: 26px;
}
#touch-controls .touch-skill {
  width: var(--skill);
  height: var(--skill);
  animation: touch-fade 0.2s ease-out;
}
#touch-controls .touch-skill .icon {
  width: 22px;
  height: 22px;
}
.touch-skill-label {
  position: absolute;
  right: calc(100% + 6px);
  top: 50%;
  transform: translateY(-50%);
  padding: 2px 8px;
  border-radius: 9px;
  background: #0b15109e;
  color: var(--hud-ink);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
  pointer-events: none;
}
#touch-controls .touch-skill[data-slot='near'] {
  right: calc(var(--attack) / 2 + 82px - var(--skill) / 2);
  bottom: calc(var(--attack) / 2 + 57px - var(--skill) / 2);
}
#touch-controls .touch-skill[data-slot='far'] {
  right: calc(var(--attack) / 2 + 18px - var(--skill) / 2);
  bottom: calc(var(--attack) / 2 + 102px - var(--skill) / 2);
}
#touch-controls .touch-skill[data-slot='high'] {
  right: calc(var(--attack) / 2 + 98px - var(--skill) / 2);
  bottom: calc(var(--attack) / 2 + 139px - var(--skill) / 2);
}
#touch-controls[data-reach='near'] .touch-prompts {
  bottom: calc(var(--gb) + var(--attack) / 2 + 57px + var(--skill) / 2 + 12px);
}
#touch-controls[data-reach='far'] .touch-prompts {
  bottom: calc(var(--gb) + var(--attack) / 2 + 102px + var(--skill) / 2 + 12px);
}
#touch-controls[data-reach='high'] .touch-prompts {
  bottom: calc(var(--gb) + var(--attack) / 2 + 139px + var(--skill) / 2 + 12px);
}
/* Viewing a traveler: their card takes the corner the hidden pad leaves free. */
.touch-mode .player-profile {
  top: auto;
  left: var(--gl);
  bottom: var(--gb);
  width: min(290px, calc(100vw - var(--gl) - var(--gr) - 132px));
  padding: 11px 13px 10px;
  border-color: var(--hud-edge);
  border-radius: 16px;
  background: var(--hud-solid);
  box-shadow: var(--hud-shadow);
  color: var(--hud-ink);
  transform: none;
}
.touch-mode .player-profile-stats {
  gap: 5px 10px;
}
/* Clothing colours: a full finger target each. */
.touch-mode .dye-swatch {
  width: 44px;
  height: 44px;
}
/* Viewing a companion or waiting on a task leaves only its own prompts, by the thumb. */
#touch-controls:is([data-mode='viewing'], [data-mode='busy']) .touch-pad {
  display: none;
}
#touch-controls:is([data-mode='viewing'], [data-mode='busy']) .touch-prompts {
  right: var(--gr);
  bottom: var(--gb);
}
@keyframes touch-slide {
  from {
    opacity: 0;
    translate: 14px 0;
  }
}
@keyframes touch-fade {
  from {
    opacity: 0;
    translate: 0 4px;
  }
}

/* The keyboard and controller HUD gives way to the touch HUD. */
body.touch-mode {
  overscroll-behavior: none;
}
.touch-mode kbd,
.touch-mode #input-cues,
.touch-mode #prompt-bar,
.touch-mode #interaction-hint,
.touch-mode #companion524-controls,
.touch-mode .riding-controls,
.touch-mode .hunt-controls,
.touch-mode .boat-controls,
.touch-mode #cancel-cook,
.touch-mode .tps-reticle,
.touch-mode .gamepad-connection {
  display: none !important;
}

/* Status: one capsule with the portrait, name, connection and party, and health. */
.touch-mode .status-plate {
  top: var(--gt);
  left: var(--gl);
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  grid-template-areas:
    'face name meta'
    'face bar bar';
  align-items: center;
  column-gap: 9px;
  row-gap: 5px;
  width: min(var(--plate), calc(100vw - var(--gl) - var(--gr) - var(--map) - 16px));
  height: var(--plate-height);
  padding: 6px 13px 6px 6px;
  border: 1px solid var(--hud-edge);
  border-radius: calc(var(--plate-height) / 2);
  background: var(--hud-glass);
  box-shadow: var(--hud-shadow);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.touch-mode .status-main,
.touch-mode .status-plate .status-text {
  display: contents;
}
.touch-mode .status-plate .portrait {
  grid-area: face;
  width: 40px;
  height: 40px;
  border: 1.5px solid #fff0cf5c;
  border-radius: 50%;
}
.touch-mode .status-text strong {
  grid-area: name;
  min-width: 0;
  max-width: none;
  overflow: hidden;
  color: var(--hud-ink);
  font-size: 13px;
  line-height: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.touch-mode .status-text small {
  grid-area: meta;
  gap: 4px;
  color: var(--hud-dim);
  font-size: 10.5px;
  line-height: 16px;
  white-space: nowrap;
}
.touch-mode #room-label,
.touch-mode #room-label + i {
  display: none;
}
.touch-mode .energy-track {
  grid-area: bar;
  width: auto;
  height: 14px;
  border-color: #ffffff24;
  border-radius: 7px;
}
.touch-mode .energy-label {
  gap: 0;
  padding: 0 7px;
  font-size: 10px;
}
.touch-mode .energy-label b,
.touch-mode .energy-label .icon {
  display: none;
}

/* Map: a round window on the area, nothing else. */
.touch-mode .map-hud {
  top: var(--gt);
  right: var(--gr);
  width: var(--map);
  gap: 0;
}
.touch-mode .minimap-button {
  width: var(--map);
  height: var(--map);
  padding: 0;
  border: 1.5px solid var(--hud-edge);
  border-radius: 50%;
  overflow: visible;
  background: #193948;
  box-shadow: var(--hud-shadow);
}
.touch-mode .minimap-button > canvas {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  opacity: 1;
}
.touch-mode .map-north {
  top: -6px;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  padding: 0 5px;
  border-radius: 7px;
  background: var(--hud-solid);
  font-size: 9px;
  line-height: 14px;
}
.touch-mode .map-key {
  display: none;
}
/* Connection: a dot before the party count in the status capsule (moved there by main.ts).
   Online is the quiet default; a lost connection names itself in place of the count. */
.touch-mode .connection {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: auto;
  min-width: 0;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  color: inherit;
  font-size: inherit;
  letter-spacing: inherit;
}
.touch-mode .connection .status-dot {
  width: 8px;
  height: 8px;
  box-shadow: 0 0 0 2px #0b1510;
}
.touch-mode #connection-label,
.touch-mode #ping-label {
  display: none;
}
.touch-mode .status-dot.offline ~ #connection-label {
  display: block;
  padding: 0 7px;
  border-radius: 8px;
  background: #6a2c1fe6;
  color: #ffe6d8;
  font-weight: 600;
}
.touch-mode .status-text small:has(.status-dot.offline) #online-count {
  display: none;
}

/* Announcements stay short and centred between the side columns, each in its own band:
   area names, then notices (the latest two), then the combat state. */
.touch-mode .area-banner {
  top: 21%;
  width: max-content;
  max-width: calc(100vw - 48px);
  pointer-events: none;
}
.touch-mode .area-banner small {
  font-size: 9px;
  letter-spacing: 4px;
}
.touch-mode .area-banner strong {
  margin-top: 6px;
  padding-left: 0.1em;
  font-size: 23px;
  letter-spacing: 0.1em;
  text-wrap: balance;
}
.touch-mode .area-banner strong:after {
  width: 84px;
  margin-top: 10px;
}
.touch-mode .toast-stack {
  top: 30%;
  width: max-content;
  max-width: calc(100vw - 2 * var(--gl) - 120px);
  gap: 6px;
  pointer-events: none;
}
.touch-mode .toast {
  min-width: 0;
  max-width: 100%;
  padding: 8px 14px;
  gap: 8px;
  border-radius: 20px;
  background: var(--hud-solid);
  font-size: 13px;
  line-height: 1.45;
  white-space: normal;
  text-wrap: pretty;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.touch-mode .toast.error {
  background: #4c2a22ee;
}
.touch-mode .toast:nth-last-child(n + 3) {
  display: none;
}
.touch-mode .toast .icon {
  width: 17px;
  height: 17px;
}
.touch-mode .combat-status {
  top: 41%;
  max-width: calc(100vw - 2 * var(--gl) - 120px);
  padding: 9px 16px;
  border-radius: 18px;
  font-size: 13px;
  line-height: 1.55;
  text-wrap: balance;
  pointer-events: none;
}
.touch-mode .combat-status.downed {
  top: 42%;
  max-width: calc(100vw - 48px);
  padding: 14px 20px;
  font-size: 15px;
}
/* Above the shared HUD layer (style.css gives every HUD child z-index 2), so notices
   arriving while downed never cover it. */
.touch-mode #combat-status.downed {
  z-index: 3;
}
/* Only a task's progress remains of the hotbar (its buttons are touch prompts); it sits
   just above that task's cancel prompt. */
.touch-mode .hotbar-wrap {
  top: auto;
  left: auto;
  right: var(--gr);
  bottom: calc(var(--gb) + var(--prompt) + 10px);
  align-items: flex-end;
  width: max-content;
  max-width: calc(100vw - var(--gl) - var(--gr));
  transform: none;
  pointer-events: none;
}
.touch-mode .cooking-status {
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  width: min(220px, 60vw);
  margin: 0;
  padding: 8px 14px 10px;
  border-color: var(--hud-edge);
  border-radius: 16px;
  background: var(--hud-solid);
  font-size: 13px;
}
.touch-mode .cooking-status progress {
  flex: none;
  width: 100%;
  height: 6px;
  accent-color: var(--hud-ember);
}

/* Landscape: the rail runs beside the status plate; prompts stand left of the pad. */
@media (orientation: landscape) {
  body.touch-mode .game-viewport {
    --map: 76px;
  }
  .touch-toolbar {
    flex-direction: row;
    top: calc(var(--gt) + (var(--plate-height) - 44px) / 2);
    left: calc(var(--gl) + var(--plate) + 12px);
  }
  .touch-move {
    width: 40%;
    height: 74%;
  }
  /* Beside the pad: past jump alone, or past the captions of the abilities beside it. */
  #touch-controls[data-reach] .touch-prompts {
    right: calc(var(--gr) + var(--attack) / 2 + 96px + var(--jump) / 2 + 14px);
    bottom: var(--gb);
    width: min(232px, 30vw);
  }
  #touch-controls:is([data-slots~='near'], [data-slots~='high']) .touch-prompts {
    right: calc(var(--gr) + 262px);
  }
  #touch-controls:is([data-mode='viewing'], [data-mode='busy']) .touch-prompts {
    right: var(--gr);
  }
}
/* Short or narrow phones keep every target at least 44px. */
@media (max-width: 359px), (max-height: 600px) and (orientation: portrait) {
  body.touch-mode .game-viewport {
    --gl: max(10px, env(safe-area-inset-left));
    --gr: max(10px, env(safe-area-inset-right));
    --map: 72px;
    --plate: 210px;
    --attack: 70px;
    --jump: 56px;
    --skill: 46px;
    --prompt: 44px;
  }
  .touch-stick {
    width: 116px;
    height: 116px;
  }
  .touch-skill-label {
    padding: 1px 6px;
    font-size: 10px;
  }
}
@media (prefers-reduced-motion: reduce) {
  #touch-controls *,
  .touch-stick {
    animation: none !important;
    transition: none !important;
  }
}

/* The conversation opens as a sheet from the bottom edge. */
.touch-mode .game-viewport > .chat-panel {
  display: none;
}
#chat-dialog {
  position: fixed;
  inset: auto 0 var(--chat-keyboard, 0px);
  margin: 0 auto;
  padding: 0;
  width: min(100%, 560px);
  max-width: 100%;
  height: min(440px, var(--chat-height, 100dvh));
  max-height: var(--chat-height, 100dvh);
  border: 1px solid #c5d0b740;
  border-bottom: 0;
  border-radius: 24px 24px 0 0;
  background: #1d2c25;
  overflow: hidden;
  box-shadow: 0 -12px 50px #0005;
}
#chat-dialog[open] {
  animation: chat-rise 180ms ease-out;
}
#chat-dialog::backdrop {
  background: #06130b70;
}
.touch-mode #chat-dialog .chat-panel {
  display: flex;
  flex-direction: column;
  position: static;
  width: 100%;
  max-width: none;
  height: 100%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
}
.touch-mode #chat-dialog .chat-heading {
  flex-shrink: 0;
  min-height: 56px;
  padding: 12px max(20px, env(safe-area-inset-right)) 12px max(20px, env(safe-area-inset-left));
}
.touch-mode #chat-dialog .chat-heading strong {
  display: block;
  font-size: 15px;
}
.touch-mode #chat-dialog .chat-heading > .icon {
  width: 20px;
  height: 20px;
}
.touch-mode #chat-dialog .chat-collapse {
  font-size: 0;
}
.touch-mode #chat-dialog .chat-collapse:after {
  content: '×';
  font-size: 26px;
}
.touch-mode #chat-dialog #chat-content {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.touch-mode #chat-dialog .chat-messages {
  flex: 1;
  min-height: 0;
  height: auto;
  padding: 12px max(20px, env(safe-area-inset-left));
  overscroll-behavior: contain;
}
.touch-mode #chat-dialog .chat-messages p {
  font-size: 14px;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.touch-mode #chat-dialog #chat-form {
  flex-shrink: 0;
  gap: 8px;
  padding: 12px max(16px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom))
    max(16px, env(safe-area-inset-left));
  background: #26372e;
}
.touch-mode #chat-dialog #chat-input {
  min-width: 0;
  min-height: 48px;
  font-size: 16px;
  padding: 12px;
}
.touch-mode #chat-dialog #chat-form button {
  min-width: 48px;
  min-height: 48px;
}
@keyframes chat-rise {
  from {
    transform: translateY(100%);
  }
  to {
    transform: translateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  #chat-dialog[open] {
    animation: none;
  }
}
.touch-mode #motion-controls[data-state='OFF'] {
  display: none;
}
.touch-mode dialog {
  max-height: calc(
    100dvh - max(16px, env(safe-area-inset-top)) - max(16px, env(safe-area-inset-bottom))
  );
  overscroll-behavior: contain;
}
.touch-mode dialog button,
.touch-mode dialog .item-actions .button,
.touch-mode .setup-screen button {
  min-height: 44px;
}
.touch-mode dialog .icon-button {
  min-width: 44px;
}
.touch-mode input,
.touch-mode select {
  font-size: 16px;
}

/* Pause menu on a phone: the tabs, then the menu's actions, slide in one row beside the back
   button, icon over name. The tabs share the row's width while everything fits. */
@media (max-width: 860px) {
  .touch-mode dialog:has(.pause-menu) .modal-top {
    top: 10px;
    right: 10px;
  }
  .touch-mode dialog:has(.pause-menu) .modal-top .modal-back {
    min-width: 0;
    min-height: 44px;
    padding: 6px 14px;
    border-radius: 22px;
  }
  .touch-mode .pause-rail {
    padding: 10px 10px 8px;
  }
  .touch-mode .pause-row {
    margin-right: 76px;
    padding-bottom: 0;
  }
  .touch-mode .pause-tabs {
    flex: 1 0 auto;
    gap: 4px;
  }
  .touch-mode .pause-tab,
  .touch-mode .pause-exits .button {
    flex: 1 0 auto;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    min-width: 64px;
    min-height: 56px;
    padding: 6px 10px;
    border-radius: 12px;
    font-size: 10.5px;
    line-height: 1.2;
    letter-spacing: 0;
    text-align: center;
  }
  .touch-mode .pause-tab .icon,
  .touch-mode .pause-exits .button .icon {
    width: 20px;
    height: 20px;
  }
  .touch-mode .pause-exits .button {
    flex-grow: 0;
  }
  .touch-mode .pause-tab[aria-selected='true'] {
    background: linear-gradient(0deg, #e0b07029, #e0b07008);
    box-shadow: inset 0 -3px 0 var(--accent);
  }
}
/* On a phone the menu takes the whole screen, inside the safe area. */
@media (max-width: 520px) {
  .touch-mode dialog:has(.pause-menu) {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border: 0;
    border-radius: 0;
  }
  .touch-mode dialog:has(.pause-menu) .modal-top {
    top: max(10px, env(safe-area-inset-top));
    right: max(10px, env(safe-area-inset-right));
  }
  .touch-mode .pause-rail {
    padding: max(10px, env(safe-area-inset-top)) 10px 8px max(10px, env(safe-area-inset-left));
  }
  .touch-mode .pause-row {
    margin-right: 70px;
  }
  .touch-mode .pause-panels {
    padding-bottom: max(20px, env(safe-area-inset-bottom));
  }
}

/* Phone start screens fit the visible viewport; only the card strips scroll. */
html:has(body.touch-mode[data-screen]) {
  overflow: hidden;
  overscroll-behavior: none;
}
body.touch-mode[data-screen] {
  overscroll-behavior: none;
}
.character-scroll-hint {
  display: none;
}
.touch-mode .screens.active {
  top: var(--screen-top, 0px);
  bottom: auto;
  height: var(--screen-height, 100dvh);
}
.touch-mode .screen {
  overflow: clip;
  overscroll-behavior: none;
}
.touch-mode #screen-title .title-content,
.touch-mode #screen-title .title-content:has([data-credits='public']) {
  flex: 1;
  min-height: 0;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas: 'hero' 'credits';
  padding: max(56px, calc(env(safe-area-inset-top) + 48px)) max(16px, env(safe-area-inset-right)) 0
    max(16px, env(safe-area-inset-left));
  gap: 12px;
}
.touch-mode #screen-title .title-hero {
  height: 100%;
  min-height: 0;
}
.touch-mode #screen-title .title-logo {
  flex: 1;
  min-height: 0;
  width: 100%;
}
.touch-mode #screen-title .title-art {
  width: 100%;
  height: 100%;
  max-height: 100%;
  object-fit: contain;
}
.touch-mode #screen-title .title-welcome {
  flex-shrink: 0;
  padding: 0;
}
.touch-mode #screen-title .menu-item {
  min-height: 44px;
  padding-top: 8px;
  padding-bottom: 8px;
  font-size: 20px;
}
.touch-mode #screen-title .title-credits {
  grid-area: credits;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  overflow-x: auto;
  overflow-y: hidden;
  min-width: 0;
  padding: 4px 0 6px;
  touch-action: pan-x;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.touch-mode #screen-title .credit-production,
.touch-mode #screen-title .credit-planning,
.touch-mode #screen-title .credit-side {
  flex-shrink: 0;
  width: auto;
  padding: 0;
  border: 0;
}
.touch-mode #screen-title .credit-side,
.touch-mode #screen-title .credit-people {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 16px;
}
.touch-mode #screen-title .title-credits h2 {
  margin: 0 0 6px;
  font-size: 12px;
  line-height: 16px;
}
.touch-mode #screen-title .credit-person {
  display: grid;
  grid-template-columns: 44px 56px;
  justify-content: center;
  justify-items: center;
  align-items: center;
  gap: 6px;
  width: 144px;
}
.touch-mode #screen-title .credit-avatar {
  width: 40px;
  height: 40px;
}
.touch-mode #screen-title .credit-qr {
  width: 56px;
  height: 56px;
}
.touch-mode #screen-title .credit-name {
  grid-column: 1 / -1;
  width: 144px;
  font-size: 11px;
  line-height: 14px;
  letter-spacing: 0;
}
.touch-mode #screen-title .title-footer {
  height: auto;
  min-height: 30px;
  padding: 8px max(16px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom));
}
.touch-mode .title-fullscreen {
  top: max(8px, env(safe-area-inset-top));
  right: max(16px, env(safe-area-inset-right));
}
.touch-mode .setup-screen {
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right))
    max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
  align-items: flex-start;
}
.touch-mode .setup-card {
  height: auto;
  max-height: 100%;
  min-height: 0;
  padding: 16px;
  gap: 12px;
  margin: 0 auto;
  overflow-y: auto;
}
.touch-mode .setup-heading {
  flex-shrink: 0;
  gap: 6px;
}
.touch-mode .character-choice-controls {
  margin-top: 0;
  padding-top: 12px;
}
.touch-mode .character-choice-actions {
  gap: 10px;
}
.touch-mode .character-choice-summary {
  font-size: 12px;
}
.touch-mode .character-choice-summary .dye-label {
  gap: 6px;
  font-size: 11px;
  letter-spacing: 0;
}
.touch-mode .character-choice-actions > .button {
  padding: 12px 16px;
}
.touch-mode .character-choice-controls .dye-swatches {
  gap: 8px;
}
.touch-mode .character-choice-controls .dye-swatch {
  width: 44px;
  height: 44px;
}
.touch-mode .character-switch .character-choice-grid {
  --character-card-height: clamp(180px, 35dvh, 260px);
}
.touch-mode .setup-heading h2 {
  font-size: 22px;
}
.touch-mode .setup-heading h2::after {
  margin-top: 4px;
}
.touch-mode .setup-identity {
  flex-shrink: 0;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.touch-mode .setup-identity label {
  display: flex;
  flex-direction: column;
  font-size: 11px;
  letter-spacing: 0.12em;
}
.touch-mode .setup-identity label > span:not(.portrait) {
  font-size: 9px;
  margin: 4px 0;
  letter-spacing: 0;
}
.touch-mode .setup-identity label > input:not([type='radio']):not([type='checkbox']) {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  margin-top: auto;
  padding: 8px 4px;
  font-size: 16px;
}
.touch-mode .character-options {
  display: flex;
  flex-direction: column;
  flex: none;
  min-height: 0;
}
.touch-mode .character-legend {
  margin-bottom: 6px;
  font-size: 11px;
  letter-spacing: 0.2em;
}
.touch-mode .character-choice-grid {
  --character-card-height: clamp(208px, calc(var(--screen-height, 100dvh) - 440px), 260px);
  flex: none;
  height: var(--character-card-height);
  min-height: 0;
  grid-template-columns: none;
  grid-template-rows: minmax(0, 1fr);
  grid-auto-flow: column;
  grid-auto-columns: min(44vw, 160px);
  gap: 12px;
  padding: 6px;
  overflow-x: auto;
  overflow-y: hidden;
  touch-action: pan-x;
  overscroll-behavior: contain;
  scroll-snap-type: x proximity;
  scroll-padding: 6px;
  scrollbar-width: thin;
}
.touch-mode .character-choice {
  display: grid;
  grid-template-rows: minmax(0, 1fr) 88px;
  min-height: 0;
  scroll-snap-align: start;
}
.touch-mode .character-choice:focus-within {
  transform: none;
  outline-offset: -2px;
}
.touch-mode .character-art {
  min-height: 0;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
}
.touch-mode .character-name {
  margin-top: 0;
  padding: 6px;
}
.touch-mode .character-name strong {
  font-size: 14px;
}
.touch-mode .character-scroll-hint {
  display: block;
  flex-shrink: 0;
  margin: 6px 0 0;
  text-align: center;
  font-size: 11px;
  line-height: 16px;
  color: var(--muted);
}
.touch-mode .setup-actions {
  flex-shrink: 0;
  margin: 0;
}
.touch-mode #setup-flow {
  top: var(--screen-top, 0px);
  bottom: auto;
  height: var(--screen-height, 100dvh);
  padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right))
    max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left));
}
.touch-mode #setup-flow .spawn-picker {
  height: min(620px, 100%);
  min-height: 0;
  padding: 20px 16px;
  overflow: hidden;
  gap: 10px;
}
.touch-mode #setup-flow .spawn-picker h3 {
  font-size: 22px;
}
.touch-mode #setup-flow .spawn-grid {
  flex: 1;
  min-height: 0;
  grid-template-columns: none;
  grid-template-rows: minmax(0, 1fr);
  grid-auto-flow: column;
  grid-auto-columns: min(68vw, 260px);
  overflow-x: auto;
  overflow-y: hidden;
  padding: 6px;
  scroll-snap-type: x proximity;
  touch-action: pan-x;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.touch-mode #setup-flow .spawn-card {
  min-height: 0;
  scroll-snap-align: start;
}
.touch-mode #setup-flow .spawn-card img {
  flex: 1;
  min-height: 0;
  height: 0;
  object-fit: cover;
}
.touch-mode #setup-flow .spawn-card strong {
  font-size: 18px;
}
.touch-mode #setup-flow .spawn-card small {
  font-size: 12px;
}
.touch-mode #setup-flow .spawn-card:focus-visible {
  transform: none;
  outline-offset: -2px;
}
/* While typing, reserve the small visible area for the fields and back button. */
.touch-mode
  .screens[data-compact='true']
  .setup-card:has(.setup-identity input:focus)
  .character-options {
  display: none;
}
@media (orientation: portrait) and (max-height: 700px) {
  .touch-mode #setup-form {
    padding: 12px;
    gap: 8px;
  }
  .touch-mode .setup-heading h2 {
    font-size: 18px;
  }
  .touch-mode .setup-heading h2::after,
  .touch-mode .setup-identity label > span {
    display: none;
  }
}
@media (orientation: landscape) {
  .touch-mode .setup-card .character-choice-grid {
    --character-card-height: clamp(128px, calc(var(--screen-height, 100dvh) - 140px), 250px);
  }
  .touch-mode #screen-title .title-content,
  .touch-mode #screen-title .title-content:has([data-credits='public']) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
    grid-template-areas: 'hero credits';
    align-items: center;
  }
  .touch-mode #setup-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 0.85fr);
    grid-template-rows: auto auto auto auto;
    padding: 12px 16px;
    gap: 8px;
  }
  .touch-mode #setup-form .setup-heading {
    display: none;
  }
  .touch-mode .setup-identity label span {
    display: none;
  }
  .touch-mode .setup-identity,
  .touch-mode .setup-card > .form-error {
    grid-column: 1 / -1;
  }
  .touch-mode .setup-card > .character-options {
    grid-column: 1;
    grid-row: 2 / 5;
  }
  .touch-mode .setup-card > .character-choice-controls {
    position: static;
    grid-column: 2;
    grid-row: 2 / 4;
    align-self: end;
    margin: 0;
    border: 0;
    padding-top: 0;
  }
  .touch-mode .setup-actions {
    grid-column: 2;
    grid-row: 4;
  }
}
