betterwithage commited on
Commit
00f1840
·
verified ·
1 Parent(s): 451899c

boot-ux: add no-white-flash branded boot-guard splash to /console (pages/console.html)

Browse files

Additive inline splash painted as first <body> node so first paint is always branded chrome + honest 'initializing…', never a white void during cold factory-rebuild boot or while the first live fetch resolves. Self-clears on first view paint; honest 'reconnecting' fallback on stall; hard-cap removal; respects prefers-reduced-motion. 0 runtime CDN, no codenames, no fabricated metrics.

Files changed (1) hide show
  1. pages/console.html +85 -0
pages/console.html CHANGED
@@ -442,6 +442,91 @@ details.raw[open] summary{color:var(--muted);}
442
  </style>
443
  </head>
444
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
445
  <div class="topbar">
446
  <button class="menu-btn" aria-label="Toggle navigation" aria-expanded="false" onclick="toggleSide()">☰</button>
447
  <span>SZL HOLDINGS</span><span class="sep">/</span>
 
442
  </style>
443
  </head>
444
  <body>
445
+ <!-- ============================================================================
446
+ SZL BOOT-GUARD (no-white-flash) — additive, 0-CDN, byte-identical across flagships.
447
+ PROBLEM: the head loads several synchronous vendored <script src> tags (THREE,
448
+ ECharts, globe.gl, etc.) BEFORE <body> is parsed; on a cold factory-rebuild boot
449
+ or a slow/ flapping egress that download window paints as a WHITE VOID, and the
450
+ bare <main>loading…</main> can persist if a view's first live fetch stalls.
451
+ FIX: paint a branded full-screen splash as the FIRST node in <body> using ONLY
452
+ inline styles (cannot be blocked by any external asset), so first paint is ALWAYS
453
+ the branded shell + an honest "initializing…" — never white. The guard self-clears
454
+ the instant the app's first view renders (MutationObserver on #content), and a
455
+ watchdog turns the copy into an honest "reconnecting" line if boot stalls past the
456
+ cap — NEVER a permanent spinner, NEVER a fabricated number. Respects
457
+ prefers-reduced-motion. Removes itself cleanly; leaves zero residue in the DOM. -->
458
+ <div id="szl-bootguard" role="status" aria-live="polite" style="position:fixed;inset:0;z-index:2147483646;background:#0a0a0a;color:#f5f5f5;display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:'Space Grotesk',Georgia,serif;-webkit-font-smoothing:antialiased;">
459
+ <div style="display:flex;align-items:center;gap:14px;">
460
+ <div id="szl-bg-mark" style="width:48px;height:48px;border-radius:11px;background:linear-gradient(135deg,#c9b787,#5fb3a3);color:#0a0a0a;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:26px;line-height:1;box-shadow:0 0 22px rgba(95,179,163,.28);">A</div>
461
+ <div style="text-align:left;">
462
+ <div style="font-size:13px;letter-spacing:.18em;color:#888;font-family:'JetBrains Mono',ui-monospace,monospace;">SZL HOLDINGS</div>
463
+ <div style="font-size:21px;font-weight:600;color:#c9b787;line-height:1.15;">a11oy</div>
464
+ </div>
465
+ </div>
466
+ <div style="margin-top:26px;width:168px;height:3px;border-radius:3px;background:rgba(201,183,135,.14);overflow:hidden;">
467
+ <div id="szl-bg-bar" style="height:100%;width:38%;border-radius:3px;background:linear-gradient(90deg,#5fb3a3,#c9b787);"></div>
468
+ </div>
469
+ <div id="szl-bg-msg" style="margin-top:16px;font-size:12px;letter-spacing:.08em;color:#9a9a9a;font-family:'JetBrains Mono',ui-monospace,monospace;">initializing&hellip;</div>
470
+ </div>
471
+ <style id="szl-bootguard-css">
472
+ @keyframes szlBgSlide{0%{transform:translateX(-120%)}100%{transform:translateX(360%)}}
473
+ #szl-bg-bar{animation:szlBgSlide 1.25s cubic-bezier(.4,0,.2,1) infinite;}
474
+ #szl-bootguard{transition:opacity .42s ease;}
475
+ #szl-bootguard.szl-bg-hide{opacity:0;pointer-events:none;}
476
+ @media (prefers-reduced-motion: reduce){
477
+ #szl-bg-bar{animation:none;width:100%;}
478
+ #szl-bootguard{transition:none;}
479
+ }
480
+ </style>
481
+ <script>
482
+ /* Boot-guard controller (inline, no deps — runs immediately, before the heavy
483
+ bundle). Clears the splash the moment the first real view paints into #content;
484
+ degrades to an honest message if boot stalls; hard-caps removal so the guard can
485
+ NEVER itself become a stuck overlay. Honesty doctrine: no fabricated state. */
486
+ (function(){
487
+ var g=document.getElementById('szl-bootguard'); if(!g) return;
488
+ var msg=document.getElementById('szl-bg-msg');
489
+ var done=false;
490
+ function clear(){
491
+ if(done) return; done=true;
492
+ try{ g.classList.add('szl-bg-hide'); }catch(e){}
493
+ setTimeout(function(){ try{ if(g&&g.parentNode) g.parentNode.removeChild(g); var s=document.getElementById('szl-bootguard-css'); if(s&&s.parentNode) s.parentNode.removeChild(s); }catch(e){} }, 480);
494
+ }
495
+ // Consider the app "booted" when #content holds real rendered markup (not the
496
+ // bare "loading…" seed). Watch for the first substantive paint.
497
+ function contentReady(){
498
+ var c=document.getElementById('content'); if(!c) return false;
499
+ var t=(c.textContent||'').trim();
500
+ // Seed states that are NOT "ready": the bare loading seed and an empty pane.
501
+ if(!t) return false;
502
+ if(c.children && c.children.length>0 && t!=='loading…' && t!=='loading\u2026') return true;
503
+ return false;
504
+ }
505
+ function tick(){ if(contentReady()) clear(); }
506
+ var mo;
507
+ try{
508
+ var c0=document.getElementById('content');
509
+ if(window.MutationObserver && c0){
510
+ mo=new MutationObserver(function(){ tick(); });
511
+ mo.observe(c0,{childList:true,subtree:true,characterData:true});
512
+ }
513
+ }catch(e){}
514
+ // Poll as a belt-and-suspenders backup (covers environments where the observer
515
+ // misses a synchronous innerHTML swap).
516
+ var poll=setInterval(function(){ tick(); if(done){ clearInterval(poll); try{mo&&mo.disconnect();}catch(e){} } }, 140);
517
+ // Honest stall message: if the shell is up but the first view hasn't painted in
518
+ // ~6s (slow cold boot / egress flap), tell the operator the truth — never a void.
519
+ setTimeout(function(){ if(!done && msg){ try{ msg.innerHTML='live meter reconnecting&hellip; <span style="color:#5fb3a3">shell ready</span>'; }catch(e){} } }, 6000);
520
+ // Hard cap: the branded chrome below is fully interactive on its own, so the
521
+ // splash MUST come down regardless — it can never be the thing that hangs.
522
+ setTimeout(clear, 9000);
523
+ // Also clear on full load as a floor.
524
+ if(document.readyState==='complete'){ setTimeout(tick,0); }
525
+ else { window.addEventListener('load', function(){ setTimeout(tick,300); }); }
526
+ })();
527
+ </script>
528
+ <!-- ============================ END SZL BOOT-GUARD ============================ -->
529
+
530
  <div class="topbar">
531
  <button class="menu-btn" aria-label="Toggle navigation" aria-expanded="false" onclick="toggleSide()">☰</button>
532
  <span>SZL HOLDINGS</span><span class="sep">/</span>