Skip to content

Commit 545930b

Browse files
committed
feat: add CRT theme with scanlines, vignette, and phosphor glow
1 parent 0207669 commit 545930b

4 files changed

Lines changed: 170 additions & 2 deletions

File tree

index.html

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@
9393
html[data-theme-style="neon"] #loading-screen .bar-inner {
9494
background: linear-gradient(90deg, #ff00b4, #00ccff);
9595
}
96+
/* CRT loading screen */
97+
html[data-theme-style="crt"] #loading-screen .bar-outer {
98+
border: 1px solid rgba(50,255,100,0.3);
99+
box-shadow: 0 0 8px rgba(50,255,100,0.1);
100+
}
101+
html[data-theme-style="crt"] #loading-screen .bar-inner {
102+
background: #22aa44;
103+
}
104+
html[data-theme-style="crt"] #loading-screen {
105+
animation: crt-flicker-screen 0.1s infinite;
106+
}
107+
@keyframes crt-flicker-screen {
108+
0%, 100% { opacity: 1; }
109+
50% { opacity: 0.985; }
110+
}
96111
@keyframes neon-bar-pulse {
97112
0% { box-shadow: 0 0 8px rgba(255,0,180,0.25), 0 0 24px rgba(0,200,255,0.12); }
98113
100% { box-shadow: 0 0 12px rgba(0,200,255,0.30), 0 0 30px rgba(255,0,180,0.15); }
@@ -115,6 +130,7 @@
115130
'dracula': { '--bg': '#282a36', '--ui-bg': '#363848', '--text': '#f8f8f2', '--text-muted': '#bfc0c0' },
116131
'redshift': { '--bg': '#0a0000', '--ui-bg': '#120000', '--text': '#cc8866', '--text-muted': '#995544' },
117132
'neon': { '--bg': '#06000a', '--ui-bg': '#0a0012', '--text': '#eeddff', '--text-muted': '#9977bb' },
133+
'crt': { '--bg': '#020a02', '--ui-bg': '#051005', '--text': '#44dd66', '--text-muted': '#22aa44' },
118134
'legacy': { '--bg': '#c0c0c0', '--ui-bg': '#c0c0c0', '--text': '#000000', '--text-muted': '#222222', '--border': '#808080', '--warning': '#cc6600' },
119135
'gg-ez': { '--bg': '#050505', '--ui-bg': '#0a0a0a', '--text': '#ffffff', '--text-muted': '#bbbbbb' },
120136
};
@@ -139,7 +155,7 @@
139155
if (id === 'light' || id === 'legacy' || (vars && vars['--bg'] && parseInt(vars['--bg'].replace('#','').slice(0,2), 16) > 128)) {
140156
document.documentElement.style.setProperty('color-scheme', 'light');
141157
}
142-
var styles = { 'legacy': 'legacy', 'gg-ez': 'rgb', 'neon': 'neon' };
158+
var styles = { 'legacy': 'legacy', 'gg-ez': 'rgb', 'neon': 'neon', 'crt': 'crt' };
143159
if (styles[id]) {
144160
document.documentElement.dataset.themeStyle = styles[id];
145161
}

src/themes/builtins.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { ThemeDef } from './types';
22
import { THEME_LEGACY } from './legacy';
33
import { THEME_RGB } from './rgb';
44
import { THEME_NEON } from './neon';
5+
import { THEME_CRT } from './crt';
56

67
export const THEME_DARK: ThemeDef = {
78
id: 'dark',
@@ -1004,5 +1005,5 @@ export const THEME_REDSHIFT: ThemeDef = {
10041005
},
10051006
};
10061007

