@vitronai/alethia 0.8.0 → 0.8.2
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 +73 -41
- package/demo/admin-panel.html +326 -36
- package/demo/agent-oversight.html +354 -49
- package/demo/claude-code-app.html +688 -94
- package/demo/crypto-readiness.html +611 -177
- package/demo/ea1-stress-test.html +262 -34
- package/demo/ecommerce.html +1116 -0
- package/demo/financial-dashboard.html +298 -34
- package/demo/incident-response.html +636 -196
- package/demo/intentional-failures.html +157 -0
- package/demo/nist-compliance.html +458 -102
- package/demo/threat-intel.html +310 -51
- package/demo/wcag-audit.html +495 -84
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +145 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/skills/alethia/SKILL.md +15 -5
|
@@ -0,0 +1,1116 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<title>Helix Outfitters — Premium Desk Accessories</title>
|
|
6
|
+
<style>
|
|
7
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
8
|
+
|
|
9
|
+
:root {
|
|
10
|
+
--bg: #0c0814;
|
|
11
|
+
--bg-1: #14101c;
|
|
12
|
+
--bg-2: #1c1428;
|
|
13
|
+
--bg-3: #261a3a;
|
|
14
|
+
--edge: rgba(255,255,255,.06);
|
|
15
|
+
--edge-strong: rgba(255,255,255,.12);
|
|
16
|
+
--ink: #faf5fc;
|
|
17
|
+
--ink-2: #e0d6e8;
|
|
18
|
+
--ink-muted: #a89bb8;
|
|
19
|
+
--ink-faint: #6b6080;
|
|
20
|
+
--pink: #f472b6;
|
|
21
|
+
--pink-bright: #f9a8d4;
|
|
22
|
+
--pink-deep: #db2777;
|
|
23
|
+
--pink-glow: #fbcfe8;
|
|
24
|
+
--indigo: #818cf8;
|
|
25
|
+
--indigo-bright: #a5b4fc;
|
|
26
|
+
--emerald: #10b981;
|
|
27
|
+
--emerald-bright: #34d399;
|
|
28
|
+
--amber: #fbbf24;
|
|
29
|
+
--rose: #fb7185;
|
|
30
|
+
}
|
|
31
|
+
html { color-scheme: dark; scroll-behavior: smooth; }
|
|
32
|
+
body {
|
|
33
|
+
font-family: "SF Pro Display", -apple-system, system-ui, sans-serif;
|
|
34
|
+
background: var(--bg);
|
|
35
|
+
color: var(--ink-2);
|
|
36
|
+
min-height: 100vh;
|
|
37
|
+
-webkit-font-smoothing: antialiased;
|
|
38
|
+
font-feature-settings: "ss01", "cv11";
|
|
39
|
+
line-height: 1.5;
|
|
40
|
+
}
|
|
41
|
+
a { color: inherit; text-decoration: none; }
|
|
42
|
+
img { display: block; max-width: 100%; }
|
|
43
|
+
|
|
44
|
+
/* ── Top nav ─────────────────────────────────────── */
|
|
45
|
+
.nav {
|
|
46
|
+
position: sticky; top: 0;
|
|
47
|
+
z-index: 30;
|
|
48
|
+
display: grid;
|
|
49
|
+
grid-template-columns: auto 1fr auto;
|
|
50
|
+
gap: 24px;
|
|
51
|
+
align-items: center;
|
|
52
|
+
padding: 14px 32px;
|
|
53
|
+
background: rgba(12,8,20,.65);
|
|
54
|
+
backdrop-filter: saturate(180%) blur(14px);
|
|
55
|
+
-webkit-backdrop-filter: saturate(180%) blur(14px);
|
|
56
|
+
border-bottom: 1px solid var(--edge);
|
|
57
|
+
}
|
|
58
|
+
.brand {
|
|
59
|
+
display: inline-flex; align-items: center; gap: 10px;
|
|
60
|
+
font-size: 16px; font-weight: 800;
|
|
61
|
+
color: var(--ink);
|
|
62
|
+
letter-spacing: -.025em;
|
|
63
|
+
}
|
|
64
|
+
.brand-mark {
|
|
65
|
+
width: 28px; height: 28px;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
background:
|
|
68
|
+
radial-gradient(circle at 30% 20%, rgba(255,255,255,.6), transparent 60%),
|
|
69
|
+
linear-gradient(135deg, var(--pink-bright), var(--pink-deep));
|
|
70
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
71
|
+
color: #14101c;
|
|
72
|
+
font-weight: 800;
|
|
73
|
+
box-shadow:
|
|
74
|
+
inset 0 1px 0 rgba(255,255,255,.4),
|
|
75
|
+
0 4px 14px rgba(244,114,182,.35);
|
|
76
|
+
}
|
|
77
|
+
.nav-search {
|
|
78
|
+
position: relative;
|
|
79
|
+
max-width: 480px;
|
|
80
|
+
margin: 0 auto;
|
|
81
|
+
width: 100%;
|
|
82
|
+
}
|
|
83
|
+
.nav-search input {
|
|
84
|
+
width: 100%;
|
|
85
|
+
padding: 9px 14px 9px 38px;
|
|
86
|
+
background: rgba(255,255,255,.04);
|
|
87
|
+
border: 1px solid var(--edge);
|
|
88
|
+
border-radius: 999px;
|
|
89
|
+
color: var(--ink);
|
|
90
|
+
font: inherit;
|
|
91
|
+
font-size: 13px;
|
|
92
|
+
outline: none;
|
|
93
|
+
transition: background .15s, border-color .15s;
|
|
94
|
+
}
|
|
95
|
+
.nav-search input:focus {
|
|
96
|
+
background: rgba(255,255,255,.06);
|
|
97
|
+
border-color: rgba(244,114,182,.5);
|
|
98
|
+
}
|
|
99
|
+
.nav-search input::placeholder { color: var(--ink-faint); }
|
|
100
|
+
.nav-search svg {
|
|
101
|
+
position: absolute; left: 13px; top: 50%; transform: translateY(-50%);
|
|
102
|
+
width: 14px; height: 14px;
|
|
103
|
+
color: var(--ink-faint);
|
|
104
|
+
}
|
|
105
|
+
.nav-actions { display: inline-flex; gap: 6px; align-items: center; }
|
|
106
|
+
.nav-icon-btn {
|
|
107
|
+
width: 38px; height: 38px;
|
|
108
|
+
border-radius: 999px;
|
|
109
|
+
border: 1px solid var(--edge);
|
|
110
|
+
background: rgba(255,255,255,.03);
|
|
111
|
+
color: var(--ink-2);
|
|
112
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
position: relative;
|
|
115
|
+
transition: background .15s, border-color .15s, color .15s;
|
|
116
|
+
}
|
|
117
|
+
.nav-icon-btn:hover { background: rgba(255,255,255,.07); border-color: var(--edge-strong); color: var(--ink); }
|
|
118
|
+
.nav-icon-btn svg { width: 16px; height: 16px; }
|
|
119
|
+
.cart-badge {
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: -2px; right: -2px;
|
|
122
|
+
min-width: 18px; height: 18px;
|
|
123
|
+
padding: 0 5px;
|
|
124
|
+
border-radius: 999px;
|
|
125
|
+
background: var(--pink);
|
|
126
|
+
color: #14101c;
|
|
127
|
+
font-size: 10px; font-weight: 800;
|
|
128
|
+
display: flex; align-items: center; justify-content: center;
|
|
129
|
+
box-shadow: 0 0 8px rgba(244,114,182,.6);
|
|
130
|
+
}
|
|
131
|
+
.cart-badge.empty { display: none; }
|
|
132
|
+
|
|
133
|
+
/* ── Hero ─────────────────────────────────────── */
|
|
134
|
+
.hero {
|
|
135
|
+
position: relative;
|
|
136
|
+
max-width: 1280px; margin: 0 auto;
|
|
137
|
+
padding: 64px 32px 32px;
|
|
138
|
+
display: grid;
|
|
139
|
+
grid-template-columns: 1.3fr 1fr;
|
|
140
|
+
gap: 48px;
|
|
141
|
+
align-items: center;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
}
|
|
144
|
+
.hero::before {
|
|
145
|
+
content: "";
|
|
146
|
+
position: absolute;
|
|
147
|
+
inset: -20% -10% 0 -10%;
|
|
148
|
+
z-index: -1;
|
|
149
|
+
background:
|
|
150
|
+
radial-gradient(ellipse 50% 60% at 20% 0%, rgba(244,114,182,.18), transparent 70%),
|
|
151
|
+
radial-gradient(ellipse 50% 60% at 80% 100%, rgba(129,140,248,.12), transparent 70%);
|
|
152
|
+
filter: blur(40px);
|
|
153
|
+
pointer-events: none;
|
|
154
|
+
}
|
|
155
|
+
.hero-eyebrow {
|
|
156
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
157
|
+
font-size: 10px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
|
|
158
|
+
color: var(--pink-bright);
|
|
159
|
+
padding: 5px 12px;
|
|
160
|
+
background: rgba(244,114,182,.10);
|
|
161
|
+
border: 1px solid rgba(244,114,182,.3);
|
|
162
|
+
border-radius: 999px;
|
|
163
|
+
margin-bottom: 18px;
|
|
164
|
+
}
|
|
165
|
+
.hero-eyebrow::before {
|
|
166
|
+
content: ""; width: 6px; height: 6px; border-radius: 999px;
|
|
167
|
+
background: var(--pink); box-shadow: 0 0 8px var(--pink);
|
|
168
|
+
}
|
|
169
|
+
.hero h1 {
|
|
170
|
+
font-size: 54px; font-weight: 800; letter-spacing: -.035em;
|
|
171
|
+
color: var(--ink); margin-bottom: 14px; line-height: 1.02;
|
|
172
|
+
background: linear-gradient(135deg, #fff 0%, var(--pink-bright) 50%, #fff 100%);
|
|
173
|
+
background-size: 200% 200%;
|
|
174
|
+
-webkit-background-clip: text; background-clip: text;
|
|
175
|
+
-webkit-text-fill-color: transparent;
|
|
176
|
+
}
|
|
177
|
+
.hero p.lead {
|
|
178
|
+
font-size: 16px; color: var(--ink-muted); line-height: 1.6;
|
|
179
|
+
max-width: 520px;
|
|
180
|
+
margin-bottom: 22px;
|
|
181
|
+
}
|
|
182
|
+
.hero p.lead strong { color: var(--ink); }
|
|
183
|
+
.hero-promo {
|
|
184
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
185
|
+
font-size: 12px;
|
|
186
|
+
padding: 10px 14px;
|
|
187
|
+
background: linear-gradient(135deg, rgba(244,114,182,.16), rgba(244,114,182,.06));
|
|
188
|
+
border: 1px solid rgba(244,114,182,.4);
|
|
189
|
+
border-radius: 12px;
|
|
190
|
+
color: var(--ink);
|
|
191
|
+
}
|
|
192
|
+
.hero-promo .code {
|
|
193
|
+
font-family: ui-monospace, "SF Mono", monospace;
|
|
194
|
+
font-weight: 700;
|
|
195
|
+
color: var(--pink-bright);
|
|
196
|
+
background: rgba(0,0,0,.3);
|
|
197
|
+
padding: 3px 8px;
|
|
198
|
+
border-radius: 4px;
|
|
199
|
+
letter-spacing: .04em;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Hero featured card — stylized "product photo" */
|
|
203
|
+
.hero-feature {
|
|
204
|
+
position: relative;
|
|
205
|
+
aspect-ratio: 4 / 5;
|
|
206
|
+
max-height: 460px;
|
|
207
|
+
border-radius: 24px;
|
|
208
|
+
background:
|
|
209
|
+
radial-gradient(ellipse 60% 40% at 50% 30%, rgba(255,255,255,.18), transparent 70%),
|
|
210
|
+
linear-gradient(135deg, #432857 0%, #1e1230 60%, #2e1c3a 100%);
|
|
211
|
+
border: 1px solid rgba(255,255,255,.1);
|
|
212
|
+
overflow: hidden;
|
|
213
|
+
display: flex; align-items: center; justify-content: center;
|
|
214
|
+
box-shadow:
|
|
215
|
+
0 30px 80px rgba(0,0,0,.45),
|
|
216
|
+
inset 0 1px 0 rgba(255,255,255,.1);
|
|
217
|
+
}
|
|
218
|
+
.hero-feature::before {
|
|
219
|
+
content: "";
|
|
220
|
+
position: absolute; inset: 0;
|
|
221
|
+
background:
|
|
222
|
+
radial-gradient(circle at 30% 80%, rgba(129,140,248,.25), transparent 50%),
|
|
223
|
+
radial-gradient(circle at 70% 30%, rgba(244,114,182,.25), transparent 50%);
|
|
224
|
+
filter: blur(30px);
|
|
225
|
+
}
|
|
226
|
+
.hero-feature-icon {
|
|
227
|
+
position: relative;
|
|
228
|
+
font-size: 140px;
|
|
229
|
+
filter: drop-shadow(0 20px 30px rgba(0,0,0,.6));
|
|
230
|
+
transform: rotate(-12deg);
|
|
231
|
+
}
|
|
232
|
+
.hero-feature-tag {
|
|
233
|
+
position: absolute;
|
|
234
|
+
top: 18px; left: 18px;
|
|
235
|
+
font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
|
|
236
|
+
padding: 5px 11px;
|
|
237
|
+
background: rgba(255,255,255,.12);
|
|
238
|
+
backdrop-filter: blur(8px);
|
|
239
|
+
border: 1px solid rgba(255,255,255,.2);
|
|
240
|
+
border-radius: 999px;
|
|
241
|
+
color: var(--ink);
|
|
242
|
+
}
|
|
243
|
+
.hero-feature-meta {
|
|
244
|
+
position: absolute;
|
|
245
|
+
bottom: 18px; left: 18px; right: 18px;
|
|
246
|
+
padding: 14px 16px;
|
|
247
|
+
background: rgba(20,16,28,.7);
|
|
248
|
+
backdrop-filter: blur(12px);
|
|
249
|
+
border: 1px solid rgba(255,255,255,.12);
|
|
250
|
+
border-radius: 14px;
|
|
251
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
252
|
+
}
|
|
253
|
+
.hero-feature-meta .name {
|
|
254
|
+
font-size: 13px; font-weight: 700; color: var(--ink);
|
|
255
|
+
}
|
|
256
|
+
.hero-feature-meta .desc {
|
|
257
|
+
font-size: 11.5px; color: var(--ink-muted); margin-top: 2px;
|
|
258
|
+
}
|
|
259
|
+
.hero-feature-meta .price {
|
|
260
|
+
font-size: 18px; font-weight: 800;
|
|
261
|
+
color: var(--pink-bright);
|
|
262
|
+
letter-spacing: -.01em;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/* ── Filter bar ─────────────────────────────────────── */
|
|
266
|
+
.filters {
|
|
267
|
+
max-width: 1280px;
|
|
268
|
+
margin: 0 auto;
|
|
269
|
+
padding: 24px 32px 12px;
|
|
270
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
271
|
+
gap: 16px;
|
|
272
|
+
flex-wrap: wrap;
|
|
273
|
+
}
|
|
274
|
+
.filters-group { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
275
|
+
.chip {
|
|
276
|
+
display: inline-flex; align-items: center; gap: 6px;
|
|
277
|
+
padding: 6px 14px;
|
|
278
|
+
background: transparent;
|
|
279
|
+
border: 1px solid var(--edge);
|
|
280
|
+
border-radius: 999px;
|
|
281
|
+
color: var(--ink-muted);
|
|
282
|
+
font: inherit;
|
|
283
|
+
font-size: 12px;
|
|
284
|
+
font-weight: 600;
|
|
285
|
+
cursor: pointer;
|
|
286
|
+
transition: all .14s ease;
|
|
287
|
+
}
|
|
288
|
+
.chip:hover { border-color: var(--edge-strong); color: var(--ink); }
|
|
289
|
+
.chip.active {
|
|
290
|
+
background: rgba(244,114,182,.14);
|
|
291
|
+
border-color: rgba(244,114,182,.5);
|
|
292
|
+
color: var(--pink-bright);
|
|
293
|
+
}
|
|
294
|
+
.results-count { color: var(--ink-faint); font-size: 12px; font-family: ui-monospace, "SF Mono", monospace; }
|
|
295
|
+
|
|
296
|
+
/* ── Product grid ─────────────────────────────────────── */
|
|
297
|
+
.products {
|
|
298
|
+
max-width: 1280px;
|
|
299
|
+
margin: 0 auto;
|
|
300
|
+
padding: 12px 32px 80px;
|
|
301
|
+
display: grid;
|
|
302
|
+
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
303
|
+
gap: 18px;
|
|
304
|
+
}
|
|
305
|
+
.product {
|
|
306
|
+
position: relative;
|
|
307
|
+
background: linear-gradient(180deg, var(--bg-1) 0%, rgba(20,16,28,.6) 100%);
|
|
308
|
+
border: 1px solid var(--edge);
|
|
309
|
+
border-radius: 16px;
|
|
310
|
+
overflow: hidden;
|
|
311
|
+
display: flex; flex-direction: column;
|
|
312
|
+
transition: border-color .15s, transform .15s, box-shadow .15s;
|
|
313
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.035);
|
|
314
|
+
}
|
|
315
|
+
.product:hover {
|
|
316
|
+
border-color: rgba(244,114,182,.4);
|
|
317
|
+
transform: translateY(-3px);
|
|
318
|
+
box-shadow:
|
|
319
|
+
inset 0 1px 0 rgba(255,255,255,.06),
|
|
320
|
+
0 12px 32px rgba(0,0,0,.45),
|
|
321
|
+
0 0 0 1px rgba(244,114,182,.15);
|
|
322
|
+
}
|
|
323
|
+
.product.hidden { display: none; }
|
|
324
|
+
.product-image {
|
|
325
|
+
position: relative;
|
|
326
|
+
aspect-ratio: 4 / 3;
|
|
327
|
+
display: flex; align-items: center; justify-content: center;
|
|
328
|
+
font-size: 64px;
|
|
329
|
+
overflow: hidden;
|
|
330
|
+
}
|
|
331
|
+
.product-image::before {
|
|
332
|
+
content: "";
|
|
333
|
+
position: absolute; inset: 0;
|
|
334
|
+
background:
|
|
335
|
+
radial-gradient(circle at 30% 30%, rgba(255,255,255,.18), transparent 50%),
|
|
336
|
+
radial-gradient(circle at 70% 70%, rgba(0,0,0,.3), transparent 60%);
|
|
337
|
+
}
|
|
338
|
+
.product-image span:first-child {
|
|
339
|
+
position: relative;
|
|
340
|
+
filter: drop-shadow(0 8px 16px rgba(0,0,0,.4));
|
|
341
|
+
transform: rotate(-6deg);
|
|
342
|
+
transition: transform .25s cubic-bezier(.16,1,.3,1);
|
|
343
|
+
}
|
|
344
|
+
.product:hover .product-image span:first-child { transform: rotate(0deg) scale(1.06); }
|
|
345
|
+
|
|
346
|
+
.product-image[data-tag="kbd"] { background: linear-gradient(135deg, #432857, #1e3a5c); }
|
|
347
|
+
.product-image[data-tag="hub"] { background: linear-gradient(135deg, #432857, #14322c); }
|
|
348
|
+
.product-image[data-tag="stand"] { background: linear-gradient(135deg, #432857, #422006); }
|
|
349
|
+
.product-image[data-tag="mouse"] { background: linear-gradient(135deg, #432857, #1a0808); }
|
|
350
|
+
.product-image[data-tag="webcam"] { background: linear-gradient(135deg, #432857, #08111c); }
|
|
351
|
+
.product-image[data-tag="mic"] { background: linear-gradient(135deg, #432857, #150e1c); }
|
|
352
|
+
|
|
353
|
+
.badge {
|
|
354
|
+
position: absolute;
|
|
355
|
+
top: 12px; left: 12px;
|
|
356
|
+
font-size: 9.5px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
|
|
357
|
+
padding: 4px 9px;
|
|
358
|
+
background: rgba(20,16,28,.85);
|
|
359
|
+
backdrop-filter: blur(6px);
|
|
360
|
+
border: 1px solid rgba(255,255,255,.14);
|
|
361
|
+
border-radius: 6px;
|
|
362
|
+
color: var(--ink);
|
|
363
|
+
z-index: 2;
|
|
364
|
+
}
|
|
365
|
+
.badge.new { color: var(--emerald-bright); border-color: rgba(52,211,153,.55); background: rgba(16,185,129,.15); }
|
|
366
|
+
.badge.sale { color: var(--amber); border-color: rgba(251,191,36,.55); background: rgba(251,191,36,.15); }
|
|
367
|
+
.badge.few-left { color: var(--rose); border-color: rgba(251,113,133,.55); background: rgba(251,113,133,.15); }
|
|
368
|
+
|
|
369
|
+
.wishlist-btn {
|
|
370
|
+
position: absolute;
|
|
371
|
+
top: 12px; right: 12px;
|
|
372
|
+
width: 32px; height: 32px;
|
|
373
|
+
display: flex; align-items: center; justify-content: center;
|
|
374
|
+
background: rgba(20,16,28,.7);
|
|
375
|
+
backdrop-filter: blur(8px);
|
|
376
|
+
border: 1px solid rgba(255,255,255,.12);
|
|
377
|
+
border-radius: 999px;
|
|
378
|
+
color: var(--ink-muted);
|
|
379
|
+
cursor: pointer;
|
|
380
|
+
transition: all .15s ease;
|
|
381
|
+
z-index: 2;
|
|
382
|
+
}
|
|
383
|
+
.wishlist-btn:hover { color: var(--pink); border-color: rgba(244,114,182,.55); }
|
|
384
|
+
.wishlist-btn.saved {
|
|
385
|
+
color: var(--pink);
|
|
386
|
+
background: rgba(244,114,182,.22);
|
|
387
|
+
border-color: var(--pink);
|
|
388
|
+
box-shadow: 0 0 12px rgba(244,114,182,.35);
|
|
389
|
+
}
|
|
390
|
+
.wishlist-btn.saved svg { fill: var(--pink); }
|
|
391
|
+
.wishlist-btn svg { width: 14px; height: 14px; transition: fill .15s; }
|
|
392
|
+
|
|
393
|
+
.product-body {
|
|
394
|
+
padding: 16px 18px 18px;
|
|
395
|
+
display: flex; flex-direction: column; flex: 1;
|
|
396
|
+
}
|
|
397
|
+
.product .category {
|
|
398
|
+
font-size: 9.5px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
|
|
399
|
+
color: var(--ink-faint);
|
|
400
|
+
margin-bottom: 4px;
|
|
401
|
+
}
|
|
402
|
+
.product h2 {
|
|
403
|
+
font-size: 14.5px; font-weight: 700;
|
|
404
|
+
color: var(--ink);
|
|
405
|
+
margin-bottom: 4px;
|
|
406
|
+
letter-spacing: -.005em;
|
|
407
|
+
}
|
|
408
|
+
.product .desc {
|
|
409
|
+
font-size: 12px; color: var(--ink-muted); line-height: 1.5;
|
|
410
|
+
margin-bottom: 10px;
|
|
411
|
+
min-height: 36px;
|
|
412
|
+
}
|
|
413
|
+
.rating {
|
|
414
|
+
display: flex; align-items: center; gap: 6px;
|
|
415
|
+
margin-bottom: 12px;
|
|
416
|
+
font-size: 11px; color: var(--ink-muted);
|
|
417
|
+
}
|
|
418
|
+
.stars { color: var(--amber); letter-spacing: 1px; font-size: 12px; }
|
|
419
|
+
.product-foot {
|
|
420
|
+
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
|
421
|
+
margin-top: auto;
|
|
422
|
+
}
|
|
423
|
+
.product .price {
|
|
424
|
+
font-size: 17px; font-weight: 800;
|
|
425
|
+
color: var(--ink);
|
|
426
|
+
letter-spacing: -.01em;
|
|
427
|
+
font-variant-numeric: tabular-nums;
|
|
428
|
+
}
|
|
429
|
+
.product .price-was {
|
|
430
|
+
font-size: 12px; color: var(--ink-faint); text-decoration: line-through;
|
|
431
|
+
margin-right: 6px;
|
|
432
|
+
font-weight: 500;
|
|
433
|
+
}
|
|
434
|
+
.btn-add {
|
|
435
|
+
padding: 8px 16px;
|
|
436
|
+
background: linear-gradient(180deg, var(--pink-bright), var(--pink));
|
|
437
|
+
color: #14101c;
|
|
438
|
+
border: 1px solid rgba(0,0,0,.2);
|
|
439
|
+
border-radius: 999px;
|
|
440
|
+
font: inherit;
|
|
441
|
+
font-size: 12px;
|
|
442
|
+
font-weight: 700;
|
|
443
|
+
cursor: pointer;
|
|
444
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 1px 2px rgba(0,0,0,.25);
|
|
445
|
+
transition: filter .12s, transform .08s, box-shadow .12s;
|
|
446
|
+
}
|
|
447
|
+
.btn-add:hover {
|
|
448
|
+
filter: brightness(1.06);
|
|
449
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 4px 14px rgba(244,114,182,.4);
|
|
450
|
+
}
|
|
451
|
+
.btn-add:active { transform: translateY(1px) scale(.98); }
|
|
452
|
+
|
|
453
|
+
/* ── Cart drawer ─────────────────────────────────────── */
|
|
454
|
+
.cart-drawer {
|
|
455
|
+
position: fixed;
|
|
456
|
+
top: 0; right: 0;
|
|
457
|
+
width: 420px; max-width: 92vw;
|
|
458
|
+
height: 100vh;
|
|
459
|
+
background: linear-gradient(180deg, var(--bg-1), var(--bg));
|
|
460
|
+
border-left: 1px solid var(--edge);
|
|
461
|
+
transform: translateX(100%);
|
|
462
|
+
transition: transform .35s cubic-bezier(.16,1,.3,1);
|
|
463
|
+
display: flex; flex-direction: column;
|
|
464
|
+
z-index: 50;
|
|
465
|
+
box-shadow: -20px 0 60px rgba(0,0,0,.5);
|
|
466
|
+
}
|
|
467
|
+
.cart-drawer.open { transform: translateX(0); }
|
|
468
|
+
.cart-overlay {
|
|
469
|
+
position: fixed; inset: 0;
|
|
470
|
+
background: rgba(12,8,20,.5);
|
|
471
|
+
backdrop-filter: blur(6px);
|
|
472
|
+
z-index: 49;
|
|
473
|
+
opacity: 0;
|
|
474
|
+
pointer-events: none;
|
|
475
|
+
transition: opacity .25s;
|
|
476
|
+
}
|
|
477
|
+
.cart-overlay.visible { opacity: 1; pointer-events: auto; }
|
|
478
|
+
|
|
479
|
+
.cart-drawer-head {
|
|
480
|
+
padding: 20px 24px;
|
|
481
|
+
border-bottom: 1px solid var(--edge);
|
|
482
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
483
|
+
}
|
|
484
|
+
.cart-drawer-head h2 {
|
|
485
|
+
font-size: 16px; font-weight: 700; color: var(--ink);
|
|
486
|
+
letter-spacing: -.01em;
|
|
487
|
+
}
|
|
488
|
+
.cart-drawer-head .count {
|
|
489
|
+
font-size: 11px; color: var(--ink-faint);
|
|
490
|
+
font-family: ui-monospace, "SF Mono", monospace;
|
|
491
|
+
margin-left: 8px;
|
|
492
|
+
}
|
|
493
|
+
.cart-close {
|
|
494
|
+
background: rgba(255,255,255,.04); border: 1px solid var(--edge);
|
|
495
|
+
width: 32px; height: 32px;
|
|
496
|
+
border-radius: 999px;
|
|
497
|
+
color: var(--ink-muted);
|
|
498
|
+
cursor: pointer; font-size: 16px; line-height: 1;
|
|
499
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
500
|
+
transition: background .12s, color .12s;
|
|
501
|
+
}
|
|
502
|
+
.cart-close:hover { background: rgba(255,255,255,.08); color: var(--ink); }
|
|
503
|
+
|
|
504
|
+
.cart-items {
|
|
505
|
+
flex: 1; overflow-y: auto;
|
|
506
|
+
padding: 14px 18px;
|
|
507
|
+
}
|
|
508
|
+
.cart-item {
|
|
509
|
+
display: flex; gap: 14px; align-items: center;
|
|
510
|
+
padding: 12px 0;
|
|
511
|
+
border-bottom: 1px solid rgba(255,255,255,.05);
|
|
512
|
+
}
|
|
513
|
+
.cart-item:last-child { border-bottom: none; }
|
|
514
|
+
.cart-item-thumb {
|
|
515
|
+
width: 50px; height: 50px;
|
|
516
|
+
border-radius: 10px;
|
|
517
|
+
background: linear-gradient(135deg, #432857, #2e1c3a);
|
|
518
|
+
display: flex; align-items: center; justify-content: center;
|
|
519
|
+
font-size: 22px;
|
|
520
|
+
flex-shrink: 0;
|
|
521
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
|
|
522
|
+
}
|
|
523
|
+
.cart-item-info { flex: 1; min-width: 0; }
|
|
524
|
+
.cart-item-name { font-size: 13px; color: var(--ink); font-weight: 600; }
|
|
525
|
+
.cart-item-price { font-size: 12px; color: var(--pink-bright); margin-top: 3px; font-variant-numeric: tabular-nums; }
|
|
526
|
+
.qty-controls {
|
|
527
|
+
display: inline-flex; align-items: center;
|
|
528
|
+
background: rgba(255,255,255,.04);
|
|
529
|
+
border: 1px solid var(--edge);
|
|
530
|
+
border-radius: 999px;
|
|
531
|
+
overflow: hidden;
|
|
532
|
+
}
|
|
533
|
+
.qty-btn {
|
|
534
|
+
background: none; border: none; color: var(--ink-muted);
|
|
535
|
+
width: 26px; height: 26px;
|
|
536
|
+
cursor: pointer; font-size: 14px; line-height: 1;
|
|
537
|
+
transition: background .12s, color .12s;
|
|
538
|
+
}
|
|
539
|
+
.qty-btn:hover { background: rgba(255,255,255,.07); color: var(--ink); }
|
|
540
|
+
.qty-val { font-size: 12px; min-width: 22px; text-align: center; color: var(--ink); font-weight: 600; }
|
|
541
|
+
|
|
542
|
+
.cart-empty {
|
|
543
|
+
text-align: center;
|
|
544
|
+
padding: 80px 30px;
|
|
545
|
+
color: var(--ink-faint);
|
|
546
|
+
font-size: 13px;
|
|
547
|
+
}
|
|
548
|
+
.cart-empty svg { width: 40px; height: 40px; opacity: .4; margin-bottom: 14px; }
|
|
549
|
+
|
|
550
|
+
.cart-foot {
|
|
551
|
+
padding: 18px 22px 22px;
|
|
552
|
+
border-top: 1px solid var(--edge);
|
|
553
|
+
background: rgba(0,0,0,.25);
|
|
554
|
+
}
|
|
555
|
+
.promo-row { display: flex; gap: 8px; margin-bottom: 10px; }
|
|
556
|
+
.promo-row input {
|
|
557
|
+
flex: 1;
|
|
558
|
+
padding: 9px 13px;
|
|
559
|
+
background: rgba(255,255,255,.04);
|
|
560
|
+
border: 1px solid var(--edge);
|
|
561
|
+
border-radius: 8px;
|
|
562
|
+
color: var(--ink);
|
|
563
|
+
font: inherit; font-size: 12.5px;
|
|
564
|
+
outline: none;
|
|
565
|
+
}
|
|
566
|
+
.promo-row input:focus { border-color: rgba(244,114,182,.5); }
|
|
567
|
+
.btn-promo {
|
|
568
|
+
padding: 9px 14px;
|
|
569
|
+
background: rgba(255,255,255,.06);
|
|
570
|
+
border: 1px solid var(--edge-strong);
|
|
571
|
+
color: var(--ink);
|
|
572
|
+
border-radius: 8px;
|
|
573
|
+
font: inherit; font-size: 12px; font-weight: 600;
|
|
574
|
+
cursor: pointer;
|
|
575
|
+
transition: background .12s;
|
|
576
|
+
}
|
|
577
|
+
.btn-promo:hover { background: rgba(255,255,255,.10); }
|
|
578
|
+
.promo-msg { font-size: 11.5px; min-height: 14px; margin-bottom: 8px; }
|
|
579
|
+
.promo-msg.ok { color: var(--emerald-bright); }
|
|
580
|
+
.promo-msg.err { color: var(--rose); }
|
|
581
|
+
|
|
582
|
+
.totals {
|
|
583
|
+
font-size: 13px;
|
|
584
|
+
color: var(--ink-2);
|
|
585
|
+
margin-bottom: 14px;
|
|
586
|
+
padding: 14px 0 0;
|
|
587
|
+
border-top: 1px solid rgba(255,255,255,.04);
|
|
588
|
+
}
|
|
589
|
+
.totals-row { display: flex; justify-content: space-between; padding: 5px 0; font-variant-numeric: tabular-nums; }
|
|
590
|
+
.totals-row strong { color: var(--ink); font-size: 17px; }
|
|
591
|
+
.totals-row.discount { color: var(--emerald-bright); }
|
|
592
|
+
|
|
593
|
+
.btn-checkout {
|
|
594
|
+
width: 100%;
|
|
595
|
+
padding: 14px;
|
|
596
|
+
background: linear-gradient(180deg, var(--pink-bright), var(--pink-deep));
|
|
597
|
+
color: #fff;
|
|
598
|
+
border: 1px solid rgba(0,0,0,.25);
|
|
599
|
+
border-radius: 12px;
|
|
600
|
+
font: inherit; font-size: 14px; font-weight: 700; letter-spacing: -.005em;
|
|
601
|
+
cursor: pointer;
|
|
602
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 6px 18px rgba(244,114,182,.3);
|
|
603
|
+
transition: filter .12s, transform .08s;
|
|
604
|
+
margin-top: 4px;
|
|
605
|
+
}
|
|
606
|
+
.btn-checkout:hover { filter: brightness(1.06); }
|
|
607
|
+
.btn-checkout:active { transform: translateY(1px); }
|
|
608
|
+
.btn-checkout[disabled] {
|
|
609
|
+
background: rgba(255,255,255,.06); color: var(--ink-faint);
|
|
610
|
+
cursor: not-allowed; box-shadow: none; filter: none;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/* ── Checkout modal ─────────────────────────────────────── */
|
|
614
|
+
.checkout-overlay {
|
|
615
|
+
position: fixed; inset: 0;
|
|
616
|
+
background: rgba(12,8,20,.85);
|
|
617
|
+
backdrop-filter: blur(10px);
|
|
618
|
+
display: none;
|
|
619
|
+
align-items: center; justify-content: center;
|
|
620
|
+
z-index: 100;
|
|
621
|
+
padding: 20px;
|
|
622
|
+
}
|
|
623
|
+
.checkout-overlay.open { display: flex; animation: fadeIn .25s ease-out; }
|
|
624
|
+
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
|
625
|
+
.checkout-card {
|
|
626
|
+
width: 480px; max-width: 100%;
|
|
627
|
+
background: linear-gradient(180deg, var(--bg-2), var(--bg-1));
|
|
628
|
+
border: 1px solid var(--edge-strong);
|
|
629
|
+
border-radius: 18px;
|
|
630
|
+
padding: 28px 30px;
|
|
631
|
+
box-shadow: 0 30px 80px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.05);
|
|
632
|
+
animation: slideUp .35s cubic-bezier(.16,1,.3,1);
|
|
633
|
+
}
|
|
634
|
+
@keyframes slideUp { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
|
|
635
|
+
.checkout-card h2 {
|
|
636
|
+
font-size: 20px; color: var(--ink);
|
|
637
|
+
margin-bottom: 6px; font-weight: 800; letter-spacing: -.02em;
|
|
638
|
+
}
|
|
639
|
+
.checkout-card .lead {
|
|
640
|
+
font-size: 13px; color: var(--ink-muted);
|
|
641
|
+
margin-bottom: 22px;
|
|
642
|
+
}
|
|
643
|
+
.field { margin-bottom: 14px; }
|
|
644
|
+
.field label {
|
|
645
|
+
display: block; font-size: 10.5px; color: var(--ink-faint);
|
|
646
|
+
margin-bottom: 6px;
|
|
647
|
+
font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
|
|
648
|
+
}
|
|
649
|
+
.field input {
|
|
650
|
+
width: 100%;
|
|
651
|
+
padding: 11px 13px;
|
|
652
|
+
background: rgba(255,255,255,.04);
|
|
653
|
+
border: 1px solid var(--edge);
|
|
654
|
+
border-radius: 10px;
|
|
655
|
+
color: var(--ink);
|
|
656
|
+
font: inherit; font-size: 13.5px;
|
|
657
|
+
outline: none;
|
|
658
|
+
transition: border-color .14s, background .14s;
|
|
659
|
+
}
|
|
660
|
+
.field input:focus { border-color: rgba(244,114,182,.5); background: rgba(255,255,255,.06); }
|
|
661
|
+
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
|
662
|
+
.checkout-actions { display: flex; gap: 10px; margin-top: 22px; }
|
|
663
|
+
.btn-cancel {
|
|
664
|
+
flex: 1;
|
|
665
|
+
padding: 12px;
|
|
666
|
+
background: rgba(255,255,255,.04);
|
|
667
|
+
border: 1px solid var(--edge-strong);
|
|
668
|
+
color: var(--ink-2);
|
|
669
|
+
border-radius: 12px;
|
|
670
|
+
font: inherit; font-size: 13px; font-weight: 600;
|
|
671
|
+
cursor: pointer;
|
|
672
|
+
transition: background .12s;
|
|
673
|
+
}
|
|
674
|
+
.btn-cancel:hover { background: rgba(255,255,255,.08); color: var(--ink); }
|
|
675
|
+
.btn-place {
|
|
676
|
+
flex: 1.6;
|
|
677
|
+
padding: 12px;
|
|
678
|
+
background: linear-gradient(180deg, var(--pink-bright), var(--pink-deep));
|
|
679
|
+
color: #fff; border: 1px solid rgba(0,0,0,.2);
|
|
680
|
+
border-radius: 12px;
|
|
681
|
+
font: inherit; font-size: 13px; font-weight: 800;
|
|
682
|
+
cursor: pointer;
|
|
683
|
+
box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 4px 14px rgba(244,114,182,.3);
|
|
684
|
+
transition: filter .12s, transform .08s;
|
|
685
|
+
}
|
|
686
|
+
.btn-place:hover { filter: brightness(1.06); }
|
|
687
|
+
.btn-place:active { transform: translateY(1px); }
|
|
688
|
+
|
|
689
|
+
.order-confirmation { text-align: center; padding: 24px 12px; }
|
|
690
|
+
.order-confirmation .check {
|
|
691
|
+
width: 72px; height: 72px;
|
|
692
|
+
border-radius: 50%;
|
|
693
|
+
background:
|
|
694
|
+
radial-gradient(circle at 30% 30%, rgba(255,255,255,.2), transparent 60%),
|
|
695
|
+
linear-gradient(135deg, var(--emerald-bright), var(--emerald));
|
|
696
|
+
display: flex; align-items: center; justify-content: center;
|
|
697
|
+
margin: 0 auto 18px;
|
|
698
|
+
color: #04140e; font-size: 36px;
|
|
699
|
+
box-shadow: 0 0 24px rgba(52,211,153,.5);
|
|
700
|
+
}
|
|
701
|
+
.order-confirmation h2 { font-size: 22px; color: var(--ink); margin-bottom: 8px; font-weight: 800; }
|
|
702
|
+
.order-confirmation p { font-size: 13.5px; color: var(--ink-muted); line-height: 1.55; }
|
|
703
|
+
.order-confirmation .order-id {
|
|
704
|
+
margin-top: 18px;
|
|
705
|
+
font-family: ui-monospace, "SF Mono", monospace;
|
|
706
|
+
font-size: 12px;
|
|
707
|
+
padding: 6px 14px;
|
|
708
|
+
background: rgba(244,114,182,.10);
|
|
709
|
+
border: 1px solid rgba(244,114,182,.3);
|
|
710
|
+
border-radius: 6px;
|
|
711
|
+
color: var(--pink-bright);
|
|
712
|
+
display: inline-block;
|
|
713
|
+
letter-spacing: .04em;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
::selection { background: rgba(244,114,182,.4); color: #fff; }
|
|
717
|
+
</style>
|
|
718
|
+
</head>
|
|
719
|
+
<body>
|
|
720
|
+
<nav class="nav">
|
|
721
|
+
<a class="brand" href="#">
|
|
722
|
+
<span class="brand-mark">H</span>
|
|
723
|
+
Helix Outfitters
|
|
724
|
+
</a>
|
|
725
|
+
<div class="nav-search">
|
|
726
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6"><circle cx="7" cy="7" r="4.5"/><path d="M10.5 10.5l3 3"/></svg>
|
|
727
|
+
<input id="search" type="search" placeholder="Search products…" aria-label="Search products">
|
|
728
|
+
</div>
|
|
729
|
+
<div class="nav-actions">
|
|
730
|
+
<button class="nav-icon-btn" aria-label="Account">
|
|
731
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="8" cy="6" r="2.5"/><path d="M3 14c0-2.5 2.2-4.5 5-4.5s5 2 5 4.5"/></svg>
|
|
732
|
+
</button>
|
|
733
|
+
<button class="nav-icon-btn" id="cart-btn" aria-label="Cart">
|
|
734
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><circle cx="6" cy="13" r="1.2"/><circle cx="12" cy="13" r="1.2"/><path d="M2 3h2l1.5 7.5h8L15 5H5"/></svg>
|
|
735
|
+
<span class="cart-badge empty" id="cart-count">0</span>
|
|
736
|
+
</button>
|
|
737
|
+
</div>
|
|
738
|
+
</nav>
|
|
739
|
+
|
|
740
|
+
<section class="hero">
|
|
741
|
+
<div class="hero-text">
|
|
742
|
+
<span class="hero-eyebrow">Spring Drop · Free shipping over $100</span>
|
|
743
|
+
<h1>Gear that gets out of your way.</h1>
|
|
744
|
+
<p class="lead">A small lineup of desk accessories from independent makers. <strong>Click-tested by Alethia</strong> — destructive checkout actions are blocked by the EA1 safety gate.</p>
|
|
745
|
+
<div class="hero-promo">
|
|
746
|
+
<span>Take 20% off your first order with</span>
|
|
747
|
+
<span class="code">HELIX20</span>
|
|
748
|
+
</div>
|
|
749
|
+
</div>
|
|
750
|
+
<div class="hero-feature">
|
|
751
|
+
<span class="hero-feature-tag">Editor's Pick</span>
|
|
752
|
+
<span class="hero-feature-icon">⌨️</span>
|
|
753
|
+
<div class="hero-feature-meta">
|
|
754
|
+
<div>
|
|
755
|
+
<div class="name">Tide Mechanical Keyboard</div>
|
|
756
|
+
<div class="desc">75% layout · Hot-swap · Linear switches</div>
|
|
757
|
+
</div>
|
|
758
|
+
<div class="price">$179</div>
|
|
759
|
+
</div>
|
|
760
|
+
</div>
|
|
761
|
+
</section>
|
|
762
|
+
|
|
763
|
+
<div class="filters">
|
|
764
|
+
<div class="filters-group">
|
|
765
|
+
<button class="chip active" data-filter="all">All</button>
|
|
766
|
+
<button class="chip" data-filter="input">Input</button>
|
|
767
|
+
<button class="chip" data-filter="display">Display</button>
|
|
768
|
+
<button class="chip" data-filter="audio">Audio</button>
|
|
769
|
+
</div>
|
|
770
|
+
<span class="results-count" id="results-count">6 products</span>
|
|
771
|
+
</div>
|
|
772
|
+
|
|
773
|
+
<section class="products" id="products">
|
|
774
|
+
<article class="product" data-cat="input" data-name="Tide Mechanical Keyboard">
|
|
775
|
+
<div class="product-image" data-tag="kbd">
|
|
776
|
+
<span>⌨️</span>
|
|
777
|
+
<span class="badge new">New</span>
|
|
778
|
+
<button class="wishlist-btn" data-wish="Tide Mechanical Keyboard" aria-label="Save to wishlist">
|
|
779
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
780
|
+
</button>
|
|
781
|
+
</div>
|
|
782
|
+
<div class="product-body">
|
|
783
|
+
<div class="category">Input · Keyboards</div>
|
|
784
|
+
<h2>Tide Mechanical Keyboard</h2>
|
|
785
|
+
<p class="desc">75% layout · hot-swap · linear switches</p>
|
|
786
|
+
<div class="rating"><span class="stars">★★★★★</span> <span>4.8 · 218 reviews</span></div>
|
|
787
|
+
<div class="product-foot">
|
|
788
|
+
<span class="price">$179</span>
|
|
789
|
+
<button class="btn-add" data-name="Tide Mechanical Keyboard" data-price="179" data-icon="⌨️">Add to Cart</button>
|
|
790
|
+
</div>
|
|
791
|
+
</div>
|
|
792
|
+
</article>
|
|
793
|
+
|
|
794
|
+
<article class="product" data-cat="input" data-name="Sigil USB-C Hub">
|
|
795
|
+
<div class="product-image" data-tag="hub">
|
|
796
|
+
<span>🔌</span>
|
|
797
|
+
<button class="wishlist-btn" data-wish="Sigil USB-C Hub" aria-label="Save to wishlist">
|
|
798
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
799
|
+
</button>
|
|
800
|
+
</div>
|
|
801
|
+
<div class="product-body">
|
|
802
|
+
<div class="category">Input · Connectivity</div>
|
|
803
|
+
<h2>Sigil USB-C Hub</h2>
|
|
804
|
+
<p class="desc">7-port · 100W passthrough · aluminum</p>
|
|
805
|
+
<div class="rating"><span class="stars">★★★★☆</span> <span>4.4 · 96 reviews</span></div>
|
|
806
|
+
<div class="product-foot">
|
|
807
|
+
<span class="price">$59</span>
|
|
808
|
+
<button class="btn-add" data-name="Sigil USB-C Hub" data-price="59" data-icon="🔌">Add to Cart</button>
|
|
809
|
+
</div>
|
|
810
|
+
</div>
|
|
811
|
+
</article>
|
|
812
|
+
|
|
813
|
+
<article class="product" data-cat="display" data-name="Aria Monitor Stand">
|
|
814
|
+
<div class="product-image" data-tag="stand">
|
|
815
|
+
<span>🖥️</span>
|
|
816
|
+
<span class="badge sale">−19%</span>
|
|
817
|
+
<button class="wishlist-btn" data-wish="Aria Monitor Stand" aria-label="Save to wishlist">
|
|
818
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
819
|
+
</button>
|
|
820
|
+
</div>
|
|
821
|
+
<div class="product-body">
|
|
822
|
+
<div class="category">Display · Stands</div>
|
|
823
|
+
<h2>Aria Monitor Stand</h2>
|
|
824
|
+
<p class="desc">Adjustable height · solid walnut · cable channel</p>
|
|
825
|
+
<div class="rating"><span class="stars">★★★★★</span> <span>4.9 · 412 reviews</span></div>
|
|
826
|
+
<div class="product-foot">
|
|
827
|
+
<span class="price"><span class="price-was">$159</span>$129</span>
|
|
828
|
+
<button class="btn-add" data-name="Aria Monitor Stand" data-price="129" data-icon="🖥️">Add to Cart</button>
|
|
829
|
+
</div>
|
|
830
|
+
</div>
|
|
831
|
+
</article>
|
|
832
|
+
|
|
833
|
+
<article class="product" data-cat="input" data-name="Vector Pro Mouse">
|
|
834
|
+
<div class="product-image" data-tag="mouse">
|
|
835
|
+
<span>🖱️</span>
|
|
836
|
+
<span class="badge few-left">Only 3 left</span>
|
|
837
|
+
<button class="wishlist-btn" data-wish="Vector Pro Mouse" aria-label="Save to wishlist">
|
|
838
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
839
|
+
</button>
|
|
840
|
+
</div>
|
|
841
|
+
<div class="product-body">
|
|
842
|
+
<div class="category">Input · Pointing</div>
|
|
843
|
+
<h2>Vector Pro Mouse</h2>
|
|
844
|
+
<p class="desc">Wireless · 8K polling · 60g titanium chassis</p>
|
|
845
|
+
<div class="rating"><span class="stars">★★★★★</span> <span>4.7 · 184 reviews</span></div>
|
|
846
|
+
<div class="product-foot">
|
|
847
|
+
<span class="price">$89</span>
|
|
848
|
+
<button class="btn-add" data-name="Vector Pro Mouse" data-price="89" data-icon="🖱️">Add to Cart</button>
|
|
849
|
+
</div>
|
|
850
|
+
</div>
|
|
851
|
+
</article>
|
|
852
|
+
|
|
853
|
+
<article class="product" data-cat="display" data-name="Halo 4K Webcam">
|
|
854
|
+
<div class="product-image" data-tag="webcam">
|
|
855
|
+
<span>📷</span>
|
|
856
|
+
<button class="wishlist-btn" data-wish="Halo 4K Webcam" aria-label="Save to wishlist">
|
|
857
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
858
|
+
</button>
|
|
859
|
+
</div>
|
|
860
|
+
<div class="product-body">
|
|
861
|
+
<div class="category">Display · Webcams</div>
|
|
862
|
+
<h2>Halo 4K Webcam</h2>
|
|
863
|
+
<p class="desc">4K @ 60fps · auto-framing · privacy shutter</p>
|
|
864
|
+
<div class="rating"><span class="stars">★★★★☆</span> <span>4.5 · 142 reviews</span></div>
|
|
865
|
+
<div class="product-foot">
|
|
866
|
+
<span class="price">$219</span>
|
|
867
|
+
<button class="btn-add" data-name="Halo 4K Webcam" data-price="219" data-icon="📷">Add to Cart</button>
|
|
868
|
+
</div>
|
|
869
|
+
</div>
|
|
870
|
+
</article>
|
|
871
|
+
|
|
872
|
+
<article class="product" data-cat="audio" data-name="Reed Studio Microphone">
|
|
873
|
+
<div class="product-image" data-tag="mic">
|
|
874
|
+
<span>🎙️</span>
|
|
875
|
+
<span class="badge new">New</span>
|
|
876
|
+
<button class="wishlist-btn" data-wish="Reed Studio Microphone" aria-label="Save to wishlist">
|
|
877
|
+
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4"><path d="M8 14s-5-3.5-5-7.5C3 4.5 4.5 3 6.5 3c1 0 1.7.4 1.5.9C8 4.4 8.5 3 10 3c2 0 3.5 1.5 3.5 3.5C13.5 10.5 8 14 8 14z"/></svg>
|
|
878
|
+
</button>
|
|
879
|
+
</div>
|
|
880
|
+
<div class="product-body">
|
|
881
|
+
<div class="category">Audio · Microphones</div>
|
|
882
|
+
<h2>Reed Studio Microphone</h2>
|
|
883
|
+
<p class="desc">USB-C · cardioid · onboard DSP</p>
|
|
884
|
+
<div class="rating"><span class="stars">★★★★★</span> <span>4.8 · 76 reviews</span></div>
|
|
885
|
+
<div class="product-foot">
|
|
886
|
+
<span class="price">$149</span>
|
|
887
|
+
<button class="btn-add" data-name="Reed Studio Microphone" data-price="149" data-icon="🎙️">Add to Cart</button>
|
|
888
|
+
</div>
|
|
889
|
+
</div>
|
|
890
|
+
</article>
|
|
891
|
+
</section>
|
|
892
|
+
|
|
893
|
+
<div class="cart-overlay" id="cart-overlay"></div>
|
|
894
|
+
<aside class="cart-drawer" id="cart-drawer">
|
|
895
|
+
<div class="cart-drawer-head">
|
|
896
|
+
<h2>Your Cart <span class="count" id="cart-count-text">0 items</span></h2>
|
|
897
|
+
<button class="cart-close" id="cart-close" aria-label="Close cart">×</button>
|
|
898
|
+
</div>
|
|
899
|
+
<div class="cart-items" id="cart-items">
|
|
900
|
+
<div class="cart-empty" id="cart-empty">
|
|
901
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.4"><circle cx="9" cy="20" r="1.4"/><circle cx="17" cy="20" r="1.4"/><path d="M3 4h2.5l2.2 11h11.3l1.8-7H7"/></svg>
|
|
902
|
+
<div>Your cart is empty.</div>
|
|
903
|
+
</div>
|
|
904
|
+
</div>
|
|
905
|
+
<div class="cart-foot">
|
|
906
|
+
<div class="promo-row">
|
|
907
|
+
<input type="text" id="promo-input" placeholder="Promo code (try HELIX20)">
|
|
908
|
+
<button class="btn-promo" id="btn-apply-promo">Apply</button>
|
|
909
|
+
</div>
|
|
910
|
+
<div class="promo-msg" id="promo-msg"></div>
|
|
911
|
+
<div class="totals">
|
|
912
|
+
<div class="totals-row"><span>Subtotal</span><span id="subtotal">$0.00</span></div>
|
|
913
|
+
<div class="totals-row discount" id="discount-row" style="display: none;"><span>Discount</span><span id="discount">-$0.00</span></div>
|
|
914
|
+
<div class="totals-row" style="margin-top: 6px;"><strong>Total</strong><strong id="total">$0.00</strong></div>
|
|
915
|
+
</div>
|
|
916
|
+
<button class="btn-checkout" id="btn-checkout" disabled>Review Order</button>
|
|
917
|
+
</div>
|
|
918
|
+
</aside>
|
|
919
|
+
|
|
920
|
+
<div class="checkout-overlay" id="checkout-overlay">
|
|
921
|
+
<div class="checkout-card" id="checkout-card">
|
|
922
|
+
<div id="checkout-form">
|
|
923
|
+
<h2>Checkout</h2>
|
|
924
|
+
<p class="lead">Local-only demo — no data leaves your machine.</p>
|
|
925
|
+
<div class="field">
|
|
926
|
+
<label for="email">Email</label>
|
|
927
|
+
<input id="email" type="email" placeholder="you@example.com" autocomplete="off">
|
|
928
|
+
</div>
|
|
929
|
+
<div class="field">
|
|
930
|
+
<label for="shipping">Shipping Address</label>
|
|
931
|
+
<input id="shipping" type="text" placeholder="123 Main St, Anytown" autocomplete="off">
|
|
932
|
+
</div>
|
|
933
|
+
<div class="field">
|
|
934
|
+
<label for="card">Card Number</label>
|
|
935
|
+
<input id="card" type="text" placeholder="•••• •••• •••• ••••" inputmode="numeric" autocomplete="off">
|
|
936
|
+
</div>
|
|
937
|
+
<div class="field-row">
|
|
938
|
+
<div class="field">
|
|
939
|
+
<label for="exp">Exp</label>
|
|
940
|
+
<input id="exp" type="text" placeholder="MM/YY" autocomplete="off">
|
|
941
|
+
</div>
|
|
942
|
+
<div class="field">
|
|
943
|
+
<label for="cvc">CVC</label>
|
|
944
|
+
<input id="cvc" type="text" placeholder="123" autocomplete="off">
|
|
945
|
+
</div>
|
|
946
|
+
</div>
|
|
947
|
+
<div class="checkout-actions">
|
|
948
|
+
<button class="btn-cancel" id="btn-cancel-checkout">Cancel</button>
|
|
949
|
+
<button class="btn-place" id="btn-place-order">Complete Purchase</button>
|
|
950
|
+
</div>
|
|
951
|
+
</div>
|
|
952
|
+
<div class="order-confirmation" id="order-confirmation" style="display: none;">
|
|
953
|
+
<div class="check">✓</div>
|
|
954
|
+
<h2>Order placed</h2>
|
|
955
|
+
<p>Thanks for shopping with Helix. A confirmation has been sent to your email.</p>
|
|
956
|
+
<div class="order-id">Order #HX-<span id="order-num"></span></div>
|
|
957
|
+
</div>
|
|
958
|
+
</div>
|
|
959
|
+
</div>
|
|
960
|
+
|
|
961
|
+
<script>
|
|
962
|
+
const cart = [];
|
|
963
|
+
let promoApplied = false;
|
|
964
|
+
const $ = (s) => document.querySelector(s);
|
|
965
|
+
const cartCountEl = $('#cart-count');
|
|
966
|
+
const cartCountTextEl = $('#cart-count-text');
|
|
967
|
+
const cartItemsEl = $('#cart-items');
|
|
968
|
+
const cartEmptyEl = $('#cart-empty');
|
|
969
|
+
const subtotalEl = $('#subtotal');
|
|
970
|
+
const discountEl = $('#discount');
|
|
971
|
+
const discountRowEl = $('#discount-row');
|
|
972
|
+
const totalEl = $('#total');
|
|
973
|
+
const checkoutBtn = $('#btn-checkout');
|
|
974
|
+
const fmt = (n) => '$' + n.toFixed(2);
|
|
975
|
+
|
|
976
|
+
function renderCart() {
|
|
977
|
+
const totalQty = cart.reduce((acc, it) => acc + it.qty, 0);
|
|
978
|
+
cartCountEl.textContent = String(totalQty);
|
|
979
|
+
cartCountEl.classList.toggle('empty', totalQty === 0);
|
|
980
|
+
cartCountTextEl.textContent = `${totalQty} item${totalQty === 1 ? '' : 's'}`;
|
|
981
|
+
checkoutBtn.disabled = cart.length === 0;
|
|
982
|
+
cartItemsEl.innerHTML = '';
|
|
983
|
+
if (cart.length === 0) {
|
|
984
|
+
cartEmptyEl.style.display = 'block';
|
|
985
|
+
cartItemsEl.appendChild(cartEmptyEl);
|
|
986
|
+
} else {
|
|
987
|
+
cartEmptyEl.style.display = 'none';
|
|
988
|
+
for (const item of cart) {
|
|
989
|
+
const row = document.createElement('div');
|
|
990
|
+
row.className = 'cart-item';
|
|
991
|
+
row.innerHTML = `
|
|
992
|
+
<div class="cart-item-thumb">${item.icon || '◇'}</div>
|
|
993
|
+
<div class="cart-item-info">
|
|
994
|
+
<div class="cart-item-name">${item.name}</div>
|
|
995
|
+
<div class="cart-item-price">${fmt(item.price * item.qty)}</div>
|
|
996
|
+
</div>
|
|
997
|
+
<div class="qty-controls" data-name="${item.name}">
|
|
998
|
+
<button class="qty-btn qty-dec" aria-label="Decrease quantity">−</button>
|
|
999
|
+
<span class="qty-val">${item.qty}</span>
|
|
1000
|
+
<button class="qty-btn qty-inc" aria-label="Increase quantity">+</button>
|
|
1001
|
+
</div>
|
|
1002
|
+
`;
|
|
1003
|
+
cartItemsEl.appendChild(row);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
const subtotal = cart.reduce((acc, it) => acc + it.price * it.qty, 0);
|
|
1007
|
+
const discount = promoApplied ? subtotal * 0.20 : 0;
|
|
1008
|
+
const total = subtotal - discount;
|
|
1009
|
+
subtotalEl.textContent = fmt(subtotal);
|
|
1010
|
+
discountEl.textContent = '-' + fmt(discount);
|
|
1011
|
+
discountRowEl.style.display = promoApplied && cart.length > 0 ? 'flex' : 'none';
|
|
1012
|
+
totalEl.textContent = fmt(total);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function openCart() {
|
|
1016
|
+
$('#cart-drawer').classList.add('open');
|
|
1017
|
+
$('#cart-overlay').classList.add('visible');
|
|
1018
|
+
}
|
|
1019
|
+
function closeCart() {
|
|
1020
|
+
$('#cart-drawer').classList.remove('open');
|
|
1021
|
+
$('#cart-overlay').classList.remove('visible');
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
document.addEventListener('click', (e) => {
|
|
1025
|
+
const addBtn = e.target.closest('.btn-add');
|
|
1026
|
+
if (addBtn) {
|
|
1027
|
+
const name = addBtn.dataset.name;
|
|
1028
|
+
const price = Number(addBtn.dataset.price);
|
|
1029
|
+
const icon = addBtn.dataset.icon || '◇';
|
|
1030
|
+
const existing = cart.find((x) => x.name === name);
|
|
1031
|
+
if (existing) existing.qty += 1;
|
|
1032
|
+
else cart.push({ name, qty: 1, price, icon });
|
|
1033
|
+
renderCart();
|
|
1034
|
+
openCart();
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const wish = e.target.closest('.wishlist-btn');
|
|
1038
|
+
if (wish) { wish.classList.toggle('saved'); return; }
|
|
1039
|
+
const qty = e.target.closest('.qty-btn');
|
|
1040
|
+
if (qty) {
|
|
1041
|
+
const ctrls = qty.closest('.qty-controls');
|
|
1042
|
+
const name = ctrls.dataset.name;
|
|
1043
|
+
const item = cart.find((x) => x.name === name);
|
|
1044
|
+
if (!item) return;
|
|
1045
|
+
if (qty.classList.contains('qty-inc')) item.qty += 1;
|
|
1046
|
+
else if (qty.classList.contains('qty-dec')) {
|
|
1047
|
+
item.qty -= 1;
|
|
1048
|
+
if (item.qty <= 0) { const idx = cart.indexOf(item); if (idx >= 0) cart.splice(idx, 1); }
|
|
1049
|
+
}
|
|
1050
|
+
renderCart();
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
1053
|
+
|
|
1054
|
+
$('#cart-btn').addEventListener('click', () => {
|
|
1055
|
+
$('#cart-drawer').classList.contains('open') ? closeCart() : openCart();
|
|
1056
|
+
});
|
|
1057
|
+
$('#cart-close').addEventListener('click', closeCart);
|
|
1058
|
+
$('#cart-overlay').addEventListener('click', closeCart);
|
|
1059
|
+
|
|
1060
|
+
$('#btn-apply-promo').addEventListener('click', () => {
|
|
1061
|
+
const code = ($('#promo-input').value || '').trim().toUpperCase();
|
|
1062
|
+
const msg = $('#promo-msg');
|
|
1063
|
+
if (code === 'HELIX20') {
|
|
1064
|
+
promoApplied = true;
|
|
1065
|
+
msg.textContent = '20% discount applied.';
|
|
1066
|
+
msg.className = 'promo-msg ok';
|
|
1067
|
+
} else if (code) {
|
|
1068
|
+
promoApplied = false;
|
|
1069
|
+
msg.textContent = 'Code not recognized.';
|
|
1070
|
+
msg.className = 'promo-msg err';
|
|
1071
|
+
} else {
|
|
1072
|
+
promoApplied = false;
|
|
1073
|
+
msg.textContent = '';
|
|
1074
|
+
msg.className = 'promo-msg';
|
|
1075
|
+
}
|
|
1076
|
+
renderCart();
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
document.querySelectorAll('.chip').forEach((chip) => {
|
|
1080
|
+
chip.addEventListener('click', () => {
|
|
1081
|
+
document.querySelectorAll('.chip').forEach((c) => c.classList.remove('active'));
|
|
1082
|
+
chip.classList.add('active');
|
|
1083
|
+
applyFilters();
|
|
1084
|
+
});
|
|
1085
|
+
});
|
|
1086
|
+
$('#search').addEventListener('input', applyFilters);
|
|
1087
|
+
|
|
1088
|
+
function applyFilters() {
|
|
1089
|
+
const cat = document.querySelector('.chip.active')?.dataset.filter || 'all';
|
|
1090
|
+
const q = ($('#search').value || '').trim().toLowerCase();
|
|
1091
|
+
let visible = 0;
|
|
1092
|
+
document.querySelectorAll('.product').forEach((p) => {
|
|
1093
|
+
const matchesCat = cat === 'all' || p.dataset.cat === cat;
|
|
1094
|
+
const matchesQ = !q || (p.dataset.name || '').toLowerCase().includes(q);
|
|
1095
|
+
const show = matchesCat && matchesQ;
|
|
1096
|
+
p.classList.toggle('hidden', !show);
|
|
1097
|
+
if (show) visible += 1;
|
|
1098
|
+
});
|
|
1099
|
+
$('#results-count').textContent = `${visible} product${visible === 1 ? '' : 's'}`;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
$('#btn-checkout').addEventListener('click', () => { $('#checkout-overlay').classList.add('open'); });
|
|
1103
|
+
$('#btn-cancel-checkout').addEventListener('click', () => { $('#checkout-overlay').classList.remove('open'); });
|
|
1104
|
+
$('#btn-place-order').addEventListener('click', () => {
|
|
1105
|
+
$('#checkout-form').style.display = 'none';
|
|
1106
|
+
$('#order-confirmation').style.display = 'block';
|
|
1107
|
+
$('#order-num').textContent = String(Math.floor(100000 + Math.random() * 900000));
|
|
1108
|
+
cart.length = 0;
|
|
1109
|
+
promoApplied = false;
|
|
1110
|
+
renderCart();
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
renderCart();
|
|
1114
|
+
</script>
|
|
1115
|
+
</body>
|
|
1116
|
+
</html>
|