/* On-screen controls. Hidden entirely unless the game mounts them, so desktop
   pays nothing — not even a hit-test region. */

/* Player-adjustable, set on <html> by Settings › Controls:
     --tc-scale     0.8 .. 1.4   button size
     --tc-opacity   0.3 .. 1     how much of the view the pad is allowed to take
   Handedness is a class, because mirroring is a layout change, not a number. */
:root { --tc-scale: 1; --tc-opacity: 1; }

#touch-ui { display: none; }
#touch-ui.on { display: block; }
#touch-ui .tc-btn, #tc-more, #tc-pause { opacity: var(--tc-opacity); }

#touch-ui .tc-zone {
  position: fixed;
  top: 0;
  bottom: 0;
  z-index: 55;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
/* The move zone stops short of the buttons so a stray thumb cannot grab both. */
#touch-ui #tc-move { left: 0; width: 46vw; }
#touch-ui #tc-look { right: 0; width: 54vw; }

/* ---- floating thumbstick ---- */
/* Above the buttons, so the sprint lock is never drawn under a control on
   the stick side. It takes no touches, so this changes nothing you can hit. */
#tc-stick {
  position: fixed;
  z-index: 58;
  width: 132px; height: 132px;
  margin: -66px 0 0 -66px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .12s;
}
#tc-stick.on { opacity: 1; }
#tc-stick-base {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid rgba(216, 208, 186, .34);
  background: radial-gradient(circle, rgba(10,12,14,.42), rgba(10,12,14,.16) 70%, transparent 72%);
  box-shadow: 0 2px 14px rgba(0,0,0,.55), inset 0 0 18px rgba(0,0,0,.25);
}
#tc-stick-knob {
  position: absolute; left: 50%; top: 50%;
  width: 58px; height: 58px;
  margin: 0; border-radius: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 38% 32%, rgba(232,226,208,.88), rgba(120,116,104,.64));
  border: 1px solid rgba(216, 208, 186, .42);
  box-shadow: 0 3px 12px rgba(0,0,0,.65);
}
/* The sprint lock rides above the stick while it is held: drag up into it
   and let go to keep running hands-free. touch.js arms it past 1.55 stick
   radii, which is where this sits at both stick sizes. */
#tc-sprint-lock {
  position: absolute; left: 50%; top: -58%;
  width: 44px; height: 44px; margin-left: -22px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(226, 220, 202, .3);
  background: rgba(12, 14, 16, .5);
  color: var(--cream-600, #cfc8b6);
  opacity: .55;
  transition: transform .1s, background .1s, opacity .1s;
}
#tc-sprint-lock svg,
#tc-sprint-badge svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}
#tc-stick.arm #tc-sprint-lock {
  opacity: 1; transform: scale(1.18);
  background: rgba(196, 140, 40, .72);
  border-color: rgba(240, 196, 104, .9);
  color: var(--cream-100, #fff6de);
}

/* Latched: a small stamp under the top-centre HUD, so it is obvious why the
   player is still running with no thumb down. Touching the stick stops it. */
#tc-sprint-badge {
  position: fixed; z-index: 57;
  left: 50%; top: calc(max(8px, env(safe-area-inset-top)) + 52px);
  transform: translateX(-50%);
  display: none; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: rgba(150, 104, 28, .72);
  border: 1px solid rgba(240, 196, 104, .55);
  color: var(--cream-100, #fff6de);
  font: 700 10px/1 var(--font-mono);
  letter-spacing: .12em; text-transform: uppercase;
  pointer-events: none;
}
#tc-sprint-badge svg { width: 15px; height: 15px; }
#touch-ui.sprint-locked #tc-sprint-badge { display: flex; }