1007-
export const BUILTIN_THEMES: ThemeDef[] = [THEME_DARK, THEME_RGB, THEME_NEON, THEME_HIGH_CONTRAST, THEME_LIGHT, THEME_LEGACY, THEME_TLESCOPE, THEME_REDSHIFT, THEME_EVERFOREST, THEME_GRUVBOX, THEME_SOLARIZED, THEME_NORD, THEME_TOKYO_NIGHT, THEME_DRACULA, THEME_CATPPUCCIN, THEME_LAVENDER];
1008+
export const BUILTIN_THEMES: ThemeDef[] = [THEME_DARK, THEME_RGB, THEME_NEON, THEME_CRT, THEME_HIGH_CONTRAST, THEME_LIGHT, THEME_LEGACY, THEME_TLESCOPE, THEME_REDSHIFT, THEME_EVERFOREST, THEME_GRUVBOX, THEME_SOLARIZED, THEME_NORD, THEME_TOKYO_NIGHT, THEME_DRACULA, THEME_CATPPUCCIN, THEME_LAVENDER];
10081009
export const DEFAULT_THEME_ID = 'dark';

src/themes/crt.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import type { ThemeDef } from './types';
2+
3+
export const THEME_CRT: ThemeDef = {
4+
id: 'crt',
5+
name: 'CRT',
6+
builtin: true,
7+
colorScheme: 'dark',
8+
themeStyle: 'crt',
9+
css: `/* CRT scanlines overlay on windows */
10+
html[data-theme-style="crt"] .draggable-window::after {
11+
content: '';
12+
position: absolute;
13+
inset: 0;
14+
pointer-events: none;
15+
background: repeating-linear-gradient(
16+
0deg,
17+
transparent 0px,
18+
transparent 2px,
19+
rgba(0,0,0,0.15) 2px,
20+
rgba(0,0,0,0.15) 4px
21+
);
22+
z-index: 100;
23+
border-radius: inherit;
24+
}
25+
/* Phosphor text glow */
26+
html[data-theme-style="crt"] .draggable-window {
27+
text-shadow: 0 0 4px rgba(50,255,100,0.3);
28+
border: 1px solid rgba(50,255,100,0.2);
29+
box-shadow:
30+
0 0 8px rgba(50,255,100,0.1),
31+
inset 0 0 40px rgba(0,0,0,0.3);
32+
border-radius: 3px;
33+
}
34+
html[data-theme-style="crt"] .draggable-window .window-titlebar {
35+
border-bottom: 1px solid rgba(50,255,100,0.1);
36+
text-shadow: 0 0 6px rgba(50,255,100,0.5), 0 0 12px rgba(50,255,100,0.2);
37+
}
38+
/* Vignette on windows */
39+
html[data-theme-style="crt"] .draggable-window::before {
40+
content: '';
41+
position: absolute;
42+
inset: 0;
43+
pointer-events: none;
44+
background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.4) 100%);
45+
z-index: 99;
46+
border-radius: inherit;
47+
}
48+
/* Modal glow */
49+
html[data-theme-style="crt"] .modal-overlay .draggable-window {
50+
box-shadow:
51+
0 0 15px rgba(50,255,100,0.15),
52+
inset 0 0 50px rgba(0,0,0,0.3);
53+
}
54+
/* Subtle flicker */
55+
html[data-theme-style="crt"] .draggable-window {
56+
animation: crt-flicker 0.1s infinite;
57+
}
58+
@keyframes crt-flicker {
59+
0%, 100% { opacity: 1; }
60+
50% { opacity: 0.985; }
61+
}
62+
/* Phosphor glow on buttons */
63+
html[data-theme-style="crt"] button:hover {
64+
text-shadow: 0 0 6px rgba(50,255,100,0.6), 0 0 12px rgba(50,255,100,0.2);
65+
}
66+
/* Glowing scrollbar */
67+
html[data-theme-style="crt"] ::-webkit-scrollbar-thumb {
68+
background: rgba(50,255,100,0.2) !important;
69+
box-shadow: 0 0 4px rgba(50,255,100,0.2);
70+
}
71+
html[data-theme-style="crt"] ::-webkit-scrollbar-thumb:hover {
72+
background: rgba(50,255,100,0.3) !important;
73+
}
74+
/* Glowing inputs */
75+
html[data-theme-style="crt"] input:focus,
76+
html[data-theme-style="crt"] select:focus {
77+
border-color: rgba(50,255,100,0.4) !important;
78+
box-shadow: 0 0 6px rgba(50,255,100,0.2);
79+
}`,
80+
vars: {
81+
'--bg': '#020a02',
82+
'--ui-bg': '#051005',
83+
'--border': '#0e2a0e',
84+
'--border-hover': '#33cc55',
85+
'--text': '#44dd66',
86+
'--text-dim': '#33cc55',
87+
'--text-muted': '#22aa44',
88+
'--text-faint': '#188833',
89+
'--text-ghost': '#0e5520',
90+
'--card-bg': 'rgba(2,10,2,0.92)',
91+
'--modal-bg': '#051005',
92+
'--modal-overlay': 'rgba(0,4,0,0.88)',
93+
'--kbd-bg': '#081808',
94+
'--link': '#188833',
95+
'--link-hover': '#44dd66',
96+
'--attrib': '#0e5520',
97+
'--panel-bg': '#061206',
98+
'--tooltip-bg': '#030c03',
99+
'--grid': '#0e2a0e',
100+
'--grid-subtle': '#081808',
101+
'--grid-dim': '#144014',
102+
'--row-border': 'rgba(50,255,100,0.04)',
103+
'--row-hover': 'rgba(50,255,100,0.06)',
104+
'--row-active': 'rgba(50,255,100,0.10)',
105+
'--row-highlight': 'rgba(50,255,100,0.08)',
106+
'--danger': '#cc4433',
107+
'--danger-bright': '#ee5544',
108+
'--warning': '#ccaa22',
109+
'--warning-bright': '#ddcc44',
110+
'--live': '#44dd66',
111+
'--handle-el': '#ccaa22',
112+
'--handle-az': '#33cc55',
113+
'--handle-hz': '#44dd66',
114+
'--handle-hz-active': '#66ee88',
115+
'--el-low': '#cc4433',
116+
'--el-mid': '#ccaa22',
117+
'--el-high': '#44dd66',
118+
'--mag-day': '#ccaa22',
119+
'--mag-twilight': '#ddcc44',
120+
'--marker-aos': '#33cc55',
121+
'--marker-los': '#0e5520',
122+
'--marker-tca': '#ccaa22',
123+
'--apsis-peri': '#22aa88',
124+
'--apsis-apo': '#ccaa22',
125+
'--marker-range': '#33cc55',
126+
'--accent': '#44dd66',
127+
'--scene-text': 'rgba(68,221,102,0.80)',
128+
'--scene-text-dim': 'rgba(68,221,102,0.50)',
129+
'--scene-shadow': '#000000',
130+
'--snap-guide': 'rgba(50,255,100,0.3)',
131+
'--radar-bg': '#010801',
132+
'--radar-grid': '#0a2a0a',
133+
'--radar-blip': '#44dd66',
134+
'--radar-blip-dim': '#1a6a2a',
135+
'--radar-text': '#33bb55',
136+
'--radar-label': '#0e5520',
137+
'--radar-sweep': 'rgba(50,255,100,0.06)',
138+
'--beam-reticle': '#ccaa22',
139+
'--beam-reticle-locked': '#44dd66',
140+
'--beam-cone': '#ccaa22',
141+
'--beam-highlight': '#ccaa22',
142+
'--beam-arc': 'rgba(50,200,100,0.4)',
143+
'--rotator': '#33cc55',
144+
'--heatmap-low': '#020a02',
145+
'--heatmap-mid': '#22aa44',
146+
'--heatmap-high': '#ccaa22',
147+
'--sky-grid': 'rgba(10,40,10,0.9)',
148+
'--sky-grid-label': '#33bb55',
149+
},
150+
};

src/themes/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export { VAR_GROUPS, cssColorToHex } from './types';
33
export { THEME_LEGACY } from './legacy';
44
export { THEME_RGB } from './rgb';
55
export { THEME_NEON } from './neon';
6+
export { THEME_CRT } from './crt';
67
export {
78
THEME_DARK, THEME_HIGH_CONTRAST, THEME_LIGHT, THEME_LAVENDER,
89
THEME_TLESCOPE, THEME_SOLARIZED, THEME_GRUVBOX, THEME_NORD,

0 commit comments

Comments
 (0)