5252 position : absolute;
5353 inset : 10px ;
5454 /* Rounder corners = more curved glass feel */
55- border-radius : 30 px / 28px ;
55+ border-radius : 32 px / 28px ;
5656 overflow : hidden;
5757 background : # 0a0e1a ;
58- /* Perspective + slight scale creates the outward convex bulge illusion */
59- transform : perspective (900px ) scale (1.018 );
60- /* SVG barrel distortion filter */
61- filter : url (# barrel- dis to rtion);
58+ /* Real barrel bulge via SVG filter + mild perspective lift */
59+ transform : perspective (900px ) scale (1.012 );
60+ transform-origin : center;
61+ filter : url (# crt- bulge-filter);
62+ box-shadow : inset 0 0 60px rgba (0 , 0 , 0 , 0.6 );
6263}
6364
6465/* Glass dome bubble highlight
8283 transparent 70% ),
8384 /* Corner darkening — outward-curved screens are dark at corners */
8485 radial-gradient (ellipse 78% 72% at 50% 50% ,
85- transparent 42 % ,
86- rgba (0 , 0 , 0 , 0.28 ) 75% ,
87- rgba (0 , 0 , 0 , 0.55 ) 100% );
86+ transparent 50 % ,
87+ rgba (0 , 0 , 0 , 0.20 ) 75% ,
88+ rgba (0 , 0 , 0 , 0.38 ) 100% );
8889 pointer-events : none;
8990 z-index : 9990 ;
9091}
110111
111112
112113/* ---- SCANLINES ----
113- * Horizontal lines that slowly scroll, like a real CRT .
114+ * Alternating bright and dark horizontal lines .
114115 */
115116.crt-scanlines {
116117 position : absolute;
117118 inset : 0 ;
118- background : repeating-linear-gradient (0deg ,
119- transparent,
120- transparent 2px ,
121- rgba (0 , 0 , 0 , 0.075 ) 2px ,
122- rgba (0 , 0 , 0 , 0.075 ) 4px );
119+ background : repeating-linear-gradient (
120+ 0deg ,
121+ rgba (255 , 255 , 255 , 0.035 ) 0px ,
122+ rgba (255 , 255 , 255 , 0.035 ) 1px ,
123+ rgba (0 , 0 , 0 , 0.18 ) 2px ,
124+ rgba (0 , 0 , 0 , 0.18 ) 4px
125+ );
123126 pointer-events : none;
124127 z-index : 9000 ;
125128 animation : scanlineScroll 12s linear infinite;
126129}
127130
128131/* ---- VIGNETTE ----
129- * Corner darkening that complements the barrel lens curvature.
130- * Made stronger than before to match the curved-screen look.
132+ * Soft corner darkening.
131133 */
132134.crt-vignette {
133- display : none;
135+ position : absolute;
136+ inset : 0 ;
137+ pointer-events : none;
138+ z-index : 8999 ;
139+ background : radial-gradient (ellipse 70% 65% at 50% 50% , transparent 50% , rgba (0 , 0 , 0 , 0.48 ) 100% );
134140}
135141
136142/* ============================================================
154160 keeping the effect feeling organic and not repetitive.
155161 ============================================================ */
156162
157- /* WAVE 1 — Horizontal sweep band */
158- .crt-wave-h {
159- position : absolute;
160- left : 0 ;
161- right : 0 ;
162- height : 4px ;
163- pointer-events : none;
164- z-index : 9003 ;
165- background : linear-gradient (180deg ,
166- transparent 0% ,
167- rgba (200 , 255 , 200 , 0.06 ) 30% ,
168- rgba (200 , 255 , 200 , 0.10 ) 50% ,
169- rgba (200 , 255 , 200 , 0.06 ) 70% ,
170- transparent 100% );
171- box-shadow : 0 0 8px rgba (200 , 255 , 200 , 0.08 );
172- animation : waveH 4.8s linear infinite;
173- }
174-
175- @keyframes waveH {
176- 0% {
177- top : -10px ;
178- opacity : 0 ;
179- }
180-
181- 3% {
182- opacity : 1 ;
183- }
184-
185- 90% {
186- opacity : 0.5 ;
187- }
188-
189- 100% {
190- top : calc (100% + 10px );
191- opacity : 0 ;
192- }
193- }
194-
195- /* WAVE 2 — Roll bar (dark, wider, moves upward) */
196- .crt-wave-roll {
197- position : absolute;
198- left : 0 ;
199- right : 0 ;
200- height : 28px ;
201- pointer-events : none;
202- z-index : 9002 ;
203- background : linear-gradient (180deg ,
204- transparent 0% ,
205- rgba (0 , 0 , 0 , 0.20 ) 20% ,
206- rgba (0 , 0 , 0 , 0.35 ) 50% ,
207- rgba (0 , 0 , 0 , 0.20 ) 80% ,
208- transparent 100% );
209- animation : waveRoll 8.2s linear infinite;
210- animation-delay : -3.1s ;
211- }
212-
213- @keyframes waveRoll {
214- 0% {
215- bottom : -40px ;
216- opacity : 0 ;
217- }
218-
219- 5% {
220- opacity : 1 ;
221- }
222-
223- 88% {
224- opacity : 0.6 ;
225- }
226-
227- 100% {
228- bottom : calc (100% + 40px );
229- opacity : 0 ;
230- }
231- }
232-
233- /* WAVE 3 — Sync jitter (whole screen skew, brief) */
234- .crt-wave-jitter {
235- position : absolute;
236- inset : 0 ;
237- pointer-events : none;
238- z-index : 9004 ;
239- opacity : 0 ;
240- mix-blend-mode : difference;
241- animation : waveJitter 12.5s step-end infinite;
242- animation-delay : -4.7s ;
243- }
244-
245- @keyframes waveJitter {
246-
247- /* 94.4% of the time: invisible */
248- 0% ,
249- 94.4% {
250- opacity : 0 ;
251- transform : none;
252- }
253-
254- /* Brief skew pulse */
255- 94 .5% {
256- opacity : 1 ;
257- transform : skewX (0.4deg ) translateX (2px );
258- background : rgba (255 , 255 , 255 , 0.015 );
259- }
260-
261- 94 .7% {
262- opacity : 1 ;
263- transform : skewX (-0.3deg ) translateX (-3px );
264- }
265-
266- 94 .9% {
267- opacity : 1 ;
268- transform : skewX (0.2deg ) translateX (1px );
269- }
270-
271- 95 .1% {
272- opacity : 0 ;
273- transform : none;
274- }
275-
276- 100% {
277- opacity : 0 ;
278- transform : none;
279- }
280- }
163+ /* WAVE layers — disabled */
281164
282165
283166/* ---- CHROMATIC ABERRATION ----
292175 overflow : hidden;
293176}
294177
295- /* Red channel — shifts left */
178+ /* Red channel — shifts left (visible but subtle) */
296179.crt-chromatic ::before {
297180 content : '' ;
298181 position : absolute;
299182 inset : 0 ;
300183 background : linear-gradient (90deg ,
301- rgba (255 , 30 , 30 , 0.02 ) 0% ,
184+ rgba (255 , 30 , 30 , 0.016 ) 0% ,
302185 transparent 5% ,
303186 transparent 95% ,
304- rgba (255 , 30 , 30 , 0.025 ) 100% );
305- transform : translateX (-1.5 px );
187+ rgba (255 , 30 , 30 , 0.016 ) 100% );
188+ transform : translateX (-0.8 px );
306189}
307190
308- /* Blue channel — shifts right */
191+ /* Blue channel — shifts right (visible but subtle) */
309192.crt-chromatic ::after {
310193 content : '' ;
311194 position : absolute;
312195 inset : 0 ;
313196 background : linear-gradient (90deg ,
314- rgba (30 , 80 , 255 , 0.025 ) 0% ,
197+ rgba (30 , 80 , 255 , 0.016 ) 0% ,
315198 transparent 5% ,
316199 transparent 95% ,
317- rgba (30 , 80 , 255 , 0.02 ) 100% );
318- transform : translateX (1.5 px );
200+ rgba (30 , 80 , 255 , 0.016 ) 100% );
201+ transform : translateX (0.8 px );
319202}
320203
321204/* ---- PHOSPHOR GLOW ----
340223 inset : 0 ;
341224 pointer-events : none;
342225 z-index : 8997 ;
343- opacity : 0.03 ;
226+ opacity : 0.028 ;
344227 background-image : url ("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E" );
345228 background-size : 150px 150px ;
346229 animation : noiseShift 0.3s steps (5 ) infinite;
546429 }
547430}
548431
549- /* ---- POWER LED ----
550- * Small green dot below the monitor bezel.
551- */
552- .crt-power-led {
553- position : absolute;
554- bottom : -22px ;
555- left : 50% ;
556- transform : translateX (-50% );
557- width : 8px ;
558- height : 8px ;
559- background : # 39ff14 ;
560- border-radius : 50% ;
561- box-shadow : 0 0 6px # 39ff14, 0 0 15px rgba (57 , 255 , 20 , 0.3 );
562- animation : ledPulse 2.5s ease-in-out infinite;
563- z-index : 2 ;
564- }
565-
566- /* ---- BRAND LABEL ---- */
432+ /* ---- POWER LED (removed) ---- */
433+ .crt-power-led ,
567434.crt-brand {
568- position : absolute;
569- bottom : -32px ;
570- left : 50% ;
571- transform : translateX (-50% );
572- font-family : 'Press Start 2P' , monospace;
573- font-size : 5px ;
574- color : rgba (255 , 255 , 255 , 0.12 );
575- letter-spacing : 5px ;
576- white-space : nowrap;
435+ display : none;
577436}
578437
579438/* ============================================================
580439 GLOBAL BACKGROUND THEME ELEMENTS
581440 These sit behind the CRT screens to provide a continuous theme.
582441 ============================================================ */
583442
443+ /* ---- GLOBAL THEME BACKGROUND ----
444+ * Hidden by default; fades in when CRT boot completes.
445+ */
446+ .global-theme-bg {
447+ opacity : 0 ;
448+ visibility : hidden;
449+ transition : opacity 220ms ease, visibility 0s linear 220ms ;
450+ }
451+
584452/* ---- SCENE ELEMENTS (trees, water, ground) ---- */
585453.menu-trees {
586454 position : absolute;
734602@keyframes waterShimmer {
735603 0% { transform : translateX (-10% ); opacity : 0.5 ; }
736604 100% { transform : translateX (10% ); opacity : 1 ; }
605+ }
606+
607+ /* ============================================================
608+ CRT BOOT STATE — scoped by body classes added in app.js
609+ ============================================================ */
610+
611+ /* Hide content layers during boot animation */
612+ body .crt-booting .global-theme-bg ,
613+ body .crt-booting .start-screen ,
614+ body .crt-booting .menu-screen {
615+ opacity : 0 ;
616+ visibility : hidden;
617+ pointer-events : none;
618+ }
619+
620+ /* Reveal when CRT boot completes */
621+ body .crt-ready .global-theme-bg {
622+ opacity : 1 ;
623+ visibility : visible;
624+ transition : opacity 220ms ease, visibility 0s linear 0s ;
737625}
0 commit comments