proto-plugin 0.1.1 → 0.1.3
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/AGENTS.md +308 -29
- package/README.md +48 -6
- package/package.json +2 -1
- package/scripts/lib/host-config.example.sh +1 -1
- package/scripts/verify-prototype-preview-states.mjs +57 -0
- package/src/components/platform-ui/controls-panel-select.tsx +4 -3
- package/src/components/platform-ui/prototype-tool-dialog.tsx +117 -0
- package/src/components/platform-ui/sidebar.tsx +34 -16
- package/src/components/prototype-gallery-client.tsx +77 -37
- package/src/components/prototypes/design-exploration-variant-preview-shell.tsx +43 -0
- package/src/components/prototypes/prototype-brief-field.tsx +33 -0
- package/src/components/prototypes/prototype-change-log-panel.tsx +59 -55
- package/src/components/prototypes/prototype-comment-provider.tsx +0 -1
- package/src/components/prototypes/prototype-comment-storage-empty-state.tsx +41 -0
- package/src/components/prototypes/prototype-create-exploration-modal.tsx +41 -64
- package/src/components/prototypes/prototype-create-prototype-modal.tsx +102 -0
- package/src/components/prototypes/prototype-create-state-modal.tsx +31 -70
- package/src/components/prototypes/prototype-default-state-map-page.tsx +4 -4
- package/src/components/prototypes/prototype-design-brief-modal.tsx +10 -10
- package/src/components/prototypes/prototype-design-brief-panel.tsx +261 -231
- package/src/components/prototypes/prototype-floating-pill.module.scss +16 -9
- package/src/components/prototypes/prototype-mobbin-gallery.tsx +18 -2
- package/src/components/prototypes/prototype-review-chrome.tsx +21 -2
- package/src/components/prototypes/prototype-review-sidebar.tsx +7 -37
- package/src/components/prototypes/prototype-spec-panel-content.tsx +5 -5
- package/src/components/prototypes/prototype-spec-panel-empty-state.tsx +53 -0
- package/src/components/prototypes/prototype-state-canvas-overlay.module.scss +20 -47
- package/src/components/prototypes/prototype-state-canvas-overlay.tsx +4 -42
- package/src/components/prototypes/prototype-variant-explorer.tsx +32 -78
- package/src/components/prototypes/prototype-vercel-preview-modal.tsx +4 -3
- package/src/components/prototypes/state-map-annotation-tooltip.module.scss +7 -7
- package/src/components/shell/prototype-component-library-empty-state.tsx +59 -0
- package/src/components/shell/prototype-gallery-nav.tsx +124 -0
- package/src/components/shell/prototype-gallery-shell.tsx +45 -13
- package/src/components/shell/prototype-link-source-modal.tsx +100 -0
- package/src/components/shell/prototype-plugin-update-popup.tsx +74 -0
- package/src/components/ui/button.tsx +4 -2
- package/src/components/ui/dialog.tsx +44 -5
- package/src/components/ui/dropdown-menu.tsx +2 -2
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/option-select.tsx +3 -3
- package/src/components/ui/scroll-area.tsx +1 -1
- package/src/components/ui/separator.tsx +1 -1
- package/src/components/ui/slider.tsx +1 -1
- package/src/components/ui/switch.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -1
- package/src/components/ui/toggle-group.tsx +1 -1
- package/src/components/ui/tooltip.tsx +2 -2
- package/src/config/create-prototype-component-library-page.tsx +74 -0
- package/src/config/create-prototype-gallery-page.tsx +26 -23
- package/src/config/create-prototype-host-app.tsx +3 -15
- package/src/config/create-prototype-site-layout.tsx +14 -1
- package/src/config/create-prototype-state-map-page.tsx +44 -0
- package/src/config/prototype-site-layout-client.tsx +23 -6
- package/src/config/with-prototype.ts +54 -0
- package/src/index.ts +71 -11
- package/src/lib/copy-text-with-attachments.ts +35 -0
- package/src/lib/format-source-directory-name.ts +12 -0
- package/src/lib/platform-ui/sidebar-interactive-cursor.ts +19 -0
- package/src/lib/pr-split/build-pr-split-plan-prompt.ts +81 -0
- package/src/lib/pr-split/pr-split-highlight.ts +3 -0
- package/src/lib/prototype-comments/core/annotation-target.ts +12 -3
- package/src/lib/prototype-comments/core/comment-capture-blocked.ts +24 -0
- package/src/lib/prototype-comments/core/screenshot.ts +68 -31
- package/src/lib/prototype-comments/core/storage.ts +3 -6
- package/src/lib/prototype-comments/core/types.ts +2 -0
- package/src/lib/prototype-comments/hooks/useLayoutShift.ts +9 -2
- package/src/lib/prototype-comments/react/CommentCaptureToolbar.tsx +45 -10
- package/src/lib/prototype-comments/react/CommentProvider.tsx +19 -0
- package/src/lib/prototype-comments/ui/CommentModeToggleButton.tsx +34 -0
- package/src/lib/prototype-comments/ui/CommentsGrid.tsx +8 -16
- package/src/lib/prototype-comments/ui/CommentsSidebar.tsx +5 -19
- package/src/lib/prototype-comments/ui/capture-styles.module.scss +5 -1
- package/src/lib/prototype-comments/ui/comments-grid-card.module.scss +0 -7
- package/src/lib/prototypes/build-design-exploration-renderers.ts +44 -0
- package/src/lib/prototypes/changelog-description-prompt.ts +58 -0
- package/src/lib/prototypes/comment-storage-setup-prompt.ts +124 -0
- package/src/lib/prototypes/create-prototype-prompt.ts +96 -0
- package/src/lib/prototypes/create-prototype-registry.ts +5 -0
- package/src/lib/prototypes/design-exploration-types.ts +261 -10
- package/src/lib/prototypes/link-source-prompt.ts +93 -0
- package/src/lib/prototypes/populate-component-library-prompt.ts +64 -0
- package/src/lib/prototypes/proto-plugin-version.ts +19 -0
- package/src/lib/prototypes/prototype-config-types.ts +2 -0
- package/src/lib/prototypes/prototype-layout-classes.ts +19 -0
- package/src/lib/prototypes/prototype-preview-state-registry.ts +5 -2
- package/src/lib/prototypes/prototype-review-context.tsx +4 -4
- package/src/lib/prototypes/prototype-state-canvas-constants.ts +1 -1
- package/src/lib/prototypes/prototype-state-canvas-types.ts +0 -2
- package/src/lib/prototypes/prototype-storage-status.ts +31 -0
- package/src/lib/prototypes/sort-prototypes-by-creation-date.ts +43 -0
- package/src/lib/prototypes/upgrade-proto-plugin-prompt.ts +40 -0
- package/src/lib/prototypes/use-proto-plugin-version-check.ts +67 -0
- package/src/lib/prototypes/use-prototype-tool-theme.tsx +1 -1
- package/src/lib/prototypes/use-toolbar-hover-panel.ts +12 -1
- package/src/lib/prototypes/variant-set-lucide-icon.tsx +24 -0
- package/src/lib/tool-portal.ts +24 -0
- package/src/lib/use-copy-to-clipboard.ts +7 -13
- package/src/server/create-host-api-route.ts +14 -16
- package/src/server/create-prototype-api-routes.ts +0 -115
- package/src/server/proto-plugin-version-route.ts +145 -0
- package/src/server/prototype-storage-status-route.ts +29 -0
- package/src/server.ts +2 -8
- package/src/styles/globals.css +357 -69
- package/src/lib/prototypes/design-exploration-default-storage.ts +0 -68
- package/src/lib/prototypes/design-exploration-default.ts +0 -51
- package/src/lib/prototypes/use-design-exploration-default.ts +0 -114
- package/src/server/redis/prototype-design-exploration-default.ts +0 -32
package/src/styles/globals.css
CHANGED
|
@@ -30,20 +30,35 @@
|
|
|
30
30
|
--tool-chrome-pink-highlight: rgba(255, 70, 100, 0.13);
|
|
31
31
|
--tool-chrome-yellow-highlight: rgba(217, 174, 0, 0.15);
|
|
32
32
|
--tool-chrome-blue-highlight: rgba(0, 151, 254, 0.13);
|
|
33
|
-
--tool-chrome-gray-highlight: rgba(255, 255, 255, 0.
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
--tool-chrome-gray-highlight: rgba(255, 255, 255, 0.08);
|
|
34
|
+
--tool-chrome-button-bg: rgba(255, 255, 255, 0.14);
|
|
35
|
+
--tool-chrome-button-text: rgba(255, 255, 255, 0.92);
|
|
36
|
+
--tool-chrome-button-bg-hover: rgba(255, 255, 255, 0.22);
|
|
37
|
+
--tool-chrome-button-text-hover: #ffffff;
|
|
38
|
+
|
|
39
|
+
/* Tool chrome surfaces — deep dark palette.
|
|
40
|
+
Chrome (ground) is darkest for sidebar + header; content (bg) is a lighter
|
|
41
|
+
elevated panel for the gallery grid and review preview frame.
|
|
42
|
+
|
|
43
|
+
Neutral scale (measured against the #151515 content surface):
|
|
44
|
+
heading #f0f0f0 ~13:1 crisp titles
|
|
45
|
+
text #d0d0d0 ~9:1 body copy
|
|
46
|
+
muted #a0a0a0 ~5:1 labels, descriptions (AA)
|
|
47
|
+
icon #9a9a9a glyphs, dimmer than body
|
|
48
|
+
border #333333 hairline dividers
|
|
49
|
+
strong #454545 inputs, structural edges */
|
|
36
50
|
--tool-chrome-ground: #121212;
|
|
37
|
-
--tool-chrome-bg: #
|
|
38
|
-
--tool-chrome-surface: #
|
|
51
|
+
--tool-chrome-bg: #151515;
|
|
52
|
+
--tool-chrome-surface: #1c1c1c;
|
|
39
53
|
--tool-chrome-surface-muted: #181818;
|
|
40
|
-
--tool-chrome-text: #
|
|
41
|
-
--tool-chrome-text-heading: #
|
|
42
|
-
--tool-chrome-text-muted: #
|
|
43
|
-
--tool-chrome-icon: #
|
|
44
|
-
--tool-chrome-icon-hover: #
|
|
54
|
+
--tool-chrome-text: #d0d0d0;
|
|
55
|
+
--tool-chrome-text-heading: #f0f0f0;
|
|
56
|
+
--tool-chrome-text-muted: #9c9c9c;
|
|
57
|
+
--tool-chrome-icon: #9a9a9a;
|
|
58
|
+
--tool-chrome-icon-hover: #d4d4d4;
|
|
45
59
|
--tool-chrome-border: #333333;
|
|
46
|
-
--tool-chrome-border-strong: #
|
|
60
|
+
--tool-chrome-border-strong: #454545;
|
|
61
|
+
--tool-dialog-separator: #404040;
|
|
47
62
|
--prototype-state-canvas-edge: var(--tool-chrome-icon-hover);
|
|
48
63
|
|
|
49
64
|
--prototype-ground: var(--tool-chrome-ground);
|
|
@@ -51,10 +66,10 @@
|
|
|
51
66
|
--tool-review-card-radius: 6px;
|
|
52
67
|
--tool-review-card-shadow:
|
|
53
68
|
0 1px 2px rgb(0 0 0 / 0.18),
|
|
54
|
-
0 0 0 1px
|
|
69
|
+
0 0 0 1px var(--tool-chrome-border);
|
|
55
70
|
--tool-review-card-shadow-hover:
|
|
56
71
|
0 1px 3px rgb(0 0 0 / 0.22),
|
|
57
|
-
0 0 0 1px
|
|
72
|
+
0 0 0 1px var(--tool-chrome-border-strong);
|
|
58
73
|
--radius: 0.625rem;
|
|
59
74
|
|
|
60
75
|
font-family: var(--tool-font-body);
|
|
@@ -68,14 +83,14 @@
|
|
|
68
83
|
--bg-main: var(--tool-chrome-bg);
|
|
69
84
|
--bg-top: var(--tool-chrome-surface);
|
|
70
85
|
--bg-subtle: var(--tool-chrome-surface-muted);
|
|
71
|
-
--bg-layered: #
|
|
86
|
+
--bg-layered: #1c1c1c;
|
|
72
87
|
--bg-invert: var(--tool-chrome-text-heading);
|
|
73
88
|
--bg-white: var(--tool-chrome-bg);
|
|
74
89
|
|
|
75
90
|
--text-primary: var(--tool-chrome-text);
|
|
76
91
|
--text-secondary: var(--tool-chrome-text-muted);
|
|
77
|
-
--text-tertiary: #
|
|
78
|
-
--text-invert: #
|
|
92
|
+
--text-tertiary: #8a8a8a;
|
|
93
|
+
--text-invert: #0d0d0d;
|
|
79
94
|
|
|
80
95
|
--border-faint: var(--tool-chrome-border);
|
|
81
96
|
--border-solid: var(--tool-chrome-border);
|
|
@@ -95,6 +110,29 @@
|
|
|
95
110
|
--shadow-md: 0 4px 12px 0 rgb(0 0 0 / 0.24);
|
|
96
111
|
--shadow-lg: 0 8px 24px 0 rgb(0 0 0 / 0.28);
|
|
97
112
|
|
|
113
|
+
/*
|
|
114
|
+
* Host coss-ui @theme inline resolves utilities via shadcn tokens (--background,
|
|
115
|
+
* --foreground, …). Bridge them to tool chrome here; source previews reset
|
|
116
|
+
* these inside [data-prototype-screenshot] / [data-prototype-source-surface].
|
|
117
|
+
*/
|
|
118
|
+
--background: var(--tool-chrome-bg);
|
|
119
|
+
--foreground: var(--tool-chrome-text-heading);
|
|
120
|
+
--card: var(--tool-chrome-surface);
|
|
121
|
+
--card-foreground: var(--tool-chrome-text-heading);
|
|
122
|
+
--popover: var(--tool-chrome-surface);
|
|
123
|
+
--popover-foreground: var(--tool-chrome-text-heading);
|
|
124
|
+
--secondary: var(--tool-chrome-surface-muted);
|
|
125
|
+
--secondary-foreground: var(--tool-chrome-text-heading);
|
|
126
|
+
--muted: var(--tool-chrome-surface-muted);
|
|
127
|
+
--muted-foreground: var(--tool-chrome-text-muted);
|
|
128
|
+
--accent: var(--tool-chrome-gray-highlight);
|
|
129
|
+
--accent-foreground: var(--tool-chrome-text-heading);
|
|
130
|
+
--destructive: var(--tool-chrome-pink);
|
|
131
|
+
--destructive-foreground: #ffffff;
|
|
132
|
+
--border: var(--tool-chrome-border);
|
|
133
|
+
--input: var(--tool-chrome-border-strong);
|
|
134
|
+
--ring: var(--tool-chrome-text-heading);
|
|
135
|
+
|
|
98
136
|
/* Tailwind @theme inline */
|
|
99
137
|
--color-background: var(--tool-chrome-bg);
|
|
100
138
|
--color-foreground: var(--tool-chrome-text);
|
|
@@ -127,68 +165,129 @@
|
|
|
127
165
|
--color-bg-main: var(--tool-chrome-bg);
|
|
128
166
|
--color-bg-top: var(--tool-chrome-surface);
|
|
129
167
|
--color-bg-subtle: var(--tool-chrome-surface-muted);
|
|
130
|
-
--color-bg-layered: #
|
|
168
|
+
--color-bg-layered: #1c1c1c;
|
|
131
169
|
--color-bg-invert: var(--tool-chrome-text-heading);
|
|
132
170
|
--color-bg-white: var(--tool-chrome-bg);
|
|
133
171
|
--color-text-primary: var(--tool-chrome-text);
|
|
134
172
|
--color-text-secondary: var(--tool-chrome-text-muted);
|
|
135
|
-
--color-text-tertiary: #
|
|
173
|
+
--color-text-tertiary: #8a8a8a;
|
|
136
174
|
--color-text-invert: #121212;
|
|
137
175
|
|
|
138
176
|
color: var(--tool-chrome-text);
|
|
139
|
-
background-color: var(--tool-chrome-
|
|
177
|
+
background-color: var(--tool-chrome-bg);
|
|
140
178
|
}
|
|
141
179
|
|
|
142
180
|
[data-prototype-root] * {
|
|
143
181
|
font-family: inherit;
|
|
144
182
|
}
|
|
145
183
|
|
|
146
|
-
|
|
184
|
+
/*
|
|
185
|
+
* Sidebar chrome — a content-dense reading surface, so it pins every semantic
|
|
186
|
+
* "content" token to the bright end of the neutral scale (headings crisp, body
|
|
187
|
+
* legible, muted labels still ~5:1). Borders step up one notch from the base so
|
|
188
|
+
* dividers and input edges read clearly against the elevated ground, without
|
|
189
|
+
* turning into harsh wireframe lines.
|
|
190
|
+
*/
|
|
191
|
+
[data-prototype-review-sidebar],
|
|
192
|
+
[data-comments-sidebar],
|
|
193
|
+
[data-platform-sidebar] {
|
|
147
194
|
font-family: var(--tool-font-body);
|
|
148
195
|
--font-sans: var(--tool-font-body);
|
|
149
196
|
--font-display: var(--tool-font-display);
|
|
150
197
|
--font-mono: var(--tool-font-body);
|
|
151
198
|
|
|
152
199
|
--tool-chrome-icon: #b0b0b0;
|
|
153
|
-
--tool-chrome-icon-hover: #
|
|
200
|
+
--tool-chrome-icon-hover: #e6e6e6;
|
|
201
|
+
--tool-chrome-gray-highlight: rgba(255, 255, 255, 0.09);
|
|
202
|
+
--tool-chrome-border: #3a3a3a;
|
|
203
|
+
--tool-chrome-border-strong: #4d4d4d;
|
|
204
|
+
--tool-chrome-input-surface: rgba(255, 255, 255, 0.035);
|
|
154
205
|
|
|
155
|
-
color: var(--tool-chrome-
|
|
156
|
-
|
|
157
|
-
--tool-chrome-text: var(--tool-chrome-icon-hover);
|
|
158
|
-
--tool-chrome-text-heading: var(--tool-chrome-icon-hover);
|
|
159
|
-
--tool-chrome-text-muted: var(--tool-chrome-icon);
|
|
206
|
+
color: var(--tool-chrome-text);
|
|
160
207
|
|
|
161
208
|
--bg-ground: var(--tool-chrome-ground);
|
|
162
209
|
--bg-main: var(--tool-chrome-bg);
|
|
163
210
|
--bg-top: var(--tool-chrome-bg);
|
|
164
211
|
--bg-subtle: var(--tool-chrome-surface-muted);
|
|
165
|
-
--bg-layered: #
|
|
212
|
+
--bg-layered: #1a1a1a;
|
|
166
213
|
--border-faint: var(--tool-chrome-border);
|
|
167
214
|
--border-solid: var(--tool-chrome-border);
|
|
168
215
|
--border-medium: var(--tool-chrome-border-strong);
|
|
169
216
|
|
|
170
|
-
--text-primary: var(--tool-chrome-
|
|
171
|
-
--text-secondary: var(--tool-chrome-
|
|
172
|
-
--text-tertiary:
|
|
217
|
+
--text-primary: var(--tool-chrome-text-heading);
|
|
218
|
+
--text-secondary: var(--tool-chrome-text);
|
|
219
|
+
--text-tertiary: var(--tool-chrome-text-muted);
|
|
220
|
+
|
|
221
|
+
--foreground: var(--tool-chrome-text-heading);
|
|
222
|
+
--muted-foreground: var(--tool-chrome-text-muted);
|
|
223
|
+
--border: var(--tool-chrome-border);
|
|
224
|
+
--input: var(--tool-chrome-border-strong);
|
|
173
225
|
|
|
174
226
|
--color-background: var(--tool-chrome-bg);
|
|
175
|
-
--color-foreground: var(--tool-chrome-
|
|
227
|
+
--color-foreground: var(--tool-chrome-text-heading);
|
|
176
228
|
--color-card: var(--tool-chrome-surface);
|
|
177
|
-
--color-card-foreground: var(--tool-chrome-
|
|
229
|
+
--color-card-foreground: var(--tool-chrome-text-heading);
|
|
178
230
|
--color-muted: var(--tool-chrome-surface-muted);
|
|
179
|
-
--color-muted-foreground: var(--tool-chrome-
|
|
231
|
+
--color-muted-foreground: var(--tool-chrome-text-muted);
|
|
180
232
|
--color-accent: var(--tool-chrome-gray-highlight);
|
|
181
|
-
--color-accent-foreground: var(--tool-chrome-
|
|
233
|
+
--color-accent-foreground: var(--tool-chrome-text-heading);
|
|
182
234
|
--color-border: var(--tool-chrome-border);
|
|
183
|
-
--color-
|
|
235
|
+
--color-border-faint: var(--tool-chrome-border);
|
|
236
|
+
--color-border-solid: var(--tool-chrome-border);
|
|
237
|
+
--color-border-medium: var(--tool-chrome-border-strong);
|
|
238
|
+
--color-input: var(--tool-chrome-border-strong);
|
|
239
|
+
--color-ring: var(--tool-chrome-text-heading);
|
|
184
240
|
--color-bg-ground: var(--tool-chrome-ground);
|
|
185
241
|
--color-bg-main: var(--tool-chrome-bg);
|
|
186
242
|
--color-bg-top: var(--tool-chrome-bg);
|
|
187
243
|
--color-bg-subtle: var(--tool-chrome-surface-muted);
|
|
188
|
-
--color-bg-layered: #
|
|
189
|
-
--color-text-primary: var(--tool-chrome-
|
|
190
|
-
--color-text-secondary: var(--tool-chrome-
|
|
191
|
-
--color-text-tertiary:
|
|
244
|
+
--color-bg-layered: #1a1a1a;
|
|
245
|
+
--color-text-primary: var(--tool-chrome-text-heading);
|
|
246
|
+
--color-text-secondary: var(--tool-chrome-text);
|
|
247
|
+
--color-text-tertiary: var(--tool-chrome-text-muted);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* Give brief/prompt inputs a faint filled surface so the field reads as an
|
|
251
|
+
affordance rather than an empty hairline rectangle. */
|
|
252
|
+
[data-prototype-review-sidebar] textarea:not([data-prototype-screenshot] *),
|
|
253
|
+
[data-comments-sidebar] textarea:not([data-prototype-screenshot] *),
|
|
254
|
+
[data-platform-sidebar] textarea:not([data-prototype-screenshot] *) {
|
|
255
|
+
background-color: var(--tool-chrome-input-surface);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
[data-prototype-review-sidebar] :is(
|
|
259
|
+
button:not(:disabled),
|
|
260
|
+
[role="button"]:not([aria-disabled="true"]),
|
|
261
|
+
a[href],
|
|
262
|
+
summary,
|
|
263
|
+
label:has([role="switch"]),
|
|
264
|
+
label:has(input[type="checkbox"])
|
|
265
|
+
),
|
|
266
|
+
[data-comments-sidebar] :is(
|
|
267
|
+
button:not(:disabled),
|
|
268
|
+
[role="button"]:not([aria-disabled="true"]),
|
|
269
|
+
a[href],
|
|
270
|
+
summary,
|
|
271
|
+
label:has([role="switch"]),
|
|
272
|
+
label:has(input[type="checkbox"])
|
|
273
|
+
),
|
|
274
|
+
[data-platform-sidebar] :is(
|
|
275
|
+
button:not(:disabled),
|
|
276
|
+
[role="button"]:not([aria-disabled="true"]),
|
|
277
|
+
a[href],
|
|
278
|
+
summary,
|
|
279
|
+
label:has([role="switch"]),
|
|
280
|
+
label:has(input[type="checkbox"])
|
|
281
|
+
),
|
|
282
|
+
#prototype-comments-sidebar-root :is(
|
|
283
|
+
button:not(:disabled),
|
|
284
|
+
[role="button"]:not([aria-disabled="true"]),
|
|
285
|
+
a[href],
|
|
286
|
+
summary,
|
|
287
|
+
label:has([role="switch"]),
|
|
288
|
+
label:has(input[type="checkbox"])
|
|
289
|
+
) {
|
|
290
|
+
cursor: pointer;
|
|
192
291
|
}
|
|
193
292
|
|
|
194
293
|
[data-prototype-root] ::selection {
|
|
@@ -198,6 +297,10 @@
|
|
|
198
297
|
|
|
199
298
|
[data-prototype-root][data-prototype-comment-theme="light"] {
|
|
200
299
|
--tool-chrome-gray-highlight: rgba(0, 0, 0, 0.05);
|
|
300
|
+
--tool-chrome-button-bg: rgba(0, 0, 0, 0.06);
|
|
301
|
+
--tool-chrome-button-text: rgba(0, 0, 0, 0.72);
|
|
302
|
+
--tool-chrome-button-bg-hover: rgba(0, 0, 0, 0.1);
|
|
303
|
+
--tool-chrome-button-text-hover: rgba(0, 0, 0, 0.92);
|
|
201
304
|
--tool-chrome-ground: #f5f5f5;
|
|
202
305
|
--tool-chrome-bg: #ffffff;
|
|
203
306
|
--tool-chrome-surface: #ffffff;
|
|
@@ -209,6 +312,7 @@
|
|
|
209
312
|
--tool-chrome-icon-hover: rgba(0, 0, 0, 0.85);
|
|
210
313
|
--tool-chrome-border: rgba(0, 0, 0, 0.1);
|
|
211
314
|
--tool-chrome-border-strong: rgba(0, 0, 0, 0.16);
|
|
315
|
+
--tool-dialog-separator: rgba(0, 0, 0, 0.12);
|
|
212
316
|
--prototype-state-canvas-edge: rgba(0, 0, 0, 0.22);
|
|
213
317
|
|
|
214
318
|
--bg-ground: var(--tool-chrome-ground);
|
|
@@ -231,6 +335,24 @@
|
|
|
231
335
|
--tool-review-card-shadow: 0 1px 2px rgb(0 0 0 / 0.04);
|
|
232
336
|
--tool-review-card-shadow-hover: 0 2px 4px rgb(0 0 0 / 0.06);
|
|
233
337
|
|
|
338
|
+
--background: var(--tool-chrome-bg);
|
|
339
|
+
--foreground: var(--tool-chrome-text-heading);
|
|
340
|
+
--card: var(--tool-chrome-surface);
|
|
341
|
+
--card-foreground: var(--tool-chrome-text-heading);
|
|
342
|
+
--popover: var(--tool-chrome-surface);
|
|
343
|
+
--popover-foreground: var(--tool-chrome-text-heading);
|
|
344
|
+
--secondary: var(--tool-chrome-surface-muted);
|
|
345
|
+
--secondary-foreground: var(--tool-chrome-text-heading);
|
|
346
|
+
--muted: var(--tool-chrome-surface-muted);
|
|
347
|
+
--muted-foreground: var(--tool-chrome-text-muted);
|
|
348
|
+
--accent: var(--tool-chrome-gray-highlight);
|
|
349
|
+
--accent-foreground: var(--tool-chrome-text-heading);
|
|
350
|
+
--destructive: var(--tool-chrome-pink);
|
|
351
|
+
--destructive-foreground: #ffffff;
|
|
352
|
+
--border: var(--tool-chrome-border);
|
|
353
|
+
--input: var(--tool-chrome-border-strong);
|
|
354
|
+
--ring: var(--tool-chrome-text-heading);
|
|
355
|
+
|
|
234
356
|
--color-background: var(--tool-chrome-bg);
|
|
235
357
|
--color-foreground: var(--tool-chrome-text-heading);
|
|
236
358
|
--color-card: var(--tool-chrome-surface);
|
|
@@ -258,7 +380,7 @@
|
|
|
258
380
|
--color-text-tertiary: rgba(0, 0, 0, 0.45);
|
|
259
381
|
|
|
260
382
|
color: var(--tool-chrome-text);
|
|
261
|
-
background-color: var(--tool-chrome-
|
|
383
|
+
background-color: var(--tool-chrome-bg);
|
|
262
384
|
}
|
|
263
385
|
|
|
264
386
|
[data-prototype-root][data-prototype-comment-theme="light"] ::selection {
|
|
@@ -368,7 +490,7 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
368
490
|
|
|
369
491
|
@media (hover: hover) and (pointer: fine) {
|
|
370
492
|
[data-prototype-root] .tool-toolbar-button:hover {
|
|
371
|
-
background:
|
|
493
|
+
background: var(--tool-chrome-surface);
|
|
372
494
|
color: var(--tool-chrome-icon-hover);
|
|
373
495
|
}
|
|
374
496
|
}
|
|
@@ -445,8 +567,28 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
445
567
|
}
|
|
446
568
|
|
|
447
569
|
[data-prototype-root] .tool-variant-card.is-active {
|
|
448
|
-
border
|
|
449
|
-
box-shadow:
|
|
570
|
+
border: 2px solid var(--tool-chrome-blue);
|
|
571
|
+
box-shadow: none;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
[data-prototype-root] .tool-variant-default-badge {
|
|
575
|
+
color: var(--tool-chrome-blue);
|
|
576
|
+
font-size: 0.625rem;
|
|
577
|
+
font-weight: 600;
|
|
578
|
+
letter-spacing: 0.06em;
|
|
579
|
+
line-height: 1;
|
|
580
|
+
text-transform: uppercase;
|
|
581
|
+
white-space: nowrap;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
[data-prototype-root] .tool-variant-original-badge {
|
|
585
|
+
color: var(--tool-chrome-text-muted);
|
|
586
|
+
font-size: 0.625rem;
|
|
587
|
+
font-weight: 600;
|
|
588
|
+
letter-spacing: 0.06em;
|
|
589
|
+
line-height: 1;
|
|
590
|
+
text-transform: uppercase;
|
|
591
|
+
white-space: nowrap;
|
|
450
592
|
}
|
|
451
593
|
|
|
452
594
|
[data-prototype-root] .tool-variant-card [data-prototype-screenshot] {
|
|
@@ -475,26 +617,90 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
475
617
|
border-radius: calc(var(--radius) + 4px);
|
|
476
618
|
border: 1px solid var(--tool-chrome-border);
|
|
477
619
|
background: var(--tool-chrome-bg);
|
|
620
|
+
color: var(--tool-chrome-text);
|
|
621
|
+
color-scheme: dark;
|
|
478
622
|
box-shadow:
|
|
479
623
|
var(--shadow-lg),
|
|
480
|
-
0 0 0 1px #
|
|
624
|
+
0 0 0 1px #2a2a2a;
|
|
625
|
+
|
|
626
|
+
/*
|
|
627
|
+
* Product preview surfaces reset shadcn tokens to light values. Re-bridge the
|
|
628
|
+
* full tool chrome token set so modal chrome matches the gallery/home screen.
|
|
629
|
+
*/
|
|
630
|
+
--bg-main: var(--tool-chrome-bg);
|
|
631
|
+
--bg-top: var(--tool-chrome-surface);
|
|
632
|
+
--bg-subtle: var(--tool-chrome-surface-muted);
|
|
633
|
+
--text-primary: var(--tool-chrome-text);
|
|
634
|
+
--text-secondary: var(--tool-chrome-text-muted);
|
|
635
|
+
--border-faint: var(--tool-chrome-border);
|
|
636
|
+
--border-solid: var(--tool-chrome-border);
|
|
637
|
+
--border-medium: var(--tool-chrome-border-strong);
|
|
638
|
+
--primary: var(--tool-chrome-blue);
|
|
639
|
+
--primary-foreground: #ffffff;
|
|
640
|
+
--primary-dark: var(--tool-chrome-blue-deep);
|
|
641
|
+
--focus-ring: var(--tool-chrome-text-heading);
|
|
642
|
+
--active: var(--tool-chrome-text-heading);
|
|
643
|
+
--input-border: var(--tool-chrome-border-strong);
|
|
644
|
+
|
|
645
|
+
--background: var(--tool-chrome-bg);
|
|
646
|
+
--foreground: var(--tool-chrome-text-heading);
|
|
647
|
+
--card: var(--tool-chrome-surface);
|
|
648
|
+
--card-foreground: var(--tool-chrome-text-heading);
|
|
649
|
+
--popover: var(--tool-chrome-surface);
|
|
650
|
+
--popover-foreground: var(--tool-chrome-text-heading);
|
|
651
|
+
--secondary: var(--tool-chrome-surface-muted);
|
|
652
|
+
--secondary-foreground: var(--tool-chrome-text-heading);
|
|
653
|
+
--muted: var(--tool-chrome-surface-muted);
|
|
654
|
+
--muted-foreground: var(--tool-chrome-text-muted);
|
|
655
|
+
--accent: var(--tool-chrome-gray-highlight);
|
|
656
|
+
--accent-foreground: var(--tool-chrome-text-heading);
|
|
657
|
+
--destructive: var(--tool-chrome-pink);
|
|
658
|
+
--destructive-foreground: #ffffff;
|
|
659
|
+
--border: var(--tool-chrome-border);
|
|
660
|
+
--input: var(--tool-chrome-border-strong);
|
|
661
|
+
--ring: var(--tool-chrome-text-heading);
|
|
662
|
+
|
|
663
|
+
--color-background: var(--tool-chrome-bg);
|
|
664
|
+
--color-foreground: var(--tool-chrome-text-heading);
|
|
665
|
+
--color-card: var(--tool-chrome-surface);
|
|
666
|
+
--color-card-foreground: var(--tool-chrome-text-heading);
|
|
667
|
+
--color-popover: var(--tool-chrome-surface);
|
|
668
|
+
--color-popover-foreground: var(--tool-chrome-text-heading);
|
|
669
|
+
--color-primary: var(--tool-chrome-blue);
|
|
670
|
+
--color-primary-foreground: #ffffff;
|
|
671
|
+
--color-primary-dark: var(--tool-chrome-blue-deep);
|
|
672
|
+
--color-secondary: var(--tool-chrome-surface-muted);
|
|
673
|
+
--color-secondary-foreground: var(--tool-chrome-text-heading);
|
|
674
|
+
--color-muted: var(--tool-chrome-surface-muted);
|
|
675
|
+
--color-muted-foreground: var(--tool-chrome-text-muted);
|
|
676
|
+
--color-accent: var(--tool-chrome-gray-highlight);
|
|
677
|
+
--color-accent-foreground: var(--tool-chrome-text-heading);
|
|
678
|
+
--color-destructive: var(--tool-chrome-pink);
|
|
679
|
+
--color-destructive-foreground: #ffffff;
|
|
680
|
+
--color-border: var(--tool-chrome-border);
|
|
681
|
+
--color-border-faint: var(--tool-chrome-border);
|
|
682
|
+
--color-border-solid: var(--tool-chrome-border);
|
|
683
|
+
--color-border-medium: var(--tool-chrome-border-strong);
|
|
684
|
+
--color-input: var(--tool-chrome-border-strong);
|
|
685
|
+
--color-ring: var(--tool-chrome-text-heading);
|
|
686
|
+
--color-focus-ring: var(--tool-chrome-text-heading);
|
|
687
|
+
--color-active: var(--tool-chrome-text-heading);
|
|
688
|
+
--color-bg-main: var(--tool-chrome-bg);
|
|
689
|
+
--color-bg-top: var(--tool-chrome-surface);
|
|
690
|
+
--color-bg-subtle: var(--tool-chrome-surface-muted);
|
|
691
|
+
--color-text-primary: var(--tool-chrome-text);
|
|
692
|
+
--color-text-secondary: var(--tool-chrome-text-muted);
|
|
481
693
|
}
|
|
482
694
|
|
|
483
695
|
[data-prototype-root][data-prototype-comment-theme="light"] .tool-dialog-surface {
|
|
696
|
+
color-scheme: light;
|
|
484
697
|
box-shadow:
|
|
485
698
|
var(--shadow-lg),
|
|
486
699
|
0 0 0 1px rgba(0, 0, 0, 0.08);
|
|
487
700
|
}
|
|
488
701
|
|
|
489
|
-
[data-prototype-root] .tool-dialog-
|
|
490
|
-
|
|
491
|
-
flex-shrink: 0;
|
|
492
|
-
background: linear-gradient(
|
|
493
|
-
90deg,
|
|
494
|
-
var(--tool-chrome-pink) 0%,
|
|
495
|
-
var(--tool-chrome-yellow) 50%,
|
|
496
|
-
var(--tool-chrome-pink) 100%
|
|
497
|
-
);
|
|
702
|
+
[data-prototype-root] .tool-dialog-separator {
|
|
703
|
+
background: var(--tool-dialog-separator);
|
|
498
704
|
}
|
|
499
705
|
|
|
500
706
|
[data-prototype-root] [role="tablist"] {
|
|
@@ -504,7 +710,11 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
504
710
|
|
|
505
711
|
[data-prototype-root] [role="tab"][data-state="active"] {
|
|
506
712
|
color: var(--tool-chrome-text-heading);
|
|
507
|
-
|
|
713
|
+
background: color-mix(in srgb, var(--tool-chrome-blue) 12%, var(--tool-chrome-surface-muted));
|
|
714
|
+
box-shadow:
|
|
715
|
+
var(--shadow-xs),
|
|
716
|
+
inset 0 0 0 1px color-mix(in srgb, var(--tool-chrome-blue) 35%, transparent);
|
|
717
|
+
font-weight: 600;
|
|
508
718
|
}
|
|
509
719
|
|
|
510
720
|
/* Section labels — compact nav chip scale */
|
|
@@ -516,16 +726,37 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
516
726
|
color: var(--tool-chrome-text-muted);
|
|
517
727
|
}
|
|
518
728
|
|
|
519
|
-
/* State map chrome —
|
|
729
|
+
/* State map chrome — dedicated canvas bed + node footer tokens per theme. */
|
|
520
730
|
[data-prototype-root] [data-prototype-state-canvas] {
|
|
521
|
-
|
|
731
|
+
--prototype-state-map-canvas-bg: var(--tool-chrome-ground);
|
|
732
|
+
--prototype-state-map-node-surface: var(--tool-chrome-surface);
|
|
733
|
+
--prototype-state-map-node-preview-bg: var(--tool-chrome-surface-muted);
|
|
734
|
+
--prototype-state-map-node-footer-bg: var(--tool-chrome-surface-muted);
|
|
735
|
+
--prototype-state-map-node-footer-border: var(--tool-chrome-border-strong);
|
|
736
|
+
--prototype-state-map-node-footer-text: var(--tool-chrome-text-heading);
|
|
737
|
+
|
|
738
|
+
background-color: var(--prototype-state-map-canvas-bg);
|
|
522
739
|
color: var(--tool-chrome-text);
|
|
523
740
|
}
|
|
524
741
|
|
|
525
|
-
|
|
526
|
-
|
|
742
|
+
[data-prototype-root][data-prototype-comment-theme="dark"] [data-prototype-state-canvas] {
|
|
743
|
+
--prototype-state-map-canvas-bg: var(--tool-chrome-ground);
|
|
744
|
+
--prototype-state-map-node-surface: var(--tool-chrome-surface);
|
|
745
|
+
--prototype-state-map-node-preview-bg: var(--tool-chrome-surface-muted);
|
|
746
|
+
--prototype-state-map-node-footer-bg: var(--tool-chrome-surface-muted);
|
|
747
|
+
--prototype-state-map-node-footer-border: var(--tool-chrome-border-strong);
|
|
748
|
+
--prototype-state-map-node-footer-text: var(--tool-chrome-text-heading);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* Restore host prototype preview theme inside screenshot capture and source
|
|
752
|
+
surfaces (component library). Fixed product values — must not inherit tool
|
|
753
|
+
theme from [data-prototype-root]. Host apps extend with --product-* tokens. */
|
|
527
754
|
[data-prototype-root] [data-prototype-screenshot],
|
|
528
|
-
[data-prototype-screenshot]
|
|
755
|
+
[data-prototype-screenshot],
|
|
756
|
+
[data-prototype-root] [data-prototype-source-surface],
|
|
757
|
+
[data-prototype-source-surface] {
|
|
758
|
+
color-scheme: light;
|
|
759
|
+
|
|
529
760
|
--font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
530
761
|
"Segoe UI Symbol", "Noto Color Emoji";
|
|
531
762
|
--font-display: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
|
|
@@ -552,38 +783,95 @@ html.prototype-theme-transition-disable :is(*, *::before, *::after) {
|
|
|
552
783
|
--focus-ring: var(--text-primary);
|
|
553
784
|
--active: var(--color-gray-900);
|
|
554
785
|
--radius: 4px;
|
|
555
|
-
|
|
556
|
-
|
|
786
|
+
|
|
787
|
+
/* shadcn base tokens — host [data-prototype-screenshot] rules override with --product-* */
|
|
788
|
+
--background: var(--bg-main);
|
|
789
|
+
--foreground: var(--text-primary);
|
|
790
|
+
--card: var(--bg-top);
|
|
791
|
+
--card-foreground: var(--text-primary);
|
|
792
|
+
--popover: var(--bg-top);
|
|
793
|
+
--popover-foreground: var(--text-primary);
|
|
794
|
+
--secondary: var(--bg-subtle);
|
|
795
|
+
--secondary-foreground: var(--text-primary);
|
|
796
|
+
--muted: color-mix(in srgb, var(--color-gray-900) 6%, transparent);
|
|
797
|
+
--muted-foreground: var(--text-secondary);
|
|
798
|
+
--accent: color-mix(in srgb, var(--color-gray-900) 6%, transparent);
|
|
799
|
+
--accent-foreground: var(--text-primary);
|
|
800
|
+
--destructive: var(--error);
|
|
801
|
+
--destructive-foreground: #ffffff;
|
|
802
|
+
--border: var(--border-solid);
|
|
803
|
+
--input: var(--border-medium);
|
|
804
|
+
--ring: var(--border-faint);
|
|
805
|
+
|
|
806
|
+
--color-background: var(--background);
|
|
807
|
+
--color-foreground: var(--foreground);
|
|
808
|
+
--color-card: var(--card);
|
|
809
|
+
--color-card-foreground: var(--card-foreground);
|
|
810
|
+
--color-popover: var(--popover);
|
|
811
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
557
812
|
--color-primary: var(--primary);
|
|
558
|
-
--color-primary-foreground:
|
|
559
|
-
--color-
|
|
560
|
-
--color-
|
|
561
|
-
--color-
|
|
813
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
814
|
+
--color-secondary: var(--secondary);
|
|
815
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
816
|
+
--color-muted: var(--muted);
|
|
817
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
818
|
+
--color-accent: var(--accent);
|
|
819
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
820
|
+
--color-destructive: var(--destructive);
|
|
821
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
822
|
+
--color-border: var(--border);
|
|
562
823
|
--color-border-faint: var(--border-faint);
|
|
563
824
|
--color-border-solid: var(--border-solid);
|
|
564
825
|
--color-border-medium: var(--border-medium);
|
|
565
826
|
--color-border-hover: var(--border-medium);
|
|
566
|
-
--color-
|
|
827
|
+
--color-input: var(--input);
|
|
828
|
+
--color-ring: var(--ring);
|
|
567
829
|
--color-focus-ring: var(--focus-ring);
|
|
568
830
|
--color-active: var(--active);
|
|
831
|
+
--color-error: var(--error);
|
|
832
|
+
--color-success: var(--success);
|
|
569
833
|
--color-bg-bedrock: var(--bg-bedrock);
|
|
570
834
|
--color-bg-main: var(--bg-main);
|
|
571
835
|
--color-bg-top: var(--bg-top);
|
|
572
836
|
--color-bg-subtle: var(--bg-subtle);
|
|
573
837
|
--color-bg-layered: var(--bg-layered);
|
|
574
838
|
--color-bg-invert: var(--bg-invert);
|
|
575
|
-
--color-bg-white:
|
|
839
|
+
--color-bg-white: var(--bg-white);
|
|
576
840
|
--color-text-primary: var(--text-primary);
|
|
577
841
|
--color-text-secondary: var(--text-secondary);
|
|
578
842
|
--color-text-tertiary: var(--text-tertiary);
|
|
579
843
|
|
|
580
844
|
font-family: var(--font-sans);
|
|
581
845
|
font-size: initial;
|
|
582
|
-
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
[data-prototype-root] [data-prototype-screenshot],
|
|
849
|
+
[data-prototype-screenshot] {
|
|
850
|
+
color: var(--text-primary);
|
|
851
|
+
background-color: var(--bg-main);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/* Source surfaces (component-library preview cards) pin light product tokens but
|
|
855
|
+
do NOT force a background — each card supplies its own via bg utilities
|
|
856
|
+
(bg-default → white, bg-brand, etc.) so they read as light components on the
|
|
857
|
+
dark page. */
|
|
858
|
+
[data-prototype-root] [data-prototype-source-surface],
|
|
859
|
+
[data-prototype-source-surface] {
|
|
860
|
+
color: var(--text-primary);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
[data-prototype-root] [data-prototype-screenshot] ::selection,
|
|
864
|
+
[data-prototype-screenshot] ::selection,
|
|
865
|
+
[data-prototype-root] [data-prototype-source-surface] ::selection,
|
|
866
|
+
[data-prototype-source-surface] ::selection {
|
|
867
|
+
background: #b4d5fe;
|
|
868
|
+
color: var(--text-primary);
|
|
583
869
|
}
|
|
584
870
|
|
|
585
871
|
[data-prototype-root] [data-prototype-screenshot] *,
|
|
586
|
-
[data-prototype-screenshot]
|
|
872
|
+
[data-prototype-screenshot] *,
|
|
873
|
+
[data-prototype-root] [data-prototype-source-surface] *,
|
|
874
|
+
[data-prototype-source-surface] * {
|
|
587
875
|
font-family: inherit;
|
|
588
876
|
}
|
|
589
877
|
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
parseDesignExplorationDefault,
|
|
3
|
-
type DesignExplorationDefaultRecord,
|
|
4
|
-
} from "./design-exploration-default";
|
|
5
|
-
|
|
6
|
-
export class DesignExplorationDefaultStorageError extends Error {
|
|
7
|
-
constructor(message: string) {
|
|
8
|
-
super(message);
|
|
9
|
-
this.name = "DesignExplorationDefaultStorageError";
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function createDesignExplorationDefaultStorageAdapter(
|
|
14
|
-
slug: string,
|
|
15
|
-
storageKeyPrefix: string,
|
|
16
|
-
) {
|
|
17
|
-
const params = new URLSearchParams({ key: storageKeyPrefix });
|
|
18
|
-
const url = `/api/prototypes/${encodeURIComponent(slug)}/design-exploration-default?${params}`;
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
async load(): Promise<DesignExplorationDefaultRecord | null> {
|
|
22
|
-
const response = await fetch(url);
|
|
23
|
-
|
|
24
|
-
if (response.status === 503) {
|
|
25
|
-
throw new DesignExplorationDefaultStorageError(
|
|
26
|
-
"Design default storage is not configured. Set Upstash Redis env vars.",
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!response.ok) {
|
|
31
|
-
const body = (await response.json().catch(() => null)) as {
|
|
32
|
-
error?: string;
|
|
33
|
-
} | null;
|
|
34
|
-
throw new DesignExplorationDefaultStorageError(
|
|
35
|
-
body?.error ?? "Failed to load design default variant.",
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const parsed: unknown = await response.json();
|
|
40
|
-
if (parsed == null) return null;
|
|
41
|
-
|
|
42
|
-
return parseDesignExplorationDefault(parsed);
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
async save(record: DesignExplorationDefaultRecord): Promise<void> {
|
|
46
|
-
const response = await fetch(url, {
|
|
47
|
-
method: "PUT",
|
|
48
|
-
headers: { "Content-Type": "application/json" },
|
|
49
|
-
body: JSON.stringify(record),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
if (response.status === 503) {
|
|
53
|
-
throw new DesignExplorationDefaultStorageError(
|
|
54
|
-
"Design default storage is not configured. Set Upstash Redis env vars.",
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (!response.ok) {
|
|
59
|
-
const body = (await response.json().catch(() => null)) as {
|
|
60
|
-
error?: string;
|
|
61
|
-
} | null;
|
|
62
|
-
throw new DesignExplorationDefaultStorageError(
|
|
63
|
-
body?.error ?? "Failed to save design default variant.",
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|