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.
- package/CHANGELOG.md +30 -0
- package/README.md +8 -15
- package/bin/cli.mjs +17 -6
- package/index.html +9 -2
- package/package.json +2 -1
- package/plugin.json +1 -1
- package/plugins/viteReactNativeFallbackPlugin.ts +568 -0
- package/plugins/viteVirtualScreensPlugin.ts +139 -8
- package/src/canvas/CanvasApp.tsx +111 -23
- package/src/canvas/FlowArrowsLayer.tsx +5 -5
- package/src/canvas/InspectorPanel.tsx +58 -49
- package/src/canvas/ScreenArtboard.tsx +90 -29
- package/src/main.tsx +70 -1
- package/src/runtime/MockNavigationContext.tsx +1007 -38
- package/src/runtime/reactNativeShim.ts +141 -0
- package/src/screens/ProductDetailScreen.tsx +32 -59
- package/src/server/astEngine.ts +10 -1
- package/src/styles.css +182 -21
- package/vite.config.ts +136 -67
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
import * as RNW from 'react-native-web';
|
|
3
|
+
|
|
4
|
+
export * from 'react-native-web';
|
|
5
|
+
|
|
6
|
+
export function useAnimatedValue(initialValue = 0): RNW.Animated.Value {
|
|
7
|
+
const ref = useRef<RNW.Animated.Value | null>(null);
|
|
8
|
+
if (!ref.current) {
|
|
9
|
+
ref.current = new RNW.Animated.Value(initialValue);
|
|
10
|
+
}
|
|
11
|
+
return ref.current;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const PermissionsAndroid = {
|
|
15
|
+
PERMISSIONS: new Proxy({} as Record<string, string>, {
|
|
16
|
+
get: (_target, prop) => String(prop),
|
|
17
|
+
}),
|
|
18
|
+
RESULTS: {
|
|
19
|
+
GRANTED: 'granted',
|
|
20
|
+
DENIED: 'denied',
|
|
21
|
+
NEVER_ASK_AGAIN: 'never_ask_again',
|
|
22
|
+
},
|
|
23
|
+
check: async () => true,
|
|
24
|
+
request: async () => 'granted',
|
|
25
|
+
requestMultiple: async () => ({}),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const ToastAndroid = {
|
|
29
|
+
SHORT: 2000,
|
|
30
|
+
LONG: 3500,
|
|
31
|
+
TOP: 0,
|
|
32
|
+
BOTTOM: 1,
|
|
33
|
+
CENTER: 2,
|
|
34
|
+
show: () => undefined,
|
|
35
|
+
showWithGravity: () => undefined,
|
|
36
|
+
showWithGravityAndOffset: () => undefined,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const ActionSheetIOS = {
|
|
40
|
+
showActionSheetWithOptions: () => undefined,
|
|
41
|
+
showShareActionSheetWithOptions: () => undefined,
|
|
42
|
+
dismissActionSheet: () => undefined,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const InputAccessoryView: React.FC<{ children?: React.ReactNode }> = ({ children }) =>
|
|
46
|
+
React.createElement(React.Fragment, null, children);
|
|
47
|
+
|
|
48
|
+
export const DrawerLayoutAndroid: React.FC<{
|
|
49
|
+
children?: React.ReactNode;
|
|
50
|
+
style?: unknown;
|
|
51
|
+
}> = ({ children, style }) =>
|
|
52
|
+
React.createElement(RNW.View, { style: [{ flex: 1 }, style] as never }, children);
|
|
53
|
+
|
|
54
|
+
export const TurboModuleRegistry = {
|
|
55
|
+
get: () => ({}),
|
|
56
|
+
getEnforcing: () => ({}),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export function requireNativeComponent(viewName: string) {
|
|
60
|
+
const Comp: React.FC<{ children?: React.ReactNode; style?: unknown }> = ({
|
|
61
|
+
children,
|
|
62
|
+
style,
|
|
63
|
+
}) => React.createElement(RNW.View, { style: style as never }, children);
|
|
64
|
+
Comp.displayName = viewName;
|
|
65
|
+
return Comp;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const codegenNativeComponent = requireNativeComponent;
|
|
69
|
+
|
|
70
|
+
export function PlatformColor(...names: string[]): string {
|
|
71
|
+
const first = (names[0] ?? '').toLowerCase();
|
|
72
|
+
if (first.includes('background')) return '#0F172A';
|
|
73
|
+
if (first.includes('label') || first.includes('text')) return '#F8FAFC';
|
|
74
|
+
return '#6366F1';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function DynamicColorIOS(tuple: { light?: string; dark?: string }): string {
|
|
78
|
+
return tuple?.dark ?? tuple?.light ?? '#6366F1';
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export const DevSettings = {
|
|
82
|
+
addMenuItem: () => undefined,
|
|
83
|
+
reload: () => undefined,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const Systrace = {
|
|
87
|
+
isEnabled: () => false,
|
|
88
|
+
beginEvent: () => undefined,
|
|
89
|
+
endEvent: () => undefined,
|
|
90
|
+
beginAsyncEvent: () => 0,
|
|
91
|
+
endAsyncEvent: () => undefined,
|
|
92
|
+
counterEvent: () => undefined,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export const Networking = {
|
|
96
|
+
addListener: () => ({ remove: () => undefined }),
|
|
97
|
+
sendRequest: () => undefined,
|
|
98
|
+
abortRequest: () => undefined,
|
|
99
|
+
clearCookies: () => undefined,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const Settings = {
|
|
103
|
+
get: () => undefined,
|
|
104
|
+
set: () => undefined,
|
|
105
|
+
watchKeys: () => 0,
|
|
106
|
+
clearWatch: () => undefined,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const ReactNativeDefault = new Proxy(
|
|
110
|
+
{
|
|
111
|
+
...RNW,
|
|
112
|
+
useAnimatedValue,
|
|
113
|
+
PermissionsAndroid,
|
|
114
|
+
ToastAndroid,
|
|
115
|
+
ActionSheetIOS,
|
|
116
|
+
InputAccessoryView,
|
|
117
|
+
DrawerLayoutAndroid,
|
|
118
|
+
TurboModuleRegistry,
|
|
119
|
+
requireNativeComponent,
|
|
120
|
+
codegenNativeComponent,
|
|
121
|
+
PlatformColor,
|
|
122
|
+
DynamicColorIOS,
|
|
123
|
+
DevSettings,
|
|
124
|
+
Systrace,
|
|
125
|
+
Networking,
|
|
126
|
+
Settings,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
get(target, prop) {
|
|
130
|
+
if (prop in target) {
|
|
131
|
+
return target[prop as keyof typeof target];
|
|
132
|
+
}
|
|
133
|
+
if (typeof prop === 'string' && /^[A-Z]/.test(prop)) {
|
|
134
|
+
return requireNativeComponent(prop);
|
|
135
|
+
}
|
|
136
|
+
return () => undefined;
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
export default ReactNativeDefault;
|
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
import React, { useState } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
View,
|
|
4
|
-
Text,
|
|
5
|
-
TouchableOpacity,
|
|
6
|
-
StyleSheet,
|
|
7
|
-
} from 'react-native';
|
|
2
|
+
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
|
8
3
|
import { useNavigation } from '../runtime/MockNavigationContext';
|
|
9
|
-
|
|
10
4
|
export default function ProductDetailScreen() {
|
|
11
5
|
const navigation = useNavigation();
|
|
12
6
|
const [selectedFinish, setSelectedFinish] = useState<'Obsidian' | 'Silver'>('Obsidian');
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
<View style={styles.container}>
|
|
7
|
+
return <View style={styles.container}>
|
|
16
8
|
<View style={styles.headerRow}>
|
|
17
|
-
<TouchableOpacity
|
|
18
|
-
activeOpacity={0.78}
|
|
19
|
-
style={styles.backButton}
|
|
20
|
-
onPress={() => navigation.navigate('Home')}
|
|
21
|
-
>
|
|
9
|
+
<TouchableOpacity activeOpacity={0.78} style={styles.backButton} onPress={() => navigation.navigate('Home')}>
|
|
22
10
|
<Text style={styles.backButtonText}>← Catalog</Text>
|
|
23
11
|
</TouchableOpacity>
|
|
24
12
|
<Text style={styles.headerBadge}>MODEL CH-01 // PRO</Text>
|
|
@@ -55,44 +43,29 @@ export default function ProductDetailScreen() {
|
|
|
55
43
|
</View>
|
|
56
44
|
|
|
57
45
|
<View style={styles.finishRow}>
|
|
58
|
-
{(['Obsidian', 'Silver'] as const).map((
|
|
59
|
-
<TouchableOpacity
|
|
60
|
-
key={finish}
|
|
61
|
-
activeOpacity={0.78}
|
|
62
|
-
style={
|
|
63
|
-
selectedFinish === finish ? styles.finishPillActive : styles.finishPill
|
|
64
|
-
}
|
|
65
|
-
onPress={() => setSelectedFinish(finish)}
|
|
66
|
-
>
|
|
46
|
+
{(['Obsidian', 'Silver'] as const).map(finish => <TouchableOpacity key={finish} activeOpacity={0.78} style={selectedFinish === finish ? styles.finishPillActive : styles.finishPill} onPress={() => setSelectedFinish(finish)}>
|
|
67
47
|
<Text style={styles.finishPillText}>{finish} Anodized</Text>
|
|
68
|
-
</TouchableOpacity>
|
|
69
|
-
))}
|
|
48
|
+
</TouchableOpacity>)}
|
|
70
49
|
</View>
|
|
71
50
|
</View>
|
|
72
51
|
|
|
73
|
-
<TouchableOpacity
|
|
74
|
-
activeOpacity={0.78}
|
|
75
|
-
style={styles.buyButton}
|
|
76
|
-
onPress={() => navigation.navigate('Checkout')}
|
|
77
|
-
>
|
|
52
|
+
<TouchableOpacity activeOpacity={0.78} style={styles.buyButton} onPress={() => navigation.navigate('Checkout')}>
|
|
78
53
|
<Text style={styles.buyButtonText}>Reserve Unit & Express Checkout</Text>
|
|
79
54
|
</TouchableOpacity>
|
|
80
|
-
</View
|
|
81
|
-
);
|
|
55
|
+
</View>;
|
|
82
56
|
}
|
|
83
|
-
|
|
84
57
|
const styles = StyleSheet.create({
|
|
85
58
|
container: {
|
|
86
59
|
flex: 1,
|
|
87
60
|
backgroundColor: '#0A0B0E',
|
|
88
61
|
padding: 20,
|
|
89
|
-
justifyContent: 'space-between'
|
|
62
|
+
justifyContent: 'space-between'
|
|
90
63
|
},
|
|
91
64
|
headerRow: {
|
|
92
65
|
flexDirection: 'row',
|
|
93
66
|
justifyContent: 'space-between',
|
|
94
67
|
alignItems: 'center',
|
|
95
|
-
marginTop: 6
|
|
68
|
+
marginTop: 6
|
|
96
69
|
},
|
|
97
70
|
backButton: {
|
|
98
71
|
backgroundColor: '#13161E',
|
|
@@ -100,18 +73,18 @@ const styles = StyleSheet.create({
|
|
|
100
73
|
paddingVertical: 9,
|
|
101
74
|
borderRadius: 8,
|
|
102
75
|
borderWidth: 1,
|
|
103
|
-
borderColor: '#222836'
|
|
76
|
+
borderColor: '#222836'
|
|
104
77
|
},
|
|
105
78
|
backButtonText: {
|
|
106
79
|
color: '#E2E8F0',
|
|
107
80
|
fontSize: 12,
|
|
108
|
-
fontWeight: '600'
|
|
81
|
+
fontWeight: '600'
|
|
109
82
|
},
|
|
110
83
|
headerBadge: {
|
|
111
84
|
color: '#38BDF8',
|
|
112
85
|
fontSize: 10,
|
|
113
86
|
fontWeight: '700',
|
|
114
|
-
letterSpacing: 1
|
|
87
|
+
letterSpacing: 1
|
|
115
88
|
},
|
|
116
89
|
showcaseCard: {
|
|
117
90
|
backgroundColor: '#11141C',
|
|
@@ -121,54 +94,54 @@ const styles = StyleSheet.create({
|
|
|
121
94
|
alignItems: 'center',
|
|
122
95
|
gap: 10,
|
|
123
96
|
borderWidth: 1,
|
|
124
|
-
borderColor: '#1E2433'
|
|
97
|
+
borderColor: '#1E2433'
|
|
125
98
|
},
|
|
126
99
|
showcaseSpecCode: {
|
|
127
100
|
color: '#64748B',
|
|
128
101
|
fontSize: 10,
|
|
129
102
|
fontWeight: '700',
|
|
130
|
-
letterSpacing: 1.2
|
|
103
|
+
letterSpacing: 1.2
|
|
131
104
|
},
|
|
132
105
|
showcaseMonogram: {
|
|
133
106
|
color: '#F8FAFC',
|
|
134
107
|
fontSize: 34,
|
|
135
108
|
fontWeight: '800',
|
|
136
|
-
letterSpacing: 2
|
|
109
|
+
letterSpacing: 2
|
|
137
110
|
},
|
|
138
111
|
showcaseTag: {
|
|
139
112
|
color: '#38BDF8',
|
|
140
113
|
fontSize: 10,
|
|
141
114
|
fontWeight: '600',
|
|
142
|
-
letterSpacing: 0.8
|
|
115
|
+
letterSpacing: 0.8
|
|
143
116
|
},
|
|
144
117
|
detailsSection: {
|
|
145
|
-
gap: 12
|
|
118
|
+
gap: 12
|
|
146
119
|
},
|
|
147
120
|
titlePriceRow: {
|
|
148
121
|
flexDirection: 'row',
|
|
149
122
|
justifyContent: 'space-between',
|
|
150
|
-
alignItems: 'baseline'
|
|
123
|
+
alignItems: 'baseline'
|
|
151
124
|
},
|
|
152
125
|
productTitle: {
|
|
153
126
|
color: '#F8FAFC',
|
|
154
127
|
fontSize: 24,
|
|
155
128
|
fontWeight: '700',
|
|
156
|
-
letterSpacing: -0.4
|
|
129
|
+
letterSpacing: -0.4
|
|
157
130
|
},
|
|
158
131
|
productPrice: {
|
|
159
132
|
color: '#10B981',
|
|
160
133
|
fontSize: 20,
|
|
161
|
-
fontWeight: '700'
|
|
134
|
+
fontWeight: '700'
|
|
162
135
|
},
|
|
163
136
|
productDescription: {
|
|
164
137
|
color: '#94A3B8',
|
|
165
138
|
fontSize: 13,
|
|
166
|
-
lineHeight: 19
|
|
139
|
+
lineHeight: 19
|
|
167
140
|
},
|
|
168
141
|
specGrid: {
|
|
169
142
|
flexDirection: 'row',
|
|
170
143
|
gap: 8,
|
|
171
|
-
marginTop: 2
|
|
144
|
+
marginTop: 2
|
|
172
145
|
},
|
|
173
146
|
specBox: {
|
|
174
147
|
flex: 1,
|
|
@@ -178,24 +151,24 @@ const styles = StyleSheet.create({
|
|
|
178
151
|
paddingHorizontal: 8,
|
|
179
152
|
alignItems: 'center',
|
|
180
153
|
borderWidth: 1,
|
|
181
|
-
borderColor: '#1E2433'
|
|
154
|
+
borderColor: '#1E2433'
|
|
182
155
|
},
|
|
183
156
|
specValue: {
|
|
184
157
|
color: '#F8FAFC',
|
|
185
158
|
fontSize: 15,
|
|
186
|
-
fontWeight: '700'
|
|
159
|
+
fontWeight: '700'
|
|
187
160
|
},
|
|
188
161
|
specLabel: {
|
|
189
162
|
color: '#64748B',
|
|
190
163
|
fontSize: 9,
|
|
191
164
|
fontWeight: '700',
|
|
192
165
|
letterSpacing: 0.8,
|
|
193
|
-
marginTop: 3
|
|
166
|
+
marginTop: 3
|
|
194
167
|
},
|
|
195
168
|
finishRow: {
|
|
196
169
|
flexDirection: 'row',
|
|
197
170
|
gap: 10,
|
|
198
|
-
marginTop: 2
|
|
171
|
+
marginTop: 2
|
|
199
172
|
},
|
|
200
173
|
finishPillActive: {
|
|
201
174
|
flex: 1,
|
|
@@ -204,7 +177,7 @@ const styles = StyleSheet.create({
|
|
|
204
177
|
paddingVertical: 11,
|
|
205
178
|
alignItems: 'center',
|
|
206
179
|
borderWidth: 1,
|
|
207
|
-
borderColor: '#38BDF8'
|
|
180
|
+
borderColor: '#38BDF8'
|
|
208
181
|
},
|
|
209
182
|
finishPill: {
|
|
210
183
|
flex: 1,
|
|
@@ -213,22 +186,22 @@ const styles = StyleSheet.create({
|
|
|
213
186
|
paddingVertical: 11,
|
|
214
187
|
alignItems: 'center',
|
|
215
188
|
borderWidth: 1,
|
|
216
|
-
borderColor: '#1E2433'
|
|
189
|
+
borderColor: '#1E2433'
|
|
217
190
|
},
|
|
218
191
|
finishPillText: {
|
|
219
192
|
color: '#E2E8F0',
|
|
220
193
|
fontSize: 12,
|
|
221
|
-
fontWeight: '600'
|
|
194
|
+
fontWeight: '600'
|
|
222
195
|
},
|
|
223
196
|
buyButton: {
|
|
224
197
|
backgroundColor: '#10B981',
|
|
225
198
|
borderRadius: 10,
|
|
226
199
|
paddingVertical: 15,
|
|
227
|
-
alignItems: 'center'
|
|
200
|
+
alignItems: 'center'
|
|
228
201
|
},
|
|
229
202
|
buyButtonText: {
|
|
230
203
|
color: '#052E16',
|
|
231
204
|
fontSize: 14,
|
|
232
|
-
fontWeight: '700'
|
|
233
|
-
}
|
|
205
|
+
fontWeight: '700'
|
|
206
|
+
}
|
|
234
207
|
});
|
package/src/server/astEngine.ts
CHANGED
|
@@ -350,10 +350,12 @@ export function normalizeRouteTarget(rawTarget: string): string {
|
|
|
350
350
|
const trimmed = rawTarget
|
|
351
351
|
.replace(/^\/+/, '')
|
|
352
352
|
.replace(/\([^)]+\)\/?/g, '')
|
|
353
|
+
.replace(/\[\.\.\.([^\]]+)\]/g, 'CatchAll_$1')
|
|
354
|
+
.replace(/\[([^\]]+)\]/g, 'By_$1')
|
|
353
355
|
.replace(/Screen$/, '')
|
|
354
356
|
.replace(/\/index$/, '');
|
|
355
357
|
if (!trimmed || trimmed === 'index') return 'Home';
|
|
356
|
-
if (trimmed.includes('-') || trimmed.includes('/') || trimmed === trimmed.toLowerCase()) {
|
|
358
|
+
if (trimmed.includes('-') || trimmed.includes('/') || trimmed.includes('_') || trimmed === trimmed.toLowerCase()) {
|
|
357
359
|
return trimmed
|
|
358
360
|
.split(/[-_/]/)
|
|
359
361
|
.filter(Boolean)
|
|
@@ -650,6 +652,13 @@ export function discoverScreenFilesSync(workspaceRoot: string): DiscoveredScreen
|
|
|
650
652
|
if (seenIds.has(routeName)) {
|
|
651
653
|
routeName = normalizeRouteTarget(noExt.replace(/[()]/g, ''));
|
|
652
654
|
}
|
|
655
|
+
if (seenIds.has(routeName)) {
|
|
656
|
+
let suffix = 2;
|
|
657
|
+
while (seenIds.has(`${routeName}${suffix}`)) {
|
|
658
|
+
suffix++;
|
|
659
|
+
}
|
|
660
|
+
routeName = `${routeName}${suffix}`;
|
|
661
|
+
}
|
|
653
662
|
seenIds.add(routeName);
|
|
654
663
|
|
|
655
664
|
const displayName = baseFileName.endsWith('Screen') ? baseFileName : `${routeName}Screen`;
|
package/src/styles.css
CHANGED
|
@@ -6,25 +6,60 @@
|
|
|
6
6
|
--font-sans: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
7
7
|
--font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
8
8
|
|
|
9
|
-
/*
|
|
10
|
-
--studio-canvas-bg: #
|
|
11
|
-
--studio-
|
|
12
|
-
--studio-surface-
|
|
13
|
-
--studio-surface-
|
|
14
|
-
--studio-
|
|
15
|
-
--studio-
|
|
16
|
-
--studio-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
--studio-
|
|
20
|
-
--studio-
|
|
21
|
-
--studio-
|
|
9
|
+
/* Explicit Light & Dark Palette Definitions (modern-web-guidance: dark-mode-toggle) */
|
|
10
|
+
--studio-canvas-bg-light: #f1f5f9;
|
|
11
|
+
--studio-canvas-bg-dark: #08090c;
|
|
12
|
+
--studio-surface-1-light: #ffffff;
|
|
13
|
+
--studio-surface-1-dark: #0d0f14;
|
|
14
|
+
--studio-surface-2-light: #f8fafc;
|
|
15
|
+
--studio-surface-2-dark: #13161e;
|
|
16
|
+
--studio-surface-3-light: #e2e8f0;
|
|
17
|
+
--studio-surface-3-dark: #191d28;
|
|
18
|
+
--studio-border-hairline-light: rgba(15, 23, 42, 0.09);
|
|
19
|
+
--studio-border-hairline-dark: rgba(255, 255, 255, 0.07);
|
|
20
|
+
--studio-border-subtle-light: #cbd5e1;
|
|
21
|
+
--studio-border-subtle-dark: #1e2330;
|
|
22
|
+
--studio-border-strong-light: #94a3b8;
|
|
23
|
+
--studio-border-strong-dark: #2a3142;
|
|
24
|
+
--studio-text-primary-light: #0f172a;
|
|
25
|
+
--studio-text-primary-dark: #f1f5f9;
|
|
26
|
+
--studio-text-secondary-light: #475569;
|
|
27
|
+
--studio-text-secondary-dark: #94a3b8;
|
|
28
|
+
--studio-text-muted-light: #64748b;
|
|
29
|
+
--studio-text-muted-dark: #64748b;
|
|
30
|
+
--studio-dot-grid-light: rgba(15, 23, 42, 0.14);
|
|
31
|
+
--studio-dot-grid-dark: rgba(148, 163, 184, 0.14);
|
|
32
|
+
--scrollbar-thumb-light: #cbd5e1;
|
|
33
|
+
--scrollbar-thumb-dark: #262d3d;
|
|
34
|
+
--scrollbar-track-light: #f1f5f9;
|
|
35
|
+
--scrollbar-track-dark: #0d0f14;
|
|
36
|
+
|
|
37
|
+
/* Base fallback values (for browsers without light-dark()) */
|
|
38
|
+
--studio-canvas-bg: var(--studio-canvas-bg-light);
|
|
39
|
+
--studio-surface-1: var(--studio-surface-1-light);
|
|
40
|
+
--studio-surface-2: var(--studio-surface-2-light);
|
|
41
|
+
--studio-surface-3: var(--studio-surface-3-light);
|
|
42
|
+
--studio-border-hairline: var(--studio-border-hairline-light);
|
|
43
|
+
--studio-border-subtle: var(--studio-border-subtle-light);
|
|
44
|
+
--studio-border-strong: var(--studio-border-strong-light);
|
|
45
|
+
--studio-text-primary: var(--studio-text-primary-light);
|
|
46
|
+
--studio-text-secondary: var(--studio-text-secondary-light);
|
|
47
|
+
--studio-text-muted: var(--studio-text-muted-light);
|
|
48
|
+
--studio-dot-grid: var(--studio-dot-grid-light);
|
|
49
|
+
--scrollbar-thumb: var(--scrollbar-thumb-light);
|
|
50
|
+
--scrollbar-track: var(--scrollbar-track-light);
|
|
22
51
|
|
|
23
52
|
/* Intentional Signal Accents */
|
|
24
|
-
--studio-accent-cyan: #
|
|
25
|
-
--studio-accent-indigo: #
|
|
26
|
-
--studio-accent-emerald: #
|
|
27
|
-
--studio-accent-amber: #
|
|
53
|
+
--studio-accent-cyan: #0284c7;
|
|
54
|
+
--studio-accent-indigo: #4f46e5;
|
|
55
|
+
--studio-accent-emerald: #059669;
|
|
56
|
+
--studio-accent-amber: #d97706;
|
|
57
|
+
--studio-badge-indigo-bg: rgba(79, 70, 229, 0.1);
|
|
58
|
+
--studio-badge-indigo-border: rgba(79, 70, 229, 0.32);
|
|
59
|
+
--studio-badge-indigo-text: #3730a3;
|
|
60
|
+
--studio-badge-emerald-bg: rgba(5, 150, 105, 0.1);
|
|
61
|
+
--studio-badge-emerald-border: rgba(5, 150, 105, 0.32);
|
|
62
|
+
--studio-badge-emerald-text: #065f46;
|
|
28
63
|
|
|
29
64
|
/* Emil Kowalski Motion & Easing Tokens (emilkowalski/skills) */
|
|
30
65
|
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
|
|
@@ -44,6 +79,132 @@
|
|
|
44
79
|
--control-py-spacious: 8px;
|
|
45
80
|
--rail-item-py-compact: 7px;
|
|
46
81
|
--rail-item-py-spacious: 10px;
|
|
82
|
+
|
|
83
|
+
@media (prefers-color-scheme: dark) {
|
|
84
|
+
--studio-canvas-bg: var(--studio-canvas-bg-dark);
|
|
85
|
+
--studio-surface-1: var(--studio-surface-1-dark);
|
|
86
|
+
--studio-surface-2: var(--studio-surface-2-dark);
|
|
87
|
+
--studio-surface-3: var(--studio-surface-3-dark);
|
|
88
|
+
--studio-border-hairline: var(--studio-border-hairline-dark);
|
|
89
|
+
--studio-border-subtle: var(--studio-border-subtle-dark);
|
|
90
|
+
--studio-border-strong: var(--studio-border-strong-dark);
|
|
91
|
+
--studio-text-primary: var(--studio-text-primary-dark);
|
|
92
|
+
--studio-text-secondary: var(--studio-text-secondary-dark);
|
|
93
|
+
--studio-text-muted: var(--studio-text-muted-dark);
|
|
94
|
+
--studio-dot-grid: var(--studio-dot-grid-dark);
|
|
95
|
+
--scrollbar-thumb: var(--scrollbar-thumb-dark);
|
|
96
|
+
--scrollbar-track: var(--scrollbar-track-dark);
|
|
97
|
+
--studio-accent-cyan: #38bdf8;
|
|
98
|
+
--studio-accent-indigo: #6366f1;
|
|
99
|
+
--studio-accent-emerald: #34d399;
|
|
100
|
+
--studio-accent-amber: #f59e0b;
|
|
101
|
+
--studio-badge-indigo-bg: rgba(99, 102, 241, 0.18);
|
|
102
|
+
--studio-badge-indigo-border: rgba(99, 102, 241, 0.4);
|
|
103
|
+
--studio-badge-indigo-text: #c7d2fe;
|
|
104
|
+
--studio-badge-emerald-bg: rgba(16, 185, 129, 0.14);
|
|
105
|
+
--studio-badge-emerald-border: rgba(16, 185, 129, 0.35);
|
|
106
|
+
--studio-badge-emerald-text: #a7f3d0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
&:has(> head > meta[name="color-scheme"][content="dark"]) {
|
|
110
|
+
color-scheme: dark;
|
|
111
|
+
--studio-canvas-bg: var(--studio-canvas-bg-dark);
|
|
112
|
+
--studio-surface-1: var(--studio-surface-1-dark);
|
|
113
|
+
--studio-surface-2: var(--studio-surface-2-dark);
|
|
114
|
+
--studio-surface-3: var(--studio-surface-3-dark);
|
|
115
|
+
--studio-border-hairline: var(--studio-border-hairline-dark);
|
|
116
|
+
--studio-border-subtle: var(--studio-border-subtle-dark);
|
|
117
|
+
--studio-border-strong: var(--studio-border-strong-dark);
|
|
118
|
+
--studio-text-primary: var(--studio-text-primary-dark);
|
|
119
|
+
--studio-text-secondary: var(--studio-text-secondary-dark);
|
|
120
|
+
--studio-text-muted: var(--studio-text-muted-dark);
|
|
121
|
+
--studio-dot-grid: var(--studio-dot-grid-dark);
|
|
122
|
+
--scrollbar-thumb: var(--scrollbar-thumb-dark);
|
|
123
|
+
--scrollbar-track: var(--scrollbar-track-dark);
|
|
124
|
+
--studio-accent-cyan: #38bdf8;
|
|
125
|
+
--studio-accent-indigo: #6366f1;
|
|
126
|
+
--studio-accent-emerald: #34d399;
|
|
127
|
+
--studio-accent-amber: #f59e0b;
|
|
128
|
+
--studio-badge-indigo-bg: rgba(99, 102, 241, 0.18);
|
|
129
|
+
--studio-badge-indigo-border: rgba(99, 102, 241, 0.4);
|
|
130
|
+
--studio-badge-indigo-text: #c7d2fe;
|
|
131
|
+
--studio-badge-emerald-bg: rgba(16, 185, 129, 0.14);
|
|
132
|
+
--studio-badge-emerald-border: rgba(16, 185, 129, 0.35);
|
|
133
|
+
--studio-badge-emerald-text: #a7f3d0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
&:has(> head > meta[name="color-scheme"][content="light"]) {
|
|
137
|
+
color-scheme: light;
|
|
138
|
+
--studio-canvas-bg: var(--studio-canvas-bg-light);
|
|
139
|
+
--studio-surface-1: var(--studio-surface-1-light);
|
|
140
|
+
--studio-surface-2: var(--studio-surface-2-light);
|
|
141
|
+
--studio-surface-3: var(--studio-surface-3-light);
|
|
142
|
+
--studio-border-hairline: var(--studio-border-hairline-light);
|
|
143
|
+
--studio-border-subtle: var(--studio-border-subtle-light);
|
|
144
|
+
--studio-border-strong: var(--studio-border-strong-light);
|
|
145
|
+
--studio-text-primary: var(--studio-text-primary-light);
|
|
146
|
+
--studio-text-secondary: var(--studio-text-secondary-light);
|
|
147
|
+
--studio-text-muted: var(--studio-text-muted-light);
|
|
148
|
+
--studio-dot-grid: var(--studio-dot-grid-light);
|
|
149
|
+
--scrollbar-thumb: var(--scrollbar-thumb-light);
|
|
150
|
+
--scrollbar-track: var(--scrollbar-track-light);
|
|
151
|
+
--studio-accent-cyan: #0284c7;
|
|
152
|
+
--studio-accent-indigo: #4f46e5;
|
|
153
|
+
--studio-accent-emerald: #059669;
|
|
154
|
+
--studio-accent-amber: #d97706;
|
|
155
|
+
--studio-badge-indigo-bg: rgba(79, 70, 229, 0.1);
|
|
156
|
+
--studio-badge-indigo-border: rgba(79, 70, 229, 0.32);
|
|
157
|
+
--studio-badge-indigo-text: #3730a3;
|
|
158
|
+
--studio-badge-emerald-bg: rgba(5, 150, 105, 0.1);
|
|
159
|
+
--studio-badge-emerald-border: rgba(5, 150, 105, 0.32);
|
|
160
|
+
--studio-badge-emerald-text: #065f46;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@supports (color: light-dark(white, black)) {
|
|
164
|
+
--studio-canvas-bg: light-dark(var(--studio-canvas-bg-light), var(--studio-canvas-bg-dark));
|
|
165
|
+
--studio-surface-1: light-dark(var(--studio-surface-1-light), var(--studio-surface-1-dark));
|
|
166
|
+
--studio-surface-2: light-dark(var(--studio-surface-2-light), var(--studio-surface-2-dark));
|
|
167
|
+
--studio-surface-3: light-dark(var(--studio-surface-3-light), var(--studio-surface-3-dark));
|
|
168
|
+
--studio-border-hairline: light-dark(
|
|
169
|
+
var(--studio-border-hairline-light),
|
|
170
|
+
var(--studio-border-hairline-dark)
|
|
171
|
+
);
|
|
172
|
+
--studio-border-subtle: light-dark(
|
|
173
|
+
var(--studio-border-subtle-light),
|
|
174
|
+
var(--studio-border-subtle-dark)
|
|
175
|
+
);
|
|
176
|
+
--studio-border-strong: light-dark(
|
|
177
|
+
var(--studio-border-strong-light),
|
|
178
|
+
var(--studio-border-strong-dark)
|
|
179
|
+
);
|
|
180
|
+
--studio-text-primary: light-dark(
|
|
181
|
+
var(--studio-text-primary-light),
|
|
182
|
+
var(--studio-text-primary-dark)
|
|
183
|
+
);
|
|
184
|
+
--studio-text-secondary: light-dark(
|
|
185
|
+
var(--studio-text-secondary-light),
|
|
186
|
+
var(--studio-text-secondary-dark)
|
|
187
|
+
);
|
|
188
|
+
--studio-text-muted: light-dark(var(--studio-text-muted-light), var(--studio-text-muted-dark));
|
|
189
|
+
--studio-dot-grid: light-dark(var(--studio-dot-grid-light), var(--studio-dot-grid-dark));
|
|
190
|
+
--scrollbar-thumb: light-dark(var(--scrollbar-thumb-light), var(--scrollbar-thumb-dark));
|
|
191
|
+
--scrollbar-track: light-dark(var(--scrollbar-track-light), var(--scrollbar-track-dark));
|
|
192
|
+
--studio-accent-cyan: light-dark(#0284c7, #38bdf8);
|
|
193
|
+
--studio-accent-indigo: light-dark(#4f46e5, #6366f1);
|
|
194
|
+
--studio-accent-emerald: light-dark(#059669, #34d399);
|
|
195
|
+
--studio-accent-amber: light-dark(#d97706, #f59e0b);
|
|
196
|
+
--studio-badge-indigo-bg: light-dark(rgba(79, 70, 229, 0.1), rgba(99, 102, 241, 0.18));
|
|
197
|
+
--studio-badge-indigo-border: light-dark(rgba(79, 70, 229, 0.32), rgba(99, 102, 241, 0.4));
|
|
198
|
+
--studio-badge-indigo-text: light-dark(#3730a3, #c7d2fe);
|
|
199
|
+
--studio-badge-emerald-bg: light-dark(rgba(5, 150, 105, 0.1), rgba(16, 185, 129, 0.14));
|
|
200
|
+
--studio-badge-emerald-border: light-dark(rgba(5, 150, 105, 0.32), rgba(16, 185, 129, 0.35));
|
|
201
|
+
--studio-badge-emerald-text: light-dark(#065f46, #a7f3d0);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Base declaration MUST stay light dark (modern-web-guidance: dark-mode-toggle) */
|
|
205
|
+
color-scheme: light dark;
|
|
206
|
+
accent-color: var(--studio-accent-cyan);
|
|
207
|
+
color: var(--studio-text-primary);
|
|
47
208
|
}
|
|
48
209
|
|
|
49
210
|
*,
|
|
@@ -79,10 +240,11 @@ body,
|
|
|
79
240
|
/* Precision architectural dot matrix on the infinite canvas */
|
|
80
241
|
.infinite-canvas-surface {
|
|
81
242
|
background-color: var(--studio-canvas-bg);
|
|
82
|
-
background-image: radial-gradient(
|
|
243
|
+
background-image: radial-gradient(var(--studio-dot-grid) 1px, transparent 1px);
|
|
83
244
|
background-size: 24px 24px;
|
|
84
245
|
touch-action: none;
|
|
85
246
|
overscroll-behavior: none;
|
|
247
|
+
transition: background-color var(--duration-micro) var(--ease-out);
|
|
86
248
|
}
|
|
87
249
|
|
|
88
250
|
/* Smooth Collapsible Studio Side Panels (emilkowalski/skills --ease-out-expo) */
|
|
@@ -92,6 +254,7 @@ body,
|
|
|
92
254
|
transition:
|
|
93
255
|
width var(--duration-panel) var(--ease-out-expo),
|
|
94
256
|
opacity var(--duration-micro) var(--ease-out),
|
|
257
|
+
background-color var(--duration-micro) var(--ease-out),
|
|
95
258
|
border-color var(--duration-micro) var(--ease-out);
|
|
96
259
|
}
|
|
97
260
|
|
|
@@ -225,8 +388,6 @@ body,
|
|
|
225
388
|
|
|
226
389
|
/* Custom Scrollbar Styling (modern-web-guidance: customize-scrollbar-color-and-thickness) */
|
|
227
390
|
.zelune-scroller {
|
|
228
|
-
--scrollbar-thumb: #262d3d;
|
|
229
|
-
--scrollbar-track: #0d0f14;
|
|
230
391
|
scrollbar-width: thin;
|
|
231
392
|
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
|
|
232
393
|
}
|
|
@@ -284,7 +445,7 @@ dialog:modal {
|
|
|
284
445
|
dialog::backdrop {
|
|
285
446
|
overflow: hidden;
|
|
286
447
|
overscroll-behavior: contain;
|
|
287
|
-
background-color: rgba(5, 7, 11, 0.
|
|
448
|
+
background-color: rgba(5, 7, 11, 0.65);
|
|
288
449
|
backdrop-filter: blur(6px);
|
|
289
450
|
}
|
|
290
451
|
|