/* Mobile viewport and tap areas. Insets are aliases so the QA fixture can
   simulate notches/home indicators without pretending to be physical Safari. */
:root {
  --viewport-height: 100vh;
  --viewport-top: 0px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}
@supports (height: 100svh) { :root { --viewport-height: 100svh; } }
@supports (height: 100dvh) { :root { --viewport-height: 100dvh; } }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
button, a, input, select { touch-action: manipulation; }
#app[data-view="wave"] #court { touch-action: none; }
/* Long presses on the game surface move the player instead of selecting HUD
   text or opening Safari's copy/image callout. Menu fields retain selection. */
#app[data-view="wave"] #court,
#app[data-view="wave"] #hud,
#app[data-view="wave"] #hud *,
#app[data-view="wave"] #stick,
#app[data-view="wave"] #stick * {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-user-drag: none;
}
#app, #title.overlay { min-height: var(--viewport-height); }
#arena.overlay { min-height: var(--viewport-height); }
@media (min-height: 601px) { #arena.overlay { height: var(--viewport-height); } }

/* A fixed outer sheet keeps its action row inside the visible browser area.
   Each existing inner scroller keeps stock, rewards, and choices accessible. */
#shop.overlay, #starter.overlay, #supply.overlay, #combine.overlay,
#results.overlay, #supply-characters.overlay, #account-panel.overlay,
#options.overlay, #confirm.overlay {
  position: fixed;
  inset: var(--viewport-top) 0 auto;
  height: var(--viewport-height);
  min-height: 0;
  max-height: none;
}
#shop.overlay, #starter.overlay, #supply.overlay, #combine.overlay,
#results.overlay, #supply-characters.overlay {
  padding-top: max(10px, var(--safe-top));
  padding-right: max(12px, var(--safe-right));
  padding-bottom: calc(var(--safe-bottom) + 16px);
  padding-left: max(12px, var(--safe-left));
}
#options.overlay, #confirm.overlay {
  --dialog-top: max(12px, var(--safe-top));
  --dialog-bottom: calc(var(--safe-bottom) + 16px);
  padding-inline: max(12px, var(--safe-left)) max(12px, var(--safe-right));
}
#account-panel.overlay {
  --account-top: max(12px, var(--safe-top));
  --account-bottom: calc(var(--safe-bottom) + 16px);
  padding-inline: max(12px, var(--safe-left)) max(12px, var(--safe-right));
}
#confirm .confirm-panel { max-height: calc(var(--viewport-height) - var(--dialog-top) - var(--dialog-bottom)); }
#account-panel .account-panel { max-height: calc(var(--viewport-height) - var(--account-top) - var(--account-bottom)); }
/* Resolve the report's percentage height against a bounded grid row.
   An auto-sized row can otherwise grow with the full victory recap and push
   the action shelf below the visible fixed sheet. */
#results.overlay { grid-template-rows: minmax(0, 1fr); overflow: hidden; }
#results .results-panel { max-height: 100%; }
#shop .shop-panel, #starter .trail-panel, #combine .fusion-panel { max-height: 100%; }
#shop .armory-scroll, #starter .setup-scroll,
#combine .fusion-scroll, #confirm #confirm-copy { -webkit-overflow-scrolling: touch; }
#shop .shop-footer { z-index: 2; }
#shop #next { min-height: 56px; font-size: 16px; padding: 12px 16px; justify-content: center; }
#shop-next-note { font-size: 12px; line-height: 1.3; }
#shop #next[aria-describedby] { white-space: normal; }

@media (max-width: 660px) {
  /* Primary action gets its own full-width row. Reroll and status sit below. */
  #shop .shop-footer { grid-template-columns: auto minmax(0, 1fr); gap: 8px 12px; padding-block: 10px; }
  #shop .shop-actions { display: contents; }
  #shop #next { grid-column: 1 / -1; grid-row: 1; width: 100%; }
  #shop #reroll { grid-column: 1; grid-row: 2; min-height: 44px; min-width: 106px; padding-inline: 12px; }
  #shop .armory-shelf-copy { grid-column: 2; grid-row: 2; }
  #shop .shop-feedback { font-size: 11px; line-height: 1.3; }
  #shop .classic-reward-actions .btn { min-height: 48px; }
  #starter #begin-run, #next-level { min-height: 56px; font-size: 16px; }
  #supply .catalog-pages .btn { min-width: 56px; min-height: 48px; }
  #confirm .review-actions .btn, #results .results-actions .btn { min-height: 52px; }
  #results #continue-endless.primary, #results #next-level.primary, #results #retry.primary { min-height: 56px; font-size: 14px; }
  input:not([type='checkbox']):not([type='radio']):not([type='range']), select, textarea { font-size: 16px; }
}
@media (max-height: 500px) and (min-width: 661px) {
  #shop .shop-actions .btn { min-height: 52px; }
  #shop .shop-footer { padding-block: 8px; }
}
@media (max-width: 660px) and (orientation: portrait) {
  /* One action row keeps more stock visible, including with a recipe pinned. */
  #shop .shop-footer { grid-template-columns: minmax(90px, 1fr) minmax(0, 2fr); gap: 4px 7px; padding-block: 8px; }
  #shop #reroll { grid-column: 1; grid-row: 1; min-width: 0; min-height: 48px; padding-inline: 7px; }
  #shop #next { grid-column: 2; grid-row: 1; padding-inline: 8px; }
  #shop .armory-shelf-copy { grid-column: 1 / -1; grid-row: 2; }
  #shop .armory-shelf-copy:has(#shop-next-note[hidden] + #shop-feedback:empty) { display: none; }
}

