/* Logo-only launch opening. Faction dossier/contact-sheet art is
   intentionally restricted to the codex and never used as a splash. */
.mfTitleReveal{position:fixed;inset:0;z-index:950;display:grid;grid-template-rows:auto 1fr auto;overflow:hidden;isolation:isolate;
  padding:max(14px,calc(var(--sat) + 12px)) max(16px,calc(var(--sar) + 14px)) max(16px,calc(var(--sab) + 12px)) max(16px,calc(var(--sal) + 14px));
  color:#edf8ff;background:#02060c;opacity:0;transform:scale(1.025);transition:opacity .28s ease,transform .7s cubic-bezier(.16,.8,.2,1);touch-action:manipulation}
.mfTitleReveal[hidden]{display:none!important}.mfTitleReveal.open{opacity:1;transform:none}
.mfTitleBackdrop{position:absolute;inset:0;z-index:-1;overflow:hidden;background:
  radial-gradient(circle at 50% 47%,rgba(41,141,213,.16),transparent 23%),
  radial-gradient(ellipse at 50% 105%,rgba(255,199,83,.08),transparent 43%),
  linear-gradient(180deg,#02050a,#06101b 52%,#02050a)}
.mfTitleBackdrop::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(0,0,0,.36),transparent 30%,transparent 70%,rgba(0,0,0,.36));box-shadow:inset 0 0 120px rgba(0,0,0,.75)}
.mfTitleGrid{position:absolute;inset:-10%;opacity:.2;background-image:
  linear-gradient(rgba(92,190,255,.08) 1px,transparent 1px),linear-gradient(90deg,rgba(92,190,255,.07) 1px,transparent 1px);
  background-size:42px 42px;transform:perspective(520px) rotateX(63deg) translateY(29%);mask-image:linear-gradient(180deg,transparent 16%,#000 64%,transparent)}
.mfTitleSweep{position:absolute;inset:-35% -20%;background:linear-gradient(103deg,transparent 45%,rgba(118,213,255,.11) 50%,transparent 55%);animation:mfTitleSweep 3.4s ease-in-out infinite}
@keyframes mfTitleSweep{from{transform:translateX(-28%)}to{transform:translateX(28%)}}
.mfTitleTop{display:flex;justify-content:space-between;align-items:center;width:min(100%,920px);margin:0 auto}
.mfTitleBuild{display:flex;align-items:center;color:#b9cddd;font:800 10px/1 var(--fT);letter-spacing:.12em}
.mfTitleBuild span{padding:8px 10px;border:1px solid rgba(116,181,220,.28);border-radius:7px;background:rgba(8,20,34,.62)}
.mfTitleSkip{min-width:54px;min-height:48px;padding:0 12px;border:1px solid rgba(158,200,226,.34);border-radius:11px;color:#dcedf8;background:rgba(5,13,23,.78);font:800 10px/1 var(--fT);letter-spacing:.12em}
.mfTitleSkip span{color:#ffd46e;margin-left:4px}.mfTitleSkip:active{transform:scale(.96)}
.mfTitleCenter{align-self:center;justify-self:center;width:min(100%,900px);text-align:center;animation:mfTitleCenterIn .9s cubic-bezier(.16,.8,.2,1) both}
@keyframes mfTitleCenterIn{from{opacity:0;transform:translateY(18px) scale(.96);filter:blur(8px)}to{opacity:1;transform:none;filter:none}}
.mfTitleArt{display:block; width:min(100%,860px); height:auto; max-height:min(37vh,340px); margin:0 auto;filter:drop-shadow(0 16px 30px rgba(0,0,0,.88));
  object-fit:contain; object-position:center; animation:mfTitleArtIn 1.15s cubic-bezier(.16,.8,.2,1) both}
.mfTitleFallback{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:130px;margin:0 auto;padding:18px;color:#eaf5ff;text-align:center;text-shadow:0 5px 16px #000}.mfTitleFallback b{font:900 clamp(42px,12vw,106px)/.84 var(--fT);letter-spacing:.04em;color:#eef5f8;-webkit-text-stroke:1px #587184}.mfTitleFallback span{margin-top:14px;color:#92c8e5;font:800 clamp(9px,1.5vw,13px)/1 var(--fT);letter-spacing:.25em}
#menuBrand.mfTitleFallback{width:min(86vw,430px);min-height:102px;margin:6px auto 2px}.mfTitleFallback#menuBrand b{font-size:clamp(31px,8.5vw,55px)}.mfTitleFallback#menuBrand span{margin-top:9px;font-size:9px;letter-spacing:.17em}
@keyframes mfTitleArtIn{0%{opacity:0;transform:translateY(10px) scale(.96);filter:blur(7px)}58%{opacity:1}100%{transform:none;filter:drop-shadow(0 16px 30px rgba(0,0,0,.88))}}
.mfTitleStatus{display:inline-flex;align-items:center;gap:8px;margin-top:25px;color:#91aabd;font:700 9px/1 var(--fU);letter-spacing:.19em}
.mfTitleStatus span{width:7px;height:7px;border-radius:50%;background:#6ed6ff;box-shadow:0 0 12px #6ed6ff;animation:mfTitlePulse 1.25s ease-in-out infinite}
@keyframes mfTitlePulse{50%{opacity:.3;transform:scale(.72)}}
.mfTitleBottom{width:min(100%,460px);margin:0 auto}.mfTitleStart{width:100%;min-height:56px;border:1px solid #fff1bb;border-radius:12px;color:#1b1101;background:linear-gradient(180deg,#fff0af,#e9bb52 47%,#bd8730 53%,#f2cd70);box-shadow:0 10px 34px rgba(0,0,0,.55),0 0 22px rgba(255,212,110,.2);font:900 14px/1 var(--fT);letter-spacing:.14em}
.mfTitleStart span{font-size:12px;margin-right:8px}.mfTitleStart:active{transform:scale(.98);filter:brightness(1.08)}
body.mfIntroOpen{overflow:hidden}
@media(max-width:640px){.mfTitleCenter{width:100%}.mfTitleArt{width:100%}.mfTitleStatus{margin-top:19px;font-size:9px;letter-spacing:.12em}}
@media(max-height:520px){.mfTitleCenter{width:min(78vw,620px)}.mfTitleStatus{margin-top:12px}.mfTitleStart{min-height:48px}}
@media(prefers-reduced-motion:reduce){.mfTitleReveal,.mfTitleCenter,.mfTitleArt,.mfTitleSweep,.mfTitleStatus span{animation:none!important;transition:none!important;transform:none!important;filter:none!important}.mfTitleReveal.open{opacity:1}}

/* The launch title owns the first painted frame. #mfBootCover (declared in
   index.html's body markup, so it survives the OTA body swap) is opaque from the
   first paint; the front-end overlays also stay hidden until the reveal is
   dismissed and intro.js sets body.mfIntroDone. The cover is dropped by intro.js
   (removeChild), NOT by a body.mfIntroDone rule — a stale class persisted across
   an OTA body.innerHTML swap must not expose the menu before the new reveal.
   Mirrors index.html's critical inline <style>; an OTA patch re-injects this
   stylesheet but keeps the installed build's old <head>. */
#mfBootCover{position:fixed;inset:0;z-index:930;background:#02060c}
body:not(.mfIntroDone) .overlay{display:none!important}

/* Menu brand art. These rules MUST live here, not only in index.html's inline
   <style>: the OTA shell keeps the installed build's old <head> and re-injects
   only the LINKED stylesheets, so an OTA-updated phone never sees that inline
   block — without this mirror the brand <img> renders at its natural 1719x915
   and swallows the menu (seen live on device at 1.32.4). */
#menuBrand{display:block;width:min(92vw,485px);max-width:calc(100vw - var(--sal) - var(--sar) - 34px);height:auto;max-height:min(27vh,235px);margin:10px auto 4px;
  filter:drop-shadow(0 10px 22px rgba(0,0,0,.75));object-fit:contain;object-position:center;
  transform:rotateY(var(--px,0)) rotateX(var(--py,0)) translateZ(18px)}
@media(max-height:720px){#menuBrand{width:min(84vw,410px);max-height:min(23vh,188px);margin-top:4px}}
