/* Expedition field kit. Layout keeps the existing input/camera safe zones. */
:root { --field-ink:#122a30; --field-panel:#152d31; --field-gold:#f4c457; --field-line:#647366; --field-paper:#f2ecd8; }
html, body { font-family: 'Trebuchet MS', system-ui, sans-serif; color:var(--field-paper); background:var(--field-ink); }
button { font-family:inherit; }
#menu { background:linear-gradient(145deg,#0e2229c9,#284540bb),url('../assets/art/jungle-v2.webp') center/cover; }
.menuCard { border-radius:8px; background:#152d31; border:1px solid #77806a; border-top:4px solid var(--field-gold); box-shadow:0 16px 40px #08151899; }
.menuCard h1 { letter-spacing:-1px; text-shadow:none; }
.menuCard h1 .poo { color:var(--field-gold); }
.menuCard h1.wordmark .tMark { width:.8em; height:.8em; filter:none; }
.tagline { line-height:1.5; color:#cad5c5; }
.segmented, .wepBtn, #weaponPanel { border-radius:6px; }
.segmented { border-color:#667568; }
.segmented button { min-height:44px; }
/* Four landscape choices must share the row with their label on desktop. */
#landscapeSeg button { padding-left:12px; padding-right:12px; }
.segmented button.selected { background:var(--field-gold); color:#17282a; }
#btnStart,#btnAgain,#btnCloseHelp { background:var(--field-gold); border-radius:5px; box-shadow:0 3px 0 #987138; letter-spacing:1.5px; }
.teamBar { width:min(204px,28vw); display:flex; flex-direction:column; background:transparent; border:0; padding:0; border-radius:4px; }
.teamBar.right { border:0; }
.teamBar > .barOuter { display:none; }
.teamBar .econ { background:#132f3de8; padding:3px 5px; border-radius:3px; }
.teamBar .teamName { font-size:12px; letter-spacing:1.5px; text-shadow:none; }
.barOuter,.barInner { border-radius:2px; }
.barOuter { height:8px; border-color:#53695b; }
#hudCenter { background:#122a30eb; padding:5px 13px; border-radius:4px; border:1px solid #687b70; }
#hudTimer { text-shadow:none; color:var(--field-gold); font-size:26px; }
#hudRound { font-size:12px; letter-spacing:1px; }
#windBanner { top:calc(env(safe-area-inset-top,0px) + 58px) !important; border-radius:4px !important; box-shadow:none !important; background:#122a30eb !important; }
#btnWeapon { border-radius:5px; border:1px solid #d6b565; background:#122a30f2; min-height:44px; }
#weaponPanel { background:#122a30fa; border-color:#b9a779; box-shadow:0 6px 20px #07181bbb; }
.wepBtn { background:#264144; border:1px solid #647568; min-height:68px; }
.wepBtn .nm { font-size:12px; }
.wepBtn .role,.wepBtn .am { font-size:12px; }
.wepBtn.selected { background:#584e2d; border-color:var(--field-gold); }
.padBtn { background:#153038e8; border-color:#a4b0a2; box-shadow:none; border-radius:12px; }
#btnFire { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:0; background:var(--field-gold); color:#162c31; border-color:#ffe49b; box-shadow:0 3px 0 #8c6b30; }
#btnFire img { width:48px; height:42px; object-fit:contain; pointer-events:none; }
#btnFire span { font-size:13px; line-height:1; pointer-events:none; }
.padBtn { border-radius:50%; background:#173949ae; border:2px solid #b0c7c4b0; }
#btnHelp,#btnQuit { border-radius:5px; background:#142e34; }
.audioToggle { min-width:44px;min-height:44px;border:1px solid #7897a6;border-radius:5px;background:#142e34;color:#f2ecd8;display:flex;align-items:center;justify-content:center;gap:7px;cursor:pointer; }
.audioToggle[aria-pressed="true"] { border-color:#f4c457;color:#f4c457; }
.audioToggle:focus-visible { outline:2px solid #fff;outline-offset:2px; }
.audioToggle span { font-size:19px;line-height:22px;pointer-events:none; }
.audioToggle small { font-size:12px;pointer-events:none; }
#btnMuteGame { position:absolute;right:calc(8px + env(safe-area-inset-right));top:calc(50px + env(safe-area-inset-top));width:44px;height:44px;padding:2px;flex-direction:column;gap:0; }
#btnMuteGame small { font-size:8px;line-height:10px; }
.menuActions { display:flex;justify-content:center;align-items:center;gap:14px;grid-column:1 / -1; }
.menuActions #btnHowTo { min-height:44px; }
#btnMuteMenu { padding:3px 10px; }
.squadStrip { order:-1; display:flex; gap:5px; margin-top:0; margin-bottom:3px; }
.squadUnit { position:relative; flex:1; min-width:0; padding:0; border:2px solid #869eaa; border-radius:5px; background:#17333e; text-align:center; overflow:hidden; }
.squadUnit img { display:block; width:100%; height:auto; aspect-ratio:1; max-height:40px; object-fit:contain; }
.squadUnit strong { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); white-space:nowrap; }
/* health: a dark track (with a 1px inset outline) plus a colour-tiered fill,
   so a bar reads at a glance even when it is only a few px tall on phones. */
.squadUnit .hpBar { display:block; height:5px; margin-top:2px; background:#0a1a1f; border-radius:2px; box-shadow:inset 0 0 0 1px rgba(4,10,13,.85); overflow:hidden; }
.squadUnit .hpFill { display:block; height:100%; width:100%; transform-origin:left; }
.squadUnit .hpFill.hp-hi { background:#8ee54c; }
.squadUnit .hpFill.hp-mid { background:#f0b429; }
.squadUnit .hpFill.hp-lo { background:#e0503a; }
/* Phone (<=915px): only the acting unit and whoever was just hit (2 s) carry
   a number — everyone else reads bar-only. Desktop keeps every number, since
   there is room and no thumb in the way (critic loop 8, HUD "to 9" line). */
.squadUnit .hpNum { display:none; }
.squadUnit.active .hpNum, .squadUnit.recent-hit .hpNum {
  display:block; position:absolute; top:2px; right:2px; z-index:1;
  font-size:10px; line-height:1; padding:1px 3px; border-radius:3px;
  background:rgba(4,10,13,.78); color:#fff6d7; pointer-events:none;
}
@media (min-width:916px) {
  .squadUnit .hpNum {
    display:block; position:absolute; top:2px; right:2px; z-index:1;
    font-size:10px; line-height:1; padding:1px 3px; border-radius:3px;
    background:rgba(4,10,13,.78); color:#fff6d7; pointer-events:none;
  }
}
.squadUnit.active { border-color:var(--field-gold); color:var(--field-gold); }
.squadUnit.dead { opacity:.35; }
@media (max-height:500px) and (orientation:landscape) {
  .teamBar { padding:0;width:156px;max-width:25vw; }
  .teamBar .teamName { position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%); }
  .teamBar .econ { margin-top:0;padding:2px 5px; }
  #hudCenter { padding:4px 10px; }
  #hudTimer { font-size:24px; }
  #hudRound { font-size:10px; }
  #windBanner { top:calc(env(safe-area-inset-top,0px) + 50px) !important;min-height:28px !important;padding:3px 7px !important;gap:5px !important; }
  #windBanner > span:nth-child(1) { font-size:10px !important;letter-spacing:.5px !important; }
  #windBanner > span:nth-child(2),#windBanner > span:nth-child(3) { font-size:20px !important; }
  #windBanner > span:nth-child(4) { font-size:10px !important; }
  .squadUnit { padding:0; }
  .squadUnit img { max-height:32px; }
  .squadUnit strong { font-size:10px; }
  .menuCard { max-height:96dvh; padding:12px 24px; }
  .menuCard h1 { font-size:30px; }
  .tagline { margin-bottom:8px; font-size:13px; }
  .menuRow { margin:6px 0; }
  #btnStart { margin-top:10px; padding:12px; }
}
#aimHint { bottom:calc(73px + env(safe-area-inset-bottom)); padding:3px 9px; font-size:11px; border-radius:4px; }
.resCard { border:1px solid #82927d; background:#152d31; border-radius:7px; }
.resTeam { border-radius:4px; border-width:1px; }
.resTeam.win { box-shadow:none; }
.resButtons button { border-radius:4px; min-height:44px; }
.resButtons .resPrimary { background:var(--field-gold); box-shadow:0 3px 0 #987138; }
@media (prefers-reduced-motion:reduce) { .wepBtn,.barInner,.padBtn { transition:none; } }

/* Direct weapon selection, with the complete arsenal one tap away. */
#weaponDock { position:absolute;left:50%;bottom:calc(10px + env(safe-area-inset-bottom));transform:translateX(-50%);display:flex;gap:7px;align-items:center;pointer-events:auto;z-index:11; }
#quickWeapons { display:flex;gap:7px; }
.quickWeapon,#weaponDock #btnWeapon { position:relative;left:auto;bottom:auto;transform:none;width:64px;height:64px;padding:3px;border:2px solid #7897a6;border-radius:7px;background:#102e3fe8;color:#fff;box-shadow:0 3px 0 #06192399;touch-action:manipulation; }
.quickWeapon img { display:block;width:48px;height:48px;margin:auto;pointer-events:none; }
.quickCost { position:absolute;right:3px;bottom:2px;min-width:16px;padding:1px 3px;background:#102331;border-radius:3px;font-size:13px;font-weight:bold; }
.quickWeapon.selected,#weaponDock #btnWeapon.selected { border-color:#ffe45e;box-shadow:0 0 0 1px #ae852c,0 3px 0 #06192399;background:#384332; }
.quickWeapon:disabled { opacity:.42; }
.quickWeapon:focus-visible,#weaponDock #btnWeapon:focus-visible { outline:3px solid #fff;outline-offset:3px; }
#weaponDock #btnWeapon { display:flex;flex-direction:column;gap:1px;justify-content:center; }
#weaponDock #btnWeapon:active { transform:scale(.96); }
#weaponDock #btnWeapon .btnWepIco { width:32px;height:32px; }
#weaponDock #btnWeapon .btnWepTxt { font-size:0; }
#weaponDock #btnWeapon .btnWepTxt::after { content:'MORE';font-size:10px;letter-spacing:1px; }
#weaponPanel { bottom:calc(100px + env(safe-area-inset-bottom));max-height:calc(100dvh - 110px);overflow-y:auto; }
body.aiming #weaponDock { opacity:.25;pointer-events:none; }
#aimHint { bottom:calc(79px + env(safe-area-inset-bottom)); }
@media(max-width:650px){.quickWeapon,#weaponDock #btnWeapon { width:52px;height:56px; }.quickWeapon img { width:40px;height:40px; }#weaponDock,#quickWeapons { gap:4px; }}

#btnFire:disabled { opacity:.45;filter:saturate(.4); }

/* Keep the current slingshot/cancel instruction visible above the thumb. */
body.aiming #aimHint { opacity:1; }

/* Weapon identity stays attached to the dock, not over an actor or target. */
#weaponDock { bottom:calc(26px + env(safe-area-inset-bottom)); }
#weaponSummary { position:absolute;top:calc(100% + 4px);left:50%;transform:translateX(-50%);width:max-content;max-width:340px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:11px;line-height:14px;color:#fff6d7;background:#102331e8;border-radius:3px;padding:0 5px;pointer-events:none; }
#aimHint { bottom:calc(97px + env(safe-area-inset-bottom)); }

/* One jump action; a second deliberate tap selects a backward hop. */
.jumpAction { display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0; }
.jumpAction span { font-size:23px;line-height:25px;pointer-events:none; }
.jumpAction small { font-size:10px;line-height:12px;pointer-events:none; }
@media(min-width:701px) and (max-width:850px) {
  #padMove { gap:6px; }
  #padMove .padBtn { width:48px;height:48px; }
}
@media(max-width:700px) {
  #padMove { display:flex;gap:6px; }
  #padMove .padBtn { width:48px;height:48px; }
  #touchStrip { height:calc(120px + env(safe-area-inset-bottom)); }
}

/* Distinct roles remain visible without opening the full arsenal. */
.quickRole { position:absolute;left:4px;bottom:4px;font-size:9px;font-weight:bold;letter-spacing:.3px;color:#fff6d7; }
.quickWeapon img { width:40px;height:40px;margin-top:0; }
@media(max-height:500px) {
  /* F13: bounded + scrollable rather than growing above the viewport; the
   * panel opens scrolled to the top (js/input.js resets scrollTop on open),
   * so the first group is always what a player sees first. */
  #weaponPanel { bottom:calc(26px + env(safe-area-inset-bottom));grid-template-columns:repeat(4,minmax(0,1fr));gap:5px;padding:7px;max-height:180px; }
  #weaponPanel .weaponPanelMeta { top:-7px;margin:-7px -7px 0; }
  #weaponPanel .weaponGroupHeading { min-height:18px;margin-top:1px;padding:1px 5px;font-size:9px; }
  .weaponFilterChip { padding:3px 9px;font-size:10px; }
  /* height grows 70→84px for the MP-04 control/limitation line; the panel
   * already scrolls here (see above), so a taller tile just means slightly
   * more scrolling, not a layout break. */
  .wepBtn { position:relative;height:84px;min-height:84px;padding:5px 4px;justify-content:flex-start; }
  .wepBtn .ico { position:absolute;left:4px;top:4px;height:22px; }
  .wepBtn .ico img { width:22px;height:22px; }
  .wepBtn .nm { padding-left:22px;min-height:24px;font-size:11px;line-height:12px; }
  .wepBtn .role { font-size:10px;line-height:11px;padding-right:18px; }
  /* Judge r6 m7: the control line wraps in full (css/style.css); it keeps the
   * cost badge's bottom row clear, as a lock reason does below. */
  .wepBtn .ctrl { font-size:8px;line-height:9px;margin-bottom:12px; }
  .wepBtn .am { position:absolute;right:4px;bottom:4px;font-size:10px; }
  /* Judge round 4 m8: the ammo badge above sits in the tile's bottom row, so
   * a lock reason pushed down by a three-line role ran under "TRADED". The
   * reason keeps that row clear, and such a tile grows past its 84px minimum
   * instead of overlapping (other tiles keep their height). */
  .wepBtn { height:auto; }
  .wepBtn .ctrl.lockedReason { margin-bottom:14px; }
}

#btnFollow { position:absolute;top:calc(8px + env(safe-area-inset-top));left:calc(50% - 108px);width:44px;height:44px;border:1px solid #7897a6;border-radius:6px;background:#102331ed;color:#fff6d7;font-size:24px;line-height:25px;pointer-events:auto; }
#btnFollow small { display:block;font-size:8px;line-height:9px; }

/* Timed clusters expose one compact, full-size touch target. */
#shotFuse { position:absolute;left:calc(50% + 184px);bottom:calc(99px + env(safe-area-inset-bottom));width:48px;height:44px;padding:2px;background:#102331ed;color:#fff6d7;border:1px solid #7897a6;border-radius:7px;pointer-events:auto;z-index:10;font-size:9px; }
#shotFuse strong { display:block;color:#ffe45e;font-size:14px; }
#shotFuse:focus-visible { outline:2px solid #fff;outline-offset:2px; }
@media(max-width:700px) { #shotFuse { left:calc(50% + 158px); } }

/* Landscape field controls occupy at most 124px at the edges. */
#weaponDock #btnWeapon { width:108px;display:grid;grid-template-columns:30px 1fr;grid-template-rows:1fr 24px;column-gap:3px; }
#weaponDock #btnWeapon .btnWepIco { width:30px;height:30px;grid-row:1 / 3; }
/* Judge round 2 #14: the pill is a fixed-width tile, so a long weapon name
   ("Scatastrophe" desktop, "Apple of Your Demise" phone) used to clip
   mid-word or spill out above the button. A 2-line clamp is the hard
   backstop -- it can never grow past max-height, ellipsing instead of
   spilling -- and js/main.js adds .nm-long/.nm-xlong by name length so a
   long name still reads at a smaller size rather than immediately clamping.
   Judge round 3 m1: word-break:break-word allows a break ANYWHERE, including
   mid-word ("Scatastroph" / "e") once a multi-word name's 2-line clamp still
   doesn't have room -- normal/normal/manual below means a break only ever
   falls at a space or an explicit &shy;, never inside a word. */
#weaponDock #btnWeapon .btnWepTxt {
  align-self:end;font-size:10px;line-height:11px;max-width:100%;max-height:22px;
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  overflow:hidden;white-space:normal;word-break:normal;overflow-wrap:normal;hyphens:manual;
}
#weaponDock #btnWeapon .btnWepTxt.nm-long { font-size:9px;line-height:10px;max-height:20px; }
#weaponDock #btnWeapon .btnWepTxt.nm-xlong { font-size:8px;line-height:9px;max-height:18px; }
/* A name with one WORD longer than the pill can ever fit on a line (no space
   to wrap at, so word-break:normal above would just let it run past the box)
   gets its own single-line lane instead: smallest step-down font, no wrap
   attempt at all, an ellipsis if it still overflows -- never a mid-word cut. */
#weaponDock #btnWeapon .btnWepTxt.nm-word {
  display:block;-webkit-line-clamp:unset;-webkit-box-orient:unset;
  font-size:8px;line-height:20px;max-height:20px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
#weaponDock #btnWeapon .btnWepTxt::after { content:none; }
#weaponDock #btnWeapon .btnWepMore { font-size:8px;line-height:9px;letter-spacing:.4px;color:#cbd8dc; }
@media (max-height:500px) and (orientation:landscape) {
  /* P2#11 (audit-r2-visual-quality.md): weaponSummary hangs below the dock
   * ("top:100% + gap", inside the dock's OWN bottom reserve) rather than
   * being independently safe-area-inset, so it ate into that reserve and
   * left only ~5px above the literal viewport edge. #weaponDock's bottom
   * offset is raised just enough that, even after weaponSummary's own
   * height is subtracted, >=12px of clearance remains beyond the dock's
   * env(safe-area-inset-bottom) — measured by test/phone-hud-safe-area
   * -check.cjs. */
  #weaponDock { bottom:calc(28px + env(safe-area-inset-bottom));gap:5px; }
  #quickWeapons { gap:5px; }
  .quickWeapon,#weaponDock #btnWeapon { width:56px;height:44px;padding:1px; }
  .quickWeapon img { width:29px;height:29px;margin-top:0; }
  .quickRole { left:3px;bottom:2px;font-size:8px; }
  .quickCost { right:2px;bottom:1px;font-size:10px;min-width:12px;padding:0 2px; }
  #weaponDock #btnWeapon { width:96px;display:grid;grid-template-columns:26px 1fr;grid-template-rows:1fr 20px;column-gap:2px; }
  #weaponDock #btnWeapon .btnWepIco { width:26px;height:26px;grid-row:1 / 3; }
  #weaponDock #btnWeapon .btnWepTxt {
    align-self:end;font-size:10px;line-height:11px;max-height:20px;
    display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
    overflow:hidden;white-space:normal;word-break:break-word;
  }
  #weaponDock #btnWeapon .btnWepTxt.nm-long { font-size:9px;line-height:10px;max-height:18px; }
  #weaponDock #btnWeapon .btnWepTxt.nm-xlong { font-size:8px;line-height:9px;max-height:16px; }
  #weaponDock #btnWeapon .btnWepMore { align-self:start; }
  #weaponSummary { top:calc(100% + 1px);font-size:10px;line-height:12px;max-width:340px; }
  #shotFuse { bottom:calc(80px + env(safe-area-inset-bottom));left:calc(166px + env(safe-area-inset-left));width:44px;height:44px; }
  #touchStrip { height:calc(76px + env(safe-area-inset-bottom)); }
  #padMove { gap:6px;bottom:calc(12px + env(safe-area-inset-bottom)); }
  #padMove .padBtn { width:48px;height:48px; }
  #btnFire { width:68px;height:68px;bottom:calc(8px + env(safe-area-inset-bottom)); }
  #btnJump { width:48px;height:48px;right:calc(92px + env(safe-area-inset-right));bottom:calc(12px + env(safe-area-inset-bottom)); }
  #btnFire img { width:37px;height:34px; }
  .hintToast { bottom:calc(116px + env(safe-area-inset-bottom)); }
  /* A lesson may yield to a recap; current melee targets remain actionable. */
  body:has(.hintToast.show) #aimHint:not(.melee-hint):not(.material-hint) { visibility:hidden; }
  #aimHint { bottom:calc(116px + env(safe-area-inset-bottom));font-size:10px;padding:2px 6px; }
  /* F39: a combat beat (attack recap / damage line) owns this small lane.
   * The persistent regrowth/harvest pill is world-space and can land
   * anywhere on screen, including right over the recap — it steps aside
   * instead of the beat losing contrast. Nothing is deleted: it reappears
   * the instant hud.js clears the recap (drops .show). Ambient nameplate/
   * status tags are canvas-drawn (js/render/hud.js) and out of reach here,
   * so the beat itself is also boosted (contrast only, no size change) to
   * read above that busier background. */
  body:has(.hintToast.show[data-key="attack-result"]) #treePrompt { display:none; }
  .hintToast.show[data-key="attack-result"] {
    background:rgba(6,14,20,.95);
    box-shadow:0 3px 14px rgba(0,0,0,.55),0 0 0 1px rgba(255,233,138,.4);
    z-index:13;
  }
}
@media (max-height:500px) and (max-width:700px) and (orientation:landscape) {
  .quickWeapon { width:44px; }
  #weaponDock #btnWeapon { width:80px; }
  #weaponDock,#quickWeapons { gap:3px; }
}
/* START while the map builds (js/main.js startGame): an opacity pulse is
 * compositor-driven, so it keeps moving while generation blocks the main thread. */
@keyframes mpBuildPulse { from { opacity:1; } to { opacity:.5; } }
#btnStart.building { animation:mpBuildPulse .55s ease-in-out infinite alternate; will-change:opacity; }

/* ---------- Short landscape phones: thin top HUD (HUD height pass) ----------
   main.js measures uiTopPx from the team bars and #windBanner, and the camera
   frames inside that band, so every pixel cut here goes to the playfield.
   - economy is one line: "2/4 | SHARED 🌴1 🍌0" (pips hidden; the count says the same)
   - portraits are 26px with the health bar laid over their bottom edge:
     6px tall, dark-outlined, green/amber/red by HP, HP number on the acting unit
   - timer + round sit on one row; wind sits beside them (one centred pair)
   - NEXT MONKEY is a one-line pill under the timer (not a second box)
   - FOLLOW rides beside quit, labelled "FOLLOW" at this width; SOUND beside help
   Below 740px the narrow block after this one tightens the same row. */
@media (orientation:landscape) and (max-height:430px) {
  #hudTop { padding:calc(4px + env(safe-area-inset-top)) calc(98px + env(safe-area-inset-right)) 0 calc(98px + env(safe-area-inset-left)); }
  .teamBar { width:min(170px,calc(50vw - 225px)); max-width:none; min-width:0; flex-shrink:1; }
  .squadStrip { gap:4px; margin-bottom:2px; }
  .squadUnit { position:relative; border-width:2px; }
  .squadUnit img { height:26px; max-height:26px; width:100%; }
  .squadUnit .hpBar { position:absolute; left:0; right:0; bottom:0; height:6px; margin:0; border-radius:0; }
  .squadUnit.active .hpNum, .squadUnit.recent-hit .hpNum { top:1px; right:1px; font-size:9px; padding:0 2px; }
  .teamBar .econ { flex-wrap:nowrap; gap:4px; padding:2px 4px; line-height:14px; width:max-content; }
  .teamBar.right .econ { align-self:flex-end; }
  .econPips, .econLbl { display:none; }
  .econAmmo { padding-right:4px; }
  .econWorld { flex-basis:auto; gap:4px; }
  .econSharedLabel { font-size:11px; }
  /* timer block + wind flow as one pair, centred between the equal team bars */
  #teamBar0 { margin-right:auto; }
  #teamBar1 { margin-left:auto; }
  #hudTop { gap:6px; }
  #hudCenter { display:flex; align-items:center; gap:6px; padding:2px 8px; min-height:28px; box-sizing:border-box; }
  #hudTimer { font-size:22px; }
  #hudRound { max-width:66px; font-size:11px; line-height:12px; letter-spacing:.5px; text-align:left; }
  #hudNext { left:0; top:calc(100% + 3px);
    width:max-content; max-width:260px; max-height:none; padding:2px 7px;
    white-space:nowrap; text-overflow:ellipsis; line-height:13px; }
  #windBanner { position:relative !important; top:auto !important; left:auto !important;
    transform:none !important; flex:0 0 auto; min-height:28px !important; padding:2px 7px !important; }
  #windBanner > span:nth-child(2), #windBanner > span:nth-child(3) { font-size:17px !important; }
  #windBanner > span:nth-child(4) { font-size:11px !important; }
  /* "🍌 wind only" already says WIND: drop the label while the note shows */
  #windBanner:has(> span:nth-child(4):not(:empty)) > span:nth-child(1) { display:none; }
  #btnQuit, #btnHelp { top:calc(4px + env(safe-area-inset-top)); width:36px; height:36px; }
  #btnQuit { left:calc(8px + env(safe-area-inset-left)); }
  #btnHelp { right:calc(8px + env(safe-area-inset-right)); }
  #btnFollow { top:calc(4px + env(safe-area-inset-top)); left:calc(48px + env(safe-area-inset-left));
    width:44px; height:44px; display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:1px; padding:0; font-size:17px; line-height:1; }
  #btnFollow small { display:block; font-size:7px; line-height:1; letter-spacing:.3px; }
  #btnMuteGame { top:calc(4px + env(safe-area-inset-top)); right:calc(48px + env(safe-area-inset-right)); }
  #btnMuteGame small { display:none; }
}
/* Narrow short landscape (568-739px, e.g. SE 568x320, S9 658x320): same one
   row, tighter. ✕ ◎ ? drop to 32px so the bars keep ~122px; the
   economy is icons+counts ("2/4 🌴1 🍌0", titles still name them); the wind
   pill loses its WIND word, and a long round label wraps inside the timer box. */
@media (orientation:landscape) and (max-height:430px) and (max-width:739.98px) {
  /* right side is wider: the 44px sound button stays (see below) */
  #hudTop { gap:4px; padding:calc(4px + env(safe-area-inset-top)) calc(90px + env(safe-area-inset-right)) 0 calc(78px + env(safe-area-inset-left)); }
  .teamBar { width:min(150px,calc(50vw - 162px)); min-width:90px; }
  .squadStrip { gap:3px; }
  .squadUnit img { height:24px; max-height:24px; }
  .squadUnit.active .hpNum, .squadUnit.recent-hit .hpNum { font-size:8px; }
  .econSharedLabel { display:none; }
  .econPending { font-size:11px; }
  #hudCenter { gap:4px; padding:2px 6px; }
  #hudTimer { font-size:18px; }
  #hudRound { max-width:64px; letter-spacing:0; }
  #hudNext { max-width:146px; }
  #windBanner { gap:3px !important; padding:2px 6px !important; }
  #windBanner > span:nth-child(1) { display:none; }
  #windBanner > span:nth-child(2), #windBanner > span:nth-child(3) { font-size:14px !important; }
  /* "🍌 wind only" shrinks to its 🍌 (the dimmed pill still says wind is off) */
  #windBanner > span:nth-child(4) { font-size:0 !important; }
  #windBanner > span:nth-child(4)::first-letter { font-size:14px; }
  /* sound stays 44px: audio-controls-check pins that target at 568x320 */
  #btnQuit, #btnHelp, #btnFollow { width:32px; height:32px; }
  #btnQuit { left:calc(6px + env(safe-area-inset-left)); }
  #btnHelp { right:calc(6px + env(safe-area-inset-right)); }
  #btnFollow { left:calc(42px + env(safe-area-inset-left)); font-size:20px; line-height:22px; }
  #btnFollow small { display:none; }
  #btnMuteGame { right:calc(42px + env(safe-area-inset-right)); }
}

/* Compact touch landscapes keep the arsenal's own dismissal toggle reachable.
 * Match the dock's 28px offset (P2#11 above) + 44px height, with a 6px clearance. */
@media (max-height:500px) and (orientation:landscape) and (pointer:coarse) {
  #weaponPanel { bottom:calc(78px + env(safe-area-inset-bottom)); }
}

/* ---------- Phone flight/impact HUD auto-collapse ----------
 * audit-r2-visual-quality.md P0#3 / R2 item 12: at phone height the top team
 * bars (portraits + economy + wind) and the bottom weapon dock together cost
 * ~32% of the screen (js/main.js syncTouchLayout's uiTopPx + uiStripPx,
 * unchanged by the compact sizing above) — every one of them is secondary
 * once a shot is committed, and that footprint is exactly what let a
 * character render under the corner portraits or the weapon bar during
 * flight/impact. js/ui/hud.js toggles body.phoneActionCompact while
 * game.state==='fly' (which already runs through the impact hold), skipped
 * entirely for a flight-controlled weapon (game.flightUtility, e.g. Fart Pack/Wee Jet)
 * whose player still needs FIRE and the dock. Collapsing these to
 * display:none shrinks the DOM rects js/main.js measures uiTopPx/uiStripPx
 * from, so the camera (unedited) automatically frames a taller playfield —
 * no camera or game code changed, only what they measure. Desktop and the
 * non-touch/tablet-height cases never match this media query, so they are
 * unaffected regardless of the class. */
@media (orientation:landscape) and (max-height:430px) {
  body.phoneActionCompact #hudTop .squadStrip,
  body.phoneActionCompact #hudTop .econ,
  body.phoneActionCompact #weaponDock {
    display: none;
  }
  /* #windBanner's own position/display are set inline by js/ui/hud.js
   * (buildWindBanner/syncWind), which beats a plain stylesheet rule. */
  body.phoneActionCompact #windBanner { display: none !important; }
  /* Controls and the turn clock fold only once the shooter has nothing left
   * to do (js/ui/hud.js phoneControlsLive): a human's retreat window and a
   * live manual airburst keep them. */
  body.phoneActionCompact.phoneControlsIdle #hudCenter,
  body.phoneActionCompact.phoneControlsIdle #padMove,
  body.phoneActionCompact.phoneControlsIdle #btnJump,
  body.phoneActionCompact.phoneControlsIdle #btnFire {
    display: none;
  }
  /* Keep #touchStrip's measured height a small NON-zero value: js/main.js's
   * syncTouchLayout falls back to a hardcoded 84px strip when the measured
   * rect height is exactly 0 ("Math.round(h) || 84"), which would be worse
   * than doing nothing. */
  body.phoneActionCompact.phoneControlsIdle #touchStrip { height: calc(10px + env(safe-area-inset-bottom)); }
}