/* Supply is intentionally a whole-sheet scroller, unlike the Armory. */
#app[data-view="supply"] #supply, #app[data-view="characters"] #supply {
  height: var(--viewport-height);
  align-items: start;
  padding: max(10px, var(--safe-top)) max(12px, var(--safe-right))
    calc(var(--safe-bottom) + 16px) max(12px, var(--safe-left));
  -webkit-overflow-scrolling: touch;
}

/* Match menu and combat insets, including toolbar/notch simulations. */
#hud .hud-top {
  top: max(17px, var(--safe-top));
  right: max(18px, var(--safe-right));
  left: max(18px, var(--safe-left));
}
#hud .hud-bottom {
  bottom: max(21px, var(--safe-bottom));
  right: max(17px, var(--safe-right));
  left: max(17px, var(--safe-left));
}
#hud .boss-hud { top: max(121px, calc(var(--safe-top) + 105px)); }
#hud .boss-hud, #hud #wave-call { left: calc(50% + (var(--safe-left) - var(--safe-right)) / 2); }
@media (max-width: 650px) {
  #hud .hud-top { right: max(9px, var(--safe-right)); left: max(9px, var(--safe-left)); }
  #hud .boss-hud { top: max(115px, calc(var(--safe-top) + 101px)); }
}
@media (max-width: 650px) and (orientation: portrait) {
  #hud #wave-call { top: max(101px, calc(var(--safe-top) + 88px)); }
  #hud:has(.boss-hud:not([hidden])) #wave-call { top: max(159px, calc(var(--safe-top) + 145px)); }
}

/* A larger invisible slider lane is easier to acquire than the narrow track.
   The volume value stays beside its label and does not move while dragging. */
@media (max-width: 660px), (any-pointer: coarse) {
  #options .settings-volume input[type="range"],
  #options:not([data-paused]) .settings-volume input[type="range"] { height: 44px; min-height: 44px; }
  #options .settings-volume input::-webkit-slider-thumb { width: 22px; height: 22px; margin-top: -8.5px; }
  #options .settings-volume input::-moz-range-thumb { width: 18px; height: 18px; }
  #options .settings-switch { height: 44px; }
  #options .settings-actions .btn { min-width: 0; min-height: 52px; gap: 10px; padding-inline: 12px; font-size: 14px; }
  #shop .offer-lock { min-height: 48px; font-size: 11px; }
  #shop .sell { min-width: 48px; min-height: 48px; font-size: 11px; }
  #shop .combine-button { min-height: 48px; }
  #shop .gear-actions { gap: 6px; }
  #shop .offer-stat, #shop .offer-stat b { font-size: 11px; line-height: 1.25; }
}

/* Short landscape leaves room between the top readouts and weapon strip.
   Compact the transient briefing, preserving its instruction and boss bars. */
@media (max-height: 360px) and (orientation: landscape) {
  #hud .hud-top { top: max(8px, var(--safe-top)); }
  #hud .readout { padding-block: 4px; }
  #hud .vital-meter--hp { min-height: 21px; }
  #hud #health-text { font-size: 13px; }
  #hud #build-rule-readout { margin-top: 0; font-size: 9px; line-height: 1.15; }
  #hud .boss-hud {
    top: max(86px, calc(var(--safe-top) + 78px));
    padding-block: 4px;
  }
  #hud .boss-hud .boss-hud-label { gap: 5px; }
  #hud .boss-hud .boss-hud-label .micro { font-size: 9px; letter-spacing: .04em; }
  #hud .boss-hud[data-finale] { gap: 8px; }
  #hud #wave-call,
  #hud:has(.boss-hud:not([hidden])) #wave-call {
    top: max(91px, calc(var(--safe-top) + 83px));
    width: min(580px, calc(100% - max(16px, var(--safe-left)) - max(16px, var(--safe-right))));
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    padding: 5px 14px 8px;
  }
  #hud:has(.boss-hud:not([hidden])) #wave-call { top: max(125px, calc(var(--safe-top) + 117px)); }
  #hud .wave-call-art { display: none; }
  #hud #wave-call .micro { font-size: 8px; line-height: 1.2; }
  #hud #wave-call strong { margin-top: 1px; font-size: 16px; line-height: 1.1; }
  #hud #wave-call small { margin-top: 2px; font-size: 11px; line-height: 1.25; }
}
