@hustle-together/api-dev-tools 1.9.0 → 2.0.1
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 +15 -0
- package/demo/hustle-together/blog/gemini-vs-claude-widgets.html +957 -0
- package/demo/hustle-together/blog/interview-driven-api-development.html +1132 -0
- package/demo/hustle-together/blog/tdd-for-ai.html +982 -0
- package/demo/hustle-together/index.html +1279 -0
- package/demo/workflow-demo.html +948 -57
- package/package.json +1 -1
package/demo/workflow-demo.html
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
--dark-grey: #444;
|
|
26
26
|
--black: #0a0a0a;
|
|
27
27
|
--glow: rgba(255, 255, 255, 0.3);
|
|
28
|
+
--accent-red: #BA0C2F;
|
|
29
|
+
--accent-red-glow: rgba(186, 12, 47, 0.4);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
body {
|
|
@@ -35,6 +37,439 @@
|
|
|
35
37
|
overflow-x: hidden;
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
/* ============================================
|
|
41
|
+
ANIMATED BACKGROUND
|
|
42
|
+
============================================ */
|
|
43
|
+
.background-pattern {
|
|
44
|
+
position: fixed;
|
|
45
|
+
top: 0;
|
|
46
|
+
left: 0;
|
|
47
|
+
width: 100%;
|
|
48
|
+
height: 100%;
|
|
49
|
+
pointer-events: none;
|
|
50
|
+
z-index: -1;
|
|
51
|
+
overflow: hidden;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.grid-svg {
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
opacity: 0.15;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.grid-line {
|
|
61
|
+
stroke: var(--grey);
|
|
62
|
+
stroke-width: 0.5;
|
|
63
|
+
fill: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Floating particles */
|
|
67
|
+
.particles {
|
|
68
|
+
position: fixed;
|
|
69
|
+
top: 0;
|
|
70
|
+
left: 0;
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
pointer-events: none;
|
|
74
|
+
z-index: -1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.particle {
|
|
78
|
+
position: absolute;
|
|
79
|
+
width: 4px;
|
|
80
|
+
height: 4px;
|
|
81
|
+
background: var(--grey);
|
|
82
|
+
opacity: 0.3;
|
|
83
|
+
border-radius: 50%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.particle.square {
|
|
87
|
+
border-radius: 0;
|
|
88
|
+
border: 1px solid var(--grey);
|
|
89
|
+
background: transparent;
|
|
90
|
+
width: 8px;
|
|
91
|
+
height: 8px;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.particle.plus {
|
|
95
|
+
border-radius: 0;
|
|
96
|
+
background: transparent;
|
|
97
|
+
width: 12px;
|
|
98
|
+
height: 12px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.particle.plus::before,
|
|
102
|
+
.particle.plus::after {
|
|
103
|
+
content: '';
|
|
104
|
+
position: absolute;
|
|
105
|
+
background: var(--grey);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.particle.plus::before {
|
|
109
|
+
width: 12px;
|
|
110
|
+
height: 1px;
|
|
111
|
+
top: 5.5px;
|
|
112
|
+
left: 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.particle.plus::after {
|
|
116
|
+
width: 1px;
|
|
117
|
+
height: 12px;
|
|
118
|
+
left: 5.5px;
|
|
119
|
+
top: 0;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* X shape particle */
|
|
123
|
+
.particle.x-shape {
|
|
124
|
+
border-radius: 0;
|
|
125
|
+
background: transparent;
|
|
126
|
+
width: 14px;
|
|
127
|
+
height: 14px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.particle.x-shape::before,
|
|
131
|
+
.particle.x-shape::after {
|
|
132
|
+
content: '';
|
|
133
|
+
position: absolute;
|
|
134
|
+
background: var(--grey);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.particle.x-shape::before {
|
|
138
|
+
width: 14px;
|
|
139
|
+
height: 1px;
|
|
140
|
+
top: 6.5px;
|
|
141
|
+
left: 0;
|
|
142
|
+
transform: rotate(45deg);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.particle.x-shape::after {
|
|
146
|
+
width: 14px;
|
|
147
|
+
height: 1px;
|
|
148
|
+
top: 6.5px;
|
|
149
|
+
left: 0;
|
|
150
|
+
transform: rotate(-45deg);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Line/dash particle */
|
|
154
|
+
.particle.line {
|
|
155
|
+
border-radius: 0;
|
|
156
|
+
width: 20px;
|
|
157
|
+
height: 1px;
|
|
158
|
+
background: var(--grey);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.particle.line-v {
|
|
162
|
+
border-radius: 0;
|
|
163
|
+
width: 1px;
|
|
164
|
+
height: 20px;
|
|
165
|
+
background: var(--grey);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Circle outline particle */
|
|
169
|
+
.particle.circle-outline {
|
|
170
|
+
width: 16px;
|
|
171
|
+
height: 16px;
|
|
172
|
+
border-radius: 50%;
|
|
173
|
+
background: transparent;
|
|
174
|
+
border: 1px solid var(--grey);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* Triangle particle */
|
|
178
|
+
.particle.triangle {
|
|
179
|
+
width: 0;
|
|
180
|
+
height: 0;
|
|
181
|
+
background: transparent;
|
|
182
|
+
border-left: 6px solid transparent;
|
|
183
|
+
border-right: 6px solid transparent;
|
|
184
|
+
border-bottom: 10px solid var(--grey);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Cursor glow effect */
|
|
188
|
+
.cursor-glow {
|
|
189
|
+
position: fixed;
|
|
190
|
+
width: 300px;
|
|
191
|
+
height: 300px;
|
|
192
|
+
background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);
|
|
193
|
+
pointer-events: none;
|
|
194
|
+
z-index: 0;
|
|
195
|
+
transform: translate(-50%, -50%);
|
|
196
|
+
transition: opacity 0.3s;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Scanlines overlay */
|
|
200
|
+
.scanlines {
|
|
201
|
+
position: fixed;
|
|
202
|
+
top: 0;
|
|
203
|
+
left: 0;
|
|
204
|
+
width: 100%;
|
|
205
|
+
height: 100%;
|
|
206
|
+
pointer-events: none;
|
|
207
|
+
z-index: 9999;
|
|
208
|
+
background: repeating-linear-gradient(
|
|
209
|
+
0deg,
|
|
210
|
+
transparent,
|
|
211
|
+
transparent 2px,
|
|
212
|
+
rgba(0, 0, 0, 0.1) 2px,
|
|
213
|
+
rgba(0, 0, 0, 0.1) 4px
|
|
214
|
+
);
|
|
215
|
+
opacity: 0.3;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/* Animated corner decorations */
|
|
219
|
+
.corner-decoration {
|
|
220
|
+
position: fixed;
|
|
221
|
+
width: 60px;
|
|
222
|
+
height: 60px;
|
|
223
|
+
border: 1px dashed var(--dark-grey);
|
|
224
|
+
opacity: 0.4;
|
|
225
|
+
z-index: 1;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.corner-decoration.top-left {
|
|
229
|
+
top: 20px;
|
|
230
|
+
left: 20px;
|
|
231
|
+
border-right: none;
|
|
232
|
+
border-bottom: none;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.corner-decoration.top-right {
|
|
236
|
+
top: 20px;
|
|
237
|
+
right: 80px;
|
|
238
|
+
border-left: none;
|
|
239
|
+
border-bottom: none;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.corner-decoration.bottom-left {
|
|
243
|
+
bottom: 20px;
|
|
244
|
+
left: 20px;
|
|
245
|
+
border-right: none;
|
|
246
|
+
border-top: none;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.corner-decoration.bottom-right {
|
|
250
|
+
bottom: 20px;
|
|
251
|
+
right: 20px;
|
|
252
|
+
border-left: none;
|
|
253
|
+
border-top: none;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* Visual flow lines between sections */
|
|
257
|
+
.flow-connector-line {
|
|
258
|
+
position: absolute;
|
|
259
|
+
width: 2px;
|
|
260
|
+
background: linear-gradient(to bottom, transparent, var(--dark-grey), transparent);
|
|
261
|
+
left: 50%;
|
|
262
|
+
bottom: -60px;
|
|
263
|
+
height: 60px;
|
|
264
|
+
opacity: 0.3;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/* Status badge animations */
|
|
268
|
+
.status-badge {
|
|
269
|
+
display: inline-flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
gap: 8px;
|
|
272
|
+
padding: 6px 14px;
|
|
273
|
+
border: 1px dashed var(--grey);
|
|
274
|
+
font-size: 0.75rem;
|
|
275
|
+
text-transform: uppercase;
|
|
276
|
+
letter-spacing: 2px;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.status-badge .pulse {
|
|
280
|
+
width: 8px;
|
|
281
|
+
height: 8px;
|
|
282
|
+
border-radius: 50%;
|
|
283
|
+
background: var(--grey);
|
|
284
|
+
animation: pulse 2s infinite;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.status-badge.active .pulse {
|
|
288
|
+
background: var(--accent-red);
|
|
289
|
+
box-shadow: 0 0 10px var(--accent-red);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
@keyframes pulse {
|
|
293
|
+
0%, 100% { transform: scale(1); opacity: 1; }
|
|
294
|
+
50% { transform: scale(1.2); opacity: 0.5; }
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* Visual data flow diagram */
|
|
298
|
+
.data-flow {
|
|
299
|
+
display: flex;
|
|
300
|
+
align-items: center;
|
|
301
|
+
justify-content: center;
|
|
302
|
+
gap: 20px;
|
|
303
|
+
margin: 30px 0;
|
|
304
|
+
flex-wrap: wrap;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
.data-node {
|
|
308
|
+
border: 1px dashed var(--grey);
|
|
309
|
+
padding: 15px 25px;
|
|
310
|
+
text-align: center;
|
|
311
|
+
position: relative;
|
|
312
|
+
min-width: 120px;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.data-node-icon {
|
|
316
|
+
font-size: 1.5rem;
|
|
317
|
+
margin-bottom: 8px;
|
|
318
|
+
display: block;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.data-node-label {
|
|
322
|
+
font-size: 0.75rem;
|
|
323
|
+
text-transform: uppercase;
|
|
324
|
+
letter-spacing: 1px;
|
|
325
|
+
color: var(--grey);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.data-arrow {
|
|
329
|
+
color: var(--grey);
|
|
330
|
+
font-size: 1.5rem;
|
|
331
|
+
animation: arrowPulse 1.5s infinite;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
@keyframes arrowPulse {
|
|
335
|
+
0%, 100% { opacity: 0.3; transform: translateX(0); }
|
|
336
|
+
50% { opacity: 1; transform: translateX(5px); }
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/* Visual checkmarks for completed items */
|
|
340
|
+
.visual-check {
|
|
341
|
+
display: inline-flex;
|
|
342
|
+
align-items: center;
|
|
343
|
+
justify-content: center;
|
|
344
|
+
width: 24px;
|
|
345
|
+
height: 24px;
|
|
346
|
+
border: 2px solid var(--grey);
|
|
347
|
+
margin-right: 12px;
|
|
348
|
+
font-size: 0.8rem;
|
|
349
|
+
transition: all 0.3s;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.visual-check.checked {
|
|
353
|
+
border-color: var(--accent-red);
|
|
354
|
+
background: rgba(186, 12, 47, 0.2);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.visual-check.checked::after {
|
|
358
|
+
content: '✓';
|
|
359
|
+
color: var(--accent-red);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/* Animated underline effect */
|
|
363
|
+
.highlight-underline {
|
|
364
|
+
position: relative;
|
|
365
|
+
display: inline-block;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.highlight-underline::after {
|
|
369
|
+
content: '';
|
|
370
|
+
position: absolute;
|
|
371
|
+
bottom: -4px;
|
|
372
|
+
left: 0;
|
|
373
|
+
width: 0;
|
|
374
|
+
height: 2px;
|
|
375
|
+
background: var(--accent-red);
|
|
376
|
+
transition: width 0.3s ease;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.highlight-underline:hover::after {
|
|
380
|
+
width: 100%;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* Visual timeline indicator */
|
|
384
|
+
.timeline-indicator {
|
|
385
|
+
position: absolute;
|
|
386
|
+
left: -40px;
|
|
387
|
+
top: 0;
|
|
388
|
+
bottom: 0;
|
|
389
|
+
width: 2px;
|
|
390
|
+
background: var(--dark-grey);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.timeline-indicator::before {
|
|
394
|
+
content: '';
|
|
395
|
+
position: absolute;
|
|
396
|
+
top: 50%;
|
|
397
|
+
left: -4px;
|
|
398
|
+
width: 10px;
|
|
399
|
+
height: 10px;
|
|
400
|
+
border: 2px solid var(--grey);
|
|
401
|
+
border-radius: 50%;
|
|
402
|
+
background: var(--black);
|
|
403
|
+
transform: translateY(-50%);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.timeline-indicator.active::before {
|
|
407
|
+
border-color: var(--accent-red);
|
|
408
|
+
box-shadow: 0 0 10px var(--accent-red-glow);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* Animated typing indicator */
|
|
412
|
+
.typing-indicator {
|
|
413
|
+
display: inline-flex;
|
|
414
|
+
gap: 4px;
|
|
415
|
+
padding: 10px 15px;
|
|
416
|
+
background: rgba(255,255,255,0.03);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.typing-indicator span {
|
|
420
|
+
width: 6px;
|
|
421
|
+
height: 6px;
|
|
422
|
+
background: var(--grey);
|
|
423
|
+
border-radius: 50%;
|
|
424
|
+
animation: typing 1.4s infinite both;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
.typing-indicator span:nth-child(2) { animation-delay: 0.2s; }
|
|
428
|
+
.typing-indicator span:nth-child(3) { animation-delay: 0.4s; }
|
|
429
|
+
|
|
430
|
+
@keyframes typing {
|
|
431
|
+
0%, 100% { transform: translateY(0); opacity: 0.3; }
|
|
432
|
+
50% { transform: translateY(-8px); opacity: 1; }
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Phase connection arrows */
|
|
436
|
+
.phase-arrow {
|
|
437
|
+
display: none;
|
|
438
|
+
position: absolute;
|
|
439
|
+
right: -22px;
|
|
440
|
+
top: 50%;
|
|
441
|
+
transform: translateY(-50%);
|
|
442
|
+
color: var(--dark-grey);
|
|
443
|
+
font-size: 1rem;
|
|
444
|
+
z-index: 2;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.phase-box:not(:nth-child(5n)) .phase-arrow {
|
|
448
|
+
display: block;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/* Glowing border effect for active elements */
|
|
452
|
+
.glow-border {
|
|
453
|
+
position: relative;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.glow-border::before {
|
|
457
|
+
content: '';
|
|
458
|
+
position: absolute;
|
|
459
|
+
top: -2px;
|
|
460
|
+
left: -2px;
|
|
461
|
+
right: -2px;
|
|
462
|
+
bottom: -2px;
|
|
463
|
+
background: linear-gradient(45deg, transparent, var(--white), transparent);
|
|
464
|
+
opacity: 0;
|
|
465
|
+
transition: opacity 0.3s;
|
|
466
|
+
z-index: -1;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.glow-border:hover::before {
|
|
470
|
+
opacity: 0.1;
|
|
471
|
+
}
|
|
472
|
+
|
|
38
473
|
/* Navigation */
|
|
39
474
|
.nav {
|
|
40
475
|
position: fixed;
|
|
@@ -56,9 +491,10 @@
|
|
|
56
491
|
}
|
|
57
492
|
|
|
58
493
|
.nav-btn:hover {
|
|
59
|
-
background: var(--
|
|
60
|
-
color:
|
|
61
|
-
|
|
494
|
+
background: var(--accent-red);
|
|
495
|
+
color: #fff;
|
|
496
|
+
border-color: var(--accent-red);
|
|
497
|
+
box-shadow: 0 0 15px var(--accent-red-glow);
|
|
62
498
|
}
|
|
63
499
|
|
|
64
500
|
/* Progress indicator */
|
|
@@ -67,7 +503,7 @@
|
|
|
67
503
|
top: 0;
|
|
68
504
|
left: 0;
|
|
69
505
|
height: 3px;
|
|
70
|
-
background: var(--
|
|
506
|
+
background: var(--accent-red);
|
|
71
507
|
width: 0%;
|
|
72
508
|
z-index: 1001;
|
|
73
509
|
}
|
|
@@ -90,6 +526,10 @@
|
|
|
90
526
|
position: relative;
|
|
91
527
|
max-width: 1000px;
|
|
92
528
|
width: 100%;
|
|
529
|
+
/* Blurred glass backdrop so boxes don't interfere with background animation */
|
|
530
|
+
background: rgba(10, 10, 10, 0.85);
|
|
531
|
+
backdrop-filter: blur(12px);
|
|
532
|
+
-webkit-backdrop-filter: blur(12px);
|
|
93
533
|
}
|
|
94
534
|
|
|
95
535
|
.ascii-border::before {
|
|
@@ -271,6 +711,140 @@
|
|
|
271
711
|
font-size: 1.1rem;
|
|
272
712
|
}
|
|
273
713
|
|
|
714
|
+
/* ============================================
|
|
715
|
+
HUSTLE BRAND TITLE
|
|
716
|
+
============================================ */
|
|
717
|
+
.hustle-brand {
|
|
718
|
+
display: flex;
|
|
719
|
+
justify-content: center;
|
|
720
|
+
gap: 20px;
|
|
721
|
+
margin-bottom: 20px;
|
|
722
|
+
flex-wrap: wrap;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
.hustle-word {
|
|
726
|
+
font-size: 4rem;
|
|
727
|
+
font-weight: bold;
|
|
728
|
+
letter-spacing: 8px;
|
|
729
|
+
opacity: 0;
|
|
730
|
+
transform: translateY(30px);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.hustle-highlight {
|
|
734
|
+
color: var(--accent-red);
|
|
735
|
+
text-shadow: 0 0 30px var(--accent-red-glow), 0 0 60px var(--accent-red-glow);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.text-red {
|
|
739
|
+
color: var(--accent-red);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/* ============================================
|
|
743
|
+
PHASE FLOW - LIGHTING UP SEQUENCE
|
|
744
|
+
============================================ */
|
|
745
|
+
.phase-flow {
|
|
746
|
+
display: flex;
|
|
747
|
+
align-items: center;
|
|
748
|
+
justify-content: center;
|
|
749
|
+
gap: 15px;
|
|
750
|
+
margin-top: 50px;
|
|
751
|
+
flex-wrap: wrap;
|
|
752
|
+
opacity: 0;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
.phase-node {
|
|
756
|
+
position: relative;
|
|
757
|
+
border: 2px solid var(--dark-grey);
|
|
758
|
+
padding: 20px 25px;
|
|
759
|
+
text-align: center;
|
|
760
|
+
min-width: 100px;
|
|
761
|
+
transition: all 0.4s ease;
|
|
762
|
+
opacity: 0;
|
|
763
|
+
transform: translateY(20px);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
.phase-node .phase-glow {
|
|
767
|
+
position: absolute;
|
|
768
|
+
top: -2px;
|
|
769
|
+
left: -2px;
|
|
770
|
+
right: -2px;
|
|
771
|
+
bottom: -2px;
|
|
772
|
+
border: 2px solid var(--accent-red);
|
|
773
|
+
opacity: 0;
|
|
774
|
+
box-shadow: 0 0 20px var(--accent-red-glow), inset 0 0 20px var(--accent-red-glow);
|
|
775
|
+
transition: opacity 0.4s ease;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
.phase-node.active {
|
|
779
|
+
border-color: var(--accent-red);
|
|
780
|
+
background: rgba(186, 12, 47, 0.1);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
.phase-node.active .phase-glow {
|
|
784
|
+
opacity: 1;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.phase-node.active .phase-icon {
|
|
788
|
+
color: var(--accent-red);
|
|
789
|
+
text-shadow: 0 0 10px var(--accent-red);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.phase-node.active .phase-label {
|
|
793
|
+
color: var(--white);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.phase-icon {
|
|
797
|
+
display: block;
|
|
798
|
+
font-size: 1.8rem;
|
|
799
|
+
font-weight: bold;
|
|
800
|
+
margin-bottom: 8px;
|
|
801
|
+
color: var(--grey);
|
|
802
|
+
transition: all 0.4s ease;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.phase-label {
|
|
806
|
+
font-size: 0.7rem;
|
|
807
|
+
text-transform: uppercase;
|
|
808
|
+
letter-spacing: 2px;
|
|
809
|
+
color: var(--dark-grey);
|
|
810
|
+
transition: all 0.4s ease;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.phase-connector-arrow {
|
|
814
|
+
color: var(--dark-grey);
|
|
815
|
+
font-size: 1.5rem;
|
|
816
|
+
opacity: 0;
|
|
817
|
+
transition: all 0.3s ease;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.phase-connector-arrow.active {
|
|
821
|
+
color: var(--accent-red);
|
|
822
|
+
text-shadow: 0 0 10px var(--accent-red-glow);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
@media (max-width: 768px) {
|
|
826
|
+
.hustle-word {
|
|
827
|
+
font-size: 2.5rem;
|
|
828
|
+
letter-spacing: 4px;
|
|
829
|
+
}
|
|
830
|
+
.hustle-brand {
|
|
831
|
+
gap: 10px;
|
|
832
|
+
}
|
|
833
|
+
.phase-flow {
|
|
834
|
+
gap: 10px;
|
|
835
|
+
}
|
|
836
|
+
.phase-node {
|
|
837
|
+
padding: 15px 18px;
|
|
838
|
+
min-width: 70px;
|
|
839
|
+
}
|
|
840
|
+
.phase-icon {
|
|
841
|
+
font-size: 1.4rem;
|
|
842
|
+
}
|
|
843
|
+
.phase-connector-arrow {
|
|
844
|
+
font-size: 1rem;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
274
848
|
.intro-text {
|
|
275
849
|
max-width: 700px;
|
|
276
850
|
margin: 40px auto 0;
|
|
@@ -312,8 +886,8 @@
|
|
|
312
886
|
}
|
|
313
887
|
|
|
314
888
|
.gap-item:hover {
|
|
315
|
-
border-color: var(--
|
|
316
|
-
box-shadow: 0 0 25px
|
|
889
|
+
border-color: var(--accent-red);
|
|
890
|
+
box-shadow: 0 0 25px var(--accent-red-glow);
|
|
317
891
|
}
|
|
318
892
|
|
|
319
893
|
.gap-item::before {
|
|
@@ -322,7 +896,7 @@
|
|
|
322
896
|
left: -35px;
|
|
323
897
|
top: 50%;
|
|
324
898
|
transform: translateY(-50%);
|
|
325
|
-
color: var(--
|
|
899
|
+
color: var(--accent-red);
|
|
326
900
|
font-size: 1.2rem;
|
|
327
901
|
}
|
|
328
902
|
|
|
@@ -381,8 +955,8 @@
|
|
|
381
955
|
}
|
|
382
956
|
|
|
383
957
|
.solution-card:hover {
|
|
384
|
-
border-color: var(--
|
|
385
|
-
box-shadow: 0 0 25px
|
|
958
|
+
border-color: var(--accent-red);
|
|
959
|
+
box-shadow: 0 0 25px var(--accent-red-glow);
|
|
386
960
|
}
|
|
387
961
|
|
|
388
962
|
.solution-icon {
|
|
@@ -422,8 +996,9 @@
|
|
|
422
996
|
}
|
|
423
997
|
|
|
424
998
|
.flow-box:hover {
|
|
425
|
-
background: rgba(
|
|
426
|
-
box-shadow: 0 0 20px var(--glow);
|
|
999
|
+
background: rgba(186, 12, 47, 0.1);
|
|
1000
|
+
box-shadow: 0 0 20px var(--accent-red-glow);
|
|
1001
|
+
border-color: var(--accent-red);
|
|
427
1002
|
}
|
|
428
1003
|
|
|
429
1004
|
.flow-arrow {
|
|
@@ -461,8 +1036,8 @@
|
|
|
461
1036
|
}
|
|
462
1037
|
|
|
463
1038
|
.hook-file:hover {
|
|
464
|
-
border-left-color: var(--
|
|
465
|
-
background: rgba(
|
|
1039
|
+
border-left-color: var(--accent-red);
|
|
1040
|
+
background: rgba(186, 12, 47, 0.1);
|
|
466
1041
|
padding-left: 25px;
|
|
467
1042
|
}
|
|
468
1043
|
|
|
@@ -494,7 +1069,8 @@
|
|
|
494
1069
|
}
|
|
495
1070
|
|
|
496
1071
|
.result-blocked {
|
|
497
|
-
border-color: var(--
|
|
1072
|
+
border-color: var(--accent-red);
|
|
1073
|
+
color: var(--accent-red);
|
|
498
1074
|
}
|
|
499
1075
|
|
|
500
1076
|
.result-allowed:hover, .result-blocked:hover {
|
|
@@ -523,14 +1099,14 @@
|
|
|
523
1099
|
}
|
|
524
1100
|
|
|
525
1101
|
.phase-box:hover {
|
|
526
|
-
border-color: var(--
|
|
527
|
-
box-shadow: 0 0 25px
|
|
1102
|
+
border-color: var(--accent-red);
|
|
1103
|
+
box-shadow: 0 0 25px var(--accent-red-glow);
|
|
528
1104
|
transform: scale(1.02);
|
|
529
1105
|
}
|
|
530
1106
|
|
|
531
1107
|
.phase-box.active {
|
|
532
|
-
border-color: var(--
|
|
533
|
-
background: rgba(
|
|
1108
|
+
border-color: var(--accent-red);
|
|
1109
|
+
background: rgba(186, 12, 47, 0.1);
|
|
534
1110
|
}
|
|
535
1111
|
|
|
536
1112
|
.phase-number {
|
|
@@ -585,7 +1161,8 @@
|
|
|
585
1161
|
}
|
|
586
1162
|
|
|
587
1163
|
.walkthrough-step.active {
|
|
588
|
-
border-color: var(--
|
|
1164
|
+
border-color: var(--accent-red);
|
|
1165
|
+
box-shadow: 0 0 20px var(--accent-red-glow);
|
|
589
1166
|
}
|
|
590
1167
|
|
|
591
1168
|
.walkthrough-header {
|
|
@@ -692,10 +1269,10 @@
|
|
|
692
1269
|
}
|
|
693
1270
|
|
|
694
1271
|
.terminal-blocked {
|
|
695
|
-
color: var(--
|
|
696
|
-
border-left: 3px solid var(--
|
|
1272
|
+
color: var(--accent-red);
|
|
1273
|
+
border-left: 3px solid var(--accent-red);
|
|
697
1274
|
padding-left: 15px;
|
|
698
|
-
background: rgba(
|
|
1275
|
+
background: rgba(186, 12, 47, 0.1);
|
|
699
1276
|
}
|
|
700
1277
|
|
|
701
1278
|
.terminal-allowed {
|
|
@@ -746,10 +1323,11 @@
|
|
|
746
1323
|
}
|
|
747
1324
|
|
|
748
1325
|
.json-line.highlight {
|
|
749
|
-
background: rgba(
|
|
1326
|
+
background: rgba(186, 12, 47, 0.15);
|
|
750
1327
|
margin: 0 -25px;
|
|
751
1328
|
padding-left: 25px;
|
|
752
1329
|
padding-right: 25px;
|
|
1330
|
+
border-left: 2px solid var(--accent-red);
|
|
753
1331
|
}
|
|
754
1332
|
|
|
755
1333
|
.json-comment {
|
|
@@ -854,9 +1432,10 @@
|
|
|
854
1432
|
}
|
|
855
1433
|
|
|
856
1434
|
.credit-link:hover {
|
|
857
|
-
background: var(--
|
|
858
|
-
color:
|
|
859
|
-
|
|
1435
|
+
background: var(--accent-red);
|
|
1436
|
+
color: #fff;
|
|
1437
|
+
border-color: var(--accent-red);
|
|
1438
|
+
box-shadow: 0 0 25px var(--accent-red-glow);
|
|
860
1439
|
}
|
|
861
1440
|
|
|
862
1441
|
.made-with {
|
|
@@ -892,8 +1471,9 @@
|
|
|
892
1471
|
|
|
893
1472
|
.section-dot:hover,
|
|
894
1473
|
.section-dot.active {
|
|
895
|
-
background: var(--
|
|
896
|
-
|
|
1474
|
+
background: var(--accent-red);
|
|
1475
|
+
border-color: var(--accent-red);
|
|
1476
|
+
box-shadow: 0 0 12px var(--accent-red-glow);
|
|
897
1477
|
}
|
|
898
1478
|
|
|
899
1479
|
/* ============================================
|
|
@@ -938,6 +1518,37 @@
|
|
|
938
1518
|
</head>
|
|
939
1519
|
<body>
|
|
940
1520
|
|
|
1521
|
+
<!-- Animated Background Grid -->
|
|
1522
|
+
<div class="background-pattern">
|
|
1523
|
+
<svg class="grid-svg" id="gridSvg">
|
|
1524
|
+
<defs>
|
|
1525
|
+
<pattern id="smallGrid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
1526
|
+
<path d="M 40 0 L 0 0 0 40" class="grid-line" stroke-dasharray="2,4"/>
|
|
1527
|
+
</pattern>
|
|
1528
|
+
<pattern id="grid" width="200" height="200" patternUnits="userSpaceOnUse">
|
|
1529
|
+
<rect width="200" height="200" fill="url(#smallGrid)"/>
|
|
1530
|
+
<path d="M 200 0 L 0 0 0 200" class="grid-line" stroke-width="1"/>
|
|
1531
|
+
</pattern>
|
|
1532
|
+
</defs>
|
|
1533
|
+
<rect id="gridRect" width="100%" height="100%" fill="url(#grid)"/>
|
|
1534
|
+
</svg>
|
|
1535
|
+
</div>
|
|
1536
|
+
|
|
1537
|
+
<!-- Floating Particles -->
|
|
1538
|
+
<div class="particles" id="particles"></div>
|
|
1539
|
+
|
|
1540
|
+
<!-- Cursor Glow Effect -->
|
|
1541
|
+
<div class="cursor-glow" id="cursorGlow"></div>
|
|
1542
|
+
|
|
1543
|
+
<!-- Scanlines Overlay -->
|
|
1544
|
+
<div class="scanlines"></div>
|
|
1545
|
+
|
|
1546
|
+
<!-- Corner Decorations -->
|
|
1547
|
+
<div class="corner-decoration top-left"></div>
|
|
1548
|
+
<div class="corner-decoration top-right"></div>
|
|
1549
|
+
<div class="corner-decoration bottom-left"></div>
|
|
1550
|
+
<div class="corner-decoration bottom-right"></div>
|
|
1551
|
+
|
|
941
1552
|
<!-- Progress Bar -->
|
|
942
1553
|
<div class="progress-bar" id="progressBar"></div>
|
|
943
1554
|
|
|
@@ -955,23 +1566,59 @@
|
|
|
955
1566
|
============================================ -->
|
|
956
1567
|
<section id="intro">
|
|
957
1568
|
<div class="ascii-border">
|
|
958
|
-
<
|
|
1569
|
+
<div class="hustle-brand" id="hustleBrand">
|
|
1570
|
+
<span class="hustle-word">HUSTLE</span>
|
|
1571
|
+
<span class="hustle-word hustle-highlight">DEV</span>
|
|
1572
|
+
<span class="hustle-word">TOOLS</span>
|
|
1573
|
+
</div>
|
|
959
1574
|
<div class="package-name" id="packageName">@hustle-together/api-dev-tools</div>
|
|
960
|
-
<div class="version" id="versionText">
|
|
1575
|
+
<div class="version" id="versionText">v2.0.0</div>
|
|
961
1576
|
<p class="tagline">"Interview first, test first, document always"<span class="cursor"></span></p>
|
|
962
1577
|
|
|
963
1578
|
<div class="intro-text">
|
|
964
1579
|
<p>
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
1580
|
+
Build APIs the <span class="text-red">right way</span> with <strong>enforced workflows</strong>.
|
|
1581
|
+
No more AI shortcuts. Research first, then structured interviews with
|
|
1582
|
+
<strong>multiple-choice options</strong> based on real findings.
|
|
968
1583
|
</p>
|
|
969
1584
|
<p style="margin-top: 20px;">
|
|
970
|
-
<strong>Scroll down</strong> to see
|
|
971
|
-
creating a <strong>Brandfetch API endpoint</strong> from scratch.
|
|
1585
|
+
<strong>Scroll down</strong> to see the 5-phase workflow in action.
|
|
972
1586
|
</p>
|
|
973
1587
|
</div>
|
|
974
1588
|
|
|
1589
|
+
<!-- Visual Quick Overview - Phases Light Up -->
|
|
1590
|
+
<div class="phase-flow" id="introFlow">
|
|
1591
|
+
<div class="phase-node" data-phase="research">
|
|
1592
|
+
<span class="phase-icon">R</span>
|
|
1593
|
+
<span class="phase-label">Research</span>
|
|
1594
|
+
<div class="phase-glow"></div>
|
|
1595
|
+
</div>
|
|
1596
|
+
<span class="phase-connector-arrow">→</span>
|
|
1597
|
+
<div class="phase-node" data-phase="interview">
|
|
1598
|
+
<span class="phase-icon">?</span>
|
|
1599
|
+
<span class="phase-label">Interview</span>
|
|
1600
|
+
<div class="phase-glow"></div>
|
|
1601
|
+
</div>
|
|
1602
|
+
<span class="phase-connector-arrow">→</span>
|
|
1603
|
+
<div class="phase-node" data-phase="test">
|
|
1604
|
+
<span class="phase-icon">T</span>
|
|
1605
|
+
<span class="phase-label">Test</span>
|
|
1606
|
+
<div class="phase-glow"></div>
|
|
1607
|
+
</div>
|
|
1608
|
+
<span class="phase-connector-arrow">→</span>
|
|
1609
|
+
<div class="phase-node" data-phase="code">
|
|
1610
|
+
<span class="phase-icon">C</span>
|
|
1611
|
+
<span class="phase-label">Code</span>
|
|
1612
|
+
<div class="phase-glow"></div>
|
|
1613
|
+
</div>
|
|
1614
|
+
<span class="phase-connector-arrow">→</span>
|
|
1615
|
+
<div class="phase-node" data-phase="docs">
|
|
1616
|
+
<span class="phase-icon">D</span>
|
|
1617
|
+
<span class="phase-label">Docs</span>
|
|
1618
|
+
<div class="phase-glow"></div>
|
|
1619
|
+
</div>
|
|
1620
|
+
</div>
|
|
1621
|
+
|
|
975
1622
|
<div class="scroll-hint">[ SCROLL TO BEGIN ]</div>
|
|
976
1623
|
</div>
|
|
977
1624
|
</section>
|
|
@@ -1180,31 +1827,35 @@
|
|
|
1180
1827
|
</div>
|
|
1181
1828
|
|
|
1182
1829
|
<div class="phase-grid">
|
|
1183
|
-
<div class="phase-box" data-phase="1">
|
|
1830
|
+
<div class="phase-box glow-border" data-phase="1">
|
|
1184
1831
|
<div class="phase-status"></div>
|
|
1185
1832
|
<div class="phase-number">01</div>
|
|
1186
1833
|
<div class="phase-name">Scope</div>
|
|
1187
1834
|
<div class="phase-desc">Define what we're building</div>
|
|
1835
|
+
<span class="phase-arrow">→</span>
|
|
1188
1836
|
</div>
|
|
1189
|
-
<div class="phase-box" data-phase="2">
|
|
1837
|
+
<div class="phase-box glow-border" data-phase="2">
|
|
1190
1838
|
<div class="phase-status"></div>
|
|
1191
1839
|
<div class="phase-number">02</div>
|
|
1192
1840
|
<div class="phase-name">Research</div>
|
|
1193
1841
|
<div class="phase-desc">Find live documentation</div>
|
|
1842
|
+
<span class="phase-arrow">→</span>
|
|
1194
1843
|
</div>
|
|
1195
|
-
<div class="phase-box" data-phase="3">
|
|
1844
|
+
<div class="phase-box glow-border" data-phase="3">
|
|
1196
1845
|
<div class="phase-status"></div>
|
|
1197
1846
|
<div class="phase-number">03</div>
|
|
1198
1847
|
<div class="phase-name">Interview</div>
|
|
1199
1848
|
<div class="phase-desc">Ask user questions</div>
|
|
1849
|
+
<span class="phase-arrow">→</span>
|
|
1200
1850
|
</div>
|
|
1201
|
-
<div class="phase-box" data-phase="4">
|
|
1851
|
+
<div class="phase-box glow-border" data-phase="4">
|
|
1202
1852
|
<div class="phase-status"></div>
|
|
1203
1853
|
<div class="phase-number">04</div>
|
|
1204
1854
|
<div class="phase-name">Deep Research</div>
|
|
1205
1855
|
<div class="phase-desc">Based on interview answers</div>
|
|
1856
|
+
<span class="phase-arrow">→</span>
|
|
1206
1857
|
</div>
|
|
1207
|
-
<div class="phase-box" data-phase="5">
|
|
1858
|
+
<div class="phase-box glow-border" data-phase="5">
|
|
1208
1859
|
<div class="phase-status"></div>
|
|
1209
1860
|
<div class="phase-number">05</div>
|
|
1210
1861
|
<div class="phase-name">Schema</div>
|
|
@@ -1213,31 +1864,35 @@
|
|
|
1213
1864
|
|
|
1214
1865
|
<div class="phase-connector">- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -</div>
|
|
1215
1866
|
|
|
1216
|
-
<div class="phase-box" data-phase="6">
|
|
1867
|
+
<div class="phase-box glow-border" data-phase="6">
|
|
1217
1868
|
<div class="phase-status"></div>
|
|
1218
1869
|
<div class="phase-number">06</div>
|
|
1219
1870
|
<div class="phase-name">Environment</div>
|
|
1220
1871
|
<div class="phase-desc">Check API keys exist</div>
|
|
1872
|
+
<span class="phase-arrow">→</span>
|
|
1221
1873
|
</div>
|
|
1222
|
-
<div class="phase-box" data-phase="7">
|
|
1874
|
+
<div class="phase-box glow-border" data-phase="7">
|
|
1223
1875
|
<div class="phase-status"></div>
|
|
1224
1876
|
<div class="phase-number">07</div>
|
|
1225
1877
|
<div class="phase-name">TDD Red</div>
|
|
1226
1878
|
<div class="phase-desc">Write failing tests</div>
|
|
1879
|
+
<span class="phase-arrow">→</span>
|
|
1227
1880
|
</div>
|
|
1228
|
-
<div class="phase-box" data-phase="8">
|
|
1881
|
+
<div class="phase-box glow-border" data-phase="8">
|
|
1229
1882
|
<div class="phase-status"></div>
|
|
1230
1883
|
<div class="phase-number">08</div>
|
|
1231
1884
|
<div class="phase-name">TDD Green</div>
|
|
1232
1885
|
<div class="phase-desc">Make tests pass</div>
|
|
1886
|
+
<span class="phase-arrow">→</span>
|
|
1233
1887
|
</div>
|
|
1234
|
-
<div class="phase-box" data-phase="9">
|
|
1888
|
+
<div class="phase-box glow-border" data-phase="9">
|
|
1235
1889
|
<div class="phase-status"></div>
|
|
1236
1890
|
<div class="phase-number">09</div>
|
|
1237
1891
|
<div class="phase-name">Refactor</div>
|
|
1238
1892
|
<div class="phase-desc">Clean up the code</div>
|
|
1893
|
+
<span class="phase-arrow">→</span>
|
|
1239
1894
|
</div>
|
|
1240
|
-
<div class="phase-box" data-phase="10">
|
|
1895
|
+
<div class="phase-box glow-border" data-phase="10">
|
|
1241
1896
|
<div class="phase-status"></div>
|
|
1242
1897
|
<div class="phase-number">10</div>
|
|
1243
1898
|
<div class="phase-name">Documentation</div>
|
|
@@ -1414,6 +2069,10 @@
|
|
|
1414
2069
|
<div class="terminal-dot"></div>
|
|
1415
2070
|
<div class="terminal-dot"></div>
|
|
1416
2071
|
<div class="terminal-title">claude-code session: /api-create brandfetch</div>
|
|
2072
|
+
<div class="status-badge active" style="margin-left: auto;">
|
|
2073
|
+
<span class="pulse"></span>
|
|
2074
|
+
<span>Live</span>
|
|
2075
|
+
</div>
|
|
1417
2076
|
</div>
|
|
1418
2077
|
|
|
1419
2078
|
<div class="terminal-comment" data-step="0">// Step 1: Research phase starts automatically</div>
|
|
@@ -1488,6 +2147,15 @@
|
|
|
1488
2147
|
• API Key Handling: server_only<br>
|
|
1489
2148
|
ALLOWED: Writing schema file...</span>
|
|
1490
2149
|
</div>
|
|
2150
|
+
|
|
2151
|
+
<div class="terminal-line" data-step="16" style="margin-top: 15px;">
|
|
2152
|
+
<span class="terminal-prompt">claude></span>
|
|
2153
|
+
<div class="typing-indicator">
|
|
2154
|
+
<span></span>
|
|
2155
|
+
<span></span>
|
|
2156
|
+
<span></span>
|
|
2157
|
+
</div>
|
|
2158
|
+
</div>
|
|
1491
2159
|
</div>
|
|
1492
2160
|
</div>
|
|
1493
2161
|
</section>
|
|
@@ -1616,13 +2284,28 @@
|
|
|
1616
2284
|
|
|
1617
2285
|
<div class="explanation" style="text-align: left;">
|
|
1618
2286
|
<div class="explanation-title">What You Get</div>
|
|
1619
|
-
<
|
|
1620
|
-
<
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
<
|
|
1625
|
-
|
|
2287
|
+
<div style="display: flex; flex-direction: column; gap: 12px;">
|
|
2288
|
+
<div style="display: flex; align-items: center;">
|
|
2289
|
+
<span class="visual-check checked"></span>
|
|
2290
|
+
<span><strong>Structured workflow</strong> - No more skipped steps or assumptions</span>
|
|
2291
|
+
</div>
|
|
2292
|
+
<div style="display: flex; align-items: center;">
|
|
2293
|
+
<span class="visual-check checked"></span>
|
|
2294
|
+
<span><strong>Real enforcement</strong> - Hooks that actually block bad behavior</span>
|
|
2295
|
+
</div>
|
|
2296
|
+
<div style="display: flex; align-items: center;">
|
|
2297
|
+
<span class="visual-check checked"></span>
|
|
2298
|
+
<span><strong>Audit trail</strong> - Every action logged to state file</span>
|
|
2299
|
+
</div>
|
|
2300
|
+
<div style="display: flex; align-items: center;">
|
|
2301
|
+
<span class="visual-check checked"></span>
|
|
2302
|
+
<span><strong>Gap detection</strong> - Catches mismatches between requirements and code</span>
|
|
2303
|
+
</div>
|
|
2304
|
+
<div style="display: flex; align-items: center;">
|
|
2305
|
+
<span class="visual-check checked"></span>
|
|
2306
|
+
<span><strong>TDD built-in</strong> - Tests written before implementation</span>
|
|
2307
|
+
</div>
|
|
2308
|
+
</div>
|
|
1626
2309
|
</div>
|
|
1627
2310
|
|
|
1628
2311
|
<div class="credit-links">
|
|
@@ -1681,7 +2364,7 @@
|
|
|
1681
2364
|
});
|
|
1682
2365
|
|
|
1683
2366
|
// ============================================
|
|
1684
|
-
// SECTION 1: INTRO ANIMATION
|
|
2367
|
+
// SECTION 1: INTRO ANIMATION - HUSTLE BRAND + PHASE LIGHTING
|
|
1685
2368
|
// ============================================
|
|
1686
2369
|
const introTL = gsap.timeline({
|
|
1687
2370
|
scrollTrigger: {
|
|
@@ -1691,12 +2374,69 @@
|
|
|
1691
2374
|
}
|
|
1692
2375
|
});
|
|
1693
2376
|
|
|
2377
|
+
// Hustle brand title animation
|
|
1694
2378
|
introTL
|
|
1695
|
-
.to('
|
|
1696
|
-
|
|
2379
|
+
.to('.hustle-word', {
|
|
2380
|
+
opacity: 1,
|
|
2381
|
+
y: 0,
|
|
2382
|
+
duration: 0.5,
|
|
2383
|
+
stagger: 0.15,
|
|
2384
|
+
ease: 'back.out(1.7)'
|
|
2385
|
+
})
|
|
2386
|
+
.to('#packageName', { opacity: 1, duration: 0.4 }, '-=0.2')
|
|
1697
2387
|
.to('#versionText', { opacity: 1, duration: 0.3 })
|
|
1698
|
-
.to('.
|
|
1699
|
-
.to('.
|
|
2388
|
+
.to('.tagline', { opacity: 1, duration: 0.4 })
|
|
2389
|
+
.to('.intro-text', { opacity: 1, duration: 0.5 }, '-=0.2')
|
|
2390
|
+
.to('#introFlow', { opacity: 1, duration: 0.3 })
|
|
2391
|
+
// Phase nodes appear one by one
|
|
2392
|
+
.to('#introFlow .phase-node', {
|
|
2393
|
+
opacity: 1,
|
|
2394
|
+
y: 0,
|
|
2395
|
+
duration: 0.3,
|
|
2396
|
+
stagger: 0.12,
|
|
2397
|
+
ease: 'power2.out'
|
|
2398
|
+
})
|
|
2399
|
+
// Arrows appear between nodes
|
|
2400
|
+
.to('#introFlow .phase-connector-arrow', {
|
|
2401
|
+
opacity: 1,
|
|
2402
|
+
duration: 0.2,
|
|
2403
|
+
stagger: 0.1
|
|
2404
|
+
}, '-=0.4')
|
|
2405
|
+
.to('.scroll-hint', { opacity: 1, duration: 0.4 }, '-=0.2');
|
|
2406
|
+
|
|
2407
|
+
// Phase lighting sequence - lights up each phase with red glow
|
|
2408
|
+
const phaseNodes = document.querySelectorAll('#introFlow .phase-node');
|
|
2409
|
+
const phaseArrows = document.querySelectorAll('#introFlow .phase-connector-arrow');
|
|
2410
|
+
|
|
2411
|
+
// Create a separate timeline for the lighting sequence that loops
|
|
2412
|
+
const lightingTL = gsap.timeline({
|
|
2413
|
+
repeat: -1,
|
|
2414
|
+
repeatDelay: 1,
|
|
2415
|
+
delay: 3 // Wait for intro animation to complete
|
|
2416
|
+
});
|
|
2417
|
+
|
|
2418
|
+
phaseNodes.forEach((node, i) => {
|
|
2419
|
+
lightingTL
|
|
2420
|
+
.call(() => {
|
|
2421
|
+
// Light up current node
|
|
2422
|
+
node.classList.add('active');
|
|
2423
|
+
// Light up the arrow before this node (if any)
|
|
2424
|
+
if (i > 0 && phaseArrows[i-1]) {
|
|
2425
|
+
phaseArrows[i-1].classList.add('active');
|
|
2426
|
+
}
|
|
2427
|
+
})
|
|
2428
|
+
.to({}, { duration: 0.5 }); // Pause to show the lit state
|
|
2429
|
+
});
|
|
2430
|
+
|
|
2431
|
+
// Keep all lit for a moment, then reset
|
|
2432
|
+
lightingTL
|
|
2433
|
+
.to({}, { duration: 1.5 })
|
|
2434
|
+
.call(() => {
|
|
2435
|
+
// Reset all
|
|
2436
|
+
phaseNodes.forEach(node => node.classList.remove('active'));
|
|
2437
|
+
phaseArrows.forEach(arrow => arrow.classList.remove('active'));
|
|
2438
|
+
})
|
|
2439
|
+
.to({}, { duration: 0.5 }); // Brief pause before restart
|
|
1700
2440
|
|
|
1701
2441
|
// ============================================
|
|
1702
2442
|
// SECTION 2: PROBLEMS ANIMATION
|
|
@@ -1968,6 +2708,157 @@
|
|
|
1968
2708
|
});
|
|
1969
2709
|
});
|
|
1970
2710
|
});
|
|
2711
|
+
|
|
2712
|
+
// ============================================
|
|
2713
|
+
// ANIMATED BACKGROUND - FLOATING PARTICLES (ENHANCED)
|
|
2714
|
+
// ============================================
|
|
2715
|
+
const particleContainer = document.getElementById('particles');
|
|
2716
|
+
// More particle types: circles, squares, X's, plus signs, lines, triangles
|
|
2717
|
+
const particleTypes = ['', 'square', 'plus', 'x-shape', 'line', 'line-v', 'circle-outline', 'triangle'];
|
|
2718
|
+
const particleCount = 50; // More particles
|
|
2719
|
+
|
|
2720
|
+
// Create particles
|
|
2721
|
+
for (let i = 0; i < particleCount; i++) {
|
|
2722
|
+
const particle = document.createElement('div');
|
|
2723
|
+
const type = particleTypes[Math.floor(Math.random() * particleTypes.length)];
|
|
2724
|
+
particle.className = `particle ${type}`;
|
|
2725
|
+
particle.style.left = `${Math.random() * 100}%`;
|
|
2726
|
+
particle.style.top = `${Math.random() * 100}%`;
|
|
2727
|
+
particleContainer.appendChild(particle);
|
|
2728
|
+
|
|
2729
|
+
// FASTER, MORE VISIBLE MOVEMENT
|
|
2730
|
+
const speed = 4 + Math.random() * 8; // Much faster: 4-12 seconds
|
|
2731
|
+
const distance = 150 + Math.random() * 250; // Larger movement range
|
|
2732
|
+
|
|
2733
|
+
// Animate each particle with GSAP - MORE MOTION
|
|
2734
|
+
gsap.to(particle, {
|
|
2735
|
+
x: `${(Math.random() - 0.5) * distance}`,
|
|
2736
|
+
y: `${(Math.random() - 0.5) * distance}`,
|
|
2737
|
+
rotation: (Math.random() - 0.5) * 720, // More rotation
|
|
2738
|
+
duration: speed,
|
|
2739
|
+
repeat: -1,
|
|
2740
|
+
yoyo: true,
|
|
2741
|
+
ease: 'sine.inOut',
|
|
2742
|
+
delay: Math.random() * 2
|
|
2743
|
+
});
|
|
2744
|
+
|
|
2745
|
+
// Fade in/out animation - more visible
|
|
2746
|
+
gsap.to(particle, {
|
|
2747
|
+
opacity: 0.15 + Math.random() * 0.4, // Higher opacity
|
|
2748
|
+
duration: 2 + Math.random() * 3,
|
|
2749
|
+
repeat: -1,
|
|
2750
|
+
yoyo: true,
|
|
2751
|
+
ease: 'sine.inOut',
|
|
2752
|
+
delay: Math.random() * 2
|
|
2753
|
+
});
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
// Add some CONSTANTLY MOVING particles that drift across the screen
|
|
2757
|
+
for (let i = 0; i < 10; i++) {
|
|
2758
|
+
const drifter = document.createElement('div');
|
|
2759
|
+
const type = particleTypes[Math.floor(Math.random() * particleTypes.length)];
|
|
2760
|
+
drifter.className = `particle ${type}`;
|
|
2761
|
+
drifter.style.left = `-20px`;
|
|
2762
|
+
drifter.style.top = `${Math.random() * 100}%`;
|
|
2763
|
+
drifter.style.opacity = '0.3';
|
|
2764
|
+
particleContainer.appendChild(drifter);
|
|
2765
|
+
|
|
2766
|
+
// Drift across the screen continuously
|
|
2767
|
+
gsap.to(drifter, {
|
|
2768
|
+
x: window.innerWidth + 40,
|
|
2769
|
+
y: (Math.random() - 0.5) * 200,
|
|
2770
|
+
rotation: Math.random() * 360,
|
|
2771
|
+
duration: 15 + Math.random() * 15,
|
|
2772
|
+
repeat: -1,
|
|
2773
|
+
ease: 'none',
|
|
2774
|
+
delay: i * 3
|
|
2775
|
+
});
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
// ============================================
|
|
2779
|
+
// ANIMATED BACKGROUND - GRID MOTION (FASTER)
|
|
2780
|
+
// ============================================
|
|
2781
|
+
const gridRect = document.getElementById('gridRect');
|
|
2782
|
+
let gridOffset = { x: 0, y: 0 };
|
|
2783
|
+
|
|
2784
|
+
// Faster, more noticeable grid drift
|
|
2785
|
+
gsap.to(gridOffset, {
|
|
2786
|
+
x: 40,
|
|
2787
|
+
y: 40,
|
|
2788
|
+
duration: 10, // Faster: was 30
|
|
2789
|
+
repeat: -1,
|
|
2790
|
+
yoyo: true, // Added yoyo for back-and-forth
|
|
2791
|
+
ease: 'sine.inOut',
|
|
2792
|
+
onUpdate: () => {
|
|
2793
|
+
gridRect.setAttribute('transform', `translate(${gridOffset.x}, ${gridOffset.y})`);
|
|
2794
|
+
}
|
|
2795
|
+
});
|
|
2796
|
+
|
|
2797
|
+
// Add subtle grid pulsing
|
|
2798
|
+
gsap.to('.grid-svg', {
|
|
2799
|
+
opacity: 0.2,
|
|
2800
|
+
duration: 4,
|
|
2801
|
+
repeat: -1,
|
|
2802
|
+
yoyo: true,
|
|
2803
|
+
ease: 'sine.inOut'
|
|
2804
|
+
});
|
|
2805
|
+
|
|
2806
|
+
// ============================================
|
|
2807
|
+
// CURSOR GLOW EFFECT
|
|
2808
|
+
// ============================================
|
|
2809
|
+
const cursorGlow = document.getElementById('cursorGlow');
|
|
2810
|
+
let mouseX = 0, mouseY = 0;
|
|
2811
|
+
let glowX = 0, glowY = 0;
|
|
2812
|
+
|
|
2813
|
+
document.addEventListener('mousemove', (e) => {
|
|
2814
|
+
mouseX = e.clientX;
|
|
2815
|
+
mouseY = e.clientY;
|
|
2816
|
+
});
|
|
2817
|
+
|
|
2818
|
+
// Smooth cursor follow
|
|
2819
|
+
function updateCursorGlow() {
|
|
2820
|
+
const dx = mouseX - glowX;
|
|
2821
|
+
const dy = mouseY - glowY;
|
|
2822
|
+
glowX += dx * 0.08;
|
|
2823
|
+
glowY += dy * 0.08;
|
|
2824
|
+
cursorGlow.style.left = `${glowX}px`;
|
|
2825
|
+
cursorGlow.style.top = `${glowY}px`;
|
|
2826
|
+
requestAnimationFrame(updateCursorGlow);
|
|
2827
|
+
}
|
|
2828
|
+
updateCursorGlow();
|
|
2829
|
+
|
|
2830
|
+
// ============================================
|
|
2831
|
+
// CORNER DECORATIONS ANIMATION
|
|
2832
|
+
// ============================================
|
|
2833
|
+
gsap.to('.corner-decoration', {
|
|
2834
|
+
opacity: 0.2,
|
|
2835
|
+
duration: 2,
|
|
2836
|
+
repeat: -1,
|
|
2837
|
+
yoyo: true,
|
|
2838
|
+
ease: 'sine.inOut',
|
|
2839
|
+
stagger: 0.5
|
|
2840
|
+
});
|
|
2841
|
+
|
|
2842
|
+
// ============================================
|
|
2843
|
+
// SECTION TRANSITION EFFECTS
|
|
2844
|
+
// ============================================
|
|
2845
|
+
sections.forEach(sectionId => {
|
|
2846
|
+
ScrollTrigger.create({
|
|
2847
|
+
trigger: `#${sectionId}`,
|
|
2848
|
+
start: 'top center',
|
|
2849
|
+
end: 'bottom center',
|
|
2850
|
+
onEnter: () => {
|
|
2851
|
+
// Pulse the grid when entering a new section
|
|
2852
|
+
gsap.to('.grid-svg', {
|
|
2853
|
+
opacity: 0.25,
|
|
2854
|
+
duration: 0.3,
|
|
2855
|
+
yoyo: true,
|
|
2856
|
+
repeat: 1,
|
|
2857
|
+
ease: 'power2.out'
|
|
2858
|
+
});
|
|
2859
|
+
}
|
|
2860
|
+
});
|
|
2861
|
+
});
|
|
1971
2862
|
</script>
|
|
1972
2863
|
|
|
1973
2864
|
</body>
|