/* ---- action buttons: an ARC, positioned by the layout model ----
 *
 * This replaces a fixed 3x4 CSS grid pinned to the bottom-right corner. The
 * grid was ~220px wide and up to 264px tall on every device, in a place the
 * player could not change — the v0.14 audit measured it as too much of the
 * play field and unadjustable, which it was.
 *
 * Positions now come from src/input/touch.js, which places each control on a
 * thumb arc and lets the player drag it somewhere else. CSS's job here is only
 * to make them round, legible and above the right things: every left/top is
 * written by applyLayout().
 */
#tc-buttons { position: fixed; inset: 0; z-index: 57; pointer-events: none; }

#touch-ui .tc-btn {
  position: fixed;
  pointer-events: auto;
  /* left/top are the CENTRE, so a size change grows around the thumb rather
     than away from it. */
  transform: translate(-50%, -50%);
  /* applyLayout() writes width/height; 44px is the WCAG / audit floor. */
  min-width: 44px; min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(226, 220, 202, .32);
  background: rgba(14, 16, 18, .5);
  color: var(--cream-600);
  font: 700 13px/1 var(--font-ui);
  letter-spacing: .04em;
  text-shadow: 0 1px 2px var(--ink);
  backdrop-filter: none;               /* deliberately not blurred: too costly */
  box-shadow: 0 2px 10px rgba(0,0,0,.5);
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-fast, .08s) var(--ease-out, ease),
    background var(--dur-fast, .1s), opacity .18s var(--ease-out, ease),
    border-color var(--dur-fast, .1s);
}
#touch-ui .tc-btn svg,
#tc-more svg,
#tc-pause svg {
  width: 46%; height: 46%;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
  pointer-events: none;
}
#touch-ui .tc-btn.down {
  background: rgba(120, 74, 42, .62);
  border-color: rgba(231, 184, 115, .6);
  transform: translate(-50%, -50%) scale(.94);
}
/* Fire earns its size from the layout model, and its colour from being the
   thing you press most. */
#touch-ui .tc-fire {
  background: rgba(96, 40, 22, .46);
  border-color: rgba(231, 160, 110, .45);
}
/* Count badge on the grenade / chatterbox buttons. The compact HUD tier hides
   the #nade-box plate on phones, so the pad button is the only surface left
   that can say HOW MANY — a small stamped count on its shoulder, not a second
   plate crowding the pad. */
#touch-ui .tc-btn .tc-count {
  position: absolute;
  top: -3px; right: -3px;
  min-width: 17px; height: 17px;
  padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px;
  border: 1px solid rgba(226, 220, 202, .38);
  background: rgba(10, 12, 14, .88);
  color: var(--cream-100, #f5efdf);
  font: 700 11px/1 var(--font-mono);
  font-style: normal;
  letter-spacing: 0;
  pointer-events: none;
}
#touch-ui .tc-btn .tc-count:empty { display: none; }

/* Hidden by the player, in this orientation. */
#touch-ui .tc-btn.tc-hidden { display: none; }
/* Standing where the interaction prompt is: fades so the words win, without
   moving and breaking the muscle memory the arc exists to build. */
#touch-ui .tc-btn.tc-yield { opacity: calc(var(--tc-opacity) * .22); }

/* iOS: a long-press on a labelled button must not pop the selection callout
   over the pad or select the caption mid-fight. */
#touch-ui .tc-btn, #tc-more, #tc-pause {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

/* Contextual controls: present in the layout, invisible and untouchable until
   they can actually do something. */
/* Contextual buttons keep their own 0/1 fade; the opacity SETTING decides what
   "on" is worth, so the two multiply rather than fight. */
#touch-ui .tc-btn.ctx { opacity: 0; pointer-events: none; transform: translate(-50%,-50%) scale(.86); }
#touch-ui .tc-btn.ctx.live { opacity: var(--tc-opacity); pointer-events: auto; transform: translate(-50%,-50%); }
#tc-stick { opacity: 0; }
#tc-stick.on { opacity: var(--tc-opacity); }
/* USE is the one worth drawing the eye to — it is how you buy, open and repair. */
#touch-ui .tc-use.live {
  border-color: rgba(240, 200, 120, .85);
  background: rgba(120, 92, 20, .5);
  animation: tcPulse 1.1s ease-in-out infinite;
}

