zelune 1.5.1 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,12 +7,19 @@ const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
7
7
  const PREFERRED_ORDER = ['Login', 'Home', 'ProductDetail', 'Checkout', 'Profile'];
8
8
 
9
9
  /**
10
- * Vite Virtual Module plugin that dynamically discovers and imports React Native / Expo
11
- * screen components from any target project (`--project /path/to/app`).
10
+ * Vite Virtual Module plugin that dynamically discovers and loads React Native / Expo
11
+ * screen components from any target project (`--project /path/to/app`) with per-screen
12
+ * dynamic import() fault isolation so a broken import or top-level exception in one screen
13
+ * can never blank out the entire Zelune studio canvas.
12
14
  */
13
15
  export function viteVirtualScreensPlugin(workspaceRoot: string): Plugin {
16
+ let isBuild = false;
17
+
14
18
  return {
15
19
  name: 'vite-virtual-zelune-screens',
20
+ configResolved(config) {
21
+ isBuild = config.command === 'build';
22
+ },
16
23
  resolveId(id) {
17
24
  if (id === VIRTUAL_MODULE_ID) {
18
25
  return RESOLVED_VIRTUAL_MODULE_ID;
@@ -25,7 +32,7 @@ export function viteVirtualScreensPlugin(workspaceRoot: string): Plugin {
25
32
  }
26
33
 
27
34
  const discovered = discoverScreenFilesSync(workspaceRoot);
28
- const importLines: string[] = [
35
+ const lines: string[] = [
29
36
  `import React from 'react';`,
30
37
  `function resolveScreenComponent(mod) {`,
31
38
  ` if (!mod) return null;`,
@@ -37,6 +44,118 @@ export function viteVirtualScreensPlugin(workspaceRoot: string): Plugin {
37
44
  ` }`,
38
45
  ` return null;`,
39
46
  `}`,
47
+ `function createIsolatedScreenComponent(screenId, filePath, loader) {`,
48
+ ` let cachedComp = null;`,
49
+ ` return function IsolatedScreenWrapper(props) {`,
50
+ ` const [state, setState] = React.useState(() => ({`,
51
+ ` Comp: cachedComp,`,
52
+ ` error: null,`,
53
+ ` attempt: 0,`,
54
+ ` }));`,
55
+ ` React.useEffect(() => {`,
56
+ ` let cancelled = false;`,
57
+ ` Promise.resolve()`,
58
+ ` .then(() => loader(state.attempt))`,
59
+ ` .then((mod) => {`,
60
+ ` if (cancelled) return;`,
61
+ ` const resolved = resolveScreenComponent(mod);`,
62
+ ` if (!resolved) {`,
63
+ ` setState((prev) => ({`,
64
+ ` ...prev,`,
65
+ ` Comp: null,`,
66
+ ` error: 'No exported React component found in ' + filePath,`,
67
+ ` }));`,
68
+ ` } else {`,
69
+ ` cachedComp = resolved;`,
70
+ ` setState((prev) => ({ ...prev, Comp: resolved, error: null }));`,
71
+ ` }`,
72
+ ` })`,
73
+ ` .catch((err) => {`,
74
+ ` if (cancelled) return;`,
75
+ ` const msg = err instanceof Error ? err.message : String(err);`,
76
+ ` setState((prev) => ({ ...prev, Comp: null, error: msg }));`,
77
+ ` });`,
78
+ ` return () => {`,
79
+ ` cancelled = true;`,
80
+ ` };`,
81
+ ` }, [state.attempt]);`,
82
+ ` if (state.error) {`,
83
+ ` return React.createElement(`,
84
+ ` 'div',`,
85
+ ` {`,
86
+ ` style: {`,
87
+ ` flex: 1,`,
88
+ ` padding: 24,`,
89
+ ` backgroundColor: '#18181B',`,
90
+ ` color: '#FCA5A5',`,
91
+ ` display: 'flex',`,
92
+ ` flexDirection: 'column',`,
93
+ ` justifyContent: 'center',`,
94
+ ` gap: 10,`,
95
+ ` fontFamily: 'var(--font-mono)',`,
96
+ ` },`,
97
+ ` },`,
98
+ ` React.createElement(`,
99
+ ` 'div',`,
100
+ ` { style: { color: '#F87171', fontWeight: 700, fontSize: 13 } },`,
101
+ ` 'Module Load Error in ' + filePath`,
102
+ ` ),`,
103
+ ` React.createElement(`,
104
+ ` 'div',`,
105
+ ` {`,
106
+ ` style: {`,
107
+ ` fontSize: 11,`,
108
+ ` color: '#FECACA',`,
109
+ ` whiteSpace: 'pre-wrap',`,
110
+ ` wordBreak: 'break-word',`,
111
+ ` maxHeight: 360,`,
112
+ ` overflowY: 'auto',`,
113
+ ` },`,
114
+ ` },`,
115
+ ` state.error`,
116
+ ` ),`,
117
+ ` React.createElement(`,
118
+ ` 'button',`,
119
+ ` {`,
120
+ ` type: 'button',`,
121
+ ` onClick: () => setState((prev) => ({ ...prev, error: null, attempt: prev.attempt + 1 })),`,
122
+ ` style: {`,
123
+ ` alignSelf: 'flex-start',`,
124
+ ` marginTop: 6,`,
125
+ ` padding: '6px 12px',`,
126
+ ` borderRadius: 6,`,
127
+ ` border: '1px solid rgba(248, 113, 113, 0.45)',`,
128
+ ` backgroundColor: 'rgba(127, 29, 29, 0.4)',`,
129
+ ` color: '#FEE2E2',`,
130
+ ` fontSize: 11,`,
131
+ ` fontWeight: 600,`,
132
+ ` cursor: 'pointer',`,
133
+ ` },`,
134
+ ` },`,
135
+ ` 'Retry Screen Load'`,
136
+ ` )`,
137
+ ` );`,
138
+ ` }`,
139
+ ` if (!state.Comp) {`,
140
+ ` return React.createElement(`,
141
+ ` 'div',`,
142
+ ` {`,
143
+ ` style: {`,
144
+ ` flex: 1,`,
145
+ ` display: 'flex',`,
146
+ ` alignItems: 'center',`,
147
+ ` justifyContent: 'center',`,
148
+ ` color: '#64748B',`,
149
+ ` fontSize: 12,`,
150
+ ` fontFamily: 'var(--font-mono)',`,
151
+ ` },`,
152
+ ` },`,
153
+ ` 'Loading ' + screenId + '...'`,
154
+ ` );`,
155
+ ` }`,
156
+ ` return React.createElement(state.Comp, props);`,
157
+ ` };`,
158
+ `}`,
40
159
  ];
41
160
 
42
161
  const mapEntries: string[] = [];
@@ -51,16 +170,28 @@ export function viteVirtualScreensPlugin(workspaceRoot: string): Plugin {
51
170
  return a.id.localeCompare(b.id);
52
171
  });
53
172
 
54
- sorted.forEach((scr, index) => {
55
- const varName = `_screenMod_${index}`;
173
+ sorted.forEach((scr) => {
56
174
  const normalizedFullPath = scr.fullPath.replace(/\\/g, '/');
57
- importLines.push(`import * as ${varName} from ${JSON.stringify(normalizedFullPath)};`);
58
- mapEntries.push(` ${JSON.stringify(scr.id)}: resolveScreenComponent(${varName})`);
175
+ const fsUrl =
176
+ '/@fs' + (normalizedFullPath.startsWith('/') ? '' : '/') + normalizedFullPath;
177
+ const loaderExpr = isBuild
178
+ ? `(attempt) => attempt > 0 ? import(/* @vite-ignore */ ${JSON.stringify(
179
+ normalizedFullPath
180
+ )} + '?t=' + Date.now()) : import(${JSON.stringify(normalizedFullPath)})`
181
+ : `(attempt) => import(/* @vite-ignore */ ${JSON.stringify(
182
+ fsUrl
183
+ )} + (attempt > 0 ? '?t=' + Date.now() : ''))`;
184
+
185
+ mapEntries.push(
186
+ ` ${JSON.stringify(scr.id)}: createIsolatedScreenComponent(${JSON.stringify(
187
+ scr.id
188
+ )}, ${JSON.stringify(scr.relPath)}, ${loaderExpr})`
189
+ );
59
190
  orderIds.push(scr.id);
60
191
  });
61
192
 
62
193
  return [
63
- ...importLines,
194
+ ...lines,
64
195
  `export const SCREEN_COMPONENTS = {`,
65
196
  mapEntries.join(',\n'),
66
197
  `};`,
@@ -16,6 +16,8 @@ import {
16
16
  PanelRightClose,
17
17
  PanelRightOpen,
18
18
  Sliders,
19
+ Sun,
20
+ Moon,
19
21
  } from 'lucide-react';
20
22
  import { SCREEN_COMPONENTS, SCREEN_ORDER } from '../screens';
21
23
  import { ScreenArtboard } from './ScreenArtboard';
@@ -67,6 +69,46 @@ export const CanvasApp: React.FC = () => {
67
69
  const [isLeftPanelOpen, setIsLeftPanelOpen] = useState<boolean>(true);
68
70
  const [isRightPanelOpen, setIsRightPanelOpen] = useState<boolean>(true);
69
71
 
72
+ // Studio color-scheme state ('dark' default, persisted in localStorage & <meta name="color-scheme">)
73
+ const [colorScheme, setColorScheme] = useState<'dark' | 'light'>(() => {
74
+ try {
75
+ return localStorage.getItem('color-scheme') === 'light' ? 'light' : 'dark';
76
+ } catch {
77
+ return 'dark';
78
+ }
79
+ });
80
+
81
+ const applyColorScheme = useCallback((next: 'dark' | 'light') => {
82
+ setColorScheme(next);
83
+ const meta = document.querySelector<HTMLMetaElement>('meta[name="color-scheme"]');
84
+ if (meta) {
85
+ meta.content = next;
86
+ }
87
+ try {
88
+ localStorage.setItem('color-scheme', next);
89
+ } catch {
90
+ // Ignore storage write errors in restricted environments
91
+ }
92
+ }, []);
93
+
94
+ const toggleColorScheme = useCallback(() => {
95
+ applyColorScheme(colorScheme === 'dark' ? 'light' : 'dark');
96
+ }, [colorScheme, applyColorScheme]);
97
+
98
+ useEffect(() => {
99
+ const handleStorage = (e: StorageEvent) => {
100
+ if (e.key !== 'color-scheme') return;
101
+ const next = e.newValue === 'light' ? 'light' : 'dark';
102
+ setColorScheme(next);
103
+ const meta = document.querySelector<HTMLMetaElement>('meta[name="color-scheme"]');
104
+ if (meta) {
105
+ meta.content = next;
106
+ }
107
+ };
108
+ window.addEventListener('storage', handleStorage);
109
+ return () => window.removeEventListener('storage', handleStorage);
110
+ }, []);
111
+
70
112
  const [pan, setPan] = useState<{ x: number; y: number }>({ x: 20, y: 10 });
71
113
  const [zoom, setZoom] = useState<number>(0.68);
72
114
  const [isPanning, setIsPanning] = useState<boolean>(false);
@@ -691,7 +733,14 @@ export const CanvasApp: React.FC = () => {
691
733
  ZL
692
734
  </div>
693
735
  <div>
694
- <div style={{ fontSize: 13.5, fontWeight: 700, letterSpacing: '-0.02em', color: '#F8FAFC' }}>
736
+ <div
737
+ style={{
738
+ fontSize: 13.5,
739
+ fontWeight: 700,
740
+ letterSpacing: '-0.02em',
741
+ color: 'var(--studio-text-primary)',
742
+ }}
743
+ >
695
744
  Zelune
696
745
  </div>
697
746
  <div
@@ -731,14 +780,16 @@ export const CanvasApp: React.FC = () => {
731
780
  borderRadius: 5,
732
781
  border: mode === 'inspect' ? '1px solid rgba(56, 189, 248, 0.35)' : '1px solid transparent',
733
782
  backgroundColor: mode === 'inspect' ? 'var(--studio-surface-3)' : 'transparent',
734
- color: mode === 'inspect' ? '#38BDF8' : 'var(--studio-text-secondary)',
783
+ color: mode === 'inspect' ? '#0284C7' : 'var(--studio-text-secondary)',
735
784
  fontSize: 12,
736
785
  fontWeight: 600,
737
786
  cursor: 'pointer',
738
787
  }}
739
788
  >
740
- <MousePointer size={14} style={{ flexShrink: 0 }} />
741
- <span className="zelune-reveal-label">Inspect &amp; Edit</span>
789
+ <MousePointer size={14} style={{ flexShrink: 0, color: mode === 'inspect' ? '#38BDF8' : 'currentColor' }} />
790
+ <span className="zelune-reveal-label" style={{ color: mode === 'inspect' ? 'var(--studio-text-primary)' : 'inherit' }}>
791
+ Inspect &amp; Edit
792
+ </span>
742
793
  </button>
743
794
 
744
795
  <button
@@ -751,8 +802,8 @@ export const CanvasApp: React.FC = () => {
751
802
  padding: '6px 9px',
752
803
  borderRadius: 5,
753
804
  border: mode === 'interact' ? '1px solid rgba(16, 185, 129, 0.4)' : '1px solid transparent',
754
- backgroundColor: mode === 'interact' ? 'rgba(6, 78, 59, 0.45)' : 'transparent',
755
- color: mode === 'interact' ? '#34D399' : 'var(--studio-text-secondary)',
805
+ backgroundColor: mode === 'interact' ? 'rgba(16, 185, 129, 0.14)' : 'transparent',
806
+ color: mode === 'interact' ? (colorScheme === 'dark' ? '#34D399' : '#059669') : 'var(--studio-text-secondary)',
756
807
  fontSize: 12,
757
808
  fontWeight: 600,
758
809
  cursor: 'pointer',
@@ -773,8 +824,8 @@ export const CanvasApp: React.FC = () => {
773
824
  padding: '7px 9px',
774
825
  borderRadius: 7,
775
826
  border: `1px solid ${showFlows ? 'rgba(99, 102, 241, 0.45)' : 'var(--studio-border-subtle)'}`,
776
- backgroundColor: showFlows ? 'rgba(30, 27, 75, 0.55)' : 'var(--studio-surface-2)',
777
- color: showFlows ? '#C7D2FE' : 'var(--studio-text-secondary)',
827
+ backgroundColor: showFlows ? 'rgba(99, 102, 241, 0.14)' : 'var(--studio-surface-2)',
828
+ color: showFlows ? (colorScheme === 'dark' ? '#C7D2FE' : '#4F46E5') : 'var(--studio-text-secondary)',
778
829
  fontSize: 12,
779
830
  fontWeight: 600,
780
831
  cursor: 'pointer',
@@ -785,7 +836,7 @@ export const CanvasApp: React.FC = () => {
785
836
  </button>
786
837
  </div>
787
838
 
788
- {/* Right: Undo/Redo, Viewport Controls & Right Inspector Toggle */}
839
+ {/* Right: Undo/Redo, Viewport Controls, Theme Toggle & Right Inspector Toggle */}
789
840
  <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
790
841
  <button
791
842
  type="button"
@@ -801,7 +852,10 @@ export const CanvasApp: React.FC = () => {
801
852
  borderRadius: 6,
802
853
  border: '1px solid var(--studio-border-subtle)',
803
854
  backgroundColor: 'var(--studio-surface-2)',
804
- color: historyState.undoAvailable > 0 ? '#E2E8F0' : '#475569',
855
+ color:
856
+ historyState.undoAvailable > 0
857
+ ? 'var(--studio-text-primary)'
858
+ : 'var(--studio-text-muted)',
805
859
  fontSize: 11.5,
806
860
  fontFamily: 'var(--font-mono)',
807
861
  cursor: historyState.undoAvailable > 0 ? 'pointer' : 'not-allowed',
@@ -825,7 +879,10 @@ export const CanvasApp: React.FC = () => {
825
879
  borderRadius: 6,
826
880
  border: '1px solid var(--studio-border-subtle)',
827
881
  backgroundColor: 'var(--studio-surface-2)',
828
- color: historyState.redoAvailable > 0 ? '#E2E8F0' : '#475569',
882
+ color:
883
+ historyState.redoAvailable > 0
884
+ ? 'var(--studio-text-primary)'
885
+ : 'var(--studio-text-muted)',
829
886
  fontSize: 11.5,
830
887
  cursor: historyState.redoAvailable > 0 ? 'pointer' : 'not-allowed',
831
888
  }}
@@ -848,7 +905,7 @@ export const CanvasApp: React.FC = () => {
848
905
  borderRadius: 6,
849
906
  border: '1px solid var(--studio-border-subtle)',
850
907
  backgroundColor: 'var(--studio-surface-2)',
851
- color: '#CBD5E1',
908
+ color: 'var(--studio-text-secondary)',
852
909
  cursor: 'pointer',
853
910
  }}
854
911
  >
@@ -862,7 +919,7 @@ export const CanvasApp: React.FC = () => {
862
919
  textAlign: 'center',
863
920
  fontSize: 11.5,
864
921
  fontFamily: 'var(--font-mono)',
865
- color: '#CBD5E1',
922
+ color: 'var(--studio-text-secondary)',
866
923
  }}
867
924
  >
868
925
  {Math.round(zoom * 100)}%
@@ -881,7 +938,7 @@ export const CanvasApp: React.FC = () => {
881
938
  borderRadius: 6,
882
939
  border: '1px solid var(--studio-border-subtle)',
883
940
  backgroundColor: 'var(--studio-surface-2)',
884
- color: '#CBD5E1',
941
+ color: 'var(--studio-text-secondary)',
885
942
  cursor: 'pointer',
886
943
  }}
887
944
  >
@@ -899,7 +956,7 @@ export const CanvasApp: React.FC = () => {
899
956
  borderRadius: 6,
900
957
  border: '1px solid var(--studio-border-subtle)',
901
958
  backgroundColor: 'var(--studio-surface-2)',
902
- color: '#CBD5E1',
959
+ color: 'var(--studio-text-secondary)',
903
960
  fontSize: 11.5,
904
961
  fontWeight: 500,
905
962
  cursor: 'pointer',
@@ -920,7 +977,7 @@ export const CanvasApp: React.FC = () => {
920
977
  borderRadius: 6,
921
978
  border: '1px solid var(--studio-border-subtle)',
922
979
  backgroundColor: 'var(--studio-surface-2)',
923
- color: '#CBD5E1',
980
+ color: 'var(--studio-text-secondary)',
924
981
  fontSize: 11.5,
925
982
  fontWeight: 500,
926
983
  cursor: 'pointer',
@@ -930,6 +987,37 @@ export const CanvasApp: React.FC = () => {
930
987
  <span className="zelune-reveal-label">Grid</span>
931
988
  </button>
932
989
 
990
+ <button
991
+ type="button"
992
+ className="zelune-interactive zelune-icon-reveal-btn"
993
+ onClick={toggleColorScheme}
994
+ title={
995
+ colorScheme === 'dark' ? 'Switch Canvas to Light Mode' : 'Switch Canvas to Dark Mode'
996
+ }
997
+ aria-label={
998
+ colorScheme === 'dark' ? 'Switch Canvas to Light Mode' : 'Switch Canvas to Dark Mode'
999
+ }
1000
+ style={{
1001
+ padding: '6px 8px',
1002
+ borderRadius: 6,
1003
+ border: '1px solid var(--studio-border-subtle)',
1004
+ backgroundColor: 'var(--studio-surface-2)',
1005
+ color: 'var(--studio-text-secondary)',
1006
+ fontSize: 11.5,
1007
+ fontWeight: 500,
1008
+ cursor: 'pointer',
1009
+ }}
1010
+ >
1011
+ {colorScheme === 'dark' ? (
1012
+ <Sun size={13} style={{ flexShrink: 0, color: '#F59E0B' }} />
1013
+ ) : (
1014
+ <Moon size={13} style={{ flexShrink: 0, color: '#6366F1' }} />
1015
+ )}
1016
+ <span className="zelune-reveal-label">
1017
+ {colorScheme === 'dark' ? 'Light' : 'Dark'}
1018
+ </span>
1019
+ </button>
1020
+
933
1021
  <div style={{ width: 1, height: 20, backgroundColor: 'var(--studio-border-subtle)', margin: '0 3px' }} />
934
1022
 
935
1023
  <button
@@ -1068,7 +1156,7 @@ export const CanvasApp: React.FC = () => {
1068
1156
  isSelected ? 'rgba(56, 189, 248, 0.35)' : 'transparent'
1069
1157
  }`,
1070
1158
  backgroundColor: isSelected ? 'var(--studio-surface-2)' : 'transparent',
1071
- color: isSelected ? '#F8FAFC' : 'var(--studio-text-secondary)',
1159
+ color: isSelected ? 'var(--studio-text-primary)' : 'var(--studio-text-secondary)',
1072
1160
  fontSize: 12.5,
1073
1161
  fontWeight: isSelected ? 600 : 500,
1074
1162
  cursor: 'pointer',
@@ -1108,7 +1196,7 @@ export const CanvasApp: React.FC = () => {
1108
1196
  fontSize: 10,
1109
1197
  fontWeight: 600,
1110
1198
  letterSpacing: '0.05em',
1111
- color: '#E2E8F0',
1199
+ color: 'var(--studio-text-primary)',
1112
1200
  marginBottom: 4,
1113
1201
  }}
1114
1202
  >
@@ -1157,12 +1245,12 @@ export const CanvasApp: React.FC = () => {
1157
1245
  borderRadius: 8,
1158
1246
  backgroundColor: 'var(--studio-surface-1)',
1159
1247
  border: '1px solid var(--studio-border-subtle)',
1160
- color: '#F1F5F9',
1248
+ color: 'var(--studio-text-primary)',
1161
1249
  fontSize: 11.5,
1162
1250
  fontFamily: 'var(--font-mono)',
1163
1251
  fontWeight: 600,
1164
1252
  cursor: 'pointer',
1165
- boxShadow: '0 10px 24px -6px rgba(0, 0, 0, 0.65)',
1253
+ boxShadow: '0 10px 24px -6px rgba(0, 0, 0, 0.28)',
1166
1254
  }}
1167
1255
  >
1168
1256
  <PanelLeftOpen size={13} color="#38BDF8" />
@@ -1193,19 +1281,19 @@ export const CanvasApp: React.FC = () => {
1193
1281
  borderRadius: 8,
1194
1282
  backgroundColor: 'var(--studio-surface-1)',
1195
1283
  border: '1px solid var(--studio-border-subtle)',
1196
- color: '#F1F5F9',
1284
+ color: 'var(--studio-text-primary)',
1197
1285
  fontSize: 11.5,
1198
1286
  fontFamily: 'var(--font-mono)',
1199
1287
  fontWeight: 600,
1200
1288
  cursor: 'pointer',
1201
- boxShadow: '0 10px 24px -6px rgba(0, 0, 0, 0.65)',
1289
+ boxShadow: '0 10px 24px -6px rgba(0, 0, 0, 0.28)',
1202
1290
  }}
1203
1291
  >
1204
1292
  <Sliders size={13} color="#38BDF8" />
1205
1293
  <span>
1206
1294
  {inspectedData ? `<${inspectedData.tagName}> L${inspectedData.line}` : 'AST Inspector'}
1207
1295
  </span>
1208
- <PanelRightOpen size={13} color="#94A3B8" />
1296
+ <PanelRightOpen size={13} color="var(--studio-text-secondary)" />
1209
1297
  </button>
1210
1298
  )}
1211
1299
 
@@ -146,7 +146,7 @@ export const FlowArrowsLayer: React.FC<FlowArrowsLayerProps> = ({
146
146
  cx={startX}
147
147
  cy={startY}
148
148
  r={4}
149
- fill="#0B0D12"
149
+ fill="var(--studio-surface-1)"
150
150
  stroke={strokeColor}
151
151
  strokeWidth={2}
152
152
  />
@@ -172,15 +172,15 @@ export const FlowArrowsLayer: React.FC<FlowArrowsLayerProps> = ({
172
172
  gap: 4,
173
173
  padding: '3px 9px',
174
174
  borderRadius: 999,
175
- backgroundColor: isHighlighted ? '#064E3B' : '#131724',
176
- border: `1px solid ${isHighlighted ? '#10B981' : '#312E81'}`,
177
- color: isHighlighted ? '#A7F3D0' : '#C7D2FE',
175
+ backgroundColor: 'var(--studio-surface-1)',
176
+ border: `1px solid ${isHighlighted ? 'var(--studio-accent-emerald)' : 'var(--studio-badge-indigo-border)'}`,
177
+ color: isHighlighted ? 'var(--studio-badge-emerald-text)' : 'var(--studio-badge-indigo-text)',
178
178
  fontSize: 10,
179
179
  fontWeight: 600,
180
180
  fontFamily: 'JetBrains Mono, monospace',
181
181
  whiteSpace: 'nowrap',
182
182
  cursor: 'pointer',
183
- boxShadow: '0 4px 12px rgba(0,0,0,0.45)',
183
+ boxShadow: '0 4px 12px rgba(0,0,0,0.2)',
184
184
  margin: '0 auto',
185
185
  }}
186
186
  >