@pugi/cli 1.0.0-alpha.241 → 1.0.0-alpha.242
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/models.json +1 -1
- package/package.json +7 -7
- package/skills/ha-prototype-web/NOTICE.md +44 -3
- package/skills/od-blog-post/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-blog-post/NOTICE.md +126 -0
- package/skills/od-blog-post/SKILL.md +81 -0
- package/skills/od-contact-widget/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-contact-widget/NOTICE.md +126 -0
- package/skills/od-contact-widget/SKILL.md +132 -0
- package/skills/od-craft/NOTICE.md +44 -3
- package/skills/od-critique/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-critique/NOTICE.md +126 -0
- package/skills/od-critique/SKILL.md +259 -0
- package/skills/od-dashboard/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-dashboard/NOTICE.md +126 -0
- package/skills/od-dashboard/SKILL.md +77 -0
- package/skills/od-design-brief/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-design-brief/NOTICE.md +126 -0
- package/skills/od-design-brief/SKILL.md +260 -0
- package/skills/od-docs-page/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-docs-page/NOTICE.md +126 -0
- package/skills/od-docs-page/SKILL.md +81 -0
- package/skills/od-email-marketing/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-email-marketing/NOTICE.md +126 -0
- package/skills/od-email-marketing/SKILL.md +85 -0
- package/skills/od-eng-runbook/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-eng-runbook/NOTICE.md +126 -0
- package/skills/od-eng-runbook/SKILL.md +52 -0
- package/skills/od-faq-page/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-faq-page/NOTICE.md +126 -0
- package/skills/od-faq-page/SKILL.md +113 -0
- package/skills/od-finance-report/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-finance-report/NOTICE.md +126 -0
- package/skills/od-finance-report/SKILL.md +62 -0
- package/skills/od-frontend-design/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-frontend-design/LICENSE.txt +177 -0
- package/skills/od-frontend-design/NOTICE.md +126 -0
- package/skills/od-frontend-design/SKILL.md +86 -0
- package/skills/od-hr-onboarding/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-hr-onboarding/NOTICE.md +126 -0
- package/skills/od-hr-onboarding/SKILL.md +53 -0
- package/skills/od-invoice/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-invoice/NOTICE.md +126 -0
- package/skills/od-invoice/SKILL.md +49 -0
- package/skills/od-kanban-board/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-kanban-board/NOTICE.md +126 -0
- package/skills/od-kanban-board/SKILL.md +51 -0
- package/skills/od-login-flow/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-login-flow/NOTICE.md +126 -0
- package/skills/od-login-flow/SKILL.md +49 -0
- package/skills/od-login-flow/references/checklist.md +19 -0
- package/skills/od-magazine-poster/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-magazine-poster/NOTICE.md +126 -0
- package/skills/od-magazine-poster/SKILL.md +90 -0
- package/skills/od-meeting-notes/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-meeting-notes/NOTICE.md +126 -0
- package/skills/od-meeting-notes/SKILL.md +48 -0
- package/skills/od-mobile-app/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-mobile-app/NOTICE.md +126 -0
- package/skills/od-mobile-app/SKILL.md +103 -0
- package/skills/od-mobile-app/assets/template.html +442 -0
- package/skills/od-mobile-app/references/checklist.md +46 -0
- package/skills/od-mobile-app/references/layouts.md +312 -0
- package/skills/od-mobile-onboarding/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-mobile-onboarding/NOTICE.md +126 -0
- package/skills/od-mobile-onboarding/SKILL.md +54 -0
- package/skills/od-pm-spec/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-pm-spec/NOTICE.md +126 -0
- package/skills/od-pm-spec/SKILL.md +53 -0
- package/skills/od-pricing-page/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-pricing-page/NOTICE.md +126 -0
- package/skills/od-pricing-page/SKILL.md +80 -0
- package/skills/od-redesign-skill/LICENSE +21 -0
- package/skills/od-redesign-skill/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-redesign-skill/NOTICE.md +126 -0
- package/skills/od-redesign-skill/SKILL.md +205 -0
- package/skills/od-reference-design-contract/NOTICE.md +44 -3
- package/skills/od-reference-design-contract/SKILL.md +1 -1
- package/skills/od-saas-landing/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-saas-landing/NOTICE.md +126 -0
- package/skills/od-saas-landing/SKILL.md +125 -0
- package/skills/od-social-carousel/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-social-carousel/NOTICE.md +126 -0
- package/skills/od-social-carousel/SKILL.md +92 -0
- package/skills/od-team-okrs/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-team-okrs/NOTICE.md +126 -0
- package/skills/od-team-okrs/SKILL.md +48 -0
- package/skills/od-waitlist-page/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-waitlist-page/NOTICE.md +126 -0
- package/skills/od-waitlist-page/SKILL.md +229 -0
- package/skills/od-waitlist-page/assets/template.html +457 -0
- package/skills/od-waitlist-page/references/checklist.md +42 -0
- package/skills/od-web-design-guidelines/LICENSE +21 -0
- package/skills/od-web-design-guidelines/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-web-design-guidelines/NOTICE.md +126 -0
- package/skills/od-web-design-guidelines/SKILL.md +66 -0
- package/skills/od-web-design-guidelines/references/guidelines.md +133 -0
- package/skills/od-web-prototype/NOTICE.md +44 -3
- package/skills/od-web-prototype/SKILL.md +1 -1
- package/skills/od-web-prototype-taste-brutalist/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-web-prototype-taste-brutalist/LICENSE-MIT-Leonxlnx +21 -0
- package/skills/od-web-prototype-taste-brutalist/NOTICE.md +126 -0
- package/skills/od-web-prototype-taste-brutalist/SKILL.md +64 -0
- package/skills/od-web-prototype-taste-editorial/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-web-prototype-taste-editorial/LICENSE-MIT-Leonxlnx +21 -0
- package/skills/od-web-prototype-taste-editorial/NOTICE.md +126 -0
- package/skills/od-web-prototype-taste-editorial/SKILL.md +61 -0
- package/skills/od-web-prototype-taste-soft/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-web-prototype-taste-soft/LICENSE-MIT-Leonxlnx +21 -0
- package/skills/od-web-prototype-taste-soft/NOTICE.md +126 -0
- package/skills/od-web-prototype-taste-soft/SKILL.md +64 -0
- package/skills/od-webgl-experience/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-webgl-experience/NOTICE.md +126 -0
- package/skills/od-webgl-experience/SKILL.md +81 -0
- package/skills/od-wireframe-annotated/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-wireframe-annotated/NOTICE.md +126 -0
- package/skills/od-wireframe-annotated/SKILL.md +90 -0
- package/skills/od-wireframe-greybox/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-wireframe-greybox/NOTICE.md +126 -0
- package/skills/od-wireframe-greybox/SKILL.md +90 -0
- package/skills/od-wireframe-mobile-flow/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-wireframe-mobile-flow/NOTICE.md +126 -0
- package/skills/od-wireframe-mobile-flow/SKILL.md +96 -0
- package/skills/od-wireframe-sketch/LICENSE-APACHE-2.0 +201 -0
- package/skills/od-wireframe-sketch/NOTICE.md +126 -0
- package/skills/od-wireframe-sketch/SKILL.md +98 -0
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>{{PRODUCT_NAME}} — Coming Soon</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family={{DISPLAY_FONT_URL}}:wght@700;800&family={{BODY_FONT_URL}}:wght@400;500;600&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--bg: {{BG_EXPRESSION}};
|
|
13
|
+
--fg: {{FG_EXPRESSION}};
|
|
14
|
+
--accent: {{ACCENT_EXPRESSION}};
|
|
15
|
+
--deco: {{DECO_EXPRESSION}};
|
|
16
|
+
--deco-stripe: {{STRIPE_EXPRESSION}};
|
|
17
|
+
--input-border: {{BORDER_EXPRESSION}};
|
|
18
|
+
--success: {{SUCCESS_EXPRESSION}};
|
|
19
|
+
--btn-label: {{BTN_LABEL_EXPRESSION}};
|
|
20
|
+
--ticker-bg: {{TICKER_BG_EXPRESSION}};
|
|
21
|
+
--ticker-fg: {{TICKER_FG_EXPRESSION}};
|
|
22
|
+
--deco-stroke: {{DECO_STROKE_EXPRESSION}};
|
|
23
|
+
--logo-shadow: {{LOGO_SHADOW_EXPRESSION}};
|
|
24
|
+
--logo-fg: {{LOGO_FG_EXPRESSION}};
|
|
25
|
+
--font-body: {{BODY_FONT_CSS}}, sans-serif;
|
|
26
|
+
--font-display: {{DISPLAY_FONT_CSS}}, serif;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
*, *::before, *::after {
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
margin: 0;
|
|
32
|
+
padding: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
html, body {
|
|
36
|
+
height: 100%;
|
|
37
|
+
overflow-x: hidden;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
body {
|
|
41
|
+
font-family: var(--font-body);
|
|
42
|
+
background-color: var(--bg);
|
|
43
|
+
color: var(--fg);
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
min-height: 100svh;
|
|
47
|
+
overflow-x: hidden;
|
|
48
|
+
overflow-y: auto;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Logo — reusable component */
|
|
52
|
+
.logo {
|
|
53
|
+
position: absolute;
|
|
54
|
+
top: 20px;
|
|
55
|
+
left: 24px;
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: center;
|
|
58
|
+
gap: 12px;
|
|
59
|
+
z-index: 10;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.logo-container {
|
|
63
|
+
width: 48px;
|
|
64
|
+
height: 48px;
|
|
65
|
+
flex-shrink: 0;
|
|
66
|
+
border-radius: 50%;
|
|
67
|
+
background: var(--accent);
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
color: var(--logo-fg);
|
|
73
|
+
font-family: var(--font-display);
|
|
74
|
+
font-size: 20px;
|
|
75
|
+
font-weight: 700;
|
|
76
|
+
letter-spacing: -0.02em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.logo-container svg {
|
|
80
|
+
width: 100%;
|
|
81
|
+
height: 100%;
|
|
82
|
+
object-fit: contain;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.logo-text {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: center;
|
|
88
|
+
gap: 8px;
|
|
89
|
+
flex-shrink: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.logo-name {
|
|
93
|
+
font-family: var(--font-display);
|
|
94
|
+
font-weight: 700;
|
|
95
|
+
font-size: 16px;
|
|
96
|
+
color: var(--fg);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.logo-dot {
|
|
100
|
+
font-size: 8px;
|
|
101
|
+
color: var(--accent);
|
|
102
|
+
opacity: 0.6;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Upper section — hero */
|
|
106
|
+
.upper {
|
|
107
|
+
flex: 0 0 auto;
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
align-items: center;
|
|
111
|
+
justify-content: center;
|
|
112
|
+
text-align: center;
|
|
113
|
+
padding: 60px 24px 40px;
|
|
114
|
+
position: relative;
|
|
115
|
+
z-index: 2;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.headline {
|
|
119
|
+
font-family: var(--font-display);
|
|
120
|
+
font-weight: 800;
|
|
121
|
+
font-size: clamp(48px, 7vw, 80px);
|
|
122
|
+
letter-spacing: -0.02em;
|
|
123
|
+
line-height: 1.1;
|
|
124
|
+
color: var(--fg);
|
|
125
|
+
max-width: 900px;
|
|
126
|
+
margin: 0 auto 18px;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.subtext {
|
|
130
|
+
font-size: clamp(14px, 1.3vw, 16px);
|
|
131
|
+
font-weight: 400;
|
|
132
|
+
line-height: 1.5;
|
|
133
|
+
color: var(--fg);
|
|
134
|
+
opacity: 0.75;
|
|
135
|
+
max-width: 480px;
|
|
136
|
+
margin-bottom: 40px;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Form */
|
|
140
|
+
.form-row {
|
|
141
|
+
display: flex;
|
|
142
|
+
gap: 8px;
|
|
143
|
+
width: 100%;
|
|
144
|
+
max-width: 560px;
|
|
145
|
+
justify-content: center;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.form-row input {
|
|
149
|
+
flex: 1;
|
|
150
|
+
min-width: 0;
|
|
151
|
+
padding: 14px 16px;
|
|
152
|
+
font-family: var(--font-body);
|
|
153
|
+
font-size: 14px;
|
|
154
|
+
color: var(--fg);
|
|
155
|
+
background: transparent;
|
|
156
|
+
border: 1.5px solid var(--input-border);
|
|
157
|
+
border-radius: 3px;
|
|
158
|
+
outline: none;
|
|
159
|
+
transition: border-color 0.2s;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.form-row input::placeholder {
|
|
163
|
+
color: var(--input-border);
|
|
164
|
+
opacity: 0.7;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.form-row input:focus {
|
|
168
|
+
border-color: var(--fg);
|
|
169
|
+
outline: 2px solid var(--fg);
|
|
170
|
+
outline-offset: 2px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.form-row button {
|
|
174
|
+
flex-shrink: 0;
|
|
175
|
+
padding: 14px 24px;
|
|
176
|
+
font-family: var(--font-body);
|
|
177
|
+
font-size: 14px;
|
|
178
|
+
font-weight: 600;
|
|
179
|
+
color: var(--btn-label);
|
|
180
|
+
background: var(--fg);
|
|
181
|
+
border: none;
|
|
182
|
+
border-radius: 2px;
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
white-space: nowrap;
|
|
185
|
+
transition: opacity 0.15s;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.form-row button:hover {
|
|
189
|
+
opacity: 0.85;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.success-msg {
|
|
193
|
+
display: none;
|
|
194
|
+
margin-top: 16px;
|
|
195
|
+
font-size: 14px;
|
|
196
|
+
font-weight: 500;
|
|
197
|
+
color: var(--success);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.success-msg.visible {
|
|
201
|
+
display: block;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/* Decoration section */
|
|
205
|
+
.deco-section {
|
|
206
|
+
flex: 1;
|
|
207
|
+
position: relative;
|
|
208
|
+
overflow: hidden;
|
|
209
|
+
min-height: 25vh;
|
|
210
|
+
display: flex;
|
|
211
|
+
flex-direction: column;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Coil pattern */
|
|
215
|
+
.coil-row {
|
|
216
|
+
display: block;
|
|
217
|
+
width: 100%;
|
|
218
|
+
height: 60px;
|
|
219
|
+
flex-shrink: 0;
|
|
220
|
+
background: var(--bg);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Accent stripe */
|
|
224
|
+
.stripe {
|
|
225
|
+
width: 100%;
|
|
226
|
+
height: 12px;
|
|
227
|
+
background: var(--deco-stripe);
|
|
228
|
+
flex-shrink: 0;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Floor with grid */
|
|
232
|
+
.grid-floor {
|
|
233
|
+
flex: 1;
|
|
234
|
+
position: relative;
|
|
235
|
+
background-color: var(--deco);
|
|
236
|
+
min-height: 80px;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.grid-svg {
|
|
240
|
+
position: absolute;
|
|
241
|
+
inset: 0;
|
|
242
|
+
width: 100%;
|
|
243
|
+
height: 100%;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* Ticker ribbon */
|
|
247
|
+
.ticker-wrap {
|
|
248
|
+
width: 100%;
|
|
249
|
+
overflow: hidden;
|
|
250
|
+
background: var(--ticker-bg);
|
|
251
|
+
padding: 10px 0;
|
|
252
|
+
flex-shrink: 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.ticker-track {
|
|
256
|
+
display: flex;
|
|
257
|
+
gap: 24px;
|
|
258
|
+
white-space: nowrap;
|
|
259
|
+
animation: ticker-scroll 20s linear infinite;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.ticker-unit {
|
|
263
|
+
font-family: var(--font-body);
|
|
264
|
+
font-size: 11px;
|
|
265
|
+
font-weight: 600;
|
|
266
|
+
letter-spacing: 0.12em;
|
|
267
|
+
text-transform: uppercase;
|
|
268
|
+
color: var(--ticker-fg);
|
|
269
|
+
flex-shrink: 0;
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
gap: 12px;
|
|
273
|
+
margin-right: -12px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.ticker-star {
|
|
277
|
+
color: var(--deco-stripe);
|
|
278
|
+
margin-right: 4px;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@keyframes ticker-scroll {
|
|
282
|
+
from { transform: translateX(0); }
|
|
283
|
+
to { transform: translateX(-50%); }
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
@media (prefers-reduced-motion: reduce) {
|
|
287
|
+
.ticker-track {
|
|
288
|
+
animation: none;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Responsive */
|
|
293
|
+
@media (max-width: 600px) {
|
|
294
|
+
.logo {
|
|
295
|
+
left: 16px;
|
|
296
|
+
top: 16px;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.logo-container {
|
|
300
|
+
width: 40px;
|
|
301
|
+
height: 40px;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.logo-name {
|
|
305
|
+
font-size: 13px;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.upper {
|
|
309
|
+
padding: 50px 20px 30px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.headline {
|
|
313
|
+
margin: 0 auto 12px;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.subtext {
|
|
317
|
+
margin-bottom: 30px;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.form-row {
|
|
321
|
+
flex-direction: column;
|
|
322
|
+
align-items: stretch;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.form-row input,
|
|
326
|
+
.form-row button {
|
|
327
|
+
width: 100%;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
</style>
|
|
331
|
+
</head>
|
|
332
|
+
<body>
|
|
333
|
+
|
|
334
|
+
<!-- Logo placeholder — replace or customize -->
|
|
335
|
+
<div class="logo">
|
|
336
|
+
<div class="logo-container" data-od-id="logo-mark">
|
|
337
|
+
{{LOGO_MARK}}
|
|
338
|
+
</div>
|
|
339
|
+
<div class="logo-text">
|
|
340
|
+
<span class="logo-name" data-od-id="logo-name">{{PRODUCT_NAME}}</span>
|
|
341
|
+
<span class="logo-dot">·</span>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
<!-- Hero section -->
|
|
346
|
+
<section class="upper">
|
|
347
|
+
<h1 class="headline" data-od-id="headline">{{PRODUCT_NAME}}<br>is launching</h1>
|
|
348
|
+
<p class="subtext" data-od-id="tagline">{{TAGLINE}}</p>
|
|
349
|
+
|
|
350
|
+
<form class="form-row" id="waitlist-form" data-od-id="form">
|
|
351
|
+
<input type="text" name="firstname" placeholder="First name">
|
|
352
|
+
<input type="email" name="email" placeholder="Work email" required>
|
|
353
|
+
<button type="submit">Join Waitlist</button>
|
|
354
|
+
</form>
|
|
355
|
+
<p class="success-msg" id="success-msg" role="status">You're on the list. We'll be in touch.</p>
|
|
356
|
+
</section>
|
|
357
|
+
|
|
358
|
+
<!-- Decorative section -->
|
|
359
|
+
<div class="deco-section">
|
|
360
|
+
|
|
361
|
+
<!-- Coil pattern (optional) -->
|
|
362
|
+
<svg class="coil-row" viewBox="0 0 1440 60" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" data-od-id="coil">
|
|
363
|
+
<g fill="none" style="stroke: var(--deco-stroke);" stroke-width="1.5">
|
|
364
|
+
<path d="M 9,60 A 41,30 0 0 1 91,60"/>
|
|
365
|
+
<path d="M 94,60 A 41,30 0 0 1 176,60"/>
|
|
366
|
+
<path d="M 179,60 A 41,30 0 0 1 261,60"/>
|
|
367
|
+
<path d="M 264,60 A 41,30 0 0 1 346,60"/>
|
|
368
|
+
<path d="M 349,60 A 41,30 0 0 1 431,60"/>
|
|
369
|
+
<path d="M 434,60 A 41,30 0 0 1 516,60"/>
|
|
370
|
+
<path d="M 519,60 A 41,30 0 0 1 601,60"/>
|
|
371
|
+
<path d="M 604,60 A 41,30 0 0 1 686,60"/>
|
|
372
|
+
<path d="M 689,60 A 41,30 0 0 1 771,60"/>
|
|
373
|
+
<path d="M 774,60 A 41,30 0 0 1 856,60"/>
|
|
374
|
+
<path d="M 859,60 A 41,30 0 0 1 941,60"/>
|
|
375
|
+
<path d="M 944,60 A 41,30 0 0 1 1026,60"/>
|
|
376
|
+
<path d="M 1029,60 A 41,30 0 0 1 1111,60"/>
|
|
377
|
+
<path d="M 1114,60 A 41,30 0 0 1 1196,60"/>
|
|
378
|
+
<path d="M 1199,60 A 41,30 0 0 1 1281,60"/>
|
|
379
|
+
<path d="M 1284,60 A 41,30 0 0 1 1366,60"/>
|
|
380
|
+
<path d="M 1369,60 A 41,30 0 0 1 1451,60"/>
|
|
381
|
+
</g>
|
|
382
|
+
</svg>
|
|
383
|
+
|
|
384
|
+
<!-- Accent stripe -->
|
|
385
|
+
<div class="stripe" data-od-id="stripe"></div>
|
|
386
|
+
|
|
387
|
+
<!-- Floor with perspective grid -->
|
|
388
|
+
<div class="grid-floor">
|
|
389
|
+
<svg class="grid-svg" viewBox="0 0 1280 400" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" data-od-id="grid">
|
|
390
|
+
<g style="stroke: var(--deco-stroke);" stroke-width="1" fill="none">
|
|
391
|
+
<!-- Radiating lines from center top -->
|
|
392
|
+
<line x1="640" y1="0" x2="0" y2="400"/>
|
|
393
|
+
<line x1="640" y1="0" x2="128" y2="400"/>
|
|
394
|
+
<line x1="640" y1="0" x2="256" y2="400"/>
|
|
395
|
+
<line x1="640" y1="0" x2="384" y2="400"/>
|
|
396
|
+
<line x1="640" y1="0" x2="512" y2="400"/>
|
|
397
|
+
<line x1="640" y1="0" x2="640" y2="400"/>
|
|
398
|
+
<line x1="640" y1="0" x2="768" y2="400"/>
|
|
399
|
+
<line x1="640" y1="0" x2="896" y2="400"/>
|
|
400
|
+
<line x1="640" y1="0" x2="1024" y2="400"/>
|
|
401
|
+
<line x1="640" y1="0" x2="1152" y2="400"/>
|
|
402
|
+
<line x1="640" y1="0" x2="1280" y2="400"/>
|
|
403
|
+
<!-- Horizontal grid lines -->
|
|
404
|
+
<line x1="0" y1="80" x2="1280" y2="80"/>
|
|
405
|
+
<line x1="0" y1="160" x2="1280" y2="160"/>
|
|
406
|
+
<line x1="0" y1="240" x2="1280" y2="240"/>
|
|
407
|
+
<line x1="0" y1="320" x2="1280" y2="320"/>
|
|
408
|
+
</g>
|
|
409
|
+
</svg>
|
|
410
|
+
</div>
|
|
411
|
+
</div>
|
|
412
|
+
|
|
413
|
+
<!-- Ticker ribbon -->
|
|
414
|
+
<div class="ticker-wrap" aria-hidden="true" data-od-id="ticker">
|
|
415
|
+
<div class="ticker-track">
|
|
416
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
417
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
418
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
419
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
420
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
421
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
422
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
423
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
424
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
425
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
426
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
427
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
428
|
+
<!-- Duplicate for seamless loop -->
|
|
429
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
430
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
431
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
432
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
433
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
434
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
435
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
436
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
437
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
438
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
439
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
440
|
+
<span class="ticker-unit">COMING SOON <span class="ticker-star">✦</span></span>
|
|
441
|
+
</div>
|
|
442
|
+
</div>
|
|
443
|
+
|
|
444
|
+
<script>
|
|
445
|
+
document.getElementById('waitlist-form').addEventListener('submit', function(e) {
|
|
446
|
+
e.preventDefault();
|
|
447
|
+
if (!this.checkValidity()) {
|
|
448
|
+
this.reportValidity();
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
this.style.display = 'none';
|
|
452
|
+
document.getElementById('success-msg').classList.add('visible');
|
|
453
|
+
});
|
|
454
|
+
</script>
|
|
455
|
+
|
|
456
|
+
</body>
|
|
457
|
+
</html>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Checklist — Waitlist Page
|
|
2
|
+
|
|
3
|
+
## P0 — Must pass before emitting `<artifact>`
|
|
4
|
+
|
|
5
|
+
- [ ] Page has exactly one primary CTA (the email field + submit button)
|
|
6
|
+
- [ ] No hero gradient that spans more than 20% of the viewport height
|
|
7
|
+
- [ ] Email input has a visible label or meaningful placeholder — not just "Email"
|
|
8
|
+
- [ ] No invented social proof numbers (e.g., "10,000 people waiting")
|
|
9
|
+
- [ ] **No countdown timer present** — countdown timers are an explicit anti-pattern for this skill (see SKILL.md §Quality gates)
|
|
10
|
+
- [ ] No horizontal scroll at 375px viewport
|
|
11
|
+
- [ ] No generic emoji icons used as decorative elements
|
|
12
|
+
- [ ] Typography uses at most two font families (display + body)
|
|
13
|
+
- [ ] First name field has no `required` attribute
|
|
14
|
+
- [ ] Work email field has `type="email"` and `required`
|
|
15
|
+
- [ ] Form does **not** use `novalidate`; JS guard calls `checkValidity()` before showing success state
|
|
16
|
+
- [ ] Success message uses `role="status"` or `aria-live="polite"` so screen readers announce it
|
|
17
|
+
- [ ] All color values derived from DESIGN.md; only allowed hardcoded exception is `#2D6A4F` for `--success`
|
|
18
|
+
- [ ] All user-supplied text tokens are HTML-escaped; color tokens adhere to strict grammar (`#hex`, `rgb/hsl/oklch`, `color-mix()`) and contain no unsafe characters (`;`, `{}`, `<`, `>`, `/*`, `@`, `url(`); font name tokens are URL-encoded in the Google Fonts URL; `{{LOGO_MARK}}` is escaped text initials or strictly sanitized inline SVG (no scripts/events)
|
|
19
|
+
|
|
20
|
+
## P1 — Should pass for quality submission
|
|
21
|
+
|
|
22
|
+
- [ ] Hero section is visually distinct and above-the-fold
|
|
23
|
+
- [ ] Email submit button has hover and active states
|
|
24
|
+
- [ ] Form validation provides clear inline feedback on error (native `reportValidity()` is acceptable)
|
|
25
|
+
- [ ] Page is scrollable (not clipped) at 375×667 and 390×844; CTA visible without scroll at those sizes
|
|
26
|
+
- [ ] Ticker animation is paused or removed under `prefers-reduced-motion: reduce`
|
|
27
|
+
- [ ] All interactive elements have visible focus styles (not just `outline: none`)
|
|
28
|
+
- [ ] Keyboard: Tab reaches each form field and the submit button; Enter submits the form
|
|
29
|
+
- [ ] Color contrast of body text on background meets WCAG AA (≥ 4.5:1)
|
|
30
|
+
- [ ] Color contrast of button label on button background meets WCAG AA (≥ 4.5:1)
|
|
31
|
+
- [ ] Color contrast of logo text/initials on logo container background meets WCAG AA (≥ 4.5:1)
|
|
32
|
+
- [ ] Logo alt text or `aria-label` present if logo is an `<img>` or meaningful SVG
|
|
33
|
+
- [ ] Ticker ribbon has `aria-hidden="true"` (decorative, not meaningful content)
|
|
34
|
+
- [ ] `<html lang="">` attribute is set to the correct language code
|
|
35
|
+
|
|
36
|
+
## P2 — Nice-to-have polish
|
|
37
|
+
|
|
38
|
+
- [ ] Google Fonts loaded with `display=swap` to avoid FOIT
|
|
39
|
+
- [ ] Form inputs have matching `autocomplete` attributes (`given-name`, `email`)
|
|
40
|
+
- [ ] Subtle micro-animation on button hover (scale or opacity only — no layout shift)
|
|
41
|
+
- [ ] Decoration zone does not cover or overlap the form at any viewport width
|
|
42
|
+
- [ ] Page title is `{{PRODUCT_NAME}} — Coming Soon`, not a generic placeholder
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Vercel Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|