/* The rarely-used three live behind the tray, so the arc stays short. */
#touch-ui .tc-btn.xtra { display: none; }
#touch-ui.show-xtra .tc-btn.xtra { display: flex; }
/* The tray handle sits at the inboard end of the arc, where the thumb already
   travels, rather than up the edge where a look drag starts. */
#tc-more {
  position: fixed; z-index: 57;
  width: 44px; height: 44px; border-radius: 50%;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(226,220,202,.22);
  background: rgba(14,16,18,.42);
  color: var(--cream-900); font: 700 17px/1 var(--font-ui);
  pointer-events: auto; touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
#touch-ui.show-xtra #tc-more { background: rgba(120,92,20,.45); color: var(--paper-bright); }

/* Fire is the one control that earns extra size and a fixed home. The
   optional left-thumb FIRE is the same trigger, so it wears the same red. */
#touch-ui .tc-fire,
#touch-ui .tc-lfire {
  width: 88px; height: 88px;
  font-size: 15px;
  color: var(--tone-f0e4d4);
  background: rgba(141, 18, 12, .52);
  border-color: rgba(212, 91, 80, .55);
  box-shadow: 0 3px 14px rgba(0,0,0,.55), 0 0 16px rgba(141,18,12,.22);
}
#touch-ui .tc-fire.down,
#touch-ui .tc-lfire.down {
  background: rgba(189, 36, 23, .72);
  border-color: rgba(240, 140, 120, .7);
}
/* Switched off in Settings: not part of the pad, even in the editor. */
#touch-ui .tc-btn.tc-off,
#touch-ui.editing .tc-btn.tc-off { display: none !important; }

@keyframes tcPulse { 50% { box-shadow: 0 0 16px rgba(240,200,120,.5); } }

/* An empty mag with rounds left is the one moment the thumb side needs to
   shout. Same glow family as the live use-button; the button never moves. */
#touch-ui .tc-btn.tc-reload.urgent {
  border-color: rgba(240, 200, 120, .85);
  box-shadow: 0 0 0 2px rgba(240, 200, 120, .35), 0 0 18px rgba(240, 200, 120, .3);
  animation: tcPulse 1.1s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  #touch-ui .tc-use.live, #touch-ui .tc-btn.tc-reload.urgent,
  #rotate-hint .rotate-icon svg { animation: none; }
  #tc-stick, #touch-ui .tc-btn { transition: none; }
}

#tc-pause {
  position: fixed;
  top: max(2px, env(safe-area-inset-top));
  right: max(2px, env(safe-area-inset-right));
  z-index: 59;                 /* above the relocated points box, see below */
  touch-action: none;
  width: 46px; height: 46px;   /* 42 was under the 44px minimum target */
  min-width: 44px; min-height: 44px;
  border-radius: 0;
  border: 1px solid rgba(190,170,135,.22);
  background: rgba(8,10,12,.58);
  color: var(--paper-dim);
  font: 700 14px/1 var(--font-ui);
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 2px 8px rgba(0,0,0,.4);
}
#tc-pause:active { color: var(--cream-500); border-color: rgba(190,170,135,.42); filter: brightness(1.08); }
@media (display-mode: standalone), (display-mode: fullscreen) {
  #tc-pause {
    top: max(2px, env(safe-area-inset-top, 0px));
    right: max(2px, env(safe-area-inset-right, 0px));
  }
}
#tc-more {
  border-radius: 50%;
  border-color: rgba(190,170,135,.2);
  background: rgba(10,12,14,.48);
  color: var(--paper-dim);
}

