fraim-framework 2.0.166 → 2.0.168
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/dist/src/ai-hub/catalog.js +43 -36
- package/dist/src/ai-hub/server.js +28 -5
- package/dist/src/cli/commands/init-project.js +1 -98
- package/dist/src/cli/commands/manager.js +40 -0
- package/dist/src/cli/commands/sync.js +17 -21
- package/dist/src/cli/fraim.js +2 -0
- package/dist/src/cli/utils/github-workflow-sync.js +12 -146
- package/dist/src/cli/utils/manager-pack-sync.js +188 -0
- package/dist/src/cli/utils/manager-publish.js +76 -0
- package/dist/src/cli/utils/user-config.js +20 -0
- package/dist/src/core/config-loader.js +9 -5
- package/dist/src/core/fraim-config-schema.generated.js +85 -31
- package/dist/src/core/manager-pack.js +26 -0
- package/dist/src/core/utils/local-registry-resolver.js +8 -1
- package/dist/src/first-run/install-state.js +1 -0
- package/dist/src/first-run/server.js +9 -0
- package/dist/src/first-run/session-service.js +117 -23
- package/dist/src/first-run/types.js +2 -5
- package/dist/src/local-mcp-server/learning-context-builder.js +45 -8
- package/dist/src/local-mcp-server/stdio-server.js +28 -0
- package/index.js +1 -1
- package/package.json +4 -1
- package/public/ai-hub/powerpoint-taskpane/index.html +236 -236
- package/public/ai-hub/powerpoint-taskpane/manifest.xml +29 -29
- package/public/ai-hub/review.css +13 -0
- package/public/ai-hub/script.js +199 -5
- package/public/ai-hub/styles.css +28 -0
- package/public/first-run/index.html +1 -1
- package/public/first-run/script.js +459 -530
- package/public/first-run/styles.css +288 -73
- package/public/portfolio/ashley.html +523 -0
- package/public/portfolio/auditya.html +83 -0
- package/public/portfolio/banke.html +83 -0
- package/public/portfolio/beza.html +659 -0
- package/public/portfolio/careena.html +632 -0
- package/public/portfolio/casey.html +568 -0
- package/public/portfolio/celia.html +490 -0
- package/public/portfolio/deidre.html +642 -0
- package/public/portfolio/gautam.html +597 -0
- package/public/portfolio/hari.html +469 -0
- package/public/portfolio/huxley.html +1354 -0
- package/public/portfolio/index.html +741 -0
- package/public/portfolio/maestro.html +518 -0
- package/public/portfolio/mandy.html +590 -0
- package/public/portfolio/mona.html +597 -0
- package/public/portfolio/pam.html +887 -0
- package/public/portfolio/procella.html +107 -0
- package/public/portfolio/qasm.html +569 -0
- package/public/portfolio/ricardo.html +489 -0
- package/public/portfolio/sade.html +560 -0
- package/public/portfolio/sam.html +654 -0
- package/public/portfolio/sechar.html +580 -0
- package/public/portfolio/sreya.html +599 -0
- package/public/portfolio/swen.html +601 -0
- package/dist/src/ai-hub/word-sideload.js +0 -95
- package/dist/src/cli/commands/test-mcp.js +0 -171
- package/dist/src/cli/setup/first-run.js +0 -242
- package/dist/src/core/config-writer.js +0 -75
- package/dist/src/core/utils/job-aliases.js +0 -47
- package/dist/src/core/utils/workflow-parser.js +0 -174
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>hUXley | AI UX and Brand Designer | FRAIM Portfolio</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=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@500;700&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--accent: #10b981;
|
|
13
|
+
--accent-2: #059669;
|
|
14
|
+
--accent-soft: #d1fae5;
|
|
15
|
+
--bg: #f0fdf8;
|
|
16
|
+
--surface: #ffffff;
|
|
17
|
+
--surface-2: #f8fafc;
|
|
18
|
+
--text: #09241c;
|
|
19
|
+
--text-2: #334155;
|
|
20
|
+
--muted: #64748b;
|
|
21
|
+
--border: #dbe7e2;
|
|
22
|
+
--shadow: 0 18px 48px rgba(5, 120, 87, 0.12);
|
|
23
|
+
}
|
|
24
|
+
[data-theme="dark"] {
|
|
25
|
+
--bg: #06131c;
|
|
26
|
+
--surface: #0d2035;
|
|
27
|
+
--surface-2: #112842;
|
|
28
|
+
--text: #ecfdf5;
|
|
29
|
+
--text-2: #cbd5e1;
|
|
30
|
+
--muted: #94a3b8;
|
|
31
|
+
--border: #1e3a5f;
|
|
32
|
+
--shadow: 0 18px 48px rgba(0, 0, 0, 0.32);
|
|
33
|
+
}
|
|
34
|
+
* { box-sizing: border-box; }
|
|
35
|
+
body {
|
|
36
|
+
margin: 0;
|
|
37
|
+
font-family: "Inter", sans-serif;
|
|
38
|
+
color: var(--text);
|
|
39
|
+
background:
|
|
40
|
+
radial-gradient(circle at top, rgba(16, 185, 129, 0.18), transparent 30%),
|
|
41
|
+
linear-gradient(180deg, rgba(255, 255, 255, 0.2), transparent 42%),
|
|
42
|
+
var(--bg);
|
|
43
|
+
}
|
|
44
|
+
.site-header {
|
|
45
|
+
position: sticky;
|
|
46
|
+
top: 0;
|
|
47
|
+
z-index: 20;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: space-between;
|
|
51
|
+
padding: 16px 24px;
|
|
52
|
+
border-bottom: 1px solid var(--border);
|
|
53
|
+
background: rgba(255, 255, 255, 0.88);
|
|
54
|
+
backdrop-filter: blur(12px);
|
|
55
|
+
}
|
|
56
|
+
[data-theme="dark"] .site-header { background: rgba(6, 19, 28, 0.88); }
|
|
57
|
+
.brand {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 10px;
|
|
61
|
+
color: var(--text);
|
|
62
|
+
text-decoration: none;
|
|
63
|
+
font-weight: 700;
|
|
64
|
+
}
|
|
65
|
+
.brand-logo {
|
|
66
|
+
width: 34px;
|
|
67
|
+
height: 34px;
|
|
68
|
+
border-radius: 10px;
|
|
69
|
+
background: linear-gradient(135deg, #10b981, #3b82f6);
|
|
70
|
+
color: #fff;
|
|
71
|
+
display: grid;
|
|
72
|
+
place-items: center;
|
|
73
|
+
}
|
|
74
|
+
.theme-btn {
|
|
75
|
+
border: 1px solid var(--border);
|
|
76
|
+
background: var(--surface);
|
|
77
|
+
color: var(--text);
|
|
78
|
+
border-radius: 999px;
|
|
79
|
+
padding: 8px 12px;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
}
|
|
82
|
+
.hero,
|
|
83
|
+
.section,
|
|
84
|
+
.footer {
|
|
85
|
+
width: min(1120px, calc(100% - 32px));
|
|
86
|
+
margin: 0 auto;
|
|
87
|
+
}
|
|
88
|
+
.hero { padding: 56px 0 28px; }
|
|
89
|
+
.hero-grid {
|
|
90
|
+
display: grid;
|
|
91
|
+
grid-template-columns: 1.15fr 0.85fr;
|
|
92
|
+
gap: 22px;
|
|
93
|
+
}
|
|
94
|
+
.panel,
|
|
95
|
+
.card {
|
|
96
|
+
background: var(--surface);
|
|
97
|
+
border: 1px solid var(--border);
|
|
98
|
+
border-radius: 28px;
|
|
99
|
+
box-shadow: var(--shadow);
|
|
100
|
+
}
|
|
101
|
+
.panel { padding: 30px; }
|
|
102
|
+
.chip {
|
|
103
|
+
display: inline-flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
padding: 7px 12px;
|
|
106
|
+
border-radius: 999px;
|
|
107
|
+
background: var(--accent-soft);
|
|
108
|
+
color: var(--accent-2);
|
|
109
|
+
font-size: 12px;
|
|
110
|
+
text-transform: uppercase;
|
|
111
|
+
letter-spacing: 0.05em;
|
|
112
|
+
font-weight: 700;
|
|
113
|
+
}
|
|
114
|
+
h1 {
|
|
115
|
+
margin: 18px 0 14px;
|
|
116
|
+
font-size: clamp(34px, 5vw, 62px);
|
|
117
|
+
line-height: 0.97;
|
|
118
|
+
letter-spacing: -0.05em;
|
|
119
|
+
}
|
|
120
|
+
.hero p,
|
|
121
|
+
.summary p,
|
|
122
|
+
.context,
|
|
123
|
+
.narrative-step {
|
|
124
|
+
color: var(--text-2);
|
|
125
|
+
line-height: 1.7;
|
|
126
|
+
}
|
|
127
|
+
.metric-grid,
|
|
128
|
+
.proof-grid,
|
|
129
|
+
.narrative {
|
|
130
|
+
display: grid;
|
|
131
|
+
grid-template-columns: repeat(3, 1fr);
|
|
132
|
+
gap: 12px;
|
|
133
|
+
}
|
|
134
|
+
.metric-grid { margin-top: 22px; }
|
|
135
|
+
.metric,
|
|
136
|
+
.summary-card,
|
|
137
|
+
.proof,
|
|
138
|
+
.narrative-step {
|
|
139
|
+
background: var(--surface-2);
|
|
140
|
+
border-radius: 20px;
|
|
141
|
+
padding: 16px;
|
|
142
|
+
}
|
|
143
|
+
.metric strong,
|
|
144
|
+
.summary-card strong,
|
|
145
|
+
.proof-label {
|
|
146
|
+
display: block;
|
|
147
|
+
margin-bottom: 6px;
|
|
148
|
+
}
|
|
149
|
+
.metric strong { font-size: 22px; }
|
|
150
|
+
.summary {
|
|
151
|
+
display: grid;
|
|
152
|
+
gap: 12px;
|
|
153
|
+
}
|
|
154
|
+
.section { padding: 18px 0 72px; }
|
|
155
|
+
.section-head {
|
|
156
|
+
display: flex;
|
|
157
|
+
align-items: center;
|
|
158
|
+
gap: 16px;
|
|
159
|
+
margin-bottom: 18px;
|
|
160
|
+
}
|
|
161
|
+
.section-head h2 {
|
|
162
|
+
margin: 0;
|
|
163
|
+
color: var(--muted);
|
|
164
|
+
text-transform: uppercase;
|
|
165
|
+
letter-spacing: 0.12em;
|
|
166
|
+
font-size: 13px;
|
|
167
|
+
}
|
|
168
|
+
.section-line {
|
|
169
|
+
flex: 1;
|
|
170
|
+
height: 1px;
|
|
171
|
+
background: var(--border);
|
|
172
|
+
}
|
|
173
|
+
.card-stack {
|
|
174
|
+
display: grid;
|
|
175
|
+
gap: 18px;
|
|
176
|
+
}
|
|
177
|
+
.card-header {
|
|
178
|
+
display: flex;
|
|
179
|
+
gap: 16px;
|
|
180
|
+
align-items: flex-start;
|
|
181
|
+
padding: 24px 24px 0;
|
|
182
|
+
cursor: pointer;
|
|
183
|
+
}
|
|
184
|
+
.card-icon {
|
|
185
|
+
width: 52px;
|
|
186
|
+
height: 52px;
|
|
187
|
+
border-radius: 16px;
|
|
188
|
+
display: grid;
|
|
189
|
+
place-items: center;
|
|
190
|
+
background: var(--accent-soft);
|
|
191
|
+
color: var(--accent-2);
|
|
192
|
+
font-family: "JetBrains Mono", monospace;
|
|
193
|
+
font-size: 14px;
|
|
194
|
+
font-weight: 700;
|
|
195
|
+
}
|
|
196
|
+
.card-meta { flex: 1; }
|
|
197
|
+
.card-tag {
|
|
198
|
+
color: var(--accent-2);
|
|
199
|
+
text-transform: uppercase;
|
|
200
|
+
letter-spacing: 0.08em;
|
|
201
|
+
font-size: 12px;
|
|
202
|
+
font-weight: 700;
|
|
203
|
+
}
|
|
204
|
+
.card-title {
|
|
205
|
+
margin: 8px 0 6px;
|
|
206
|
+
font-size: 25px;
|
|
207
|
+
line-height: 1.08;
|
|
208
|
+
}
|
|
209
|
+
.card-subtitle {
|
|
210
|
+
color: var(--muted);
|
|
211
|
+
font-size: 13px;
|
|
212
|
+
}
|
|
213
|
+
.card-toggle {
|
|
214
|
+
font-size: 28px;
|
|
215
|
+
color: var(--muted);
|
|
216
|
+
}
|
|
217
|
+
.card-body {
|
|
218
|
+
display: none;
|
|
219
|
+
padding: 22px 24px 24px;
|
|
220
|
+
}
|
|
221
|
+
.card.open .card-body { display: block; }
|
|
222
|
+
.card.open .card-toggle { transform: rotate(90deg); }
|
|
223
|
+
.context {
|
|
224
|
+
margin: 0 0 16px;
|
|
225
|
+
background: var(--surface-2);
|
|
226
|
+
border-radius: 18px;
|
|
227
|
+
padding: 16px 18px;
|
|
228
|
+
}
|
|
229
|
+
.proof-label {
|
|
230
|
+
color: var(--muted);
|
|
231
|
+
text-transform: uppercase;
|
|
232
|
+
letter-spacing: 0.1em;
|
|
233
|
+
font-size: 11px;
|
|
234
|
+
font-weight: 700;
|
|
235
|
+
}
|
|
236
|
+
.artifact-label {
|
|
237
|
+
margin: 0 0 12px;
|
|
238
|
+
color: var(--muted);
|
|
239
|
+
text-transform: uppercase;
|
|
240
|
+
letter-spacing: 0.08em;
|
|
241
|
+
font-size: 12px;
|
|
242
|
+
font-weight: 700;
|
|
243
|
+
}
|
|
244
|
+
.artifact-shell {
|
|
245
|
+
background: var(--surface);
|
|
246
|
+
border: 1px solid var(--border);
|
|
247
|
+
border-radius: 20px;
|
|
248
|
+
overflow: hidden;
|
|
249
|
+
}
|
|
250
|
+
.source-ref {
|
|
251
|
+
margin-top: 16px;
|
|
252
|
+
font-size: 12px;
|
|
253
|
+
color: var(--muted);
|
|
254
|
+
display: flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
gap: 6px;
|
|
257
|
+
}
|
|
258
|
+
.source-ref a { color: var(--accent-2); text-decoration: none; }
|
|
259
|
+
.source-ref a:hover { text-decoration: underline; }
|
|
260
|
+
|
|
261
|
+
.ashley-dashboard {
|
|
262
|
+
background: #0f172a;
|
|
263
|
+
border-radius: 20px;
|
|
264
|
+
overflow: hidden;
|
|
265
|
+
border: 1px solid #1e293b;
|
|
266
|
+
}
|
|
267
|
+
.ashley-topbar {
|
|
268
|
+
background: #1e293b;
|
|
269
|
+
padding: 12px 18px;
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
justify-content: space-between;
|
|
273
|
+
gap: 12px;
|
|
274
|
+
}
|
|
275
|
+
.ashley-topbar-left {
|
|
276
|
+
display: flex;
|
|
277
|
+
align-items: center;
|
|
278
|
+
gap: 10px;
|
|
279
|
+
}
|
|
280
|
+
.ashley-avatar-sm {
|
|
281
|
+
width: 30px;
|
|
282
|
+
height: 30px;
|
|
283
|
+
border-radius: 50%;
|
|
284
|
+
background: linear-gradient(135deg, #3b82f6, #8b5cf6);
|
|
285
|
+
display: flex;
|
|
286
|
+
align-items: center;
|
|
287
|
+
justify-content: center;
|
|
288
|
+
font-size: 11px;
|
|
289
|
+
font-weight: 700;
|
|
290
|
+
color: #fff;
|
|
291
|
+
}
|
|
292
|
+
.ashley-name {
|
|
293
|
+
font-size: 13px;
|
|
294
|
+
font-weight: 600;
|
|
295
|
+
color: #e2e8f0;
|
|
296
|
+
}
|
|
297
|
+
.ashley-topbar-date {
|
|
298
|
+
font-size: 12px;
|
|
299
|
+
color: #94a3b8;
|
|
300
|
+
}
|
|
301
|
+
.ashley-topbar-badge {
|
|
302
|
+
background: #3b82f6;
|
|
303
|
+
color: #fff;
|
|
304
|
+
font-size: 11px;
|
|
305
|
+
font-weight: 600;
|
|
306
|
+
border-radius: 999px;
|
|
307
|
+
padding: 3px 10px;
|
|
308
|
+
}
|
|
309
|
+
.ashley-layout {
|
|
310
|
+
display: grid;
|
|
311
|
+
grid-template-columns: 220px 1fr;
|
|
312
|
+
min-height: 320px;
|
|
313
|
+
}
|
|
314
|
+
.ashley-sidebar {
|
|
315
|
+
background: #1e293b;
|
|
316
|
+
border-right: 1px solid #334155;
|
|
317
|
+
padding: 16px 0;
|
|
318
|
+
}
|
|
319
|
+
.ashley-sidebar-section { padding: 0 14px 12px; }
|
|
320
|
+
.ashley-sidebar-label {
|
|
321
|
+
font-size: 10px;
|
|
322
|
+
font-weight: 700;
|
|
323
|
+
letter-spacing: 0.1em;
|
|
324
|
+
text-transform: uppercase;
|
|
325
|
+
color: #64748b;
|
|
326
|
+
margin-bottom: 8px;
|
|
327
|
+
}
|
|
328
|
+
.ashley-cal-item {
|
|
329
|
+
display: flex;
|
|
330
|
+
align-items: center;
|
|
331
|
+
gap: 8px;
|
|
332
|
+
padding: 6px 8px;
|
|
333
|
+
border-radius: 7px;
|
|
334
|
+
margin-bottom: 2px;
|
|
335
|
+
}
|
|
336
|
+
.ashley-cal-item.active { background: #334155; }
|
|
337
|
+
.ashley-cal-dot {
|
|
338
|
+
width: 8px;
|
|
339
|
+
height: 8px;
|
|
340
|
+
border-radius: 50%;
|
|
341
|
+
flex-shrink: 0;
|
|
342
|
+
}
|
|
343
|
+
.ashley-cal-name {
|
|
344
|
+
font-size: 12px;
|
|
345
|
+
color: #cbd5e1;
|
|
346
|
+
}
|
|
347
|
+
.ashley-sidebar-divider {
|
|
348
|
+
height: 1px;
|
|
349
|
+
background: #334155;
|
|
350
|
+
margin: 8px 14px;
|
|
351
|
+
}
|
|
352
|
+
.ashley-main { padding: 16px; }
|
|
353
|
+
.ashley-date-strip {
|
|
354
|
+
display: flex;
|
|
355
|
+
gap: 6px;
|
|
356
|
+
margin-bottom: 16px;
|
|
357
|
+
overflow-x: auto;
|
|
358
|
+
padding-bottom: 2px;
|
|
359
|
+
}
|
|
360
|
+
.ashley-day-pill {
|
|
361
|
+
display: flex;
|
|
362
|
+
flex-direction: column;
|
|
363
|
+
align-items: center;
|
|
364
|
+
padding: 8px 12px;
|
|
365
|
+
border-radius: 10px;
|
|
366
|
+
min-width: 46px;
|
|
367
|
+
flex-shrink: 0;
|
|
368
|
+
background: #111827;
|
|
369
|
+
}
|
|
370
|
+
.ashley-day-pill.today { background: #3b82f6; }
|
|
371
|
+
.ashley-day-dow {
|
|
372
|
+
font-size: 10px;
|
|
373
|
+
color: #94a3b8;
|
|
374
|
+
font-weight: 600;
|
|
375
|
+
letter-spacing: 0.05em;
|
|
376
|
+
}
|
|
377
|
+
.ashley-day-num {
|
|
378
|
+
font-size: 16px;
|
|
379
|
+
font-weight: 700;
|
|
380
|
+
color: #e2e8f0;
|
|
381
|
+
}
|
|
382
|
+
.ashley-events {
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-direction: column;
|
|
385
|
+
gap: 8px;
|
|
386
|
+
}
|
|
387
|
+
.ashley-event-card {
|
|
388
|
+
display: flex;
|
|
389
|
+
border-radius: 10px;
|
|
390
|
+
overflow: hidden;
|
|
391
|
+
background: #1e293b;
|
|
392
|
+
border: 1px solid #334155;
|
|
393
|
+
}
|
|
394
|
+
.ashley-event-accent { width: 4px; flex-shrink: 0; }
|
|
395
|
+
.ashley-event-body {
|
|
396
|
+
padding: 10px 12px;
|
|
397
|
+
flex: 1;
|
|
398
|
+
min-width: 0;
|
|
399
|
+
}
|
|
400
|
+
.ashley-event-time {
|
|
401
|
+
font-size: 11px;
|
|
402
|
+
color: #94a3b8;
|
|
403
|
+
font-weight: 600;
|
|
404
|
+
margin-bottom: 3px;
|
|
405
|
+
}
|
|
406
|
+
.ashley-event-title {
|
|
407
|
+
font-size: 13px;
|
|
408
|
+
color: #e2e8f0;
|
|
409
|
+
font-weight: 600;
|
|
410
|
+
margin-bottom: 4px;
|
|
411
|
+
}
|
|
412
|
+
.ashley-event-meta {
|
|
413
|
+
display: flex;
|
|
414
|
+
align-items: center;
|
|
415
|
+
gap: 8px;
|
|
416
|
+
}
|
|
417
|
+
.ashley-event-loc {
|
|
418
|
+
font-size: 11px;
|
|
419
|
+
color: #94a3b8;
|
|
420
|
+
}
|
|
421
|
+
.ashley-event-attendees { display: flex; }
|
|
422
|
+
.ashley-attendee {
|
|
423
|
+
width: 18px;
|
|
424
|
+
height: 18px;
|
|
425
|
+
border-radius: 50%;
|
|
426
|
+
border: 2px solid #1e293b;
|
|
427
|
+
display: flex;
|
|
428
|
+
align-items: center;
|
|
429
|
+
justify-content: center;
|
|
430
|
+
font-size: 8px;
|
|
431
|
+
font-weight: 700;
|
|
432
|
+
color: #fff;
|
|
433
|
+
margin-left: -4px;
|
|
434
|
+
}
|
|
435
|
+
.ashley-event-actions {
|
|
436
|
+
display: flex;
|
|
437
|
+
align-items: center;
|
|
438
|
+
padding: 0 12px;
|
|
439
|
+
gap: 4px;
|
|
440
|
+
}
|
|
441
|
+
.ashley-action-btn {
|
|
442
|
+
padding: 6px 8px;
|
|
443
|
+
border-radius: 6px;
|
|
444
|
+
background: transparent;
|
|
445
|
+
border: none;
|
|
446
|
+
font-size: 13px;
|
|
447
|
+
color: #94a3b8;
|
|
448
|
+
}
|
|
449
|
+
.ashley-fab {
|
|
450
|
+
display: inline-flex;
|
|
451
|
+
align-items: center;
|
|
452
|
+
gap: 6px;
|
|
453
|
+
background: #3b82f6;
|
|
454
|
+
color: #fff;
|
|
455
|
+
border: none;
|
|
456
|
+
border-radius: 8px;
|
|
457
|
+
padding: 8px 14px;
|
|
458
|
+
font-size: 12px;
|
|
459
|
+
font-weight: 600;
|
|
460
|
+
margin-top: 14px;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.voice-demo {
|
|
464
|
+
background: linear-gradient(160deg, #0f172a 0%, #1a103c 100%);
|
|
465
|
+
border-radius: 20px;
|
|
466
|
+
padding: 32px 24px;
|
|
467
|
+
display: flex;
|
|
468
|
+
flex-direction: column;
|
|
469
|
+
align-items: center;
|
|
470
|
+
gap: 24px;
|
|
471
|
+
border: 1px solid #2d1b69;
|
|
472
|
+
position: relative;
|
|
473
|
+
overflow: hidden;
|
|
474
|
+
}
|
|
475
|
+
.voice-demo::before {
|
|
476
|
+
content: "";
|
|
477
|
+
position: absolute;
|
|
478
|
+
top: -80px;
|
|
479
|
+
left: 50%;
|
|
480
|
+
transform: translateX(-50%);
|
|
481
|
+
width: 320px;
|
|
482
|
+
height: 320px;
|
|
483
|
+
background: radial-gradient(circle, rgba(139, 92, 246, 0.15) 0%, transparent 70%);
|
|
484
|
+
pointer-events: none;
|
|
485
|
+
}
|
|
486
|
+
.voice-state-flow {
|
|
487
|
+
display: flex;
|
|
488
|
+
align-items: center;
|
|
489
|
+
gap: 8px;
|
|
490
|
+
flex-wrap: wrap;
|
|
491
|
+
justify-content: center;
|
|
492
|
+
}
|
|
493
|
+
.vstate {
|
|
494
|
+
padding: 5px 12px;
|
|
495
|
+
border-radius: 999px;
|
|
496
|
+
font-size: 11px;
|
|
497
|
+
font-weight: 600;
|
|
498
|
+
letter-spacing: 0.05em;
|
|
499
|
+
background: rgba(255, 255, 255, 0.06);
|
|
500
|
+
color: rgba(255, 255, 255, 0.45);
|
|
501
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
502
|
+
}
|
|
503
|
+
.vstate.active {
|
|
504
|
+
background: rgba(139, 92, 246, 0.25);
|
|
505
|
+
color: #ddd6fe;
|
|
506
|
+
border-color: rgba(139, 92, 246, 0.4);
|
|
507
|
+
}
|
|
508
|
+
.vstate-arrow { color: rgba(255, 255, 255, 0.25); }
|
|
509
|
+
.voice-center {
|
|
510
|
+
display: flex;
|
|
511
|
+
flex-direction: column;
|
|
512
|
+
align-items: center;
|
|
513
|
+
gap: 16px;
|
|
514
|
+
}
|
|
515
|
+
.mic-ring-outer {
|
|
516
|
+
width: 120px;
|
|
517
|
+
height: 120px;
|
|
518
|
+
border-radius: 50%;
|
|
519
|
+
display: flex;
|
|
520
|
+
align-items: center;
|
|
521
|
+
justify-content: center;
|
|
522
|
+
position: relative;
|
|
523
|
+
}
|
|
524
|
+
.mic-ring-pulse {
|
|
525
|
+
position: absolute;
|
|
526
|
+
inset: 0;
|
|
527
|
+
border-radius: 50%;
|
|
528
|
+
border: 2px solid rgba(139, 92, 246, 0.5);
|
|
529
|
+
animation: pulse-ring 1.8s ease-out infinite;
|
|
530
|
+
}
|
|
531
|
+
.mic-ring-pulse:nth-child(2) { animation-delay: 0.6s; }
|
|
532
|
+
.mic-ring-pulse:nth-child(3) { animation-delay: 1.2s; }
|
|
533
|
+
@keyframes pulse-ring {
|
|
534
|
+
0% { transform: scale(1); opacity: 0.8; }
|
|
535
|
+
100% { transform: scale(1.8); opacity: 0; }
|
|
536
|
+
}
|
|
537
|
+
.mic-btn {
|
|
538
|
+
width: 80px;
|
|
539
|
+
height: 80px;
|
|
540
|
+
border-radius: 50%;
|
|
541
|
+
background: linear-gradient(135deg, #7c3aed, #8b5cf6);
|
|
542
|
+
display: flex;
|
|
543
|
+
align-items: center;
|
|
544
|
+
justify-content: center;
|
|
545
|
+
position: relative;
|
|
546
|
+
z-index: 1;
|
|
547
|
+
border: none;
|
|
548
|
+
color: #fff;
|
|
549
|
+
font-size: 22px;
|
|
550
|
+
font-weight: 700;
|
|
551
|
+
}
|
|
552
|
+
.voice-status { text-align: center; }
|
|
553
|
+
.voice-status-label {
|
|
554
|
+
font-size: 13px;
|
|
555
|
+
font-weight: 600;
|
|
556
|
+
color: #ddd6fe;
|
|
557
|
+
margin-bottom: 4px;
|
|
558
|
+
}
|
|
559
|
+
.voice-status-sub {
|
|
560
|
+
font-size: 12px;
|
|
561
|
+
color: rgba(255, 255, 255, 0.45);
|
|
562
|
+
}
|
|
563
|
+
.waveform {
|
|
564
|
+
display: flex;
|
|
565
|
+
align-items: center;
|
|
566
|
+
gap: 3px;
|
|
567
|
+
height: 40px;
|
|
568
|
+
}
|
|
569
|
+
.waveform-bar {
|
|
570
|
+
width: 3px;
|
|
571
|
+
border-radius: 3px;
|
|
572
|
+
background: #8b5cf6;
|
|
573
|
+
animation: wave 1.2s ease-in-out infinite;
|
|
574
|
+
}
|
|
575
|
+
.waveform-bar:nth-child(1) { height: 12px; animation-delay: 0s; }
|
|
576
|
+
.waveform-bar:nth-child(2) { height: 24px; animation-delay: 0.1s; }
|
|
577
|
+
.waveform-bar:nth-child(3) { height: 36px; animation-delay: 0.2s; }
|
|
578
|
+
.waveform-bar:nth-child(4) { height: 28px; animation-delay: 0.3s; }
|
|
579
|
+
.waveform-bar:nth-child(5) { height: 16px; animation-delay: 0.4s; }
|
|
580
|
+
.waveform-bar:nth-child(6) { height: 32px; animation-delay: 0.5s; }
|
|
581
|
+
.waveform-bar:nth-child(7) { height: 20px; animation-delay: 0.6s; }
|
|
582
|
+
.waveform-bar:nth-child(8) { height: 36px; animation-delay: 0.7s; }
|
|
583
|
+
.waveform-bar:nth-child(9) { height: 14px; animation-delay: 0.8s; }
|
|
584
|
+
.waveform-bar:nth-child(10) { height: 26px; animation-delay: 0.9s; }
|
|
585
|
+
@keyframes wave {
|
|
586
|
+
0%, 100% { transform: scaleY(1); }
|
|
587
|
+
50% { transform: scaleY(0.35); }
|
|
588
|
+
}
|
|
589
|
+
.voice-transcript {
|
|
590
|
+
background: rgba(255, 255, 255, 0.05);
|
|
591
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
592
|
+
border-radius: 12px;
|
|
593
|
+
padding: 14px 18px;
|
|
594
|
+
width: 100%;
|
|
595
|
+
max-width: 360px;
|
|
596
|
+
text-align: center;
|
|
597
|
+
}
|
|
598
|
+
.transcript-user {
|
|
599
|
+
font-size: 13px;
|
|
600
|
+
color: rgba(255, 255, 255, 0.7);
|
|
601
|
+
font-style: italic;
|
|
602
|
+
margin-bottom: 10px;
|
|
603
|
+
}
|
|
604
|
+
.transcript-ashley {
|
|
605
|
+
font-size: 13px;
|
|
606
|
+
color: #a7f3d0;
|
|
607
|
+
font-weight: 500;
|
|
608
|
+
}
|
|
609
|
+
.voice-flow-detail {
|
|
610
|
+
display: grid;
|
|
611
|
+
grid-template-columns: repeat(4, 1fr);
|
|
612
|
+
gap: 10px;
|
|
613
|
+
width: 100%;
|
|
614
|
+
max-width: 420px;
|
|
615
|
+
}
|
|
616
|
+
.vflow-step {
|
|
617
|
+
background: rgba(255, 255, 255, 0.05);
|
|
618
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
619
|
+
border-radius: 10px;
|
|
620
|
+
padding: 12px 8px;
|
|
621
|
+
text-align: center;
|
|
622
|
+
}
|
|
623
|
+
.vflow-icon {
|
|
624
|
+
font-size: 16px;
|
|
625
|
+
font-weight: 700;
|
|
626
|
+
color: #ddd6fe;
|
|
627
|
+
margin-bottom: 6px;
|
|
628
|
+
}
|
|
629
|
+
.vflow-label {
|
|
630
|
+
font-size: 11px;
|
|
631
|
+
font-weight: 600;
|
|
632
|
+
color: rgba(255, 255, 255, 0.55);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.c360-demo {
|
|
636
|
+
background: #0f172a;
|
|
637
|
+
border-radius: 20px;
|
|
638
|
+
overflow: hidden;
|
|
639
|
+
border: 1px solid #1e293b;
|
|
640
|
+
}
|
|
641
|
+
.c360-header {
|
|
642
|
+
background: linear-gradient(135deg, #1e293b, #1a1040);
|
|
643
|
+
padding: 20px 20px 0;
|
|
644
|
+
}
|
|
645
|
+
.c360-profile-row {
|
|
646
|
+
display: flex;
|
|
647
|
+
align-items: flex-start;
|
|
648
|
+
gap: 14px;
|
|
649
|
+
margin-bottom: 20px;
|
|
650
|
+
}
|
|
651
|
+
.c360-avatar {
|
|
652
|
+
width: 52px;
|
|
653
|
+
height: 52px;
|
|
654
|
+
border-radius: 50%;
|
|
655
|
+
background: linear-gradient(135deg, #6366f1, #8b5cf6);
|
|
656
|
+
display: flex;
|
|
657
|
+
align-items: center;
|
|
658
|
+
justify-content: center;
|
|
659
|
+
font-size: 18px;
|
|
660
|
+
font-weight: 700;
|
|
661
|
+
color: #fff;
|
|
662
|
+
flex-shrink: 0;
|
|
663
|
+
}
|
|
664
|
+
.c360-profile-info { flex: 1; min-width: 0; }
|
|
665
|
+
.c360-name {
|
|
666
|
+
font-size: 16px;
|
|
667
|
+
font-weight: 700;
|
|
668
|
+
color: #e2e8f0;
|
|
669
|
+
}
|
|
670
|
+
.c360-company {
|
|
671
|
+
font-size: 13px;
|
|
672
|
+
color: #94a3b8;
|
|
673
|
+
margin-bottom: 6px;
|
|
674
|
+
}
|
|
675
|
+
.c360-tags {
|
|
676
|
+
display: flex;
|
|
677
|
+
gap: 6px;
|
|
678
|
+
flex-wrap: wrap;
|
|
679
|
+
}
|
|
680
|
+
.c360-tag {
|
|
681
|
+
padding: 3px 10px;
|
|
682
|
+
border-radius: 999px;
|
|
683
|
+
font-size: 11px;
|
|
684
|
+
font-weight: 600;
|
|
685
|
+
}
|
|
686
|
+
.tag-premium { background: rgba(234, 179, 8, 0.15); color: #fbbf24; }
|
|
687
|
+
.tag-renewal { background: rgba(239, 68, 68, 0.15); color: #fca5a5; }
|
|
688
|
+
.tag-enterprise { background: rgba(99, 102, 241, 0.15); color: #c7d2fe; }
|
|
689
|
+
.c360-tabs {
|
|
690
|
+
display: flex;
|
|
691
|
+
gap: 0;
|
|
692
|
+
border-bottom: 1px solid #1e293b;
|
|
693
|
+
overflow-x: auto;
|
|
694
|
+
}
|
|
695
|
+
.c360-tab {
|
|
696
|
+
padding: 10px 16px;
|
|
697
|
+
font-size: 12px;
|
|
698
|
+
font-weight: 600;
|
|
699
|
+
color: #94a3b8;
|
|
700
|
+
border-bottom: 2px solid transparent;
|
|
701
|
+
white-space: nowrap;
|
|
702
|
+
}
|
|
703
|
+
.c360-tab.active {
|
|
704
|
+
color: #818cf8;
|
|
705
|
+
border-bottom-color: #818cf8;
|
|
706
|
+
}
|
|
707
|
+
.c360-body { padding: 18px 20px; }
|
|
708
|
+
.c360-score-row {
|
|
709
|
+
display: grid;
|
|
710
|
+
grid-template-columns: auto 1fr;
|
|
711
|
+
gap: 20px;
|
|
712
|
+
margin-bottom: 18px;
|
|
713
|
+
align-items: center;
|
|
714
|
+
}
|
|
715
|
+
.c360-metrics {
|
|
716
|
+
display: grid;
|
|
717
|
+
grid-template-columns: repeat(3, 1fr);
|
|
718
|
+
gap: 10px;
|
|
719
|
+
}
|
|
720
|
+
.c360-metric {
|
|
721
|
+
background: #111827;
|
|
722
|
+
border: 1px solid #1f2937;
|
|
723
|
+
border-radius: 12px;
|
|
724
|
+
padding: 12px;
|
|
725
|
+
text-align: center;
|
|
726
|
+
}
|
|
727
|
+
.c360-metric-val {
|
|
728
|
+
font-size: 20px;
|
|
729
|
+
font-weight: 800;
|
|
730
|
+
}
|
|
731
|
+
.c360-metric-label {
|
|
732
|
+
margin-top: 4px;
|
|
733
|
+
font-size: 11px;
|
|
734
|
+
color: #94a3b8;
|
|
735
|
+
text-transform: uppercase;
|
|
736
|
+
letter-spacing: 0.05em;
|
|
737
|
+
}
|
|
738
|
+
.c360-timeline-label {
|
|
739
|
+
font-size: 11px;
|
|
740
|
+
font-weight: 700;
|
|
741
|
+
text-transform: uppercase;
|
|
742
|
+
letter-spacing: 0.08em;
|
|
743
|
+
color: #94a3b8;
|
|
744
|
+
margin-bottom: 10px;
|
|
745
|
+
}
|
|
746
|
+
.c360-event {
|
|
747
|
+
display: grid;
|
|
748
|
+
grid-template-columns: auto 1fr auto;
|
|
749
|
+
gap: 10px;
|
|
750
|
+
align-items: center;
|
|
751
|
+
padding: 10px 0;
|
|
752
|
+
border-top: 1px solid #1f2937;
|
|
753
|
+
}
|
|
754
|
+
.c360-event:first-of-type { border-top: none; }
|
|
755
|
+
.c360-event-dot {
|
|
756
|
+
width: 10px;
|
|
757
|
+
height: 10px;
|
|
758
|
+
border-radius: 50%;
|
|
759
|
+
}
|
|
760
|
+
.c360-event-text {
|
|
761
|
+
font-size: 13px;
|
|
762
|
+
color: #e2e8f0;
|
|
763
|
+
}
|
|
764
|
+
.c360-event-time {
|
|
765
|
+
font-size: 11px;
|
|
766
|
+
color: #94a3b8;
|
|
767
|
+
}
|
|
768
|
+
.c360-sentiment {
|
|
769
|
+
display: inline-flex;
|
|
770
|
+
align-items: center;
|
|
771
|
+
padding: 2px 8px;
|
|
772
|
+
border-radius: 999px;
|
|
773
|
+
font-size: 10px;
|
|
774
|
+
font-weight: 700;
|
|
775
|
+
text-transform: uppercase;
|
|
776
|
+
letter-spacing: 0.04em;
|
|
777
|
+
}
|
|
778
|
+
.sent-pos { background: rgba(74, 222, 128, 0.15); color: #86efac; }
|
|
779
|
+
.sent-neg { background: rgba(248, 113, 113, 0.15); color: #fca5a5; }
|
|
780
|
+
.sent-neu { background: rgba(148, 163, 184, 0.15); color: #cbd5e1; }
|
|
781
|
+
|
|
782
|
+
.design-system-board {
|
|
783
|
+
padding: 18px;
|
|
784
|
+
background: linear-gradient(180deg, #f8fffb, #ecfdf5);
|
|
785
|
+
}
|
|
786
|
+
[data-theme="dark"] .design-system-board {
|
|
787
|
+
background: linear-gradient(180deg, #10201b, #0d1a16);
|
|
788
|
+
}
|
|
789
|
+
.design-grid {
|
|
790
|
+
display: grid;
|
|
791
|
+
grid-template-columns: 220px 1fr;
|
|
792
|
+
gap: 14px;
|
|
793
|
+
}
|
|
794
|
+
.design-panel,
|
|
795
|
+
.design-specimens {
|
|
796
|
+
border: 1px solid var(--border);
|
|
797
|
+
border-radius: 18px;
|
|
798
|
+
background: var(--surface);
|
|
799
|
+
padding: 16px;
|
|
800
|
+
}
|
|
801
|
+
.design-label {
|
|
802
|
+
font-size: 11px;
|
|
803
|
+
font-weight: 700;
|
|
804
|
+
color: var(--muted);
|
|
805
|
+
text-transform: uppercase;
|
|
806
|
+
letter-spacing: 0.08em;
|
|
807
|
+
margin-bottom: 10px;
|
|
808
|
+
}
|
|
809
|
+
.token-stack {
|
|
810
|
+
display: grid;
|
|
811
|
+
gap: 10px;
|
|
812
|
+
}
|
|
813
|
+
.token-row {
|
|
814
|
+
display: grid;
|
|
815
|
+
grid-template-columns: 52px 1fr;
|
|
816
|
+
gap: 10px;
|
|
817
|
+
align-items: center;
|
|
818
|
+
}
|
|
819
|
+
.swatch {
|
|
820
|
+
height: 40px;
|
|
821
|
+
border-radius: 12px;
|
|
822
|
+
border: 1px solid var(--border);
|
|
823
|
+
}
|
|
824
|
+
.token-copy strong {
|
|
825
|
+
display: block;
|
|
826
|
+
font-size: 13px;
|
|
827
|
+
}
|
|
828
|
+
.token-copy span {
|
|
829
|
+
font-size: 12px;
|
|
830
|
+
color: var(--muted);
|
|
831
|
+
}
|
|
832
|
+
.specimen-grid {
|
|
833
|
+
display: grid;
|
|
834
|
+
grid-template-columns: repeat(3, 1fr);
|
|
835
|
+
gap: 12px;
|
|
836
|
+
}
|
|
837
|
+
.specimen {
|
|
838
|
+
border: 1px solid var(--border);
|
|
839
|
+
border-radius: 16px;
|
|
840
|
+
overflow: hidden;
|
|
841
|
+
background: var(--surface-2);
|
|
842
|
+
}
|
|
843
|
+
.specimen-top {
|
|
844
|
+
height: 70px;
|
|
845
|
+
background: linear-gradient(135deg, rgba(16, 185, 129, 0.18), rgba(59, 130, 246, 0.2));
|
|
846
|
+
border-bottom: 1px solid var(--border);
|
|
847
|
+
}
|
|
848
|
+
.specimen-body { padding: 12px; }
|
|
849
|
+
.specimen-body strong {
|
|
850
|
+
display: block;
|
|
851
|
+
margin-bottom: 6px;
|
|
852
|
+
font-size: 13px;
|
|
853
|
+
}
|
|
854
|
+
.specimen-body p {
|
|
855
|
+
margin: 0;
|
|
856
|
+
font-size: 12px;
|
|
857
|
+
color: var(--muted);
|
|
858
|
+
line-height: 1.6;
|
|
859
|
+
}
|
|
860
|
+
.footer {
|
|
861
|
+
padding: 0 0 44px;
|
|
862
|
+
text-align: center;
|
|
863
|
+
color: var(--muted);
|
|
864
|
+
font-size: 13px;
|
|
865
|
+
}
|
|
866
|
+
.footer a { color: var(--accent-2); text-decoration: none; }
|
|
867
|
+
|
|
868
|
+
@media (max-width: 900px) {
|
|
869
|
+
.hero-grid,
|
|
870
|
+
.metric-grid,
|
|
871
|
+
.proof-grid,
|
|
872
|
+
.narrative,
|
|
873
|
+
.design-grid,
|
|
874
|
+
.specimen-grid {
|
|
875
|
+
grid-template-columns: 1fr;
|
|
876
|
+
}
|
|
877
|
+
.c360-score-row,
|
|
878
|
+
.ashley-layout,
|
|
879
|
+
.voice-flow-detail {
|
|
880
|
+
grid-template-columns: 1fr;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
@media (max-width: 640px) {
|
|
884
|
+
.site-header { padding: 14px 16px; }
|
|
885
|
+
.card-header { padding: 20px 20px 0; }
|
|
886
|
+
.card-body { padding: 18px 20px 20px; }
|
|
887
|
+
.panel { padding: 24px; }
|
|
888
|
+
.ashley-topbar,
|
|
889
|
+
.c360-profile-row {
|
|
890
|
+
flex-direction: column;
|
|
891
|
+
align-items: flex-start;
|
|
892
|
+
}
|
|
893
|
+
.c360-metrics { grid-template-columns: 1fr; }
|
|
894
|
+
}
|
|
895
|
+
</style>
|
|
896
|
+
</head>
|
|
897
|
+
<body>
|
|
898
|
+
<header class="site-header">
|
|
899
|
+
<a class="brand" href="/">
|
|
900
|
+
<span class="brand-logo">F</span>
|
|
901
|
+
<span>FRAIM</span>
|
|
902
|
+
</a>
|
|
903
|
+
<button class="theme-btn" type="button" onclick="toggleTheme()">Theme</button>
|
|
904
|
+
</header>
|
|
905
|
+
|
|
906
|
+
<section class="hero">
|
|
907
|
+
<div class="hero-grid">
|
|
908
|
+
<div class="panel">
|
|
909
|
+
<div class="chip">AI UX and Brand Designer</div>
|
|
910
|
+
<h1>Interfaces that feel deliberate from first click to shipped system.</h1>
|
|
911
|
+
<p>hUXley turns ambitious product ideas into buyer-facing surfaces people can trust: richer interaction models, stronger visual storytelling, and reusable design systems that keep the whole product family coherent.</p>
|
|
912
|
+
<div class="metric-grid">
|
|
913
|
+
<div class="metric">
|
|
914
|
+
<strong>3 shipped UI stories</strong>
|
|
915
|
+
spanning dashboard, voice, and customer health workflows
|
|
916
|
+
</div>
|
|
917
|
+
<div class="metric">
|
|
918
|
+
<strong>1 shared system</strong>
|
|
919
|
+
that keeps product, portfolio, and website surfaces aligned
|
|
920
|
+
</div>
|
|
921
|
+
<div class="metric">
|
|
922
|
+
<strong>Concrete deliverables</strong>
|
|
923
|
+
instead of abstract design claims
|
|
924
|
+
</div>
|
|
925
|
+
</div>
|
|
926
|
+
</div>
|
|
927
|
+
<aside class="panel summary">
|
|
928
|
+
<div class="summary-card">
|
|
929
|
+
<strong>Interaction-heavy product surfaces</strong>
|
|
930
|
+
Dashboards, voice workflows, and multi-state interfaces that still feel clear.
|
|
931
|
+
</div>
|
|
932
|
+
<div class="summary-card">
|
|
933
|
+
<strong>Visual systems that scale</strong>
|
|
934
|
+
Shared tokens, page rhythm, and repeatable modules that keep every surface in the same design language.
|
|
935
|
+
</div>
|
|
936
|
+
<div class="summary-card">
|
|
937
|
+
<strong>Customer-facing design work</strong>
|
|
938
|
+
Portfolio work stays visual and concrete instead of collapsing into process language.
|
|
939
|
+
</div>
|
|
940
|
+
</aside>
|
|
941
|
+
</div>
|
|
942
|
+
</section>
|
|
943
|
+
|
|
944
|
+
<section class="section">
|
|
945
|
+
<div class="section-head">
|
|
946
|
+
<h2>Selected Work</h2>
|
|
947
|
+
<div class="section-line"></div>
|
|
948
|
+
</div>
|
|
949
|
+
<div class="card-stack">
|
|
950
|
+
<article class="card open" id="card1">
|
|
951
|
+
<div class="card-header" onclick="toggleCard(1)">
|
|
952
|
+
<div class="card-icon">DASH</div>
|
|
953
|
+
<div class="card-meta">
|
|
954
|
+
<div class="card-tag">Calendar | Interaction Design</div>
|
|
955
|
+
<div class="card-title">Ashley Interactive Dashboard</div>
|
|
956
|
+
<div class="card-subtitle">Ashley Calendar AI | Feature Spec #1150</div>
|
|
957
|
+
</div>
|
|
958
|
+
<div class="card-toggle">›</div>
|
|
959
|
+
</div>
|
|
960
|
+
<div class="card-body">
|
|
961
|
+
<div class="narrative">
|
|
962
|
+
<div class="narrative-step">
|
|
963
|
+
<strong>Problem</strong>
|
|
964
|
+
Ashley's daily briefing showed context but still forced users elsewhere to act on it.
|
|
965
|
+
</div>
|
|
966
|
+
<div class="narrative-step">
|
|
967
|
+
<strong>What hUXley built</strong>
|
|
968
|
+
A darker, operator-grade calendar surface with inline event actions, calendar filters, and a visible HITL queue.
|
|
969
|
+
</div>
|
|
970
|
+
<div class="narrative-step">
|
|
971
|
+
<strong>Outcome</strong>
|
|
972
|
+
The dashboard became a real command surface instead of a read-only summary.
|
|
973
|
+
</div>
|
|
974
|
+
</div>
|
|
975
|
+
<p class="artifact-label">Live Artifact | Interactive dashboard prototype</p>
|
|
976
|
+
<div class="artifact-shell ashley-dashboard">
|
|
977
|
+
<div class="ashley-topbar">
|
|
978
|
+
<div class="ashley-topbar-left">
|
|
979
|
+
<div class="ashley-avatar-sm">A</div>
|
|
980
|
+
<span class="ashley-name">Ashley Executive Dashboard</span>
|
|
981
|
+
</div>
|
|
982
|
+
<div class="ashley-topbar-date">Thu, May 21 | 3 calendars</div>
|
|
983
|
+
<div class="ashley-topbar-badge">3 pending</div>
|
|
984
|
+
</div>
|
|
985
|
+
<div class="ashley-layout">
|
|
986
|
+
<div class="ashley-sidebar">
|
|
987
|
+
<div class="ashley-sidebar-section">
|
|
988
|
+
<div class="ashley-sidebar-label">My Calendars</div>
|
|
989
|
+
<div class="ashley-cal-item active">
|
|
990
|
+
<div class="ashley-cal-dot" style="background:#3b82f6;"></div>
|
|
991
|
+
<span class="ashley-cal-name">Work</span>
|
|
992
|
+
</div>
|
|
993
|
+
<div class="ashley-cal-item">
|
|
994
|
+
<div class="ashley-cal-dot" style="background:#10b981;"></div>
|
|
995
|
+
<span class="ashley-cal-name">Personal</span>
|
|
996
|
+
</div>
|
|
997
|
+
<div class="ashley-cal-item">
|
|
998
|
+
<div class="ashley-cal-dot" style="background:#f59e0b;"></div>
|
|
999
|
+
<span class="ashley-cal-name">Team Shared</span>
|
|
1000
|
+
</div>
|
|
1001
|
+
</div>
|
|
1002
|
+
<div class="ashley-sidebar-divider"></div>
|
|
1003
|
+
<div class="ashley-sidebar-section">
|
|
1004
|
+
<div class="ashley-sidebar-label">HITL Queue</div>
|
|
1005
|
+
<div class="ashley-cal-item">
|
|
1006
|
+
<div class="ashley-cal-dot" style="background:#ef4444;"></div>
|
|
1007
|
+
<span class="ashley-cal-name">Reschedule: Standup</span>
|
|
1008
|
+
</div>
|
|
1009
|
+
<div class="ashley-cal-item">
|
|
1010
|
+
<div class="ashley-cal-dot" style="background:#8b5cf6;"></div>
|
|
1011
|
+
<span class="ashley-cal-name">Confirm: Q2 Review</span>
|
|
1012
|
+
</div>
|
|
1013
|
+
</div>
|
|
1014
|
+
</div>
|
|
1015
|
+
<div class="ashley-main">
|
|
1016
|
+
<div class="ashley-date-strip">
|
|
1017
|
+
<div class="ashley-day-pill"><span class="ashley-day-dow">MON</span><span class="ashley-day-num">19</span></div>
|
|
1018
|
+
<div class="ashley-day-pill"><span class="ashley-day-dow">TUE</span><span class="ashley-day-num">20</span></div>
|
|
1019
|
+
<div class="ashley-day-pill today"><span class="ashley-day-dow">WED</span><span class="ashley-day-num">21</span></div>
|
|
1020
|
+
<div class="ashley-day-pill"><span class="ashley-day-dow">THU</span><span class="ashley-day-num">22</span></div>
|
|
1021
|
+
<div class="ashley-day-pill"><span class="ashley-day-dow">FRI</span><span class="ashley-day-num">23</span></div>
|
|
1022
|
+
</div>
|
|
1023
|
+
<div class="ashley-events">
|
|
1024
|
+
<div class="ashley-event-card">
|
|
1025
|
+
<div class="ashley-event-accent" style="background:#3b82f6;"></div>
|
|
1026
|
+
<div class="ashley-event-body">
|
|
1027
|
+
<div class="ashley-event-time">9:00 - 9:30 AM</div>
|
|
1028
|
+
<div class="ashley-event-title">Engineering Standup</div>
|
|
1029
|
+
<div class="ashley-event-meta">
|
|
1030
|
+
<span class="ashley-event-loc">Zoom</span>
|
|
1031
|
+
<div class="ashley-event-attendees">
|
|
1032
|
+
<div class="ashley-attendee" style="background:#3b82f6;">S</div>
|
|
1033
|
+
<div class="ashley-attendee" style="background:#10b981;">K</div>
|
|
1034
|
+
<div class="ashley-attendee" style="background:#8b5cf6;">R</div>
|
|
1035
|
+
</div>
|
|
1036
|
+
</div>
|
|
1037
|
+
</div>
|
|
1038
|
+
<div class="ashley-event-actions">
|
|
1039
|
+
<button class="ashley-action-btn" type="button">Edit</button>
|
|
1040
|
+
</div>
|
|
1041
|
+
</div>
|
|
1042
|
+
<div class="ashley-event-card">
|
|
1043
|
+
<div class="ashley-event-accent" style="background:#8b5cf6;"></div>
|
|
1044
|
+
<div class="ashley-event-body">
|
|
1045
|
+
<div class="ashley-event-time">11:00 AM - 12:00 PM</div>
|
|
1046
|
+
<div class="ashley-event-title">Q2 Strategy Review</div>
|
|
1047
|
+
<div class="ashley-event-meta">
|
|
1048
|
+
<span class="ashley-event-loc">Conf Room B</span>
|
|
1049
|
+
<div class="ashley-event-attendees">
|
|
1050
|
+
<div class="ashley-attendee" style="background:#ec4899;">M</div>
|
|
1051
|
+
<div class="ashley-attendee" style="background:#f59e0b;">J</div>
|
|
1052
|
+
</div>
|
|
1053
|
+
</div>
|
|
1054
|
+
</div>
|
|
1055
|
+
<div class="ashley-event-actions">
|
|
1056
|
+
<button class="ashley-action-btn" type="button">Edit</button>
|
|
1057
|
+
</div>
|
|
1058
|
+
</div>
|
|
1059
|
+
<div class="ashley-event-card">
|
|
1060
|
+
<div class="ashley-event-accent" style="background:#10b981;"></div>
|
|
1061
|
+
<div class="ashley-event-body">
|
|
1062
|
+
<div class="ashley-event-time">3:00 - 3:45 PM</div>
|
|
1063
|
+
<div class="ashley-event-title">1:1 with Alex</div>
|
|
1064
|
+
<div class="ashley-event-meta">
|
|
1065
|
+
<span class="ashley-event-loc">Google Meet</span>
|
|
1066
|
+
<div class="ashley-event-attendees">
|
|
1067
|
+
<div class="ashley-attendee" style="background:#06b6d4;">A</div>
|
|
1068
|
+
</div>
|
|
1069
|
+
</div>
|
|
1070
|
+
</div>
|
|
1071
|
+
<div class="ashley-event-actions">
|
|
1072
|
+
<button class="ashley-action-btn" type="button">Edit</button>
|
|
1073
|
+
</div>
|
|
1074
|
+
</div>
|
|
1075
|
+
</div>
|
|
1076
|
+
<button class="ashley-fab" type="button">+ Add Event</button>
|
|
1077
|
+
</div>
|
|
1078
|
+
</div>
|
|
1079
|
+
</div>
|
|
1080
|
+
<div class="source-ref">
|
|
1081
|
+
Source: <a href="#">Ashley-Calendar-AI · feat/1150-dashboard-improvements</a> · Feature Spec #1150
|
|
1082
|
+
</div>
|
|
1083
|
+
</div>
|
|
1084
|
+
</article>
|
|
1085
|
+
|
|
1086
|
+
<article class="card" id="card2">
|
|
1087
|
+
<div class="card-header" onclick="toggleCard(2)">
|
|
1088
|
+
<div class="card-icon">VOICE</div>
|
|
1089
|
+
<div class="card-meta">
|
|
1090
|
+
<div class="card-tag">Voice | Workflow Simplification</div>
|
|
1091
|
+
<div class="card-title">Voice-First Scheduling</div>
|
|
1092
|
+
<div class="card-subtitle">Ashley Calendar AI | Feature Spec #1134</div>
|
|
1093
|
+
</div>
|
|
1094
|
+
<div class="card-toggle">›</div>
|
|
1095
|
+
</div>
|
|
1096
|
+
<div class="card-body">
|
|
1097
|
+
<div class="narrative">
|
|
1098
|
+
<div class="narrative-step">
|
|
1099
|
+
<strong>Problem</strong>
|
|
1100
|
+
Mobile executives still had to type through moments where hands-free interaction mattered most.
|
|
1101
|
+
</div>
|
|
1102
|
+
<div class="narrative-step">
|
|
1103
|
+
<strong>What hUXley built</strong>
|
|
1104
|
+
A four-state voice interface with visible listening, processing, and confirmation feedback.
|
|
1105
|
+
</div>
|
|
1106
|
+
<div class="narrative-step">
|
|
1107
|
+
<strong>Outcome</strong>
|
|
1108
|
+
Scheduling feels immediate because the interface makes system state legible at every step.
|
|
1109
|
+
</div>
|
|
1110
|
+
</div>
|
|
1111
|
+
<p class="artifact-label">Live Artifact | Voice workflow prototype</p>
|
|
1112
|
+
<div class="artifact-shell voice-demo">
|
|
1113
|
+
<div class="voice-state-flow">
|
|
1114
|
+
<div class="vstate">IDLE</div>
|
|
1115
|
+
<span class="vstate-arrow">></span>
|
|
1116
|
+
<div class="vstate active">RECORDING</div>
|
|
1117
|
+
<span class="vstate-arrow">></span>
|
|
1118
|
+
<div class="vstate">PROCESSING</div>
|
|
1119
|
+
<span class="vstate-arrow">></span>
|
|
1120
|
+
<div class="vstate">RESPONDING</div>
|
|
1121
|
+
</div>
|
|
1122
|
+
<div class="voice-center">
|
|
1123
|
+
<div class="mic-ring-outer">
|
|
1124
|
+
<div class="mic-ring-pulse"></div>
|
|
1125
|
+
<div class="mic-ring-pulse"></div>
|
|
1126
|
+
<div class="mic-ring-pulse"></div>
|
|
1127
|
+
<button class="mic-btn" type="button">MIC</button>
|
|
1128
|
+
</div>
|
|
1129
|
+
<div class="waveform">
|
|
1130
|
+
<div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div>
|
|
1131
|
+
<div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div><div class="waveform-bar"></div>
|
|
1132
|
+
</div>
|
|
1133
|
+
<div class="voice-status">
|
|
1134
|
+
<div class="voice-status-label">Recording - tap to stop</div>
|
|
1135
|
+
<div class="voice-status-sub">Whisper STT | 2.3s</div>
|
|
1136
|
+
</div>
|
|
1137
|
+
</div>
|
|
1138
|
+
<div class="voice-transcript">
|
|
1139
|
+
<div class="transcript-user">"Schedule a 30-minute 1:1 with Jamie tomorrow at 2pm"</div>
|
|
1140
|
+
<div class="transcript-ashley">Done - Ashley scheduled it, sent the invite, and confirmed the change back in voice.</div>
|
|
1141
|
+
</div>
|
|
1142
|
+
<div class="voice-flow-detail">
|
|
1143
|
+
<div class="vflow-step"><div class="vflow-icon">STT</div><div class="vflow-label">Speech to text</div></div>
|
|
1144
|
+
<div class="vflow-step"><div class="vflow-icon">INT</div><div class="vflow-label">Intent parse</div></div>
|
|
1145
|
+
<div class="vflow-step"><div class="vflow-icon">CAL</div><div class="vflow-label">Calendar write</div></div>
|
|
1146
|
+
<div class="vflow-step"><div class="vflow-icon">TTS</div><div class="vflow-label">Voice reply</div></div>
|
|
1147
|
+
</div>
|
|
1148
|
+
</div>
|
|
1149
|
+
<div class="source-ref">
|
|
1150
|
+
Source: <a href="#">Ashley-Calendar-AI · feat/1134-voice-mode</a> · Feature Spec #1134
|
|
1151
|
+
</div>
|
|
1152
|
+
</div>
|
|
1153
|
+
</article>
|
|
1154
|
+
|
|
1155
|
+
<article class="card" id="card3">
|
|
1156
|
+
<div class="card-header" onclick="toggleCard(3)">
|
|
1157
|
+
<div class="card-icon">C360</div>
|
|
1158
|
+
<div class="card-meta">
|
|
1159
|
+
<div class="card-tag">Data Visualization | Customer UX</div>
|
|
1160
|
+
<div class="card-title">Customer 360 Health Score Dashboard</div>
|
|
1161
|
+
<div class="card-subtitle">CustomerEQ | Feature Specs #98-99</div>
|
|
1162
|
+
</div>
|
|
1163
|
+
<div class="card-toggle">›</div>
|
|
1164
|
+
</div>
|
|
1165
|
+
<div class="card-body">
|
|
1166
|
+
<div class="narrative">
|
|
1167
|
+
<div class="narrative-step">
|
|
1168
|
+
<strong>Problem</strong>
|
|
1169
|
+
CX managers were juggling survey, support, loyalty, and account data across separate views.
|
|
1170
|
+
</div>
|
|
1171
|
+
<div class="narrative-step">
|
|
1172
|
+
<strong>What hUXley built</strong>
|
|
1173
|
+
A single account profile with a visible health score, sentiment cues, and timeline context.
|
|
1174
|
+
</div>
|
|
1175
|
+
<div class="narrative-step">
|
|
1176
|
+
<strong>Outcome</strong>
|
|
1177
|
+
Risk becomes visible fast enough to act before the account deteriorates.
|
|
1178
|
+
</div>
|
|
1179
|
+
</div>
|
|
1180
|
+
<p class="artifact-label">Live Artifact | Customer 360 profile prototype</p>
|
|
1181
|
+
<div class="artifact-shell c360-demo">
|
|
1182
|
+
<div class="c360-header">
|
|
1183
|
+
<div class="c360-profile-row">
|
|
1184
|
+
<div class="c360-avatar">JR</div>
|
|
1185
|
+
<div class="c360-profile-info">
|
|
1186
|
+
<div class="c360-name">Jordan Rivera</div>
|
|
1187
|
+
<div class="c360-company">Apex Systems | VP Operations | 340 seats</div>
|
|
1188
|
+
<div class="c360-tags">
|
|
1189
|
+
<span class="c360-tag tag-premium">Premium</span>
|
|
1190
|
+
<span class="c360-tag tag-renewal">Renewal at Risk</span>
|
|
1191
|
+
<span class="c360-tag tag-enterprise">Enterprise</span>
|
|
1192
|
+
</div>
|
|
1193
|
+
</div>
|
|
1194
|
+
</div>
|
|
1195
|
+
<div class="c360-tabs">
|
|
1196
|
+
<div class="c360-tab active">Health Score</div>
|
|
1197
|
+
<div class="c360-tab">Activity</div>
|
|
1198
|
+
<div class="c360-tab">Loyalty</div>
|
|
1199
|
+
<div class="c360-tab">Cases</div>
|
|
1200
|
+
<div class="c360-tab">Surveys</div>
|
|
1201
|
+
</div>
|
|
1202
|
+
</div>
|
|
1203
|
+
<div class="c360-body">
|
|
1204
|
+
<div class="c360-score-row">
|
|
1205
|
+
<div style="position:relative; width:100px; height:70px; flex-shrink:0;">
|
|
1206
|
+
<svg width="100" height="60" viewBox="0 0 100 50" aria-hidden="true">
|
|
1207
|
+
<path d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="#1e293b" stroke-width="10" stroke-linecap="round"></path>
|
|
1208
|
+
<path d="M 10 50 A 40 40 0 0 1 90 50" fill="none" stroke="#4ade80" stroke-width="10" stroke-linecap="round" stroke-dasharray="125.6" stroke-dashoffset="35"></path>
|
|
1209
|
+
</svg>
|
|
1210
|
+
<div style="position:absolute;bottom:2px;left:50%;transform:translateX(-50%);font-size:20px;font-weight:800;color:#4ade80;">72</div>
|
|
1211
|
+
<div style="position:absolute;top:32px;left:50%;transform:translateX(-50%);font-size:9px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;white-space:nowrap;">Health Score</div>
|
|
1212
|
+
</div>
|
|
1213
|
+
<div class="c360-metrics">
|
|
1214
|
+
<div class="c360-metric">
|
|
1215
|
+
<div class="c360-metric-val" style="color:#60a5fa;">72</div>
|
|
1216
|
+
<div class="c360-metric-label">NPS</div>
|
|
1217
|
+
</div>
|
|
1218
|
+
<div class="c360-metric">
|
|
1219
|
+
<div class="c360-metric-val" style="color:#4ade80;">4.8</div>
|
|
1220
|
+
<div class="c360-metric-label">CSAT</div>
|
|
1221
|
+
</div>
|
|
1222
|
+
<div class="c360-metric">
|
|
1223
|
+
<div class="c360-metric-val" style="color:#fbbf24;">3.2</div>
|
|
1224
|
+
<div class="c360-metric-label">CES</div>
|
|
1225
|
+
</div>
|
|
1226
|
+
</div>
|
|
1227
|
+
</div>
|
|
1228
|
+
<div class="c360-timeline">
|
|
1229
|
+
<div class="c360-timeline-label">Recent Activity</div>
|
|
1230
|
+
<div class="c360-event">
|
|
1231
|
+
<div class="c360-event-dot" style="background:#4ade80;"></div>
|
|
1232
|
+
<div class="c360-event-text">Survey response - Q1 Satisfaction <span class="c360-sentiment sent-pos">Positive</span></div>
|
|
1233
|
+
<div class="c360-event-time">2d ago</div>
|
|
1234
|
+
</div>
|
|
1235
|
+
<div class="c360-event">
|
|
1236
|
+
<div class="c360-event-dot" style="background:#ef4444;"></div>
|
|
1237
|
+
<div class="c360-event-text">Case opened - Bulk import failing <span class="c360-sentiment sent-neg">P1</span></div>
|
|
1238
|
+
<div class="c360-event-time">4d ago</div>
|
|
1239
|
+
</div>
|
|
1240
|
+
<div class="c360-event">
|
|
1241
|
+
<div class="c360-event-dot" style="background:#94a3b8;"></div>
|
|
1242
|
+
<div class="c360-event-text">Loyalty redemption - Gift card issued <span class="c360-sentiment sent-neu">Neutral</span></div>
|
|
1243
|
+
<div class="c360-event-time">1w ago</div>
|
|
1244
|
+
</div>
|
|
1245
|
+
</div>
|
|
1246
|
+
</div>
|
|
1247
|
+
</div>
|
|
1248
|
+
<div class="source-ref">
|
|
1249
|
+
Source: <a href="#">CustomerEQ · feat/customer-360-health-score</a> · Feature Specs #98-99
|
|
1250
|
+
</div>
|
|
1251
|
+
</div>
|
|
1252
|
+
</article>
|
|
1253
|
+
|
|
1254
|
+
<article class="card" id="card4">
|
|
1255
|
+
<div class="card-header" onclick="toggleCard(4)">
|
|
1256
|
+
<div class="card-icon">SYS</div>
|
|
1257
|
+
<div class="card-meta">
|
|
1258
|
+
<div class="card-tag">Design System Creation</div>
|
|
1259
|
+
<div class="card-title">Design systems that turn strong screens into a repeatable product language</div>
|
|
1260
|
+
<div class="card-subtitle">FRAIM | design-system-creation</div>
|
|
1261
|
+
</div>
|
|
1262
|
+
<div class="card-toggle">›</div>
|
|
1263
|
+
</div>
|
|
1264
|
+
<div class="card-body">
|
|
1265
|
+
<p class="context">hUXley does more than make individual screens look good. The same visual decisions can be organized into a design system so product pages, portfolio pages, and future launches all feel like they belong to the same company.</p>
|
|
1266
|
+
<div class="proof-grid">
|
|
1267
|
+
<div class="proof">
|
|
1268
|
+
<div class="proof-label">Token baseline</div>
|
|
1269
|
+
Color, type, spacing, and content modules stay consistent across every surface.
|
|
1270
|
+
</div>
|
|
1271
|
+
<div class="proof">
|
|
1272
|
+
<div class="proof-label">Specimen requirement</div>
|
|
1273
|
+
The system includes applied examples, not just abstract guidance.
|
|
1274
|
+
</div>
|
|
1275
|
+
<div class="proof">
|
|
1276
|
+
<div class="proof-label">Outcome</div>
|
|
1277
|
+
New buyer-facing pages can launch faster without drifting into a different visual language.
|
|
1278
|
+
</div>
|
|
1279
|
+
</div>
|
|
1280
|
+
<p class="artifact-label">Live Artifact | Design-system specimen board</p>
|
|
1281
|
+
<div class="artifact-shell design-system-board">
|
|
1282
|
+
<div class="design-grid">
|
|
1283
|
+
<div class="design-panel">
|
|
1284
|
+
<div class="design-label">Core Tokens</div>
|
|
1285
|
+
<div class="token-stack">
|
|
1286
|
+
<div class="token-row">
|
|
1287
|
+
<div class="swatch" style="background:linear-gradient(135deg,#10b981,#3b82f6);"></div>
|
|
1288
|
+
<div class="token-copy"><strong>Signal palette</strong><span>Trust, action, and proof states</span></div>
|
|
1289
|
+
</div>
|
|
1290
|
+
<div class="token-row">
|
|
1291
|
+
<div class="swatch" style="background:linear-gradient(180deg,#ffffff,#ecfdf5);"></div>
|
|
1292
|
+
<div class="token-copy"><strong>Surface rhythm</strong><span>Layered cards with consistent spacing</span></div>
|
|
1293
|
+
</div>
|
|
1294
|
+
<div class="token-row">
|
|
1295
|
+
<div class="swatch" style="background:linear-gradient(180deg,#111827,#1e293b);"></div>
|
|
1296
|
+
<div class="token-copy"><strong>Dense product canvas</strong><span>Used for high-information demos</span></div>
|
|
1297
|
+
</div>
|
|
1298
|
+
</div>
|
|
1299
|
+
</div>
|
|
1300
|
+
<div class="design-specimens">
|
|
1301
|
+
<div class="design-label">Applied Specimens</div>
|
|
1302
|
+
<div class="specimen-grid">
|
|
1303
|
+
<div class="specimen">
|
|
1304
|
+
<div class="specimen-top"></div>
|
|
1305
|
+
<div class="specimen-body">
|
|
1306
|
+
<strong>Portfolio proof card</strong>
|
|
1307
|
+
<p>Story first, then artifact, then source attribution.</p>
|
|
1308
|
+
</div>
|
|
1309
|
+
</div>
|
|
1310
|
+
<div class="specimen">
|
|
1311
|
+
<div class="specimen-top"></div>
|
|
1312
|
+
<div class="specimen-body">
|
|
1313
|
+
<strong>Pricing comparison block</strong>
|
|
1314
|
+
<p>Role promise and evidence stay aligned with the same visual language.</p>
|
|
1315
|
+
</div>
|
|
1316
|
+
</div>
|
|
1317
|
+
<div class="specimen">
|
|
1318
|
+
<div class="specimen-top"></div>
|
|
1319
|
+
<div class="specimen-body">
|
|
1320
|
+
<strong>Website hero module</strong>
|
|
1321
|
+
<p>Brand tone lands in real interface structure, not just copy.</p>
|
|
1322
|
+
</div>
|
|
1323
|
+
</div>
|
|
1324
|
+
</div>
|
|
1325
|
+
</div>
|
|
1326
|
+
</div>
|
|
1327
|
+
</div>
|
|
1328
|
+
</div>
|
|
1329
|
+
</article>
|
|
1330
|
+
</div>
|
|
1331
|
+
</section>
|
|
1332
|
+
|
|
1333
|
+
<footer class="footer">
|
|
1334
|
+
Part of <a href="/">FRAIM</a> | <a href="/portfolio/index.html">View all employees</a>
|
|
1335
|
+
</footer>
|
|
1336
|
+
|
|
1337
|
+
<script>
|
|
1338
|
+
function toggleTheme() {
|
|
1339
|
+
const html = document.documentElement;
|
|
1340
|
+
html.setAttribute("data-theme", html.getAttribute("data-theme") === "dark" ? "light" : "dark");
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
function toggleCard(num) {
|
|
1344
|
+
const card = document.getElementById("card" + num);
|
|
1345
|
+
const willOpen = !card.classList.contains("open");
|
|
1346
|
+
document.querySelectorAll(".card").forEach((item) => item.classList.remove("open"));
|
|
1347
|
+
if (willOpen) {
|
|
1348
|
+
card.classList.add("open");
|
|
1349
|
+
card.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
</script>
|
|
1353
|
+
</body>
|
|
1354
|
+
</html>
|