/* Combat placement belongs here; shared surfaces and states use HUD components. */
body:not(.touch) #abilities #ab-5 .defenseLabel{position:absolute;inset:auto 0 var(--hud-space-1);z-index:3;white-space:pre-line;text-align:center;pointer-events:none;background:var(--hud-surface-glass);color:var(--hud-accent);font:var(--hud-weight-strong) var(--hud-text-xs)/1 var(--hud-font-label);}
body:not(.touch) #abilities #ab-5 .n{top:var(--hud-space-1);right:var(--hud-space-1);bottom:auto;left:auto;transform:none;background:var(--hud-surface-glass);z-index:3;}
body:not(.touch) #abilities #ab-5 .guardTicks{left:50%;right:auto;bottom:calc(100% + var(--hud-space-1));transform:translateX(-50%);white-space:nowrap;font:var(--hud-weight-strong) var(--hud-text-xs)/var(--hud-leading) var(--hud-font-label);background:var(--hud-surface-glass);}
body:not(.touch) #abilities #ab-5.defense-active{outline:var(--hud-border-width) solid var(--hud-accent);}
body:not(.touch) #abilities #ab-5:focus-visible{outline:var(--hud-border-width) solid var(--hud-focus);}
body:not(.touch) #abilities #ab-5 .desktopControlState{inset:20% 0 auto;}
body.touch #ab-5 .defenseLabel{display:none;}
#desktopControl[hidden],.desktopControlState[hidden]{display:none!important;}
#desktopControl{
  position:fixed;left:50%;bottom:clamp(230px,36vh,380px);transform:translateX(-50%);
  z-index:12;pointer-events:none;max-width:min(600px,calc(100vw - var(--hud-space-6)));width:max-content;
  padding:var(--hud-space-2) var(--hud-space-3);border:var(--hud-border-width) solid var(--hud-danger);
  border-radius:var(--hud-radius);background:var(--hud-surface-glass);color:var(--hud-text);text-align:center;
}
.desktopControlEffects{display:flex;justify-content:center;flex-wrap:wrap;gap:var(--hud-space-2) var(--hud-space-4);}
.desktopControlEffect{display:flex;align-items:center;gap:var(--hud-space-2);font:var(--hud-weight-strong) var(--hud-text-count)/var(--hud-leading-title) var(--hud-font-display);}
.desktopControlEffect img{width:28px;height:28px;}
.desktopControlEffect time{color:var(--hud-accent);font-variant-numeric:tabular-nums;}
.desktopControlHint{margin-top:var(--hud-space-1);}
body:not(.touch) #abilities .desktopControlState{position:absolute;inset:auto 0 22%;z-index:5;pointer-events:none;text-align:center;padding:var(--hud-space-1) 0;font:var(--hud-weight-strong) var(--hud-text-xs)/var(--hud-leading) var(--hud-font-label);color:var(--hud-danger);}
body:not(.touch) #abilities .desktop-control-blocked{outline:var(--hud-border-width) solid var(--hud-danger);outline-offset:var(--hud-border-hairline);}
body.touch #desktopControl,body.touch .desktopControlState{display:none;}
@media(max-height:500px){#desktopControl{bottom:200px;padding:var(--hud-space-1) var(--hud-space-2);}.desktopControlEffect{font-size:var(--hud-text-body);}.desktopControlHint{font-size:var(--hud-text-sm);}}
#combatChrome[hidden],#combatRespawn[hidden],.combatUpgrade[hidden],.combatSkillState[hidden]{display:none!important;}
#combatChrome{position:fixed;inset:0;z-index:9;pointer-events:none;}
#combatChrome button{pointer-events:auto;touch-action:manipulation;}
#combatTeams{position:absolute;left:calc(var(--sal) + 136px);top:calc(var(--sat) + var(--hud-space-2));right:calc(var(--sar) + 64px);height:var(--hud-target);display:flex;align-items:center;justify-content:space-around;gap:var(--hud-space-2);padding:var(--hud-space-1) var(--hud-space-2);}
.combatTeam{display:grid;grid-template-columns:auto auto;gap:0 var(--hud-space-1);min-width:0;font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);}
.combatTeam small{grid-column:span 2;height:var(--hud-space-1);background:var(--hud-surface-inset);}
.combatTeam i{display:block;height:100%;background:currentColor;}
#combatTeam0{color:var(--hud-team-0);}#combatTeam1{color:var(--hud-team-1);}#combatTeam2{color:var(--hud-team-2);}
.combatTeam.eliminated{text-decoration:line-through;color:var(--hud-text-muted);}
#combatTime{font:var(--hud-text-sm)/var(--hud-leading) var(--hud-font-body);font-variant-numeric:tabular-nums;}
#combatShop{position:absolute;top:calc(var(--sat) + 124px);left:calc(var(--sal) + var(--hud-space-2));width:112px;display:grid;gap:var(--hud-space-1);}
#combatShop button{min-height:var(--hud-target);display:flex;align-items:center;gap:var(--hud-space-1);width:100%;padding:var(--hud-space-1);text-align:left;}
#combatShop button>span:last-child{min-width:0;flex:1;letter-spacing:0;}
#combatShop .hudSprite{width:24px;height:24px;flex:none;}
#combatBuy{min-height:60px!important;}
#combatBuyName{font-weight:400;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere;}
#combatBuyReason{display:block;color:var(--hud-text-muted);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);}
#combatBuy:disabled{opacity:1;color:var(--hud-text-muted);}
#combatBuyIcon{position:relative;flex:none;width:28px;height:28px;overflow:hidden;display:grid;place-items:center;}
#combatBuyIcon .itemIcon{width:28px;height:28px;}
#combatDetailsButton{position:absolute;left:calc(var(--sal) + 128px);bottom:calc(var(--sab) + var(--hud-space-2));min-height:var(--hud-target);min-width:var(--hud-target);padding:var(--hud-space-1);display:flex;align-items:center;gap:var(--hud-space-1);}
#combatDetailsButton .hudSprite{width:24px;height:24px;}
#combatRespawn{position:absolute;top:calc(var(--sat) + 60px);left:50%;transform:translateX(-50%);}
#combatUpgrades{position:absolute;right:calc(var(--sar) + var(--hud-space-2));bottom:calc(var(--sab) + 184px);display:flex;gap:var(--hud-space-1);}
.combatUpgrade{width:var(--hud-target);height:var(--hud-target);padding:var(--hud-space-1);color:var(--hud-accent);}
.combatUpgrade{position:relative;display:grid;place-items:center;}
.combatUpgrade .skillIcon{width:100%;height:100%;border-radius:var(--hud-radius);}
.combatUpgrade>b{position:absolute;right:0;bottom:0;background:var(--hud-surface-overlay);font:var(--hud-text-count)/1 var(--hud-font-body);padding:0 var(--hud-space-1);}
.combatSkillState{position:absolute;z-index:4;inset:25% 0 auto;text-align:center;pointer-events:none;padding:var(--hud-space-1) 0;}
.combatSkillState[data-reason]{inset:auto 0 20%;}
.combatSkillState{display:none;}
body.combat-hud .combatSkillState{display:block;}
body.touch.combat-hud{--combat-size:var(--hud-control-comfortable);--combat-map:96px;}
body.touch.combat-hud[data-combat-preset="compact"]{--combat-size:var(--hud-control-compact);}
body.touch.combat-hud[data-combat-map="large"]{--combat-map:120px;}
body.touch.combat-hud #mobileMinimap{left:calc(var(--sal) + var(--hud-space-2));right:auto;top:calc(var(--sat) + var(--hud-space-2));bottom:auto;width:var(--combat-map);height:var(--combat-map);}
body.touch.combat-hud #combatShop{top:calc(var(--sat) + var(--combat-map) + var(--hud-space-4));}
body.touch.combat-hud #stick{width:112px;height:112px;}
body.touch.combat-hud #stickNub{width:48px;height:48px;}
body.touch.combat-hud #hudTop{position:static;}
body.touch.combat-hud #heroPanel{position:fixed;top:auto;left:calc(var(--sal) + 128px);bottom:calc(var(--sab) + 60px);width:168px;max-width:168px;min-width:0;z-index:8;padding:var(--hud-space-1);gap:var(--hud-space-1);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);}
body.touch.combat-hud #heroPanel .vitalHeading{font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);color:var(--hud-text);}
body.touch.combat-hud #heroPanel .vitalHeading b{color:var(--hud-health);}
body.touch.combat-hud #heroPanel #resourceLabel{color:var(--hud-resource);}
body.touch.combat-hud #heroPanel .bar{gap:0;}
body.touch.combat-hud #heroPanel .track{height:var(--hud-space-1);background:var(--hud-surface-inset);border:0;}
body.touch.combat-hud #heroMeta{gap:var(--hud-space-1);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);}
body.touch.combat-hud #heroMeta i{display:none;}
body.touch.combat-hud #heroMeta i:first-child,body.touch.combat-hud #heroMeta #soulTxt,body.touch.combat-hud #heroMeta #spTxt{display:inline-flex;}
body.touch.combat-hud #heroMeta #spTxt:not(.unspent){display:none;}
body.touch.combat-hud #abilities{position:fixed;left:auto;top:auto;right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px));bottom:calc(var(--sab) + var(--hud-space-2));width:180px;height:164px;display:block;transform:none;pointer-events:none;}
body.touch.combat-hud #abilities .slot{position:absolute;width:var(--combat-size);height:var(--combat-size);border:var(--hud-border-width) solid var(--hud-border);border-radius:var(--hud-radius);background:var(--hud-surface-slot);animation:none;}
body.touch.combat-hud #abilities .slot.ready{border-color:var(--hud-focus);box-shadow:none;}
body.touch.combat-hud #abilities .slot.universal{border-color:var(--hud-accent);}
body.touch.combat-hud #abilities .slot.locked{filter:none;}
body.touch.combat-hud #abilities .slot.locked .skillIcon{opacity:var(--hud-disabled-opacity);}
body.touch.combat-hud #ab-1{right:120px;bottom:0;}
body.touch.combat-hud #ab-2{right:108px;bottom:60px;}
/* Second skill cut (heroes-data.js, SKILL_CUTS): the third button takes its place. */
body.touch.combat-hud #abilities.cut-2 #ab-3{right:108px;bottom:60px;}
body.touch.combat-hud #ab-3{right:60px;bottom:108px;}
body.touch.combat-hud #ab-4{right:0;bottom:72px;}
body.touch.combat-hud #ab-5{right:180px;bottom:0;}
body.touch.combat-hud #abilities .n{font:var(--hud-text-xs)/1 var(--hud-font-body);color:var(--hud-resource);}
body.touch.combat-hud #abilities .combat-unavailable .n{visibility:hidden;}
body.touch.combat-hud #abilities .return-ready .n{color:var(--hud-focus);}
body.touch.combat-hud #companionSkills{bottom:164px;max-width:180px;}
body.touch.combat-hud #touchBtns{position:fixed;left:auto;top:auto;right:calc(var(--sar) + 248px + var(--combat-inset,0px));bottom:calc(var(--sab) + var(--hud-space-2));transform:none;gap:var(--hud-space-1);}
body.touch.combat-hud #touchBtns .tbtn{width:var(--hud-target);height:var(--hud-target);border:var(--hud-border-hairline) solid var(--hud-border);border-radius:var(--hud-radius);background:var(--hud-surface-glass);color:var(--hud-text);}
body.touch.combat-hud #tbShop,body.touch.combat-hud #tbFullscreen{display:none!important;}
body.touch.combat-hud #tbAttack{position:fixed;right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px));bottom:calc(var(--sab) + var(--hud-space-2));width:56px;height:56px;border:var(--hud-border-width) solid var(--hud-focus);border-radius:50%;background:var(--hud-surface-glass);color:var(--hud-text);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);z-index:10;touch-action:none;}
body.touch.combat-hud #tbAttack{padding:var(--hud-space-1);letter-spacing:0;}
body.touch.combat-hud #tbAttack>.hudSprite{width:calc(var(--hud-control-compact) - var(--hud-space-3));height:calc(var(--hud-control-compact) - var(--hud-space-3));}
body.touch.combat-hud #tbAttack progress{display:block;width:70%;height:var(--hud-space-1);margin:var(--hud-space-1) auto;accent-color:var(--hud-focus);border:0;}
body.touch.combat-hud #tbAttack[data-state="disabled"],body.touch.combat-hud #tbAttack[data-state="no-target"]{border-color:var(--hud-border);color:var(--hud-text-muted);}
body.touch.combat-hud #tbAttack[aria-pressed="true"]{background:var(--hud-surface-raised);}
body.touch.combat-hud #tbStop{position:absolute;bottom:52px;right:0;}
body.touch.combat-hud #itemsPanel{position:fixed;left:calc(var(--sal) + 136px);right:auto;top:calc(var(--sat) + 64px);bottom:auto;display:flex;flex-wrap:wrap;width:144px;gap:var(--hud-space-1);}
body.touch.combat-hud #itemsPanel .itemSlot{width:var(--hud-target);height:var(--hud-target);}
body.touch.combat-hud #itemsPanel .itemSlot:not(.active){display:none;}
body.touch.combat-hud #hudUtilityBar{right:calc(var(--sar) + var(--hud-space-2));top:calc(var(--sat) + var(--hud-space-2));}
body.touch.combat-hud #relaySurgeHud{left:calc(var(--sal) + 328px);right:calc(var(--sar) + 220px);top:calc(var(--sat) + 60px);bottom:auto;max-width:none;width:auto;transform:none;padding:var(--hud-space-1);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);border:0;background:var(--hud-surface-glass);text-align:left;letter-spacing:0;}
body.touch.combat-hud #relaySurgeHud .relay-surge-icon{width:24px;height:24px;}
body.touch.combat-hud #relaySurgeHud .relay-surge-label{min-width:0;}
body.touch.combat-hud #relaySurgeHud strong,body.touch.combat-hud #relaySurgeHud small{font:inherit;white-space:normal;}
body.touch.combat-hud #relaySurgeHud[data-phase="urgent"]{color:var(--hud-danger);}
/* Urgent text temporarily occupies the strategic strip, leaving touch controls clear. */
body.touch.combat-hud #banner{position:fixed;left:calc(var(--sal) + 136px);right:calc(var(--sar) + 64px);top:calc(var(--sat) + var(--hud-space-2));bottom:auto;width:auto;max-width:none;min-height:var(--hud-target);transform:none;box-sizing:border-box;font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-label);letter-spacing:0;padding:var(--hud-space-2);z-index:11;}
body.combat-hud:has(#banner.in) #combatTeams{visibility:hidden;}
/* The latest elimination shares the strategic strip; urgent warnings take priority. */
body.touch.combat-hud #killFeed{position:fixed;left:calc(var(--sal) + 136px);right:calc(var(--sar) + 64px);top:calc(var(--sat) + var(--hud-space-2));width:auto;max-width:none;min-height:var(--hud-target);justify-content:center;z-index:10;}
body.touch.combat-hud .kfRow{gap:var(--hud-space-1);padding:var(--hud-space-1) var(--hud-space-2);font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);background:var(--hud-surface-glass);border:var(--hud-border-hairline) solid var(--hud-border);}
body.touch.combat-hud .kfRow:not(:last-child){display:none;}
body.combat-hud:has(#killFeed .kfRow) #combatTeams,body.combat-hud:has(#banner.in) #killFeed{visibility:hidden;}
#combatDetails{width:600px;max-width:calc(100vw - var(--sal) - var(--sar) - var(--hud-space-6));max-height:calc(100dvh - var(--sat) - var(--sab) - var(--hud-space-6));overflow:auto;}
/* Nonmodal, so the fight goes on: it sits in the free strip under the top bar, right of the minimap and
   stick, left of the skill arc, and ends above the defense button. */
#combatEvolutionDialog{position:fixed;z-index:18;top:calc(var(--sat) + 56px);left:calc(var(--sal) + 128px);right:calc(var(--sar) + 176px);bottom:auto;margin:0 auto;box-sizing:border-box;width:420px;max-width:calc(100vw - var(--sal) - var(--sar) - 304px);max-height:calc(100dvh - var(--sat) - 132px);overflow:auto;}
body.combat-hud #combatEvolutionDialog #evolutionPanel{position:static;inset:auto;transform:none;width:100%;max-width:none;max-height:none;border:0;}
body.combat-hud #heroPanel #evolutionPanel[data-view="collapsed"]{position:static;inset:auto;transform:none;width:100%;max-width:none;max-height:none;margin-top:var(--hud-space-1);}
body.combat-hud #evolutionPanel .evolutionReopen{min-height:var(--hud-target);}
body.combat-hud #evolutionPanel{pointer-events:auto;}
/* Small phones (568-640 wide) squeeze the picker between minimap and skills to ~260px: stack the choices
   as full-width rows and drop the role word so each gain/cost line keeps a readable width without scrolling. */
#combatEvolutionDialog{container-type:inline-size;}
@container (max-width:340px){
  body.combat-hud #combatEvolutionDialog #evolutionPanel .evolutionOptions{grid-template-columns:1fr;padding:0;}
  body.combat-hud #combatEvolutionDialog #evolutionPanel .evolutionRole{display:none;}
  body.combat-hud #combatEvolutionDialog #evolutionPanel .hud-upgrade-choice{min-height:0;}
}
@media (max-height:360px){
  body.combat-hud #combatEvolutionDialog{padding:var(--hud-space-2);}
}
body.combat-hud.tutorial-active #relaySurgeHud{display:none;}
/* Death camera dock on short touch screens: use the free column between the vitals/joystick and the ability
   buttons instead of centring over them (portrait stays behind the rotate gate). Compact phones put the vitals
   top-left, so the dock drops below them. */
@media(max-height:500px){
  body.touch.combat-hud #deathCameraHud{left:calc(var(--sal) + 304px);right:calc(var(--sar) + 196px + var(--combat-inset,0px));top:auto;bottom:calc(var(--sab) + var(--hud-space-2));width:auto;max-width:none;transform:none;max-height:calc(100dvh - var(--sat) - var(--sab) - 120px);}
}
@media(max-width:740px),(max-height:360px){
  html body.touch.combat-hud #deathCameraHud{left:calc(var(--sal) + 112px);right:calc(var(--sar) + var(--combat-cluster-w,188px) + var(--hud-space-3) + var(--combat-inset,0px));top:auto;bottom:calc(var(--sab) + var(--hud-space-2));width:auto;max-width:none;transform:none;max-height:calc(100dvh - var(--sat) - var(--sab) - 150px);}
}
#combatDetails h2{font:var(--hud-text-sm)/var(--hud-leading) var(--hud-font-label);flex:1;}
body.touch.combat-hud #combatDetails #itemsPanel{display:flex!important;position:static;width:auto;max-width:none;}
body.touch.combat-hud #combatDetails #itemsPanel .itemSlot{display:flex;}
#combatSkillDetails{display:grid;gap:var(--hud-space-3);margin-top:var(--hud-space-4);}
.combatSkillDetail{display:flex;gap:var(--hud-space-2);align-items:center;font:var(--hud-text-sm)/var(--hud-leading) var(--hud-font-body);}
.combatSkillDetail .skillIcon{position:relative;flex:none;width:var(--hud-target);height:var(--hud-target);}
@media(max-width:740px),(max-height:360px){
  body.touch.combat-hud{--combat-size:var(--hud-control-compact);--combat-map:80px;--combat-inset:0px!important;}
  body.touch.combat-hud[data-combat-map="large"]{--combat-map:96px;}
  #combatTeams{left:calc(var(--sal) + 112px);right:calc(var(--sar) + 56px);gap:var(--hud-space-1);}
  body.touch.combat-hud #banner{left:calc(var(--sal) + 112px);right:calc(var(--sar) + 56px);}
  body.touch.combat-hud #killFeed{left:calc(var(--sal) + 112px);right:calc(var(--sar) + 56px);}
  #combatShop{width:96px;}
  #combatShop .hudSprite{width:20px;height:20px;}
  #combatBuyIcon{display:none;}
  body.touch.combat-hud #combatShop{top:calc(var(--sat) + var(--combat-map) + var(--hud-space-3));gap:0;}
  #combatBuy{height:52px;min-height:52px!important;overflow:hidden;}
  #combatBuyName{-webkit-line-clamp:1;}
  body.touch.combat-hud #stick{width:96px;height:96px;}
  body.touch.combat-hud #stickNub{width:44px;height:44px;}
  body.touch.combat-hud #heroPanel{top:calc(var(--sat) + 60px);bottom:auto;left:calc(var(--sal) + 112px);width:132px;max-width:132px;}
  #combatDetailsButton{left:calc(var(--sal) + 120px);bottom:calc(var(--sab) + var(--hud-space-2));}
  #combatDetailsLabel{display:none;}
  body.touch.combat-hud #abilities{width:172px;}
  body.touch.combat-hud #ab-1{right:104px;}
  body.touch.combat-hud #ab-2{right:100px;bottom:52px;}
  /* Second skill cut (heroes-data.js, SKILL_CUTS): the third button takes its place. */
  body.touch.combat-hud #abilities.cut-2 #ab-3{right:100px;bottom:52px;}
  body.touch.combat-hud #ab-3{right:52px;bottom:88px;}
  body.touch.combat-hud #ab-4{right:0;bottom:68px;}
  body.touch.combat-hud #ab-5{right:156px;}
  body.touch.combat-hud #touchBtns{right:calc(var(--sar) + 216px);}
  body.touch.combat-hud #itemsPanel{left:calc(var(--sal) + 264px);top:calc(var(--sat) + 60px);width:144px;}
  body.touch.combat-hud #relaySurgeHud{left:calc(var(--sal) + 264px);right:calc(var(--sar) + 56px);top:calc(var(--sat) + 60px);}
  body.touch.combat-hud #relaySurgeHud .relay-surge-icon{display:none;}
  body.touch.combat-hud #relaySurgeHud small{display:none;}
  #combatUpgrades{left:calc(var(--sal) + 112px);right:auto;bottom:calc(var(--sab) + 60px);}
  body.touch.combat-hud #companionSkills{bottom:160px;right:0;max-width:160px;}
}
@media(max-height:360px){body.touch.combat-hud[data-combat-map="large"]{--combat-map:88px;}}
@media(max-height:300px){body.touch.combat-hud #combatBuy{display:none;}}
/* -- Neon touch layout (Sept 2026, approved mockup): borderless chrome, portrait chip instead of the vitals
   panel, skills on a polar arc around the attack button, floating joystick. Every rule is appended here so it
   overrides the older fixed-pixel layout above without editing it. Polar maths: the attack centre sits --arc-ax
   from the shared right/bottom origin; a control at angle A and radius r is placed at
   right = ax + r*(-cos A) - size/2, bottom = ax + r*sin A - size/2. -- */
body.touch.combat-hud{--arc-r:132px;--arc-r2:200px;--arc-ax:36px;--attack-size:72px;--combat-small:44px;--combat-map:104px;--combat-cluster-w:280px;--combat-cluster-h:260px;--combat-ult:calc(var(--combat-size) + 8px);--combat-glass:rgba(12,10,16,.55);--combat-rim:rgba(255,255,255,.32);}
body.touch.combat-hud[data-combat-map="large"]{--combat-map:120px;}
/* Top-left column: minimap, gold pill, portrait chip. */
body.touch.combat-hud #mobileMinimap{border:0;border-radius:6px;background:var(--combat-glass);}
body.touch.combat-hud #combatShop{top:calc(var(--sat) + var(--combat-map) + var(--hud-space-3));left:calc(var(--sal) + var(--hud-space-2));width:auto;display:flex;align-items:center;gap:var(--hud-space-1);}
body.touch.combat-hud #combatOpenShop{min-height:32px;height:32px;width:auto;padding:0 12px 0 8px;border:0;border-radius:999px;background:var(--combat-glass);font:700 14px/1 var(--hud-font-display);letter-spacing:.04em;gap:6px;}
body.touch.combat-hud #combatOpenShop .hudSprite{width:20px;height:20px;}
body.touch.combat-hud #combatOpenShop>span:last-child{font-size:0;letter-spacing:0;}
body.touch.combat-hud #combatCredits{font:700 14px/1 var(--hud-font-display);color:var(--hud-accent);}
body.touch.combat-hud #combatBuy{min-height:32px!important;height:32px;width:32px;padding:0;border-radius:50%;border:1.5px solid var(--hud-accent);background:var(--combat-glass);display:grid;place-items:center;overflow:hidden;box-shadow:0 0 8px rgba(242,193,78,.35);}
body.touch.combat-hud #combatBuy>span:last-child{display:none;}
body.touch.combat-hud #combatBuyIcon{display:grid;width:22px;height:22px;}
body.touch.combat-hud #combatBuyIcon .itemIcon{width:22px;height:22px;}
body.touch.combat-hud #combatBuy:disabled{border-color:var(--combat-rim);box-shadow:none;opacity:.75;}
body.touch.combat-hud #heroPanel{position:fixed;top:calc(var(--sat) + var(--combat-map) + var(--hud-space-3) + 40px);left:calc(var(--sal) + var(--hud-space-2));bottom:auto;width:auto;max-width:none;min-width:0;padding:0;gap:var(--hud-space-1);background:transparent;border:0;box-shadow:none;display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;}
body.touch.combat-hud #heroPanel .bar,body.touch.combat-hud #heroPanel #xpTrack{display:none;}
body.touch.combat-hud #orbitalPortrait{display:block;position:relative;left:auto;top:auto;width:40px;height:40px;border-radius:50%;overflow:hidden;border:2px solid var(--combat-rim);background:var(--combat-glass);}
body.touch.combat-hud #orbitalPortrait .heroPortrait{display:block;width:100%;height:100%;border:0;border-radius:50%;}
body.touch.combat-hud #orbitalPortrait .heroPortrait img{width:100%;height:100%;object-fit:cover;}
body.touch.combat-hud #heroMeta{display:flex;align-items:center;gap:var(--hud-space-1);}
body.touch.combat-hud #heroMeta i:first-child{position:relative;z-index:1;display:grid;place-items:center;width:20px;height:20px;margin-left:-16px;border-radius:50%;background:var(--hud-focus);color:#08131a;font-size:0;box-shadow:0 0 0 2px #0b0a0e;}
body.touch.combat-hud #lvlTxt{font:700 10px/1 var(--hud-font-display);}
body.touch.combat-hud #heroMeta #soulTxt,body.touch.combat-hud #heroMeta #spTxt{height:20px;padding:0 6px;border-radius:999px;background:var(--combat-glass);font-size:0;gap:3px;}
body.touch.combat-hud #heroMeta #soulTxt>span,body.touch.combat-hud #heroMeta #spTxt>span{font:600 10px/1 var(--hud-font-body);}
body.touch.combat-hud #heroMeta #soulTxt img,body.touch.combat-hud #heroMeta #spTxt .hudSprite{width:14px;height:14px;}
body.touch.combat-hud #combatDetailsButton{left:calc(var(--sal) + var(--hud-space-2) + 4px);top:calc(var(--sat) + var(--combat-map) + var(--hud-space-3) + 88px);bottom:auto;width:32px;height:32px;min-width:32px;min-height:32px;padding:0;justify-content:center;border-radius:50%;border:1px solid var(--combat-rim);background:var(--combat-glass);}
body.touch.combat-hud #combatDetailsButton .hudSprite,body.touch.combat-hud #combatDetailsButton .hud-icon{width:18px;height:18px;}
body.touch.combat-hud #combatDetailsLabel{display:none;}
/* Top strip: one borderless line, timer in the middle, reactor entry stays clear of it. */
body.touch.combat-hud #combatTeams{left:calc(var(--sal) + var(--combat-map) + 24px);right:calc(var(--sar) + 150px);justify-content:center;gap:var(--hud-space-4);border:0;background:transparent;box-shadow:none;text-shadow:0 1px 3px #000,0 0 8px rgba(0,0,0,.8);}
body.touch.combat-hud .combatTeam{font:700 13px/1.1 var(--hud-font-display);letter-spacing:.08em;}
body.touch.combat-hud .combatTeam small{height:3px;border-radius:2px;background:rgba(255,255,255,.15);}
body.touch.combat-hud #combatTeam0{order:0;}body.touch.combat-hud #combatTeam1{order:1;}body.touch.combat-hud #combatTime{order:2;padding:0 var(--hud-space-1);}body.touch.combat-hud #combatTeam2{order:3;}
body.touch.combat-hud #hudUtilityBar{gap:var(--hud-space-1);align-items:center;}
body.touch.combat-hud #hudUtilityBar .btn{border-radius:999px;border:1px solid var(--combat-rim);background:var(--combat-glass);}
body.touch.combat-hud #reactorEntry{min-height:32px;height:32px;padding:0 10px;font:600 11px/1 var(--hud-font-body);letter-spacing:.04em;}
body.touch.combat-hud #btnHudOptions{width:36px;height:36px;padding:0;}
body.touch.combat-hud #combatRespawn{top:calc(var(--sat) + 44px);}
/* Kill feed and objective line sit under the strip instead of replacing it. */
body.combat-hud:has(#killFeed .kfRow) #combatTeams{visibility:visible;}
body.touch.combat-hud #killFeed{left:calc(var(--sal) + var(--combat-map) + 24px);right:calc(var(--sar) + 150px);top:calc(var(--sat) + 40px);min-height:0;}
body.touch.combat-hud .kfRow{border:0;background:transparent;text-shadow:0 1px 3px #000;opacity:.85;}
body.touch.combat-hud #banner{left:calc(var(--sal) + var(--combat-map) + 24px);right:calc(var(--sar) + 150px);border:0;background:var(--combat-glass);}
body.touch.combat-hud #relaySurgeHud{left:calc(var(--sal) + var(--combat-map) + 24px);right:calc(var(--sar) + 150px);top:calc(var(--sat) + 40px);background:transparent;justify-content:center;text-align:center;color:var(--hud-text-muted);font:600 11px/1.2 var(--hud-font-body);letter-spacing:.06em;}
body.touch.combat-hud #relaySurgeHud .relay-surge-icon{width:20px;height:20px;}
body.touch.combat-hud #relaySurgeHud small{display:none;}
body.touch.combat-hud #relaySurgeHud[data-phase="2"]{color:var(--hud-text);}
body.touch.combat-hud #relaySurgeHud[data-phase="idle"]{color:var(--hud-text-muted);opacity:.75;}
body.touch.combat-hud #relaySurgeHud[data-phase="idle"] .relay-surge-icon{width:16px;height:16px;}
body.combat-hud:has(#killFeed .kfRow) #relaySurgeHud{visibility:hidden;}
/* Floating joystick: the dashed ring is only a resting hint; the zone moves it under the thumb. */
#stickZone{display:none;}
body.touch.combat-hud #stickZone{display:block;position:fixed;left:var(--sal);bottom:var(--sab);width:42vw;height:56dvh;z-index:6;touch-action:none;user-select:none;-webkit-user-select:none;}
body.touch.combat-hud #stick{width:112px;height:112px;border:1.5px dashed rgba(255,255,255,.28);background:rgba(255,255,255,.03);transition:opacity .15s;}
body.touch.combat-hud #stick.floating{border-style:solid;border-color:rgba(111,227,255,.35);background:rgba(12,10,16,.35);}
body.touch.combat-hud #stickNub{width:48px;height:48px;background:rgba(111,227,255,.22);border:1.5px solid rgba(111,227,255,.7);}
/* Right cluster: attack anchors the corner; skills, utilities and item actives orbit it. */
body.touch.combat-hud #tbAttack{width:var(--attack-size);height:var(--attack-size);border-width:2.5px;background:radial-gradient(circle at 50% 40%,rgba(111,227,255,.22),rgba(12,10,16,.6) 70%);box-shadow:0 0 18px rgba(111,227,255,.35);}
body.touch.combat-hud #tbAttack>.hudSprite{width:36px;height:36px;}
body.touch.combat-hud #tbAttack[data-state="disabled"],body.touch.combat-hud #tbAttack[data-state="no-target"]{box-shadow:none;background:var(--combat-glass);}
body.touch.combat-hud #abilities,body.touch.combat-hud #touchBtns,body.touch.combat-hud #combatUpgrades{position:fixed;left:auto;top:auto;right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px));bottom:calc(var(--sab) + var(--hud-space-2));width:var(--combat-cluster-w);height:var(--combat-cluster-h);display:block;transform:none;pointer-events:none;}
body.touch.combat-hud #abilities .slot{border-radius:50%;border:1.5px solid var(--combat-rim);background:var(--combat-glass);overflow:hidden;}
body.touch.combat-hud #abilities .slot .skillIcon{border-radius:50%;}
body.touch.combat-hud #abilities .slot.ready{border-color:var(--hud-focus);box-shadow:0 0 10px rgba(111,227,255,.35);}
body.touch.combat-hud #abilities .slot.universal{border-color:rgba(242,193,78,.5);}
body.touch.combat-hud #abilities .slot.universal.ready{border-color:var(--hud-accent);box-shadow:0 0 10px rgba(242,193,78,.35);}
body.touch.combat-hud #abilities .n,body.touch.combat-hud #abilities .k{display:none;}
body.touch.combat-hud #ab-1{right:calc(var(--arc-ax) + var(--arc-r) - var(--combat-size) / 2);bottom:calc(var(--arc-ax) - var(--combat-size) / 2);}
body.touch.combat-hud #ab-2{right:calc(var(--arc-ax) + var(--arc-r) * .866 - var(--combat-size) / 2);bottom:calc(var(--arc-ax) + var(--arc-r) * .5 - var(--combat-size) / 2);}
/* Second skill cut (heroes-data.js, SKILL_CUTS): the third button takes its place. */
body.touch.combat-hud #abilities.cut-2 #ab-3{right:calc(var(--arc-ax) + var(--arc-r) * .866 - var(--combat-size) / 2);bottom:calc(var(--arc-ax) + var(--arc-r) * .5 - var(--combat-size) / 2);}
body.touch.combat-hud #ab-3{right:calc(var(--arc-ax) + var(--arc-r) * .5 - var(--combat-size) / 2);bottom:calc(var(--arc-ax) + var(--arc-r) * .866 - var(--combat-size) / 2);}
body.touch.combat-hud #abilities #ab-4{width:var(--combat-ult);height:var(--combat-ult);right:calc(var(--arc-ax) - var(--combat-ult) / 2);bottom:calc(var(--arc-ax) + var(--arc-r) - var(--combat-ult) / 2);border-color:rgba(242,193,78,.5);}
body.touch.combat-hud #ab-4.ready{border-color:var(--hud-accent);box-shadow:0 0 12px rgba(242,193,78,.4);}
body.touch.combat-hud #abilities #ab-5{width:var(--hud-target);height:var(--hud-target);right:calc(var(--arc-ax) + var(--arc-r2) * .94 - var(--hud-target) / 2);bottom:calc(var(--arc-ax) + var(--arc-r2) * .342 - var(--hud-target) / 2);}
body.touch.combat-hud #touchBtns .tbtn{position:absolute;width:var(--combat-small);height:var(--combat-small);border-radius:50%;border:1px solid var(--combat-rim);background:var(--combat-glass);pointer-events:auto;}
body.touch.combat-hud #touchBtns .tbtn .hudSprite{width:20px;height:20px;}
body.touch.combat-hud #tbRecall,body.touch.combat-hud #tbBuyback{right:calc(var(--arc-ax) + var(--arc-r2) - var(--combat-small) / 2);bottom:calc(var(--arc-ax) - var(--combat-small) / 2);}
body.touch.combat-hud #tbStop{right:calc(var(--arc-ax) + var(--arc-r2) * .731 - var(--combat-small) / 2);bottom:calc(var(--arc-ax) + var(--arc-r2) * .682 - var(--combat-small) / 2);}
body.touch.combat-hud #itemsPanel{left:auto;top:auto;right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px) + var(--arc-ax) + var(--arc-r2) * .375 - var(--hud-target) / 2);bottom:calc(var(--sab) + var(--hud-space-2) + var(--arc-ax) + var(--arc-r2) * .927 - var(--hud-target) / 2);width:var(--hud-target);display:flex;flex-direction:column;flex-wrap:nowrap;gap:var(--hud-space-1);}
body.touch.combat-hud #itemsPanel .itemSlot{border-radius:50%;border:1px solid rgba(122,140,255,.7);background:var(--combat-glass);overflow:hidden;}
body.touch.combat-hud #companionSkills{left:0;right:auto;top:0;bottom:auto;max-width:150px;}
/* Level-up becomes a gold + badge pinned to the skill it upgrades. */
body.touch.combat-hud .combatUpgrade{position:absolute;width:22px;height:22px;min-width:0;min-height:0;padding:0;border:0;border-radius:50%;background:var(--hud-accent);color:#1a1200;box-shadow:0 0 8px var(--hud-accent);pointer-events:auto;z-index:2;}
body.touch.combat-hud .combatUpgrade .skillIcon{display:none;}
body.touch.combat-hud .combatUpgrade>b{position:static;background:transparent;padding:0;font:700 15px/1 var(--hud-font-display);}
body.touch.combat-hud #combatUpgrade1{right:calc(var(--arc-ax) + var(--arc-r) + var(--combat-size) / 2 - 10px);bottom:calc(var(--arc-ax) + var(--combat-size) / 2 - 12px);}
body.touch.combat-hud #combatUpgrade2{right:calc(var(--arc-ax) + var(--arc-r) * .866 + var(--combat-size) / 2 - 10px);bottom:calc(var(--arc-ax) + var(--arc-r) * .5 + var(--combat-size) / 2 - 12px);}
body.touch.combat-hud #combatUpgrade3{right:calc(var(--arc-ax) + var(--arc-r) * .5 + var(--combat-size) / 2 - 10px);bottom:calc(var(--arc-ax) + var(--arc-r) * .866 + var(--combat-size) / 2 - 12px);}
body.touch.combat-hud #combatUpgrade4{right:calc(var(--arc-ax) + var(--combat-ult) / 2 - 10px);bottom:calc(var(--arc-ax) + var(--arc-r) + var(--combat-ult) / 2 - 12px);}
/* Death camera dock uses the free column between the joystick zone and the arc. */
body.touch.combat-hud #deathCameraHud{left:calc(var(--sal) + 42vw + var(--hud-space-2));right:calc(var(--sar) + var(--combat-cluster-w) + var(--hud-space-3) + var(--combat-inset,0px));}
@media(max-width:740px),(max-height:360px){
  body.touch.combat-hud{--arc-r:112px;--arc-r2:170px;--arc-ax:30px;--attack-size:60px;--combat-small:44px;--combat-map:80px;--combat-cluster-w:240px;--combat-cluster-h:224px;}
  body.touch.combat-hud[data-combat-map="large"]{--combat-map:96px;}
  body.touch.combat-hud #tbAttack>.hudSprite{width:30px;height:30px;}
  body.touch.combat-hud #stick{width:96px;height:96px;}
  body.touch.combat-hud #stickNub{width:44px;height:44px;}
  body.touch.combat-hud #combatTeams,body.touch.combat-hud #killFeed,body.touch.combat-hud #banner,body.touch.combat-hud #relaySurgeHud{left:calc(var(--sal) + var(--combat-map) + 16px);right:calc(var(--sar) + 140px);}
  body.touch.combat-hud .combatTeam{font-size:12px;}
}
/* -- Decluttered touch pass: one death message, icon-only companions, item actives in a row that grows
   leftward instead of a column climbing into the reactor/options corner. -- */
body.touch.combat-hud #abilities .combatSkillState[data-reason="dead"]{display:none;}
/* Skill role under each touch button (Burst, Area, Control...), the way mobile MOBAs label their casts. */
.skillRole{display:none;}
body.touch.combat-hud #abilities .slot{overflow:visible;}
body.touch.combat-hud #abilities .skillRole{display:block;position:absolute;left:50%;top:100%;z-index:4;transform:translateX(-50%);margin-top:1px;padding:0 var(--hud-space-1);white-space:nowrap;pointer-events:none;color:var(--hud-text);font:600 var(--hud-text-xs)/1.2 var(--hud-font-label);text-shadow:0 1px 2px #000,0 0 3px #000;}
body.touch.combat-hud:has(#deathCameraHud:not([hidden])) #combatRespawn{display:none!important;}
body.touch.combat-hud #itemsPanel .itemSlot{-webkit-touch-callout:none;user-select:none;-webkit-user-select:none;}
body.touch.combat-hud #itemsPanel{right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px) + var(--arc-ax) + var(--combat-ult) / 2 + var(--hud-space-2));bottom:calc(var(--sab) + var(--hud-space-2) + var(--arc-ax) + var(--arc-r) + var(--combat-ult) / 2 + var(--hud-space-2));width:auto;flex-direction:row-reverse;}
body.touch.combat-hud #companionSkills{left:auto;right:calc(var(--arc-ax) - var(--combat-ult) / 2);top:auto;bottom:calc(var(--arc-ax) + var(--arc-r) + var(--combat-ult) / 2 + var(--hud-space-2) + var(--hud-target) + var(--hud-space-1));max-width:none;flex-direction:row-reverse;gap:var(--hud-space-1);}
body.touch.combat-hud #companionSkills .hud-companion-skill{display:block;position:relative;width:28px;height:28px;padding:0;border-radius:50%;overflow:hidden;background:var(--combat-glass);border:1px solid var(--combat-rim);}
body.touch.combat-hud #companionSkills .hud-companion-skill[data-ready="true"]{border-color:var(--hud-focus);}
body.touch.combat-hud #companionSkills .companionIcon{display:block;width:100%;height:100%;}
body.touch.combat-hud #companionSkills small,body.touch.combat-hud #companionSkills b{display:none;}
body.touch.combat-hud #companionSkills .hud-companion-skill:not([data-ready="true"]) .companionIcon{opacity:.45;}
/* -- Mobile Legends comparison, round 3 (2026-09-15): the attack button is the dominant thumb anchor, locked
   skills keep their art, the score is one small centred pill with team kills, K/D/A and ping, the minimap is
   larger, Recall and the team skill sit at the bottom centre as labelled battle spells, and a purchase card
   names what an item gave. -- */
body.touch.combat-hud{--attack-size:88px;--arc-r:144px;--arc-ax:46px;--combat-map:112px;--combat-cluster-w:300px;--combat-cluster-h:280px;--combat-spell:40px;}
body.touch.combat-hud[data-combat-map="large"]{--combat-map:120px;}
body.touch.combat-hud #tbAttack>.hudSprite{width:46px;height:46px;}
/* Locked skills: greyed art with a small level pill at the bottom edge instead of a block over the icon. */
body.touch.combat-hud #abilities .slot.locked .skillIcon{opacity:.72;filter:grayscale(1) brightness(.85);}
body.touch.combat-hud #abilities .combatSkillState[data-reason="locked"]{inset:auto -4px -3px;padding:0 3px;border-radius:999px;background:rgba(8,6,12,.85);font:700 9px/14px var(--hud-font-body);color:var(--hud-text);}
body.touch.combat-hud #abilities .slot.locked .skillRole{display:none;}
/* Score pill: centred, sized to its content, team identity by colour. */
body.touch.combat-hud #combatTeams{left:50%;right:auto;transform:translateX(-50%);width:auto;height:28px;min-height:28px;padding:0 12px;gap:12px;border-radius:999px;background:var(--combat-glass);white-space:nowrap;}
body.touch.combat-hud .combatTeam{display:inline-grid;grid-template-columns:auto auto auto;align-items:baseline;gap:0 4px;}
body.touch.combat-hud .combatTeam b{font-size:0;width:8px;height:8px;border-radius:50%;background:currentColor;align-self:center;}
body.touch.combat-hud .combatTeam em{font:700 14px/1 var(--hud-font-display);font-style:normal;font-variant-numeric:tabular-nums;}
body.touch.combat-hud .combatTeam>span{font:600 10px/1 var(--hud-font-body);color:var(--hud-text-muted);}
body.touch.combat-hud .combatTeam>span::before{content:'▮';margin-right:1px;font-size:8px;}
body.touch.combat-hud .combatTeam small{grid-column:1/-1;height:2px;margin-top:2px;}
body.touch.combat-hud #combatKda{order:4;display:inline-flex;align-items:center;gap:6px;padding-left:10px;border-left:1px solid var(--combat-rim);font:600 11px/1 var(--hud-font-body);color:var(--hud-text);font-variant-numeric:tabular-nums;letter-spacing:0;}
body.touch.combat-hud #combatPing{color:var(--hud-health);}
body.touch.combat-hud #combatPing[data-quality="fair"]{color:var(--hud-accent);}
body.touch.combat-hud #combatPing[data-quality="poor"]{color:var(--hud-danger);}
body.touch.combat-hud #combatPing[hidden]{display:none;}
/* Notices take the band under the pill; the pill no longer hides for them. */
body.touch.combat-hud #banner{top:calc(var(--sat) + 40px);}
body.combat-hud:has(#banner.in) #combatTeams{visibility:visible;}
body.combat-hud:has(#banner.in) #relaySurgeHud{visibility:hidden;}
body.touch.combat-hud #matchMoment{top:calc(var(--sat) + 92px);}
body.touch.combat-hud #matchMoment .mmHead{font-size:22px;}
body.touch.combat-hud #matchMoment .heroPortrait{width:28px;height:28px;}
/* Battle spells: Recall (or Buyback) and the team skill, small and labelled, at the bottom centre. Both boxes
   share the arc origin at the right edge, so 50vw minus that origin reaches the screen centre. */
/* Recall and Buyback keep a 44px hit box; the smaller spell circle is drawn by ::before. */
body.touch.combat-hud #touchBtns #tbRecall,body.touch.combat-hud #touchBtns #tbBuyback{width:var(--combat-small);height:var(--combat-small);right:calc(50vw + 2px - var(--sar) - var(--hud-space-2) - var(--combat-inset,0px));bottom:12px;border:0;background:transparent;}
body.touch.combat-hud #touchBtns #tbRecall::before,body.touch.combat-hud #touchBtns #tbBuyback::before{inset:calc((var(--combat-small) - var(--combat-spell)) / 2);z-index:-1;border-radius:50%;border:1px solid var(--combat-rim);background:var(--combat-glass);}
body.touch.combat-hud #touchBtns #tbRecall::after,body.touch.combat-hud #touchBtns #tbBuyback::after{margin-top:calc(1px - (var(--combat-small) - var(--combat-spell)) / 2);}
body.touch.combat-hud #abilities #ab-5{width:var(--combat-spell);height:var(--combat-spell);right:calc(50vw - 6px - var(--combat-spell) - var(--sar) - var(--hud-space-2) - var(--combat-inset,0px));bottom:16px;}
body.touch.combat-hud #abilities #ab-5 .skillRole{display:none;}
body.touch.combat-hud #tbRecall::before,body.touch.combat-hud #tbBuyback::before,body.touch.combat-hud #abilities #ab-5::before{content:'';position:absolute;inset:-4px;}
body.touch.combat-hud #tbRecall::after,body.touch.combat-hud #tbBuyback::after,body.touch.combat-hud #abilities #ab-5::after{content:attr(data-label);position:absolute;left:50%;top:100%;transform:translateX(-50%);margin-top:1px;white-space:nowrap;pointer-events:none;color:var(--hud-text);font:600 10px/12px var(--hud-font-label);text-transform:none;letter-spacing:0;text-shadow:0 1px 2px #000,0 0 3px #000;}
html body.touch.combat-hud #deathCameraHud{bottom:calc(var(--sab) + 64px);}
/* Reading a recap needs more room than the compact spectator controls. */
html body.combat-hud #deathCameraHud[data-recap-expanded="true"],html body:not(.touch):not(.inlobby):not(.spectating) #deathCameraHud[data-recap-expanded="true"]{left:50%;right:auto;top:calc(var(--sat) + var(--hud-space-2));bottom:auto;transform:translateX(-50%);width:min(480px,calc(100vw - var(--sal) - var(--sar) - var(--hud-space-6)));max-width:none;max-height:calc(100dvh - var(--sat) - var(--sab) - var(--hud-space-4));padding:var(--hud-space-2);background:var(--hud-surface-overlay);}
body:has(#deathCameraHud[data-recap-expanded="true"]:not([hidden])) #tutBox{visibility:hidden;}
/* Purchase card beside the scrap pill. */
/* Outside #combatChrome so every layout shows it: under the banner on a phone held upright and on desktop,
   beside the scrap pill in the landscape chrome. */
#combatPurchase{position:fixed;z-index:9;left:calc(var(--sal) + 8px);top:calc(var(--sat) + 262px);display:flex;align-items:center;gap:var(--hud-space-2);max-width:min(260px,calc(100vw - var(--sal) - var(--sar) - 16px));padding:5px 10px 5px 5px;border-radius:10px;background:var(--combat-glass,rgba(12,10,16,.55));border:1px solid rgba(242,193,78,.55);color:var(--hud-text);font:600 10px/1.3 var(--hud-font-body);opacity:0;transform:translateX(-6px);transition:opacity .18s,transform .18s;pointer-events:none;}
#combatPurchase.in{opacity:1;transform:none;}
#combatPurchase .itemIcon{position:relative;width:30px;height:30px;flex:none;}
#combatPurchase b{display:block;color:var(--hud-accent);font:700 12px/1.2 var(--hud-font-display);}
#combatPurchase small{display:block;font:inherit;}
body:not(.match-focus) #combatPurchase{display:none;}
body.combat-hud #combatPurchase{left:calc(var(--sal) + 116px);top:calc(var(--sat) + var(--combat-map,96px) + 12px);}
@media(prefers-reduced-motion:reduce){#combatPurchase{transition:opacity .18s;transform:none;}}
@media(max-width:740px),(max-height:360px){
  body.touch.combat-hud{--attack-size:76px;--arc-r:118px;--arc-ax:40px;--combat-map:96px;--combat-cluster-w:256px;--combat-cluster-h:240px;--combat-spell:36px;}
  body.touch.combat-hud[data-combat-map="large"]{--combat-map:104px;}
  body.touch.combat-hud #tbAttack>.hudSprite{width:38px;height:38px;}
  body.touch.combat-hud #matchMoment{top:calc(var(--sat) + 84px);}
  body.touch.combat-hud #matchMoment .mmHead{font-size:18px;}
  body.touch.combat-hud #banner{top:calc(var(--sat) + 38px);}
}
/* 320px-tall phones: the left column (map, scrap, portrait, Pilot) must stay above the joystick. */
@media(max-height:340px){
  body.touch.combat-hud{--combat-map:80px;}
  body.touch.combat-hud[data-combat-map="large"]{--combat-map:88px;}
}

/* -- Skill state reads as art, not a sentence (2026-09-15). Stun and silence show their world
   sprite centred on the button; "Unavailable", "Low resource" and "Respawn" are dimming only. -- */
body.touch.combat-hud #abilities .combatSkillState[data-reason="control"]{
  inset:0;display:grid;place-items:center;padding:0;background:rgba(8,6,12,.45);border-radius:50%;
}
body.touch.combat-hud #abilities .combatSkillState[data-reason="control"] img{
  width:26px;height:26px;filter:drop-shadow(0 1px 2px #000);
}
body.touch.combat-hud #abilities .slot.combat-unavailable:not(.locked) .skillIcon{opacity:.6;filter:grayscale(.7) brightness(.8);}
/* Item actives are thumb buttons: keep them above the ability cluster and let the cooldown veil
   pass taps through to the slot that handles them. */
body.touch.combat-hud #itemsPanel{z-index:9;}
body.touch.combat-hud #itemsPanel .itemSlot .veil{pointer-events:none;}

/* -- Kill notices, mobile (2026-09-16): one elimination filled the centre band under the score pill while
   the match-moment callout repeated the same two names right below it, so a single death read as two HUDs
   stacked across the middle of the screen. The feed goes back to the small transparent stack in the
   top-right corner, under the utility buttons, where it stays out of the notice band, the relay line and
   the thumb arc; the callout keeps its headline only (js/match-moments.js drops the plain-kill callout on
   touch, since the corner already names the pair). -- */
body.touch.combat-hud #killFeed{
  left:auto;right:calc(var(--sar) + var(--hud-space-2));top:calc(var(--sat) + 48px);
  width:auto;max-width:42vw;min-height:0;align-items:flex-end;justify-content:flex-start;gap:2px;
}
body.touch.combat-hud .kfRow{gap:4px;padding:0;font:600 10px/1.2 var(--hud-font-body);opacity:.8;}
body.touch.combat-hud .kfRow .heroPortrait{width:16px;height:16px;}
body.touch.combat-hud .kfRow .kfArrow{font-size:8px;}
/* Two lines at most: a third would reach the companion icons above the item actives. */
body.touch.combat-hud .kfRow{display:none;}
body.touch.combat-hud .kfRow:nth-last-child(-n+2){display:flex;}
body.touch.combat-hud .kfRow:not(:last-child){opacity:.55;}
/* The corner no longer shares a lane with the notice band or the relay line. */
body.touch.combat-hud:has(#banner.in) #killFeed{visibility:visible;}
body.touch.combat-hud:has(#killFeed .kfRow) #relaySurgeHud{visibility:visible;}
/* -- Thumb cluster, neon pass (2026-09-15): a skill on cooldown painted a square shade across the bottom
   of a round button, because the slot keeps overflow:visible so the role caption can sit under it. The
   shade sweeps as a dial inside the circle now, the basic attack keeps its icon on the centre with the
   readiness bar hanging under it, and the skill and attack rings carry the Neon São Paulo magenta
   instead of the cyan the rest of the HUD spends on "ready". Gold still means ultimate. -- */
body.touch.combat-hud #abilities .slot .veil{inset:0;height:auto!important;border-radius:50%;transition:none;background:conic-gradient(rgba(6,4,10,.74) var(--cd,0turn),transparent 0);}
body.touch.combat-hud #tbAttack{display:grid;place-items:center;padding:0;}
body.touch.combat-hud #tbAttack>.hudSprite{grid-area:1/1;}
body.touch.combat-hud #tbAttack progress{position:absolute;left:50%;bottom:14%;transform:translateX(-50%);width:46%;margin:0;}
body.touch.combat-hud #abilities .slot{border-color:rgba(255,79,174,.34);}
body.touch.combat-hud #abilities .slot.ready{border-color:var(--hud-edge-glow);box-shadow:0 0 10px rgba(255,79,174,.38);}
body.touch.combat-hud #tbAttack{border-color:var(--hud-edge-glow);background:radial-gradient(circle at 50% 40%,rgba(255,79,174,.2),rgba(12,10,16,.62) 70%);box-shadow:0 0 18px rgba(255,79,174,.38);}
body.touch.combat-hud #tbAttack progress{appearance:none;-webkit-appearance:none;border-radius:999px;overflow:hidden;background:rgba(6,4,10,.8);}
body.touch.combat-hud #tbAttack progress::-webkit-progress-bar{background:rgba(6,4,10,.8);}
body.touch.combat-hud #tbAttack progress::-webkit-progress-value{background:var(--hud-edge-glow);}
body.touch.combat-hud #tbAttack progress::-moz-progress-bar{background:var(--hud-edge-glow);}
body.touch.combat-hud #tbAttack[data-state="disabled"],body.touch.combat-hud #tbAttack[data-state="no-target"]{border-color:var(--hud-border);box-shadow:none;background:var(--combat-glass);}
body.touch.combat-hud #companionSkills .hud-companion-skill[data-ready="true"]{border-color:var(--hud-edge-glow);}
/* The arc places the ult by id, which outranked its own ready rule, so it never brightened. */
body.touch.combat-hud #abilities #ab-4.ready{border-color:var(--hud-accent);box-shadow:0 0 12px rgba(242,193,78,.4);}
/* -- Collapsed evolution entry is a chip in the vitals row, not a second line. As a full-width row it added
   ~48px under the portrait, which on a 320px-tall phone dropped the left column onto the Pilot button and the
   joystick. The row never wraps: the chip shrinks (and its label ellipsises) and the panel stops short of the
   ability cluster. -- */
body.touch.combat-hud #heroPanel{flex-wrap:nowrap;max-width:calc(100vw - var(--sal) - var(--sar) - var(--hud-space-2) - var(--hud-space-3) - var(--combat-cluster-w) - var(--combat-inset,0px));}
body.touch.combat-hud #orbitalPortrait,body.touch.combat-hud #heroMeta{flex:none;}
body.touch.combat-hud #heroPanel #combatStatus{flex:0 1 auto;min-width:0;}
body.touch.combat-hud #heroPanel #evolutionPanel[data-view="collapsed"]{flex:0 1 auto;min-width:0;width:auto;margin-top:0;background:transparent;border:0;}
body.touch.combat-hud #evolutionPanel[data-view="collapsed"] .evolutionReopen{gap:var(--hud-space-1);padding:0 10px;border-radius:999px;border:1px solid var(--combat-rim);background:var(--combat-glass);}
body.touch.combat-hud #evolutionPanel[data-view="collapsed"] .evolutionReopen>span{flex:none;}
body.touch.combat-hud #evolutionPanel[data-view="collapsed"] .evolutionReopen b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:700 10px/1.2 var(--hud-font-display);}

/* Studio readout pass: changing numbers keep their width, text stays secondary. */
#clock{font-variant-numeric:tabular-nums;padding:var(--hud-space-1) var(--hud-space-3);border-radius:var(--hud-radius);}
#scoreLine{font-variant-numeric:tabular-nums;}
#scoreLine b{color:var(--hud-text);font-weight:var(--hud-weight-strong);}
#heroPanel .vitalHeading,#heroPanel .vitalHeading b{font-variant-numeric:tabular-nums;}
body.touch.combat-hud #combatTeams{box-shadow:var(--hud-chrome-highlight);}
body.touch.combat-hud #combatTime{font-family:var(--hud-font-display);font-size:var(--hud-text-count);font-variant-numeric:tabular-nums;}
body:not(.touch) #heroPanel .track{border-radius:var(--hud-radius);}

@media(min-width:1440px) and (min-height:600px){
 body:not(.touch):not(.inlobby) #heroPanel .vitalHeading{font-size:var(--hud-text-sm);}
 body:not(.touch):not(.inlobby) #clock{font:var(--hud-weight-strong) var(--hud-text-count)/var(--hud-leading-title) var(--hud-font-display);letter-spacing:var(--hud-tracking-label);}
}
/* Keep utility taps as reliable as combat taps without enlarging the artwork. */
body.touch.combat-hud #combatOpenShop,body.touch.combat-hud #reactorEntry,body.touch.combat-hud #combatTeams{min-height:var(--hud-target);height:var(--hud-target);}
body.touch.combat-hud #combatBuy{min-height:var(--hud-target)!important;height:var(--hud-target);width:var(--hud-target);}
body.touch.combat-hud #btnHudOptions,body.touch.combat-hud #combatDetailsButton{min-width:var(--hud-target);min-height:var(--hud-target);width:var(--hud-target);height:var(--hud-target);}
body.touch.combat-hud #heroPanel{top:calc(var(--sat) + var(--combat-map) + var(--hud-space-3) + 52px);}
body.touch.combat-hud #combatDetailsButton{left:calc(var(--sal) + 128px);top:calc(var(--sat) + var(--combat-map) + var(--hud-space-1));}
/* The purchase card ("Starter Rod +10 attack damage") shared that corner and the button sat on its icon and
   first digit; it starts just past the button now. */
body.touch.combat-hud #combatPurchase{left:calc(var(--sal) + 128px + var(--hud-target) + var(--hud-space-2));}
body.touch.combat-hud #abilities #ab-5{min-width:var(--hud-target);min-height:var(--hud-target);width:var(--hud-target);height:var(--hud-target);}
/* Manual leveling is a separate, labeled touch row: a small + must not steal a skill drag. */
body.touch.combat-hud #combatUpgrades{left:50%;right:auto;top:auto;bottom:calc(var(--sab) + 72px);width:max-content;height:var(--hud-target);display:flex;gap:var(--hud-space-1);transform:translateX(-50%);}
body.touch.combat-hud #combatUpgrades .combatUpgrade{position:relative;inset:auto;width:calc(var(--hud-target) + var(--hud-space-4));height:auto;min-width:var(--hud-target);min-height:var(--hud-target);padding:var(--hud-space-1);border-radius:var(--hud-radius);background:var(--hud-surface-panel);border:var(--hud-border-width) solid var(--hud-accent);color:var(--hud-accent);gap:var(--hud-space-1);}
body.touch.combat-hud #combatUpgrades .combatUpgrade .skillIcon{display:block;width:var(--hud-space-6);height:var(--hud-space-6);}
body.touch.combat-hud #combatUpgrades .combatUpgrade>b{position:absolute;right:0;top:0;bottom:auto;padding:0 var(--hud-space-1);background:var(--hud-surface-overlay);}

/* -- Three-skill thumb arc (2026-09-20, Mobile Legends reference): every hero now keeps two basics and the
   ultimate (heroes-data.js SKILL_CUTS), so the four-stop arc left a hole where the cut skill sat. The kept
   basics take 0deg and 45deg and the ultimate 90deg, all closer to the attack button and larger, whichever
   slot was cut (hud.js sets #abilities[data-cut]). Recall is the battle spell a player reaches for most, so it
   is the larger one and sits nearest the skills; Shield base moves to the left of it. -- */
body.touch.combat-hud{--arc-r:104px;--combat-size:58px;--combat-ult:66px;--combat-recall:52px;}
body.touch.combat-hud #abilities[data-cut="1"] #ab-2,body.touch.combat-hud #abilities[data-cut="2"] #ab-1,body.touch.combat-hud #abilities[data-cut="3"] #ab-1{--arc-cos:1;--arc-sin:0;}
body.touch.combat-hud #abilities[data-cut="1"] #ab-3,body.touch.combat-hud #abilities[data-cut="2"] #ab-3,body.touch.combat-hud #abilities[data-cut="3"] #ab-2{--arc-cos:.7071;--arc-sin:.7071;}
body.touch.combat-hud #abilities[data-cut] #ab-4{--arc-cos:0;--arc-sin:1;--arc-size:var(--combat-ult);}
body.touch.combat-hud #abilities[data-cut] #ab-1,body.touch.combat-hud #abilities[data-cut] #ab-2,body.touch.combat-hud #abilities[data-cut] #ab-3,body.touch.combat-hud #abilities[data-cut] #ab-4{
  width:var(--arc-size,var(--combat-size));height:var(--arc-size,var(--combat-size));
  right:calc(var(--arc-ax) + var(--arc-r) * var(--arc-cos) - var(--arc-size,var(--combat-size)) / 2);
  bottom:calc(var(--arc-ax) + var(--arc-r) * var(--arc-sin) - var(--arc-size,var(--combat-size)) / 2);
}
/* WebKit drops a border-radius + overflow clip once the art or the cooldown dial gets its own layer, so a
   skill on cooldown showed its square atlas tile around the circle on iPhone. clip-path holds everywhere. */
body.touch.combat-hud #abilities .slot>.skillIcon,body.touch.combat-hud #abilities .slot>.veil{clip-path:circle(50%);}
/* The cooldown count was a glass band 26px tall across the full button width, a dark rectangle poking out
   of both sides of the circle. The dial already dims the art, so the count is bare text on the centre. */
body.touch.combat-hud #abilities .combatSkillState:not([data-reason]){inset:0;display:grid;place-items:center;padding:0;border-radius:50%;background:transparent;font:700 18px/1 var(--hud-font-display);text-shadow:0 1px 2px #000,0 0 6px rgba(0,0,0,.9);}
body.touch.combat-hud #abilities #ab-4 .combatSkillState:not([data-reason]){font-size:20px;}
/* The aiming ring was an outline, which older Safari draws square; a spread shadow follows the circle. */
body.touch.combat-hud #abilities .slot.aiming{outline:0;box-shadow:0 0 0 3px #8deaff,0 0 14px rgba(141,234,255,.45);}
/* Recall: the primary battle spell, just right of centre. Shield base: the smaller one, just left. */
body.touch.combat-hud #touchBtns #tbRecall,body.touch.combat-hud #touchBtns #tbBuyback{width:var(--combat-recall);height:var(--combat-recall);right:calc(var(--spell-x) - var(--hud-space-2) - var(--combat-recall) - var(--sar) - var(--hud-space-2) - var(--combat-inset,0px));bottom:10px;}
body.touch.combat-hud #touchBtns #tbRecall::before,body.touch.combat-hud #touchBtns #tbBuyback::before{inset:0;border:1.5px solid var(--hud-focus);box-shadow:0 0 10px rgba(111,227,255,.3);}
body.touch.combat-hud #touchBtns #tbRecall::after,body.touch.combat-hud #touchBtns #tbBuyback::after{margin-top:1px;font-size:11px;}
body.touch.combat-hud #touchBtns #tbRecall .hudSprite,body.touch.combat-hud #touchBtns #tbBuyback .hudSprite{width:28px;height:28px;}
/* The spell pair sits at the centre until the floating stick's zone (--sal + 42vw) reaches it, then both
   slide right together: Shield base keeps 4px off the zone and Recall stays one gap to its right. */
body.touch.combat-hud{--spell-x:min(50vw + 4px, 58vw - var(--hud-target) - 4px - var(--sal));}
body.touch.combat-hud #abilities #ab-5{right:calc(var(--spell-x) - var(--sar) - var(--hud-space-2) - var(--combat-inset,0px));bottom:16px;}
@media(max-width:740px),(max-height:360px){
  body.touch.combat-hud{--arc-r:92px;--combat-size:52px;--combat-ult:58px;--combat-recall:48px;}
}

/* -- Phone pass, iPhone 15 landscape (2026-09-20): the manual level-up row sat centred at 50vw, which on a
   852x393 screen is inside the floating stick's 42vw zone -- the "+" buttons floated over the map and shared
   their taps with the joystick. They become a column just outside the skill arc, on the free band between
   the spells and the thumb cluster, above the stick zone in both position and stacking order. -- */
body.touch.combat-hud #combatUpgrades{
  left:auto;top:auto;transform:none;z-index:9;
  right:calc(var(--sar) + var(--hud-space-2) + var(--combat-inset,0px) + var(--arc-ax) + var(--arc-r) + var(--combat-size) / 2 + 4px);
  bottom:calc(var(--sab) + var(--hud-space-2) + 16px);
  width:calc(var(--hud-target) + var(--hud-space-4));height:max-content;flex-direction:column-reverse;
}

.combatUpgradeRole{font:var(--hud-text-xs)/var(--hud-leading) var(--hud-font-body);color:var(--hud-text);text-transform:none;}


/* ── ONE PAW (vertical, one thumb) ──────────────────────────────────────────
   The mode's whole promise is that there is nothing to press: the ability bar,
   the attack button and the item row come off the screen, and the landing zone
   for the stick becomes the entire lower half. The HUD that stays is the part
   that only reports — clock, health, level. */
body.onepaw #abilities,
body.onepaw #tbAttack,
body.onepaw #touchBtns,
body.onepaw #items,
body.onepaw #shopBtn,
body.onepaw #combatShop{display:none !important;}
/* With no button row to make space for, the street gets the whole screen and the stick floats on
   top of it: resize() reads the canvas rect, so a taller stage simply shows more of the crater.
   The portrait rule in style.css reserves 150px for a row of controls this mode does not have, and
   it is more specific than a plain body.onepaw, so this has to out-specify it inside the same
   query rather than merely come later. */
body.onepaw #stage{height:100dvh;}
@media (max-width:900px) and (orientation:portrait){
  body.onepaw.touch:not(.inlobby) #stage{height:100dvh;width:100vw;}
  /* The canvas itself is the real fix. In portrait the game keeps a 16:9 LANDSCAPE canvas, wider
     than the screen and centred with left:50%, because portrait was only ever the state behind the
     "rotate your phone" gate. ONE PAW turned that gate off, so the player was looking at a landscape
     canvas jammed into an upright window: the drawing is portrait, the box it is shown in was not,
     and everything in it came out stretched. Here the canvas is simply the screen, and resize()
     reads its box, so the view matches the shape it is drawn into. */
  body.onepaw.touch:not(.inlobby) #game{
    position:absolute;left:0;top:0;transform:none;
    width:100vw;height:100dvh;max-width:none;max-height:none;
  }
}
/* A <dialog> with no [open] was still painting: in the landscape HUD other chrome covered it, and
   with that chrome gone it is a pink box sitting on the street. */
body.onepaw #heroPractice:not([open]){display:none !important;}
/* The vitals panel is laid out for a landscape HUD and eats a third of a portrait screen. Scaled
   from its own corner it keeps every bar and readout, at a size a phone can spare. A narrow desktop window
   needs it as much as a phone; the desktop band below (1100px and up) sets transform:none itself. */
body.onepaw #heroPanel{transform:scale(.74);transform-origin:top left;opacity:.94;}
/* A tablet has the room a phone does not: at .74 its health and energy numbers were 7.4px on a 10-inch screen.
   It reads them at the desktop band's 11px instead. */
@media (min-width:700px) and (min-height:700px){body.onepaw.touch #heroPanel{transform:scale(1.1);}}
/* ONE PAW levels and buys for the pilot in every format, so the two automation switches switch nothing. */
body.onepaw #autoLvlLabel,body.onepaw #autoBuyLabel{display:none !important;}
body.onepaw #focusDetailsButton{display:none;}
/* The objective card sat under that panel. In portrait it crosses the top instead. */
body.onepaw #relaySurgeHud{top:108px;left:50%;right:auto;transform:translateX(-50%);max-width:min(92vw,340px);}
/* An upright phone has the minimap in the top-right corner at the same height (style.css: 96px, 8px in), and a
   centred card ran under it. The card is centred in the band left of the map instead. */
@media(orientation:portrait){
  body.onepaw.touch:not(.inlobby) #relaySurgeHud{top:calc(108px + var(--sat));left:calc(8px + var(--sal));right:calc(112px + var(--sar));
    transform:none;width:fit-content;max-width:none;margin-inline:auto;box-sizing:border-box;}
}
/* The whole lower screen is the thumb's landing zone. The zone was only switched on by body.combat-hud, which
   js/combat-hud.js sets in landscape alone, so an upright phone had no zone at all and only the resting ring took
   the thumb (the tutorial says "drag anywhere"); in landscape the combat HUD's 42vw corner box missed the ring,
   which ONE PAW parks in the middle. Declared for every ONE PAW touch match, above both. */
body.onepaw.touch:not(.inlobby) #stickZone{display:block;position:fixed;inset:40% 0 0 0;width:auto;height:auto;z-index:6;
  touch-action:none;user-select:none;-webkit-user-select:none;}
/* The stick rests in the MIDDLE of the bottom edge, the way a one-thumb game does it: upright, the
   phone is held in one hand and the thumb comes up the centre, not the corner, so a ring parked in
   the bottom-left is a reach across the screen before the match even starts. It still floats to
   wherever the thumb lands inside the zone; this is only where it waits and where it returns. */
body.onepaw.touch:not(.inlobby) #stick:not(.floating){
  left:50%;right:auto;transform:translateX(-50%);
  bottom:calc(30px + var(--sab));
}
body.onepaw #stick{opacity:.35;}
/* The kit at a glance: four tiny skill icons over the thumb band, each darkened by a sweep for the
   cooldown it has left (--cd, 0..1, from js/one-paw.js). Display only — nothing in ONE PAW is pressed. */
#onePawKit{display:none;}
/* Match-only: the lobby can hold a live pilot behind the home screen, and the strip then sat on the hero card. */
body.onepaw:not(.inlobby) #onePawKit:not([hidden]){
  position:fixed;left:0;right:0;bottom:calc(max(22%, 162px + var(--sab,0px)) + 26px);z-index:6;pointer-events:none;
  display:flex;justify-content:center;gap:6px;
}
body.onepaw .opKit{position:relative;width:20px;height:20px;border-radius:50%;overflow:hidden;opacity:.8;
  box-shadow:0 0 0 1px var(--hud-border-subtle),0 2px 6px rgba(0,0,0,.6);}
body.onepaw .opKit .skillIcon{position:absolute;inset:0;width:100%;height:100%;}
body.onepaw .opKit::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:conic-gradient(rgba(0,0,0,.72) calc(var(--cd,0) * 360deg),transparent 0);}
body.onepaw .opKit.ready{opacity:1;box-shadow:0 0 0 1px var(--hud-accent),0 2px 6px rgba(0,0,0,.6);}
body.onepaw .opKit.locked{opacity:.4;filter:grayscale(1);}
/* The kit and the verb clear the resting ring (30px off the bottom, at most 124px tall): 22% of a short phone
   put them on it. */
body.onepaw #onePawVerb{
  position:fixed;left:0;right:0;bottom:max(22%, 162px + var(--sab,0px));z-index:6;pointer-events:none;text-align:center;
  font:var(--hud-weight-strong) var(--hud-text-body)/1 var(--hud-font-display);
  letter-spacing:.18em;color:var(--hud-text);text-shadow:0 2px 8px #000;
}
/* The pick tray (js/one-paw.js): the level-up augments, or the level-4 evolution on its own, tapped at the
   bottom edge of the screen. Each card leads with one word for what it does (.opTag), then its name. It sat over
   the thumb band at first and covered the street ahead of the pilot; the bottom edge is the one strip of the
   picture nobody is walking into. It sits above the stick zone's z-index so a tap on a card never also walks.
   On touch it waits just above the resting stick ring (30px off the bottom, at most 124px tall), not on it:
   laid over the ring, a thumb coming back to walk landed on a card and picked it. */
#onePawPick{display:none;}
body.onepaw #onePawPick:not([hidden]){
  position:fixed;left:50%;transform:translateX(-50%);bottom:calc(8px + var(--sab,0px));z-index:8;
  width:min(94vw,380px);display:flex;flex-direction:column;gap:var(--hud-space-1);
  touch-action:none;user-select:none;-webkit-user-select:none;
}
body.onepaw .opHead{display:flex;justify-content:space-between;align-items:baseline;padding:0 var(--hud-space-1);
  font:var(--hud-weight-strong) var(--hud-text-sm)/1 var(--hud-font-display);letter-spacing:.14em;color:var(--hud-text);text-shadow:0 2px 6px #000;}
body.onepaw .opTitle{color:var(--hud-accent);}
body.onepaw #onePawPick[data-kind="evolve"] .opTitle{color:#7cf0c0;}
body.onepaw .opClock{color:var(--hud-text-muted);letter-spacing:.06em;}
body.onepaw .opCards{display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:var(--hud-space-2);}
body.onepaw .opCard{
  display:flex;flex-direction:column;align-items:center;gap:1px;min-width:0;min-height:92px;
  padding:6px var(--hud-space-1);border-radius:10px;cursor:pointer;
  background:var(--hud-surface-glass);border:var(--hud-border-width) solid var(--op-col,#fff);
  box-shadow:0 0 12px color-mix(in srgb,var(--op-col,#fff) 45%,transparent),0 4px 12px rgba(0,0,0,.6);
  color:var(--hud-text);font-family:var(--hud-font-label);text-align:center;
}
body.onepaw .opCard{position:relative;}
body.onepaw .opKey{position:absolute;top:4px;left:4px;line-height:1.2;}
body.onepaw .opCard:active{transform:scale(.96);}
body.onepaw .opCard:focus-visible{outline:2px solid var(--hud-focus);outline-offset:2px;}
body.onepaw .opCard.opBest{animation:opBest 1.2s ease-in-out infinite;}
@keyframes opBest{50%{box-shadow:0 0 22px var(--op-col,#fff),0 4px 12px rgba(0,0,0,.6);}}
body.onepaw .opIcon{display:grid;place-items:center;width:32px;height:32px;}
body.onepaw .opIcon .reactorIcon,body.onepaw .opIcon .evolutionIcon{width:32px;height:32px;flex:none;}
body.onepaw.touch:not(.inlobby) #onePawPick:not([hidden]){bottom:calc(162px + var(--sab,0px));}
/* The tray takes the bottom edge while it is up; the kit and the verb it would cover step aside for it. */
body.onepaw-picking #onePawKit,body.onepaw-picking #onePawVerb{visibility:hidden;}
/* Lifted over the ring, the tray reaches the gear cells beside it; they are read-only and wait a few seconds. */
body.onepaw-picking.touch #itemsPanel{visibility:hidden;}
/* The gear strip (js/gear-strip.js): an upright phone hides the item row (style.css), so the dog's items stand in
   a column under the minimap, one small icon each, darkened by a sweep for the cooldown a timed item has left
   (--cd, 0..1) and popped when it fires. Display only, like the kit: nothing in ONE PAW is pressed, and it sits
   under the map and the notice lane (#banner, 214px), right of the street the dog walks, over no bar. */
#gearStrip{display:none;}
body.onepaw.touch:not(.inlobby):not(.spectating) #gearStrip:not([hidden]){
  position:fixed;right:calc(8px + var(--sar,0px));top:calc(264px + var(--sat,0px));z-index:6;pointer-events:none;
  display:flex;flex-direction:column;align-items:center;gap:var(--hud-space-1);}
/* Sideways (a phone on its side, a tablet, the Steam Deck's handheld view) the item row used to hang off the skill
   arc, which ONE PAW hides: it floated beside the dog and dropped every item without a timer. The strip stands in
   for it there too, down the right edge under the kill feed (two 10px rows from 48px, ending near 90px); the row
   itself stays in Gear & Details. */
body.onepaw.touch:not(.inlobby) #stage>#itemsPanel{display:none;}
@media (orientation:landscape){
  body.onepaw.touch:not(.inlobby):not(.spectating) #gearStrip:not([hidden]){top:calc(104px + var(--sat,0px));}
}
body.onepaw .gsItem{position:relative;display:grid;place-items:center;width:26px;height:26px;border-radius:7px;overflow:hidden;
  font-size:15px;line-height:1;background:var(--hud-surface-glass);opacity:.9;
  box-shadow:0 0 0 1px var(--hud-border-subtle),0 2px 6px rgba(0,0,0,.6);}
body.onepaw .gsItem :is(.itemArt,img){position:absolute;inset:0;width:100%;height:100%;border-radius:0;}
body.onepaw .gsItem.timed::after{content:"";position:absolute;inset:0;
  background:conic-gradient(rgba(0,0,0,.72) calc(var(--cd,0) * 360deg),transparent 0);}
body.onepaw .gsItem.ready{opacity:1;box-shadow:0 0 0 1px var(--hud-accent),0 2px 6px rgba(0,0,0,.6);}
body.onepaw .gsItem.fired{animation:gsFired .6s ease-out;}
@keyframes gsFired{0%{transform:scale(1.45);}100%{transform:scale(1);}}
@media (prefers-reduced-motion:reduce){body.onepaw .gsItem.fired{animation:none;}}
/* The tray takes the lower screen while it is up; the strip steps aside with the kit. */
body.onepaw-picking #gearStrip{visibility:hidden;}
/* A phone on its side has no height to stack them over the ring: they sit beside it, on its right. */
@media (orientation:landscape) and (max-height:500px){
  body.onepaw:not(.inlobby) #onePawKit:not([hidden]){left:calc(50% + 74px);right:auto;justify-content:flex-start;bottom:calc(30px + var(--sab,0px) + 44px);}
  body.onepaw #onePawVerb{left:calc(50% + 74px);right:auto;text-align:left;bottom:calc(30px + var(--sab,0px) + 16px);}
  /* Lifted over the ring on a phone this short, the tray lands on the pilot (it stands mid-screen). The strip
     right of the ring is free while it is up (the kit and the verb hide), so the tray takes the bottom-right. */
  body.onepaw.touch:not(.inlobby) #onePawPick:not([hidden]){
    left:auto;right:calc(10px + var(--sar,0px));transform:none;bottom:calc(8px + var(--sab,0px));
    width:min(360px,calc(50vw - 70px - var(--sar,0px)));}
}
/* Short screens: compact cards, so the lifted tray stays under the pilot's feet. */
@media (max-height:640px){
  body.onepaw.touch .opCard{min-height:0;padding:4px var(--hud-space-1);}
  body.onepaw.touch .opIcon,body.onepaw.touch .opIcon .reactorIcon,body.onepaw.touch .opIcon .evolutionIcon{width:22px;height:22px;}
}
body.onepaw .opTag{font:var(--hud-weight-strong) 15px/1.05 var(--hud-font-display);letter-spacing:.06em;text-transform:uppercase;
  color:var(--op-col,#fff);overflow-wrap:anywhere;}
body.onepaw .opName{font-size:11px;line-height:1.2;font-weight:var(--hud-weight-label);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;}
body.onepaw .opSub{font-size:9.5px;line-height:1.1;letter-spacing:.08em;color:var(--hud-text-muted);text-transform:uppercase;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;}
@media (prefers-reduced-motion:reduce){body.onepaw .opCard.opBest{animation:none;}}
/* Gear cards (js/item-picks.js): the item's own painted tile, its price in scrap, and the scrap the dog has in the
   header. A card the scrap does not cover yet is dimmed and cannot be pressed; it lights up when the scrap arrives. */
body.onepaw #onePawPick[data-kind="item"] .opTitle{color:var(--hud-sticker-go);}
body.onepaw .opScrap{margin-left:auto;margin-right:var(--hud-space-2);color:var(--hud-sticker-go);letter-spacing:.06em;}
body.onepaw .opIcon .itemArt{width:32px;height:32px;}
body.onepaw .opCard.opLocked{opacity:var(--hud-disabled-opacity);filter:grayscale(.7);cursor:default;}
body.onepaw .opCard.opLocked:active{transform:none;}
@media (max-height:640px){body.onepaw.touch .opIcon .itemArt{width:22px;height:22px;}}
body.onepaw:not(.touch) .opIcon .itemArt{width:44px;height:44px;}

/* ── ONE PAW on a desktop ────────────────────────────────────────────────────
   The desktop band (desktop-ui.css) is laid out for five skill slots and six item cells, and ONE PAW
   shows neither: what was left was a screen-wide strip with two bars at one end and the scrap at the
   other, and the phone's scale(.74) shrank it from its corner so the level badge drifted into the
   middle. Here the band is only as wide as what it reports: portrait, bars, the kit's cooldowns, scrap
   and Bones, centred on the bottom edge. The pick tray, which a phone has to lay on the bottom edge,
   has a whole side of the screen on a desktop and takes the right one, clear of the band and the dog. */
@media (min-width:1100px) and (min-height:600px){
  :root{
    --op-s:1;
    --op-pad:10px;
    --op-pw:calc(56px * var(--op-s));
    --op-vw:calc(300px * var(--op-s));
    --op-kw:calc(120px * var(--op-s) + 18px);
    --op-gw:calc(88px * var(--op-s));
    --op-w:calc(var(--op-pad) * 2 + var(--op-pw) + 14px + var(--op-vw) + 16px + var(--op-kw) + 16px + var(--op-gw));
    --op-h:calc(var(--op-pw) + var(--op-pad) * 2);
    /* Centred, or pushed left of the 220px canvas minimap when a narrow window would put it underneath. */
    --op-x:min(calc(50vw - var(--op-w) / 2),calc(100vw - 236px - var(--op-w)));
    --op-b:calc(var(--sab,0px) + 12px);
    --op-vx:calc(var(--op-x) + var(--op-pad) + var(--op-pw) + 14px);
    --op-kx:calc(var(--op-vx) + var(--op-vw) + 16px);
    --op-gx:calc(var(--op-kx) + var(--op-kw) + 16px);
  }
  @media (min-width:1600px){:root{--op-s:1.15;}}
  @media (min-width:2300px){:root{--op-s:1.35;}}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroPanel{
    position:fixed;left:var(--op-x);top:auto;bottom:var(--op-b);width:var(--op-w);height:var(--op-h);
    min-width:0;max-width:none;box-sizing:border-box;transform:none;opacity:1;justify-content:center;gap:5px;
    padding:0 calc(var(--op-w) - (var(--op-vx) - var(--op-x)) - var(--op-vw)) 0 calc(var(--op-vx) - var(--op-x));
  }
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroPanel::before{
    inset:0;width:auto;bottom:0;clip-path:polygon(14px 0,100% 0,100% 100%,0 100%,0 14px);}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #orbitalPortrait{display:block;position:absolute;left:var(--op-pad);top:var(--op-pad);}
  body.onepaw:not(.touch):not(.inlobby) #orbitalPortrait .heroPortrait{width:var(--op-pw);height:var(--op-pw);}
  body.onepaw:not(.touch):not(.inlobby) #heroPanel .bar,
  body.onepaw:not(.touch):not(.inlobby) #heroPanel .track{flex:none;height:calc(17px * var(--op-s));}
  body.onepaw:not(.touch):not(.inlobby) #heroPanel .vitalHeading{font-size:calc(11px * var(--op-s));}
  /* The label sits on the yellow fill: the blue resource colour vanished into it, so it reads like HEALTH. */
  body.onepaw:not(.touch):not(.inlobby) #heroPanel #resourceLabel{color:var(--hud-text);}
  body.onepaw:not(.touch):not(.inlobby) #xpTrack{flex:none;}
  /* The stats row is a zero-size anchor; only level, scrap and Bones come back, each at its own block.
     The auto toggles stay off: ONE PAW buys and levels for the pilot. */
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta{
    position:fixed;left:0;bottom:0;width:0;height:0;min-height:0;padding:0;gap:0;overflow:visible;
    font:var(--hud-text-xs)/1.2 var(--hud-font-body);color:var(--hud-text-muted,#aeb8cc);}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta>*,
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #autoBuyLabel{display:none;}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta>i:first-child{
    display:block;position:fixed;left:calc(var(--op-x) + var(--op-pad));bottom:calc(var(--op-b) + var(--op-pad) + 2px);width:var(--op-pw);
    box-sizing:border-box;text-align:center;font:var(--hud-weight-strong) 10px/14px var(--hud-font-label);
    color:var(--hud-text);background:rgba(7,10,18,.72);border:var(--hud-border-hairline) solid rgba(255,255,255,.2);
    border-radius:var(--hud-radius);letter-spacing:.5px;white-space:nowrap;overflow:hidden;text-shadow:0 1px 2px #000;}
  /* The sticker keyline pushes the portrait in from the band's edge; the badge follows it. */
  html body.hud-theme-sticker.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta>i:first-child{margin-left:var(--hud-sticker-keyline-width);}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta>.gold{
    display:inline;position:fixed;left:var(--op-gx);bottom:calc(var(--op-b) + var(--op-h) / 2 + 1px);padding:0;border:0;background:none;
    font:var(--hud-weight-strong) calc(16px * var(--op-s))/1.2 var(--hud-font-body);text-shadow:0 1px 3px #000;}
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #heroMeta>#soulTxt{
    display:inline-flex;align-items:center;gap:3px;position:fixed;left:var(--op-gx);top:auto;bottom:calc(var(--op-b) + var(--op-h) / 2 - 20px * var(--op-s));
    font:calc(12px * var(--op-s))/1.2 var(--hud-font-body);text-shadow:0 1px 3px #000;}
  /* Items sit on the band's right shoulder, above it, never under the minimap. */
  body.onepaw:not(.touch):not(.inlobby):not(.spectating) #itemsPanel{
    position:fixed;left:auto;right:calc(100vw - var(--op-x) - var(--op-w));bottom:calc(var(--op-b) + var(--op-h) + 6px);
    display:flex;gap:4px;max-width:none;}
  body.onepaw:not(.touch):not(.inlobby) #itemsPanel .itemSlot{width:32px;height:32px;}
  /* The kit's cooldowns live inside the band, between the bars and the scrap, at a size a mouse player reads. */
  body.onepaw:not(.touch):not(.inlobby) #onePawKit:not([hidden]){
    left:var(--op-kx);right:auto;width:var(--op-kw);justify-content:flex-start;gap:6px;
    bottom:calc(var(--op-b) + (var(--op-h) - 30px * var(--op-s)) / 2);}
  body.onepaw:not(.touch) .opKit{width:calc(30px * var(--op-s));height:calc(30px * var(--op-s));}
  body.onepaw:not(.touch):not(.inlobby) #onePawVerb{bottom:calc(var(--op-b) + var(--op-h) + 44px);}
}
/* The tray takes the right side, one card per row, so nothing it opens covers the band or the kit. */
body.onepaw:not(.touch) #onePawPick:not([hidden]){
  left:auto;right:calc(var(--sar,0px) + 20px);top:50%;bottom:auto;transform:translateY(-50%);width:min(300px,34vw);}
body.onepaw-picking:not(.touch) #onePawKit,body.onepaw-picking:not(.touch) #onePawVerb{visibility:visible;}
body.onepaw:not(.touch) .opCards{grid-template-columns:1fr;}
body.onepaw:not(.touch) .opCard{
  display:grid;grid-template-columns:44px minmax(0,1fr);column-gap:12px;row-gap:1px;align-items:center;justify-items:start;
  min-height:0;padding:10px 40px 10px 12px;text-align:left;}
body.onepaw:not(.touch) .opIcon{grid-row:1 / 4;grid-column:1;width:44px;height:44px;}
body.onepaw:not(.touch) .opIcon .reactorIcon,body.onepaw:not(.touch) .opIcon .evolutionIcon{width:44px;height:44px;}
body.onepaw:not(.touch) :is(.opTag,.opName,.opSub){grid-column:2;}
body.onepaw:not(.touch) .opTag{font-size:16px;}
body.onepaw:not(.touch) .opName{font-size:12px;}
body.onepaw:not(.touch) .opKey{top:50%;left:auto;right:12px;transform:translateY(-50%);}


/* ── ONE PAW: the two pickers ───────────────────────────────────────────────
   The reactor draft and the evolution choice are this mode's pick-one moments —
   the only things in it that are meant to be tapped — and both were laid out for
   a landscape HUD. The reactor sheet was 240px wide and pushed to one side of a
   375px screen; the evolution dialog computed max-width:71px, because its rule
   subtracts fixed side margins that only exist in landscape, which made it
   unusable. In portrait both become a bottom sheet: full width, under the thumb,
   one card per row, scrolling if the choices do not fit. */
/* `:not([hidden])` is not decoration. `#evolutionPanel[hidden]{display:none}` in evolutions.css and
   a plain `body.onepaw #evolutionPanel` weigh the same in ids and classes, and this sheet comes
   later, so it won: the empty panel was laid out as a full-width bottom sheet and sat on the street
   as a pink bar across the bottom of every ONE PAW match. */
body.onepaw #evolutionPanel:not([hidden]),
body.onepaw #reactorDialog[open],
body.onepaw #combatEvolutionDialog[open]{
  position:fixed;left:0;right:0;bottom:0;top:auto;
  width:100vw;max-width:100vw;min-width:0;margin:0;
  max-height:88dvh;overflow-y:auto;-webkit-overflow-scrolling:touch;
  border-radius:var(--hud-radius) var(--hud-radius) 0 0;
  padding:var(--hud-space-3) var(--hud-space-3) max(var(--hud-space-3),env(safe-area-inset-bottom));
  display:flex;flex-direction:column;gap:var(--hud-space-2);
}
/* One choice per row, each one a real thumb target rather than a dense column. */
body.onepaw #reactorDialog .reactorChoices,
body.onepaw #evolutionPanel .hud-choices,
body.onepaw #combatEvolutionDialog .hud-choices,
body.onepaw #combatEvolutionDialog .reactorChoices{
  display:grid;grid-template-columns:1fr;gap:var(--hud-space-2);width:100%;
}
/* A card is sized by what it says, with a floor that keeps it a thumb target. The type does the
   work: at 10 and 12px these read as a desktop tooltip blown up, which is what made the sheet feel
   like mostly air. Bigger text in a tighter box is both easier to read and smaller on screen. */
body.onepaw #reactorDialog .hud-choice,
body.onepaw #combatEvolutionDialog .hud-choice,
body.onepaw #evolutionPanel .hud-upgrade-choice{
  width:100%;min-height:56px;text-align:left;padding:var(--hud-space-2) var(--hud-space-3);
}
body.onepaw #evolutionPanel .evolutionName b,
body.onepaw #reactorDialog .hud-choice b,
body.onepaw #reactorDialog .hud-choice strong{font-size:15px;line-height:1.3;}
body.onepaw #evolutionPanel .evolutionRole,
body.onepaw #reactorDialog .hud-choice small{font-size:12.5px;line-height:1.35;}
/* "Choose a reactor" under a heading that already says so: a line of screen for no information. */
body.onepaw #reactorDialog > .hud-stack > p{display:none;}
body.onepaw #evolutionPanel .evolutionTldr{font-size:12.5px;line-height:1.35;}
body.onepaw #evolutionPanel .evolutionIcon img{width:34px;height:34px;}
/* The close control is a corner button, not a choice: it must not be caught by the card rule and
   drag an 84px header up around a 10px title. */
body.onepaw #evolutionPanel header{
  display:flex;align-items:center;justify-content:space-between;gap:var(--hud-space-2);
  width:100%;min-height:0;padding:0;
}
body.onepaw #evolutionPanel header h2,
body.onepaw #evolutionPanel header .hud-label{font-size:14px;line-height:1.2;margin:0;}
body.onepaw #evolutionPanel header button{
  flex:0 0 auto;width:40px;min-width:40px;height:40px;min-height:40px;padding:0;font-size:20px;
}
/* The confirm or reroll stays reachable while the choices scroll behind it. */
body.onepaw #reactorDialog > .hud-stack > .btn.hud-action,
body.onepaw #combatEvolutionDialog > .hud-stack > .btn.hud-action{
  position:sticky;bottom:0;z-index:2;width:100%;min-height:52px;
}