/* Landscape phones are short: shrink so the controls do not eat the view. */
@media (orientation: landscape) and (max-height: 460px) {
  /* Button sizes come from the layout model, which is already keyed on the
     short edge — nothing to override here but the stick. */
  #tc-stick { width: 108px; height: 108px; margin: -54px 0 0 -54px; }
  #tc-stick-knob { width: 48px; height: 48px; }
}

/* Portrait: block interaction and nudge the player to rotate. */
#rotate-hint {
  position: fixed; inset: 0; z-index: 95;
  display: none;
  align-items: center; justify-content: center;
  flex-direction: column; gap: 16px;
  background: rgba(3, 4, 6, .94);
  color: var(--tone-ebe4d4);
  font-family:var(--font-ui);
  letter-spacing: .1em; text-transform: uppercase; text-align: center;
  padding: max(24px, env(safe-area-inset-top)) 28px max(24px, env(safe-area-inset-bottom));
}
#rotate-hint .rotate-icon {
  width: 80px; height: 80px;
  display: flex; align-items: center; justify-content: center;
  border: 2px solid rgba(190, 160, 110, .35);
  border-radius: 12px;
  background: rgba(12, 14, 16, .72);
  box-shadow: 0 8px 32px rgba(0, 0, 0, .55), inset 0 1px rgba(255, 240, 215, .06);
}
#rotate-hint .rotate-icon svg {
  width: 52px; height: 52px;
  fill: none; stroke: var(--cream-700); stroke-width: 2.2;
  stroke-linecap: round; stroke-linejoin: round;
  animation: rotNudge 2s ease-in-out infinite;
}
#rotate-hint .rotate-title {
  font: 800 20px/1.2 var(--font-display);
  letter-spacing: .14em;
  color: var(--tone-f0e8d6);
  text-shadow: 0 2px 8px var(--ink);
}
#rotate-hint .rotate-sub {
  font: 400 13px/1.55 var(--font-ui);
  font-style: italic;
  letter-spacing: .03em;
  text-transform: none;
  color: var(--tone-9a9284);
  max-width: 300px;
}
@keyframes rotNudge { 35% { transform: rotate(-90deg); } 100% { transform: rotate(-90deg); } }
html.is-touch.portrait-block #rotate-hint { display: flex; }
/* Escape hatch for rotation-locked devices — secondary, not the main path. */
#rotate-anyway {
  margin-top: 10px; padding: 11px 18px; min-height: 44px;
  cursor: pointer; pointer-events: auto;
  background: transparent; border: 1px solid rgba(190, 160, 110, .28);
  border-radius: 3px; color: var(--tone-8a8378);
  font: 700 10px/1 var(--font-mono); letter-spacing: .14em; text-transform: uppercase;
  opacity: .75;
}
#rotate-anyway:active { background: rgba(120, 25, 18, .45); color: var(--cream-600); opacity: 1; }

/* The touch HUD arrangement moved to hud-layout.css, which now owns every
   HUD position at every size. This file is the on-screen CONTROLS: the pad,
   the stick, the pause button and the orientation gate. */

/* Menus need bigger hit targets and to fit a short landscape viewport. */
html.is-touch .mbtn { min-height: 46px; font-size: 14px; }
html.is-touch .diff-btn { min-height: 40px; padding: 10px 16px; }
html.is-touch .slider-row input { height: 30px; }

