;
;
/* ============================================================================
MOBILE HUD STACK POLICY
----------------------------------------------------------------------------
Combat alerts, economy coaching, intel, production and the command dock were
all individually correct but had no shared owner. On a phone they could fill
the entire screen at once. This late takeover gives those existing systems a
priority order without coupling their simulation code:
critical alert > direct tap feedback > one primary panel > coach banner
The permanent Army / Select / Stop / Build row stays reachable. Everything
else collapses while a primary panel is open and returns when it closes.
============================================================================ */
let mfUiCoachPending='',mfUiCoachFlushT=0,mfUiSyncFrame=0;
function mfUiInlineOpen(id){
const el=document.getElementById(id);
return !!(el&&el.style.display==='block');
}
function mfUiPanelOpen(){
return mfUiInlineOpen('buildMenu')||mfUiInlineOpen('prodMenu')||mfUiInlineOpen('bldMenu2');
}
function mfUiIntelOpen(){ return mfUiInlineOpen('unitCard'); }
function mfUiCriticalOpen(){ return mfUiInlineOpen('atkAlert')||mfUiInlineOpen('waveAlert'); }
function mfUiBusy(){ return mfUiPanelOpen()||mfUiIntelOpen()||mfUiCriticalOpen(); }
function mfUiClosePrimary(){
const intel=document.getElementById('unitCard');
if(intel){ clearTimeout(intel._t); intel.style.display='none'; }
if(typeof closeMenus==='function') closeMenus();
mfUiQueueSync();
}
function mfUiEnsurePanelChrome(id,label){
const el=document.getElementById(id); if(!el) return;
let bar=el.querySelector(':scope > .mfPanelChrome');
if(!bar){
bar=document.createElement('header');bar.className='mfPanelChrome';
bar.innerHTML='';
bar.querySelector('button').addEventListener('pointerdown',ev=>{
ev.preventDefault();ev.stopPropagation();mfUiClosePrimary();if(typeof sfx==='function')sfx('ui');
});
el.insertAdjacentElement('afterbegin',bar);
}
bar.querySelector('span').textContent=label;
}
function mfUiInstallChrome(){
mfUiEnsurePanelChrome('buildMenu','STRUCTURES');
mfUiEnsurePanelChrome('prodMenu','PRODUCTION');
mfUiEnsurePanelChrome('bldMenu2','STRUCTURE CONTROL');
}
function mfUiFlushCoach(){
clearTimeout(mfUiCoachFlushT);
if(!mfUiCoachPending||mfUiBusy()) return;
const msg=mfUiCoachPending;mfUiCoachPending='';
mfUiCoachFlushT=setTimeout(()=>{
if(mfUiBusy()){mfUiCoachPending=msg;return;}
if(typeof mfUiBaseShowCoach==='function')mfUiBaseShowCoach(msg);
},420);
}
function mfUiSync(){
mfUiSyncFrame=0;mfUiInstallChrome();
const body=document.body,panel=mfUiPanelOpen(),intel=mfUiIntelOpen();
const wave=mfUiInlineOpen('waveAlert'),attack=mfUiInlineOpen('atkAlert');
body.classList.toggle('uiPanelOpen',panel);
body.classList.toggle('uiIntelOpen',intel);
body.classList.toggle('uiPrimaryOpen',panel||intel);
body.classList.toggle('uiWaveOpen',wave);
body.classList.toggle('uiAttackOpen',attack);
for(const id of ['buildMenu','prodMenu','bldMenu2']){
const el=document.getElementById(id);if(el)el.setAttribute('aria-hidden',intel?'true':'false');
}
const coach=document.getElementById('coach');
if((panel||intel||wave||attack)&&coach&&Number(getComputedStyle(coach).opacity)>.05){
mfUiCoachPending=coach.textContent||mfUiCoachPending;
clearTimeout(coachHideT);coach.style.opacity=0;
}
if(!(panel||intel||wave||attack))mfUiFlushCoach();
}
function mfUiQueueSync(){
if(!mfUiSyncFrame)mfUiSyncFrame=requestAnimationFrame(mfUiSync);
}
/* Coach messages explain slow economy problems; they are never more urgent
than the panel the player deliberately opened or an incoming enemy wave. */
const mfUiBaseShowCoach=showCoach;
showCoach=function(msg){
if(mfUiBusy()){
mfUiCoachPending=msg;
const el=document.getElementById('coach');if(el)el.style.opacity=0;
return;
}
mfUiCoachPending='';mfUiBaseShowCoach(msg);
};
/* Automatic first-seen cards must not become a second primary panel. Explicit
info-button inspections remain available and temporarily replace the menu. */
const mfUiBaseShowIntelMarkup=showIntelMarkup;
showIntelMarkup=function(markup,pinned){
if(!pinned&&mfUiPanelOpen()) return;
mfUiBaseShowIntelMarkup(markup,pinned);mfUiQueueSync();
};
const mfUiBaseCloseMenus=closeMenus;
closeMenus=function(){mfUiBaseCloseMenus();mfUiQueueSync();};
const mfUiBaseOpenBldMenu=openBldMenu;
openBldMenu=function(b){mfUiBaseOpenBldMenu(b);mfUiQueueSync();};
const mfUiBaseRenderBuildMenu=renderBuildMenu;
renderBuildMenu=function(){mfUiBaseRenderBuildMenu();mfUiEnsurePanelChrome('buildMenu','STRUCTURES');mfUiQueueSync();};
const mfUiBaseRenderProdMenu=renderProdMenu;
renderProdMenu=function(){mfUiBaseRenderProdMenu();mfUiEnsurePanelChrome('prodMenu','PRODUCTION');mfUiQueueSync();};
const mfUiBaseRenderBldPanel=renderBldPanel;
renderBldPanel=function(){mfUiBaseRenderBldPanel();mfUiEnsurePanelChrome('bldMenu2','STRUCTURE CONTROL');mfUiQueueSync();};
const mfUiWatch=new MutationObserver(mfUiQueueSync);
for(const id of ['buildMenu','prodMenu','bldMenu2','unitCard','atkAlert','waveAlert']){
const el=document.getElementById(id);if(el)mfUiWatch.observe(el,{attributes:true,attributeFilter:['style','class']});
}
mfUiInstallChrome();mfUiSync();