@@ -2176,3 +2176,203 @@ input[type="range"]::-moz-range-thumb {
21762176 top : 16px ;
21772177 left : calc ((100vw - 300px ) / 2 );
21782178}
2179+
2180+ /* ============================================================
2181+ BOOT OVERLAY
2182+ Full-screen loader shown until the data + chart finish painting.
2183+ On narrow viewports it doubles as a "use a laptop" gate.
2184+ ============================================================ */
2185+
2186+ .boot-overlay {
2187+ position : fixed;
2188+ inset : 0 ;
2189+ z-index : 9999 ;
2190+ background : var (--bg );
2191+ background-image :
2192+ radial-gradient (
2193+ ellipse 80% 60% at 70% 10% ,
2194+ rgba (230 , 163 , 86 , 0.06 ),
2195+ transparent 70%
2196+ ),
2197+ radial-gradient (
2198+ ellipse 60% 50% at 30% 90% ,
2199+ rgba (230 , 163 , 86 , 0.03 ),
2200+ transparent 70%
2201+ );
2202+ color : var (--ink );
2203+ display : flex;
2204+ align-items : center;
2205+ justify-content : center;
2206+ padding : 32px ;
2207+ opacity : 1 ;
2208+ transition : opacity 400ms ease;
2209+ }
2210+
2211+ .boot-overlay .is-hidden {
2212+ opacity : 0 ;
2213+ pointer-events : none;
2214+ }
2215+
2216+ .boot-inner {
2217+ max-width : 520px ;
2218+ width : 100% ;
2219+ text-align : center;
2220+ display : flex;
2221+ flex-direction : column;
2222+ align-items : center;
2223+ gap : 32px ;
2224+ }
2225+
2226+ .boot-brand {
2227+ display : flex;
2228+ align-items : baseline;
2229+ gap : 10px ;
2230+ font-family : var (--display );
2231+ font-weight : 300 ;
2232+ font-size : 28px ;
2233+ letter-spacing : -0.01em ;
2234+ }
2235+
2236+ .boot-brand .brand-mark {
2237+ color : var (--accent );
2238+ font-size : 0.7em ;
2239+ position : relative;
2240+ top : -2px ;
2241+ }
2242+
2243+ .boot-brand .brand-name em {
2244+ color : var (--accent );
2245+ font-style : italic;
2246+ font-weight : 400 ;
2247+ }
2248+
2249+ /* ------- WIDE STATE (default) ------- */
2250+
2251+ .boot-wide {
2252+ display : flex;
2253+ flex-direction : column;
2254+ align-items : center;
2255+ gap : 18px ;
2256+ }
2257+
2258+ .boot-spinner {
2259+ display : flex;
2260+ gap : 8px ;
2261+ }
2262+
2263+ .boot-spinner span {
2264+ display : block;
2265+ width : 8px ;
2266+ height : 8px ;
2267+ border-radius : 50% ;
2268+ background : var (--accent );
2269+ animation : bootPulse 1.2s infinite ease-in-out;
2270+ }
2271+
2272+ .boot-spinner span : nth-child (2 ) { animation-delay : 0.15s ; }
2273+ .boot-spinner span : nth-child (3 ) { animation-delay : 0.30s ; }
2274+
2275+ @keyframes bootPulse {
2276+ 0% , 80% , 100% { opacity : 0.25 ; transform : scale (0.85 ); }
2277+ 40% { opacity : 1 ; transform : scale (1.1 ); }
2278+ }
2279+
2280+ .boot-status {
2281+ display : flex;
2282+ align-items : center;
2283+ gap : 14px ;
2284+ font-family : var (--mono );
2285+ font-size : 11px ;
2286+ text-transform : uppercase;
2287+ letter-spacing : 0.12em ;
2288+ color : var (--ink-faint );
2289+ }
2290+
2291+ .boot-status-label {
2292+ color : var (--accent );
2293+ font-weight : 500 ;
2294+ }
2295+
2296+ .boot-status-text {
2297+ color : var (--ink-dim );
2298+ text-transform : none;
2299+ letter-spacing : 0 ;
2300+ font-style : italic;
2301+ font-family : var (--display );
2302+ font-size : 14px ;
2303+ }
2304+
2305+ /* ------- NARROW STATE (hidden by default) ------- */
2306+
2307+ .boot-narrow {
2308+ display : none;
2309+ flex-direction : column;
2310+ align-items : center;
2311+ gap : 18px ;
2312+ max-width : 360px ;
2313+ }
2314+
2315+ .boot-icon {
2316+ width : 64px ;
2317+ height : 48px ;
2318+ color : var (--accent );
2319+ }
2320+
2321+ .boot-narrow-title {
2322+ margin : 0 ;
2323+ font-family : var (--display );
2324+ font-style : italic;
2325+ font-weight : 300 ;
2326+ font-size : 28px ;
2327+ line-height : 1.15 ;
2328+ color : var (--ink );
2329+ }
2330+
2331+ .boot-narrow-body {
2332+ margin : 0 ;
2333+ color : var (--ink-dim );
2334+ font-size : 14px ;
2335+ line-height : 1.55 ;
2336+ }
2337+
2338+ .boot-narrow-body strong {
2339+ color : var (--ink );
2340+ font-weight : 500 ;
2341+ }
2342+
2343+ .boot-url {
2344+ font-family : var (--mono );
2345+ font-size : 12px ;
2346+ color : var (--accent );
2347+ background : var (--bg-panel );
2348+ border : 1px solid var (--rule-strong );
2349+ padding : 2px 8px ;
2350+ border-radius : 3px ;
2351+ white-space : nowrap;
2352+ }
2353+
2354+ .boot-narrow-meta {
2355+ margin-top : 8px ;
2356+ font-family : var (--mono );
2357+ font-size : 9.5px ;
2358+ text-transform : uppercase;
2359+ letter-spacing : 0.18em ;
2360+ color : var (--ink-faint );
2361+ }
2362+
2363+ /* ------- VIEWPORT SWITCH -------
2364+ Below 900px the chart UI is essentially unusable; we show the
2365+ narrow-state copy instead and keep the overlay locked on. */
2366+ @media (max-width : 899px ) {
2367+ .boot-wide { display : none; }
2368+ .boot-narrow { display : flex; }
2369+ /* Critical: even after .is-hidden is added by JS, keep the gate up
2370+ because the actual app behind it is broken on this width. */
2371+ .boot-overlay .is-hidden {
2372+ opacity : 1 ;
2373+ pointer-events : auto;
2374+ }
2375+ /* Also hide the underlying page so nothing flashes behind the gate */
2376+ body .loaded .topbar ,
2377+ body .loaded main { display : none; }
2378+ }
0 commit comments