/* ---- persona picker on the title screen ---- */
.persona-btn {
  display: flex; align-items: center; gap: 7px;
  padding: 8px 13px; cursor: pointer; pointer-events: auto;
  background: rgba(10,13,16,.72); border: 1px solid rgba(150,150,150,.22); border-radius: 3px;
  color: var(--paper-mute); font: 700 11px/1 var(--font-mono); letter-spacing: .1em; text-transform: uppercase;
  transition: color .15s, border-color .15s, background .15s;
}
.persona-btn:hover { color: var(--cream-600); border-color: var(--steel-400); }
.persona-btn.sel { color: var(--paper-bright); background: rgba(120,25,18,.42); border-color: var(--denied); }
.pb-dot { width: 9px; height: 9px; border-radius: 50%; box-shadow: 0 0 0 1px rgba(0,0,0,.6) inset; }
#callsign-row { display: flex; align-items: center; gap: 10px; margin-top: 9px; }
#callsign { color: var(--tone-c7bfa9); font: 700 12px/1 var(--font-mono); letter-spacing: .16em; }
#callsign-reroll {
  cursor: pointer; pointer-events: auto;
  /* 24px here used to beat menu.css's 44px minimum purely because touch.css
     loads later. Sized correctly at source instead. */
  width: 44px; height: 44px; border-radius: 3px;
  background: rgba(10,13,16,.72); border: 1px solid rgba(150,150,150,.22);
  color: var(--paper-mute); font-size: 13px; line-height: 1;
}
#callsign-reroll:hover { color: var(--cream-500); border-color: var(--steel-400); }
html.is-touch .persona-btn { padding: 11px 15px; font-size: 12px; }
/* 24x24 is far under the 44px minimum — this is a thumb, not a cursor. */
html.is-touch #callsign-reroll { width: 44px; height: 44px; font-size: 18px; }
html.is-touch .ctl-tab { min-height: 44px; }
html.is-touch #coop-input { min-height: 48px; }

/* ---------------------------------------------------------------------------
   Pause / game-over panels on a phone.

   The .panel is a desktop dialog: 38px/48px padding, a two-column stats grid and
   180px sliders. On a 390px-tall landscape phone that is taller than the viewport
   and wider than is comfortable, which is the "funky" look. Reflow rather than
   just shrink — a scaled-down desktop dialog still reads as a desktop dialog.
   --------------------------------------------------------------------------- */
html.is-touch .panel {
  padding: 12px 12px;
  max-width: min(560px, 98vw);
  max-height: min(94vh, calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom) - 8px));
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: 5px;
}
html.is-touch .panel h2 { font-size: clamp(22px, 6vw, 34px); }
html.is-touch .panel .subtitle { margin-top: 8px; font-size: 11px; letter-spacing: .2em; }

/* Stats read better as rows than as a squeezed two-column grid. */
html.is-touch .panel .stats {
  grid-template-columns: 1fr auto;
  gap: 7px 14px; margin: 14px 0 6px; max-width: none; padding: 12px 0;
}
html.is-touch .panel .stats span { font-size: 10px; }
html.is-touch .panel .stats b { font-size: 14px; }

/* Sliders: full width, and a thumb-sized track. */
html.is-touch .slider-row {
  display: grid; grid-template-columns: minmax(7em, 9em) 1fr 3.6em;
  align-items: center; gap: 10px; margin-top: 11px; font-size: 10px;
}
html.is-touch .slider-row input { width: 100%; height: 34px; }
html.is-touch .slider-row .val { text-align: right; }

/* Buttons stack full width so they are unmissable with a thumb. */
html.is-touch .panel .menu-col { margin-top: 10px; gap: 6px; width: 100%; }
html.is-touch .panel .mbtn {
  min-width: 0; width: 100%; min-height: 44px;
  justify-content: center; font-size: 15px;
}
/* The graphics-tier row wraps instead of overflowing. */
html.is-touch .panel .diff-row,
html.is-touch .panel [data-q] { flex-wrap: wrap; }
html.is-touch .panel [data-q] { min-height: 44px; padding: 10px 16px; }

/* The touch pad must not sit on top of an open panel. */
html.is-touch #pause-screen.active ~ #touch-ui,
html.is-touch #gameover-screen.active ~ #touch-ui { display: none; }


/* ---------------------------------------------------------------------------
   LEFT-HANDED. The arc mirrors itself inside the layout model — including a
   custom layout the player dragged — so all that is left here is the two drag
   surfaces and the tray handle.
   --------------------------------------------------------------------------- */
