htmlboard 0.1.0 → 0.3.0
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/README.md +120 -92
- package/bin/htmlboard.js +93 -59
- package/package.json +2 -2
- package/skills/htmlboard/SKILL.md +27 -33
- package/src/client/explorer.css +302 -598
- package/src/client/explorer.js +983 -601
- package/src/client/favicon.svg +1 -0
- package/src/client/fonts/OFL-bricolage-grotesque.txt +93 -0
- package/src/client/fonts/OFL-inter.txt +93 -0
- package/src/client/fonts/bricolage-grotesque.woff2 +0 -0
- package/src/client/fonts/inter.woff2 +0 -0
- package/src/client/index.html +87 -175
- package/src/client/logo.svg +1 -0
- package/src/client/mark.svg +1 -0
- package/src/designs.js +398 -0
- package/src/index.js +8 -2
- package/src/migrate.js +193 -0
- package/src/server.js +93 -212
- package/src/templates/{artboards/desktop.html → 01-screens/01-desktop.html} +2 -0
- package/src/templates/{artboards/mobile.html → 01-screens/02-mobile.html} +2 -0
- package/src/templates/{artboards/components.html → 02-components/01-ui-kit.html} +2 -0
- package/src/templates/designs.json +0 -50
package/src/client/explorer.css
CHANGED
|
@@ -1,703 +1,407 @@
|
|
|
1
|
-
/* HtmlBoard
|
|
2
|
-
:root {
|
|
3
|
-
--bg-app: #090a0f;
|
|
4
|
-
--bg-topbar: rgba(14, 16, 24, 0.85);
|
|
5
|
-
--bg-sidebar: #0e111a;
|
|
6
|
-
--bg-canvas: #090b12;
|
|
7
|
-
--bg-card: #131722;
|
|
8
|
-
--bg-card-header: #171b29;
|
|
9
|
-
--bg-btn: rgba(255, 255, 255, 0.05);
|
|
10
|
-
--bg-btn-hover: rgba(255, 255, 255, 0.1);
|
|
11
|
-
--border-subtle: #1c2132;
|
|
12
|
-
--border-card: #282e44;
|
|
13
|
-
--border-focus: #6366f1;
|
|
14
|
-
--text-primary: #f8fafc;
|
|
15
|
-
--text-secondary: #94a3b8;
|
|
16
|
-
--text-muted: #64748b;
|
|
17
|
-
--accent: #6366f1;
|
|
18
|
-
--accent-glow: rgba(99, 102, 241, 0.35);
|
|
19
|
-
--accent-light: #818cf8;
|
|
20
|
-
--emerald: #10b981;
|
|
21
|
-
--amber: #f59e0b;
|
|
22
|
-
--rose: #f43f5e;
|
|
23
|
-
--purple: #a855f7;
|
|
24
|
-
--font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
25
|
-
--font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
* {
|
|
29
|
-
box-sizing: border-box;
|
|
30
|
-
margin: 0;
|
|
31
|
-
padding: 0;
|
|
32
|
-
user-select: none;
|
|
33
|
-
-webkit-font-smoothing: antialiased;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
body {
|
|
37
|
-
font-family: var(--font-sans);
|
|
38
|
-
background: var(--bg-app);
|
|
39
|
-
color: var(--text-primary);
|
|
40
|
-
overflow: hidden;
|
|
41
|
-
height: 100vh;
|
|
42
|
-
width: 100vw;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
#app {
|
|
46
|
-
display: flex;
|
|
47
|
-
flex-direction: column;
|
|
48
|
-
height: 100vh;
|
|
49
|
-
width: 100vw;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/* Topbar */
|
|
53
|
-
.topbar {
|
|
54
|
-
height: 52px;
|
|
55
|
-
background: var(--bg-topbar);
|
|
56
|
-
backdrop-filter: blur(16px);
|
|
57
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
58
|
-
display: flex;
|
|
59
|
-
align-items: center;
|
|
60
|
-
justify-content: space-between;
|
|
61
|
-
padding: 0 16px;
|
|
62
|
-
z-index: 50;
|
|
63
|
-
flex-shrink: 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.topbar-left, .topbar-center, .topbar-right {
|
|
67
|
-
display: flex;
|
|
68
|
-
align-items: center;
|
|
69
|
-
gap: 12px;
|
|
70
|
-
}
|
|
1
|
+
/* HtmlBoard explorer. Its own dark chrome, so the designs stand out on the canvas. */
|
|
71
2
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
3
|
+
@font-face {
|
|
4
|
+
font-family: 'Inter';
|
|
5
|
+
font-style: normal;
|
|
6
|
+
font-weight: 400 700;
|
|
7
|
+
font-display: swap;
|
|
8
|
+
src: url(fonts/inter.woff2) format('woff2');
|
|
77
9
|
}
|
|
78
10
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: 'Bricolage Grotesque';
|
|
13
|
+
font-style: normal;
|
|
14
|
+
font-weight: 500 800;
|
|
15
|
+
font-display: swap;
|
|
16
|
+
src: url(fonts/bricolage-grotesque.woff2) format('woff2');
|
|
83
17
|
}
|
|
84
18
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
-
|
|
92
|
-
|
|
19
|
+
/* One cool family of greys at the accent's hue (oklch 258, barely tinted), so the chrome sits with
|
|
20
|
+
the logo's blue and keeps out of the designs' way. Text colours pass WCAG AA on every surface. */
|
|
21
|
+
:root {
|
|
22
|
+
--x-canvas: #15171B; /* oklch(0.205 0.008 258) */
|
|
23
|
+
--x-panel: #1E2126; /* oklch(0.248 0.009 258) */
|
|
24
|
+
--x-raised: #282C30; /* oklch(0.29 0.01 258) */
|
|
25
|
+
--x-line: #36393F; /* oklch(0.345 0.011 258) */
|
|
26
|
+
--x-line-soft: #2B2E33; /* oklch(0.3 0.01 258): dividers inside a panel */
|
|
27
|
+
--x-text: #EDEEF1; /* 13.9:1 on the panel */
|
|
28
|
+
--x-text-soft: #A2A8B1; /* 6.7:1 */
|
|
29
|
+
--x-text-faint: #878D95; /* 4.8:1 */
|
|
30
|
+
--x-accent: #3D9DFF; /* the logo's pegs */
|
|
31
|
+
--x-accent-text: #8BC2FF; /* the accent as text: 8.7:1 */
|
|
32
|
+
--x-accent-wash: rgb(61 157 255 / 0.16);
|
|
33
|
+
--x-on-accent: #15171B; /* text on the accent: 6.4:1 (white would be 2.8:1) */
|
|
34
|
+
--x-wash: rgb(255 255 255 / 0.06);
|
|
35
|
+
--x-dot: rgb(255 255 255 / 0.1);
|
|
36
|
+
--x-live: #3DD68C;
|
|
37
|
+
--x-glass: color-mix(in srgb, var(--x-raised) 84%, transparent);
|
|
38
|
+
--x-float: inset 0 1px 0 rgb(255 255 255 / 0.05), 0 10px 32px rgb(0 0 0 / 0.5);
|
|
39
|
+
--font-ui: 'Inter', system-ui, sans-serif;
|
|
40
|
+
--font-display: 'Bricolage Grotesque', 'Inter', system-ui, sans-serif;
|
|
41
|
+
color-scheme: dark;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
*, ::before, ::after { box-sizing: border-box; }
|
|
45
|
+
|
|
46
|
+
html, body { height: 100%; margin: 0; overflow: hidden; }
|
|
93
47
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
border: 1px solid var(--border-subtle);
|
|
97
|
-
padding: 4px 10px;
|
|
98
|
-
border-radius: 6px;
|
|
99
|
-
font-size: 12px;
|
|
100
|
-
color: var(--text-secondary);
|
|
48
|
+
body {
|
|
49
|
+
font-family: var(--font-ui);
|
|
101
50
|
font-weight: 500;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
overflow: hidden;
|
|
105
|
-
text-overflow: ellipsis;
|
|
51
|
+
color: var(--x-text);
|
|
52
|
+
background: var(--x-canvas);
|
|
106
53
|
}
|
|
107
54
|
|
|
108
|
-
|
|
109
|
-
.filter-tabs {
|
|
110
|
-
display: flex;
|
|
111
|
-
background: rgba(0, 0, 0, 0.3);
|
|
112
|
-
padding: 3px;
|
|
113
|
-
border-radius: 8px;
|
|
114
|
-
border: 1px solid var(--border-subtle);
|
|
115
|
-
}
|
|
55
|
+
:focus-visible { outline: 2px solid var(--x-accent); outline-offset: 2px; }
|
|
116
56
|
|
|
117
|
-
|
|
118
|
-
background: transparent;
|
|
119
|
-
border: none;
|
|
120
|
-
color: var(--text-muted);
|
|
121
|
-
font-size: 12px;
|
|
122
|
-
font-weight: 500;
|
|
123
|
-
padding: 5px 12px;
|
|
124
|
-
border-radius: 6px;
|
|
125
|
-
cursor: pointer;
|
|
126
|
-
transition: all 0.15s ease;
|
|
127
|
-
}
|
|
57
|
+
[hidden] { display: none !important; }
|
|
128
58
|
|
|
129
|
-
|
|
130
|
-
|
|
59
|
+
kbd {
|
|
60
|
+
display: inline-block;
|
|
61
|
+
min-width: 1.6em;
|
|
62
|
+
padding: 0 4px;
|
|
63
|
+
border: 1px solid var(--x-line);
|
|
64
|
+
border-radius: 4px;
|
|
65
|
+
background: var(--x-raised);
|
|
66
|
+
font: inherit;
|
|
67
|
+
font-size: 0.92em;
|
|
68
|
+
line-height: 1.5;
|
|
69
|
+
text-align: center;
|
|
131
70
|
}
|
|
132
71
|
|
|
133
|
-
.
|
|
134
|
-
background: var(--accent);
|
|
135
|
-
color: #fff;
|
|
136
|
-
font-weight: 600;
|
|
137
|
-
box-shadow: 0 2px 8px var(--accent-glow);
|
|
138
|
-
}
|
|
72
|
+
.app { display: flex; height: 100%; }
|
|
139
73
|
|
|
140
|
-
/*
|
|
141
|
-
.search-box {
|
|
142
|
-
display: flex;
|
|
143
|
-
align-items: center;
|
|
144
|
-
gap: 8px;
|
|
145
|
-
background: rgba(0, 0, 0, 0.35);
|
|
146
|
-
border: 1px solid var(--border-subtle);
|
|
147
|
-
border-radius: 8px;
|
|
148
|
-
padding: 5px 10px;
|
|
149
|
-
position: relative;
|
|
150
|
-
transition: border-color 0.15s ease;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.search-box:focus-within {
|
|
154
|
-
border-color: var(--border-focus);
|
|
155
|
-
}
|
|
74
|
+
/* ---------- The list ---------- */
|
|
156
75
|
|
|
157
|
-
.
|
|
158
|
-
|
|
76
|
+
.sidebar {
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
flex: none;
|
|
80
|
+
width: 272px;
|
|
81
|
+
border-right: 1px solid var(--x-line-soft);
|
|
82
|
+
background: var(--x-panel);
|
|
159
83
|
}
|
|
160
84
|
|
|
161
|
-
.
|
|
162
|
-
background: transparent;
|
|
163
|
-
border: none;
|
|
164
|
-
outline: none;
|
|
165
|
-
color: var(--text-primary);
|
|
166
|
-
font-size: 12px;
|
|
167
|
-
width: 140px;
|
|
168
|
-
font-family: var(--font-sans);
|
|
169
|
-
user-select: text;
|
|
170
|
-
}
|
|
85
|
+
.app.is-collapsed .sidebar { display: none; }
|
|
171
86
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
87
|
+
/* htmlboard's own row: the logo (a link to the project) and the version */
|
|
88
|
+
.brand { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 14px 16px 12px; border-bottom: 1px solid var(--x-line-soft); }
|
|
89
|
+
.brand-logo { display: block; border-radius: 4px; }
|
|
90
|
+
.brand-logo img { display: block; width: auto; height: 18px; }
|
|
91
|
+
.version { font-size: 11px; color: var(--x-text-faint); font-variant-numeric: tabular-nums; }
|
|
175
92
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
border: 1px solid var(--border-subtle);
|
|
181
|
-
border-radius: 4px;
|
|
182
|
-
padding: 2px 5px;
|
|
183
|
-
color: var(--text-muted);
|
|
184
|
-
}
|
|
93
|
+
/* The project's title, the count running on after its last word */
|
|
94
|
+
.sidebar-head { padding: 16px 16px 10px; }
|
|
95
|
+
.sidebar-head h1 { display: inline; margin: 0; font: 800 24px/1.1 var(--font-display); overflow-wrap: anywhere; }
|
|
96
|
+
.count { margin-left: 8px; font-size: 13px; color: var(--x-text-soft); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
185
97
|
|
|
186
|
-
|
|
187
|
-
.zoom-controls {
|
|
188
|
-
display: flex;
|
|
189
|
-
align-items: center;
|
|
190
|
-
gap: 4px;
|
|
191
|
-
background: rgba(0, 0, 0, 0.35);
|
|
192
|
-
border: 1px solid var(--border-subtle);
|
|
193
|
-
border-radius: 8px;
|
|
194
|
-
padding: 2px 6px;
|
|
195
|
-
}
|
|
98
|
+
.search { position: relative; margin: 0 12px 4px; }
|
|
196
99
|
|
|
197
|
-
.
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
background: var(--bg-btn-hover);
|
|
210
|
-
color: var(--text-primary);
|
|
100
|
+
.search svg {
|
|
101
|
+
position: absolute;
|
|
102
|
+
left: 9px;
|
|
103
|
+
top: 50%;
|
|
104
|
+
width: 15px;
|
|
105
|
+
height: 15px;
|
|
106
|
+
fill: none;
|
|
107
|
+
stroke: var(--x-text-faint);
|
|
108
|
+
stroke-width: 2;
|
|
109
|
+
stroke-linecap: round;
|
|
110
|
+
transform: translateY(-50%);
|
|
111
|
+
pointer-events: none;
|
|
211
112
|
}
|
|
212
113
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
width: 32px;
|
|
114
|
+
.search input {
|
|
115
|
+
width: 100%;
|
|
216
116
|
height: 32px;
|
|
217
|
-
|
|
218
|
-
border: 1px solid
|
|
219
|
-
background: transparent;
|
|
220
|
-
color: var(--text-secondary);
|
|
221
|
-
display: flex;
|
|
222
|
-
align-items: center;
|
|
223
|
-
justify-content: center;
|
|
224
|
-
cursor: pointer;
|
|
225
|
-
transition: all 0.15s ease;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
.btn-icon:hover {
|
|
229
|
-
background: var(--bg-btn-hover);
|
|
230
|
-
color: var(--text-primary);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.btn-text {
|
|
234
|
-
background: transparent;
|
|
235
|
-
border: none;
|
|
236
|
-
color: var(--text-secondary);
|
|
237
|
-
font-size: 12px;
|
|
238
|
-
font-weight: 500;
|
|
239
|
-
padding: 5px 8px;
|
|
117
|
+
padding: 0 30px;
|
|
118
|
+
border: 1px solid var(--x-line-soft);
|
|
240
119
|
border-radius: 6px;
|
|
241
|
-
|
|
242
|
-
|
|
120
|
+
background: var(--x-canvas);
|
|
121
|
+
color: var(--x-text);
|
|
122
|
+
font: inherit;
|
|
123
|
+
font-size: 13px;
|
|
243
124
|
}
|
|
244
125
|
|
|
245
|
-
.
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
126
|
+
.search input::placeholder { color: var(--x-text-faint); opacity: 1; }
|
|
127
|
+
.search input:focus { border-color: var(--x-accent); outline: none; box-shadow: 0 0 0 3px var(--x-accent-wash); }
|
|
128
|
+
.search input::-webkit-search-cancel-button { appearance: none; }
|
|
249
129
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
gap: 6px;
|
|
255
|
-
background: rgba(16, 185, 129, 0.1);
|
|
256
|
-
border: 1px solid rgba(16, 185, 129, 0.25);
|
|
257
|
-
padding: 4px 10px;
|
|
258
|
-
border-radius: 20px;
|
|
130
|
+
.search kbd {
|
|
131
|
+
position: absolute;
|
|
132
|
+
right: 7px;
|
|
133
|
+
top: 50%;
|
|
259
134
|
font-size: 11px;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
.live-dot {
|
|
265
|
-
width: 7px;
|
|
266
|
-
height: 7px;
|
|
267
|
-
border-radius: 50%;
|
|
268
|
-
background: var(--emerald);
|
|
269
|
-
box-shadow: 0 0 8px var(--emerald);
|
|
270
|
-
animation: pulse-live 2s infinite ease-in-out;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.live-indicator.disconnected {
|
|
274
|
-
background: rgba(244, 63, 94, 0.1);
|
|
275
|
-
border-color: rgba(244, 63, 94, 0.25);
|
|
276
|
-
color: var(--rose);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
.live-indicator.disconnected .live-dot {
|
|
280
|
-
background: var(--rose);
|
|
281
|
-
box-shadow: 0 0 8px var(--rose);
|
|
282
|
-
animation: none;
|
|
135
|
+
color: var(--x-text-faint);
|
|
136
|
+
transform: translateY(-50%);
|
|
137
|
+
pointer-events: none;
|
|
283
138
|
}
|
|
284
139
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
50% { transform: scale(1.3); opacity: 1; }
|
|
288
|
-
100% { transform: scale(0.95); opacity: 0.8; }
|
|
289
|
-
}
|
|
140
|
+
/* The filters: all, the devices (and any other category), as chips that wrap */
|
|
141
|
+
.filters { display: flex; flex-wrap: wrap; gap: 4px; margin: 8px 12px 0; }
|
|
290
142
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
143
|
+
.filter {
|
|
144
|
+
height: 26px;
|
|
145
|
+
padding: 0 10px;
|
|
146
|
+
border: 1px solid var(--x-line-soft);
|
|
147
|
+
border-radius: 13px;
|
|
148
|
+
background: none;
|
|
149
|
+
color: var(--x-text-soft);
|
|
150
|
+
font: inherit;
|
|
151
|
+
font-size: 12px;
|
|
152
|
+
cursor: pointer;
|
|
297
153
|
}
|
|
298
154
|
|
|
299
|
-
|
|
300
|
-
.
|
|
301
|
-
|
|
302
|
-
background: var(--bg-sidebar);
|
|
303
|
-
border-right: 1px solid var(--border-subtle);
|
|
304
|
-
display: flex;
|
|
305
|
-
flex-direction: column;
|
|
306
|
-
flex-shrink: 0;
|
|
307
|
-
transition: margin-left 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
|
308
|
-
z-index: 40;
|
|
309
|
-
}
|
|
155
|
+
.filter:hover:not(:disabled) { background: var(--x-wash); color: var(--x-text); }
|
|
156
|
+
.filter[aria-pressed='true'] { border-color: transparent; background: var(--x-accent-wash); color: var(--x-accent-text); }
|
|
157
|
+
.filter:disabled { color: var(--x-text-faint); border-style: dashed; cursor: default; }
|
|
310
158
|
|
|
311
|
-
.
|
|
312
|
-
margin-left: -260px;
|
|
313
|
-
}
|
|
159
|
+
.search input:focus ~ kbd, .search input:not(:placeholder-shown) ~ kbd { display: none; }
|
|
314
160
|
|
|
315
|
-
.
|
|
316
|
-
height: 42px;
|
|
317
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
318
|
-
display: flex;
|
|
319
|
-
align-items: center;
|
|
320
|
-
justify-content: space-between;
|
|
321
|
-
padding: 0 16px;
|
|
322
|
-
}
|
|
161
|
+
.list { flex: 1; overflow-y: auto; padding: 0 8px 16px; scrollbar-width: thin; scrollbar-color: var(--x-line) transparent; }
|
|
323
162
|
|
|
324
|
-
.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
letter-spacing: 0.08em;
|
|
163
|
+
.list h2 {
|
|
164
|
+
margin: 18px 8px 4px;
|
|
165
|
+
font-size: 12px;
|
|
328
166
|
font-weight: 700;
|
|
329
|
-
|
|
167
|
+
letter-spacing: 0.06em;
|
|
168
|
+
text-transform: uppercase;
|
|
169
|
+
color: var(--x-text-soft);
|
|
330
170
|
}
|
|
331
171
|
|
|
332
|
-
.
|
|
333
|
-
font-size: 11px;
|
|
334
|
-
color: var(--text-muted);
|
|
335
|
-
font-family: var(--font-mono);
|
|
336
|
-
}
|
|
172
|
+
.list .section-desc { margin: -2px 8px 6px; font-size: 12px; line-height: 1.45; color: var(--x-text-soft); }
|
|
337
173
|
|
|
338
|
-
.
|
|
339
|
-
|
|
340
|
-
overflow-y: auto;
|
|
341
|
-
padding: 12px 8px;
|
|
342
|
-
display: flex;
|
|
343
|
-
flex-direction: column;
|
|
344
|
-
gap: 16px;
|
|
345
|
-
}
|
|
174
|
+
.list ul { margin: 0; padding: 0; list-style: none; }
|
|
175
|
+
.list section > ul:first-child { margin-top: 12px; } /* a section without a title (the files at the top) */
|
|
346
176
|
|
|
347
|
-
.
|
|
348
|
-
font-size: 11px;
|
|
349
|
-
font-weight: 600;
|
|
350
|
-
color: var(--text-muted);
|
|
351
|
-
padding: 4px 8px;
|
|
352
|
-
text-transform: uppercase;
|
|
353
|
-
letter-spacing: 0.05em;
|
|
177
|
+
.item {
|
|
354
178
|
display: flex;
|
|
355
|
-
align-items:
|
|
179
|
+
align-items: baseline;
|
|
356
180
|
justify-content: space-between;
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
align-items: center;
|
|
369
|
-
justify-content: space-between;
|
|
370
|
-
padding: 8px 10px;
|
|
371
|
-
border-radius: 6px;
|
|
372
|
-
font-size: 13px;
|
|
373
|
-
color: var(--text-secondary);
|
|
181
|
+
gap: 12px;
|
|
182
|
+
width: 100%;
|
|
183
|
+
padding: 6px 8px;
|
|
184
|
+
border: 0;
|
|
185
|
+
border-radius: 5px;
|
|
186
|
+
background: none;
|
|
187
|
+
color: inherit;
|
|
188
|
+
font: inherit;
|
|
189
|
+
font-size: 14px;
|
|
190
|
+
line-height: 20px;
|
|
191
|
+
text-align: left;
|
|
374
192
|
cursor: pointer;
|
|
375
|
-
transition: all 0.12s ease;
|
|
376
193
|
}
|
|
377
194
|
|
|
378
|
-
.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
195
|
+
.item:hover { background: var(--x-wash); }
|
|
196
|
+
.item[aria-current='true'] { background: var(--x-accent-wash); color: var(--x-text); }
|
|
197
|
+
.item .dims { flex: none; font-size: 12px; color: var(--x-text-faint); font-variant-numeric: tabular-nums; }
|
|
198
|
+
.item[aria-current='true'] .dims { color: var(--x-accent-text); }
|
|
382
199
|
|
|
383
|
-
.
|
|
384
|
-
background: rgba(99, 102, 241, 0.15);
|
|
385
|
-
color: var(--accent-light);
|
|
386
|
-
font-weight: 500;
|
|
387
|
-
}
|
|
200
|
+
.no-match { margin: 0; padding: 12px 16px 0; font-size: 13px; color: var(--x-text-soft); }
|
|
388
201
|
|
|
389
|
-
.sidebar-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
color: var(--text-
|
|
202
|
+
.sidebar-hint {
|
|
203
|
+
margin: 0;
|
|
204
|
+
padding: 12px 16px 16px;
|
|
205
|
+
border-top: 1px solid var(--x-line-soft);
|
|
206
|
+
font-size: 12px;
|
|
207
|
+
line-height: 1.6;
|
|
208
|
+
color: var(--x-text-soft);
|
|
396
209
|
}
|
|
397
210
|
|
|
398
|
-
/*
|
|
399
|
-
|
|
400
|
-
|
|
211
|
+
/* ---------- The canvas ---------- */
|
|
212
|
+
|
|
213
|
+
.viewport {
|
|
401
214
|
position: relative;
|
|
215
|
+
flex: 1;
|
|
402
216
|
overflow: hidden;
|
|
403
|
-
|
|
404
|
-
|
|
217
|
+
touch-action: none;
|
|
218
|
+
background-color: var(--x-canvas);
|
|
219
|
+
background-image: radial-gradient(circle at 1px 1px, var(--x-dot) 1px, transparent 0);
|
|
220
|
+
background-size: var(--grid, 32px) var(--grid, 32px);
|
|
221
|
+
outline: none;
|
|
405
222
|
}
|
|
406
223
|
|
|
407
|
-
.
|
|
408
|
-
|
|
409
|
-
}
|
|
224
|
+
.viewport.is-panning, .viewport.is-panning * { cursor: grabbing; }
|
|
225
|
+
.viewport.is-space { cursor: grab; }
|
|
410
226
|
|
|
411
|
-
.
|
|
412
|
-
position: absolute;
|
|
413
|
-
top: 0;
|
|
414
|
-
left: 0;
|
|
415
|
-
width: 100%;
|
|
416
|
-
height: 100%;
|
|
417
|
-
transform-origin: 0 0;
|
|
418
|
-
will-change: transform;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
/* Infinite Dot Grid */
|
|
422
|
-
.canvas-grid {
|
|
423
|
-
position: absolute;
|
|
424
|
-
inset: -50000px;
|
|
425
|
-
background-image: radial-gradient(circle, #22283a 1.2px, transparent 1.2px);
|
|
426
|
-
background-size: 28px 28px;
|
|
427
|
-
pointer-events: none;
|
|
428
|
-
}
|
|
227
|
+
.world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
|
|
429
228
|
|
|
430
|
-
|
|
431
|
-
.canvas-content {
|
|
229
|
+
.frame {
|
|
432
230
|
position: absolute;
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
/* Grow with the artboards instead of the viewport: each section is one row */
|
|
436
|
-
width: max-content;
|
|
437
|
-
padding: 80px;
|
|
438
|
-
display: flex;
|
|
439
|
-
flex-direction: column;
|
|
440
|
-
gap: 64px;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
.canvas-section {
|
|
444
|
-
display: flex;
|
|
445
|
-
flex-direction: column;
|
|
446
|
-
gap: 24px;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
.canvas-section-header {
|
|
450
|
-
display: flex;
|
|
451
|
-
flex-direction: column;
|
|
452
|
-
gap: 4px;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
.canvas-section-title {
|
|
456
|
-
font-size: 22px;
|
|
457
|
-
font-weight: 700;
|
|
458
|
-
letter-spacing: -0.02em;
|
|
459
|
-
color: var(--text-primary);
|
|
231
|
+
background: #FFFFFF;
|
|
232
|
+
box-shadow: 0 1px 3px rgb(0 0 0 / 0.5), 0 12px 40px rgb(0 0 0 / 0.4);
|
|
460
233
|
}
|
|
461
234
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
235
|
+
/* The canvas takes every pointer event (wheel included, so Ctrl + scroll never zooms the page):
|
|
236
|
+
designs are pictures here, and Open shows one on its own. */
|
|
237
|
+
.frame iframe { display: block; width: 100%; height: 100%; border: 0; pointer-events: none; }
|
|
466
238
|
|
|
467
|
-
.
|
|
468
|
-
|
|
469
|
-
flex-wrap: nowrap;
|
|
470
|
-
align-items: flex-start;
|
|
471
|
-
gap: 48px;
|
|
472
|
-
}
|
|
239
|
+
/* Designs the search leaves out stay in place, faded. */
|
|
240
|
+
.frame.is-dimmed { opacity: 0.2; }
|
|
473
241
|
|
|
474
|
-
|
|
475
|
-
.artboard-frame {
|
|
476
|
-
flex: none;
|
|
477
|
-
background: var(--bg-card);
|
|
478
|
-
border: 1px solid var(--border-card);
|
|
479
|
-
border-radius: 14px;
|
|
480
|
-
box-shadow: 0 20px 40px -15px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(255, 255, 255, 0.03);
|
|
481
|
-
display: flex;
|
|
482
|
-
flex-direction: column;
|
|
483
|
-
overflow: hidden;
|
|
484
|
-
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
|
485
|
-
}
|
|
242
|
+
.overlay { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
|
|
486
243
|
|
|
487
|
-
.
|
|
488
|
-
border-color: #3b4260;
|
|
489
|
-
box-shadow: 0 24px 50px -12px rgba(0, 0, 0, 0.7), 0 0 20px var(--accent-glow);
|
|
490
|
-
}
|
|
244
|
+
.label, .section-title, .outline, .size { position: absolute; left: 0; top: 0; }
|
|
491
245
|
|
|
492
|
-
.
|
|
493
|
-
border-color: var(--accent);
|
|
494
|
-
box-shadow: 0 0 0 2px var(--accent), 0 24px 50px -12px rgba(99, 102, 241, 0.4);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
/* Artboard Header */
|
|
498
|
-
.artboard-header {
|
|
499
|
-
height: 42px;
|
|
500
|
-
background: var(--bg-card-header);
|
|
501
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
502
|
-
display: flex;
|
|
503
|
-
align-items: center;
|
|
504
|
-
justify-content: space-between;
|
|
505
|
-
padding: 0 14px;
|
|
506
|
-
gap: 12px;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
.artboard-title-group {
|
|
510
|
-
display: flex;
|
|
511
|
-
align-items: center;
|
|
512
|
-
gap: 8px;
|
|
246
|
+
.label {
|
|
513
247
|
overflow: hidden;
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
.artboard-title {
|
|
517
|
-
font-size: 13px;
|
|
248
|
+
font-size: 12px;
|
|
518
249
|
font-weight: 600;
|
|
250
|
+
line-height: 16px;
|
|
519
251
|
white-space: nowrap;
|
|
520
|
-
overflow: hidden;
|
|
521
252
|
text-overflow: ellipsis;
|
|
522
|
-
color: var(--text-
|
|
253
|
+
color: var(--x-text-soft);
|
|
523
254
|
}
|
|
524
255
|
|
|
525
|
-
.
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
256
|
+
.label.is-hover { color: var(--x-text); }
|
|
257
|
+
.label.is-selected { color: var(--x-accent); }
|
|
258
|
+
.label.is-dimmed { opacity: 0.35; }
|
|
259
|
+
|
|
260
|
+
.section-title { font: 700 20px/24px var(--font-display); letter-spacing: 0.01em; white-space: nowrap; color: var(--x-text); }
|
|
261
|
+
|
|
262
|
+
.outline--hover { box-shadow: 0 0 0 1px var(--x-accent); }
|
|
263
|
+
.outline--selected { box-shadow: 0 0 0 2px var(--x-accent); }
|
|
264
|
+
|
|
265
|
+
.size {
|
|
529
266
|
padding: 2px 6px;
|
|
530
267
|
border-radius: 4px;
|
|
531
|
-
|
|
268
|
+
background: var(--x-accent);
|
|
269
|
+
color: var(--x-on-accent);
|
|
270
|
+
font-size: 11px;
|
|
271
|
+
font-weight: 600;
|
|
272
|
+
line-height: 14px;
|
|
273
|
+
white-space: nowrap;
|
|
274
|
+
font-variant-numeric: tabular-nums;
|
|
532
275
|
}
|
|
533
276
|
|
|
534
|
-
|
|
535
|
-
.badge-desktop { background: rgba(59, 130, 246, 0.18); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
|
|
536
|
-
.badge-tablet { background: rgba(16, 185, 129, 0.18); color: #34d399; border: 1px solid rgba(16, 185, 129, 0.3); }
|
|
537
|
-
.badge-components { background: rgba(245, 158, 11, 0.18); color: #fbbf24; border: 1px solid rgba(245, 158, 11, 0.3); }
|
|
538
|
-
.badge-responsive { background: rgba(99, 102, 241, 0.18); color: #a5b4fc; border: 1px solid rgba(99, 102, 241, 0.3); }
|
|
277
|
+
/* ---------- Toolbar, shortcuts, messages ---------- */
|
|
539
278
|
|
|
540
|
-
.
|
|
279
|
+
.toolbar {
|
|
280
|
+
position: absolute;
|
|
281
|
+
bottom: 16px;
|
|
282
|
+
left: 50%;
|
|
541
283
|
display: flex;
|
|
542
284
|
align-items: center;
|
|
543
|
-
gap:
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
285
|
+
gap: 2px;
|
|
286
|
+
padding: 4px;
|
|
287
|
+
border: 1px solid var(--x-line);
|
|
288
|
+
border-radius: 10px;
|
|
289
|
+
background: var(--x-glass);
|
|
290
|
+
backdrop-filter: blur(16px) saturate(1.4);
|
|
291
|
+
box-shadow: var(--x-float);
|
|
292
|
+
transform: translateX(-50%);
|
|
551
293
|
}
|
|
552
294
|
|
|
553
|
-
.
|
|
554
|
-
|
|
555
|
-
height: 26px;
|
|
556
|
-
border-radius: 6px;
|
|
557
|
-
border: 1px solid transparent;
|
|
558
|
-
background: transparent;
|
|
559
|
-
color: var(--text-muted);
|
|
560
|
-
display: flex;
|
|
295
|
+
.tool {
|
|
296
|
+
display: inline-flex;
|
|
561
297
|
align-items: center;
|
|
562
298
|
justify-content: center;
|
|
299
|
+
gap: 6px;
|
|
300
|
+
min-width: 34px;
|
|
301
|
+
height: 34px;
|
|
302
|
+
padding: 0 8px;
|
|
303
|
+
border: 0;
|
|
304
|
+
border-radius: 6px;
|
|
305
|
+
background: none;
|
|
306
|
+
color: var(--x-text);
|
|
307
|
+
font: inherit;
|
|
308
|
+
font-size: 13px;
|
|
309
|
+
text-decoration: none;
|
|
563
310
|
cursor: pointer;
|
|
564
|
-
transition: all 0.15s ease;
|
|
565
311
|
}
|
|
566
312
|
|
|
567
|
-
.
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
313
|
+
.tool:hover { background: var(--x-wash); }
|
|
314
|
+
.tool[aria-pressed='true'] { color: var(--x-accent-text); }
|
|
315
|
+
.tool[aria-disabled='true'] { opacity: 0.4; pointer-events: none; }
|
|
571
316
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
317
|
+
.tool svg {
|
|
318
|
+
width: 17px;
|
|
319
|
+
height: 17px;
|
|
320
|
+
fill: none;
|
|
321
|
+
stroke: currentColor;
|
|
322
|
+
stroke-width: 2;
|
|
323
|
+
stroke-linecap: round;
|
|
324
|
+
stroke-linejoin: round;
|
|
578
325
|
}
|
|
579
326
|
|
|
580
|
-
.
|
|
581
|
-
border: none;
|
|
582
|
-
background: #fff;
|
|
583
|
-
display: block;
|
|
584
|
-
}
|
|
327
|
+
.zoom { min-width: 58px; font-variant-numeric: tabular-nums; }
|
|
585
328
|
|
|
586
|
-
|
|
587
|
-
.pointer-shield {
|
|
588
|
-
position: absolute;
|
|
589
|
-
inset: 0;
|
|
590
|
-
z-index: 30;
|
|
591
|
-
display: none;
|
|
592
|
-
cursor: inherit;
|
|
593
|
-
}
|
|
329
|
+
.sep { width: 1px; height: 20px; margin: 0 4px; background: var(--x-line); }
|
|
594
330
|
|
|
595
|
-
.
|
|
596
|
-
|
|
597
|
-
}
|
|
331
|
+
.live { display: inline-flex; align-items: center; gap: 6px; padding: 0 8px; font-size: 12px; color: var(--x-text-soft); }
|
|
332
|
+
.live::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--x-live); }
|
|
333
|
+
.live.is-off::before { background: var(--x-text-faint); }
|
|
598
334
|
|
|
599
|
-
|
|
600
|
-
.canvas-hud {
|
|
335
|
+
.help {
|
|
601
336
|
position: absolute;
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
border:
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
gap: 10px;
|
|
613
|
-
font-size: 11px;
|
|
614
|
-
color: var(--text-muted);
|
|
615
|
-
pointer-events: none;
|
|
616
|
-
z-index: 40;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
.canvas-hud kbd {
|
|
620
|
-
font-family: var(--font-mono);
|
|
621
|
-
background: rgba(255, 255, 255, 0.1);
|
|
622
|
-
padding: 2px 5px;
|
|
623
|
-
border-radius: 4px;
|
|
624
|
-
color: var(--text-secondary);
|
|
337
|
+
right: 16px;
|
|
338
|
+
bottom: 72px;
|
|
339
|
+
width: min(340px, calc(100% - 32px));
|
|
340
|
+
padding: 14px 16px 10px;
|
|
341
|
+
border: 1px solid var(--x-line);
|
|
342
|
+
border-radius: 10px;
|
|
343
|
+
background: var(--x-glass);
|
|
344
|
+
backdrop-filter: blur(16px) saturate(1.4);
|
|
345
|
+
box-shadow: var(--x-float);
|
|
346
|
+
font-size: 13px;
|
|
625
347
|
}
|
|
626
348
|
|
|
627
|
-
.
|
|
628
|
-
|
|
629
|
-
}
|
|
349
|
+
.help h2 { margin: 0 0 8px; font: 700 18px/1.2 var(--font-display); }
|
|
350
|
+
.help dl { margin: 0; }
|
|
351
|
+
.help dl > div { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; border-top: 1px solid var(--x-line-soft); }
|
|
352
|
+
.help dt { color: var(--x-text-soft); }
|
|
353
|
+
.help dd { margin: 0; text-align: right; }
|
|
630
354
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
355
|
+
.toast {
|
|
356
|
+
position: absolute;
|
|
357
|
+
top: 16px;
|
|
358
|
+
left: 50%;
|
|
359
|
+
max-width: calc(100% - 32px);
|
|
360
|
+
padding: 8px 14px;
|
|
361
|
+
border: 1px solid var(--x-line);
|
|
362
|
+
border-radius: 8px;
|
|
363
|
+
background: var(--x-glass);
|
|
364
|
+
backdrop-filter: blur(16px) saturate(1.4);
|
|
365
|
+
box-shadow: var(--x-float);
|
|
366
|
+
font-size: 13px;
|
|
367
|
+
white-space: nowrap;
|
|
368
|
+
overflow: hidden;
|
|
369
|
+
text-overflow: ellipsis;
|
|
641
370
|
opacity: 0;
|
|
642
371
|
pointer-events: none;
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
.modal-backdrop.open {
|
|
647
|
-
opacity: 1;
|
|
648
|
-
pointer-events: auto;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
.modal-card {
|
|
652
|
-
width: 90%;
|
|
653
|
-
max-width: 520px;
|
|
654
|
-
background: var(--bg-card);
|
|
655
|
-
border: 1px solid var(--border-card);
|
|
656
|
-
border-radius: 16px;
|
|
657
|
-
padding: 24px;
|
|
658
|
-
box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.8);
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
.modal-header {
|
|
662
|
-
display: flex;
|
|
663
|
-
align-items: center;
|
|
664
|
-
justify-content: space-between;
|
|
665
|
-
margin-bottom: 20px;
|
|
666
|
-
border-bottom: 1px solid var(--border-subtle);
|
|
667
|
-
padding-bottom: 12px;
|
|
372
|
+
transform: translateX(-50%);
|
|
373
|
+
transition: opacity 0.2s;
|
|
668
374
|
}
|
|
669
375
|
|
|
670
|
-
.
|
|
671
|
-
font-size: 18px;
|
|
672
|
-
font-weight: 700;
|
|
673
|
-
}
|
|
376
|
+
.toast.is-on { opacity: 1; }
|
|
674
377
|
|
|
675
|
-
.
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
378
|
+
.notice {
|
|
379
|
+
position: absolute;
|
|
380
|
+
inset: 0;
|
|
381
|
+
display: grid;
|
|
382
|
+
place-content: center;
|
|
383
|
+
gap: 8px;
|
|
384
|
+
padding: 32px;
|
|
385
|
+
background: var(--x-canvas);
|
|
386
|
+
font-size: 15px;
|
|
387
|
+
line-height: 1.6;
|
|
388
|
+
text-align: center;
|
|
679
389
|
}
|
|
680
390
|
|
|
681
|
-
.
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
font-size: 13px;
|
|
686
|
-
color: var(--text-secondary);
|
|
687
|
-
}
|
|
391
|
+
.notice-mark { justify-self: center; width: auto; height: 72px; margin-bottom: 8px; }
|
|
392
|
+
.notice strong { font: 800 24px/1.2 var(--font-display); }
|
|
393
|
+
.notice p { max-width: 34em; margin: 0; color: var(--x-text-soft); }
|
|
394
|
+
.notice code { padding: 2px 6px; border-radius: 4px; background: var(--x-raised); color: var(--x-text); font-size: 14px; }
|
|
688
395
|
|
|
689
|
-
.
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
396
|
+
/* Phones: the toolbar keeps its icons only. */
|
|
397
|
+
@media (max-width: 520px) {
|
|
398
|
+
.toolbar { bottom: 10px; }
|
|
399
|
+
.tool span { display: none; }
|
|
400
|
+
.zoom { min-width: 48px; }
|
|
401
|
+
.live { padding: 0 6px; font-size: 0; }
|
|
402
|
+
.help { bottom: 64px; }
|
|
693
403
|
}
|
|
694
404
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
background: rgba(255, 255, 255, 0.08);
|
|
698
|
-
border: 1px solid var(--border-subtle);
|
|
699
|
-
padding: 3px 7px;
|
|
700
|
-
border-radius: 6px;
|
|
701
|
-
font-size: 11px;
|
|
702
|
-
color: var(--text-primary);
|
|
405
|
+
@media (prefers-reduced-motion: reduce) {
|
|
406
|
+
.toast { transition: none; }
|
|
703
407
|
}
|