html.left-handed #touch-ui #tc-move { left: auto; right: 0; }
html.left-handed #touch-ui #tc-look { right: auto; left: 0; }

/* ---------------------------------------------------------------------------
   EDIT LAYOUT. Drag anything anywhere, per orientation.
   --------------------------------------------------------------------------- */
#touch-ui.editing { display: block; }
#touch-ui.editing .tc-zone { pointer-events: none; }
/* Everything is visible and grabbable while editing, including the contextual
   controls that are normally waiting for something to happen. */
#touch-ui.editing .tc-btn,
#touch-ui.editing .tc-btn.ctx,
#touch-ui.editing .tc-btn.xtra {
  display: flex !important;
  opacity: 1 !important;
  pointer-events: auto !important;
  transform: translate(-50%, -50%) !important;
  border-style: dashed;
  border-color: rgba(231, 184, 115, .7);
  cursor: grab;
}
#touch-ui.editing .tc-btn.tc-hidden {
  opacity: .3 !important;
  border-color: rgba(150, 145, 130, .5);
}
#touch-ui.editing .tc-btn.tc-picked {
  border-style: solid;
  border-color: var(--amber-hot);
  box-shadow: 0 0 0 3px rgba(231, 184, 115, .3), 0 4px 16px rgba(0,0,0,.6);
}
#touch-ui.editing #tc-stick { opacity: .35; }
#touch-ui.editing #tc-sprint-badge { display: none; }

/* ---------------------------------------------------------------------------
   THE LAYOUT EDITOR BAR. Deliberately a bar and not a panel: the thing being
   edited is the whole screen behind it, so it takes one strip and gets out of
   the way. It also sits at the TOP, because the controls being dragged live at
   the bottom.
   --------------------------------------------------------------------------- */
#touch-editor {
  position: fixed; z-index: 96;
  top: 0; left: 0; right: 0;
  padding: max(8px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-right))
           10px max(10px, env(safe-area-inset-left));
  background: linear-gradient(180deg, rgba(6,8,10,.97), rgba(6,8,10,.86) 76%, rgba(6,8,10,0));
  pointer-events: none;
}
#touch-editor[hidden] { display: none; }
.te-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  max-width: 900px; margin: 0 auto;
  pointer-events: auto;
}
.te-copy { flex: 1 1 190px; min-width: 0; }
.te-copy b {
  display: block; color: var(--cream-200);
  font: 800 15px/1.2 var(--font-display);
  letter-spacing: .04em; text-transform: uppercase;
}
.te-copy span {
  display: block; margin-top: 2px; color: var(--paper-dim);
  font: 400 12px/1.4 var(--font-ui); font-style: italic;
}
.te-picked {
  display: flex; align-items: center; gap: 8px; flex: 1 1 240px; min-width: 0;
  padding: 6px 10px;
  background: rgba(20,24,28,.9);
  border: 1px solid rgba(231,184,115,.4); border-radius: 4px;
}
.te-picked[hidden] { display: none; }
#te-picked-name {
  flex: 0 0 auto; max-width: 96px; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis;
  color: var(--amber-hot); font: 700 11px/1 var(--font-mono);
  letter-spacing: .1em; text-transform: uppercase;
}
.te-picked label {
  color: var(--paper-dim); font: 700 10px/1 var(--font-mono);
  letter-spacing: .1em; text-transform: uppercase;
}
.te-picked input[type="range"] { flex: 1 1 70px; min-width: 60px; height: 34px; accent-color: var(--copper); }
.te-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.te-actions .diff-btn, .te-actions .mbtn { min-height: 44px; }
.te-actions .mbtn { min-width: 0; width: auto; padding: 12px 22px; }
@media (max-width: 560px) {
  .te-copy span { display: none; }
  .te-picked { flex-basis: 100%; order: 3; }
}
