@hustle-together/api-dev-tools 1.8.0 → 2.0.0
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 +45 -2
- 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 +881 -157
- package/hooks/enforce-interview.py +52 -2
- package/hooks/track-tool-use.py +51 -2
- package/package.json +1 -1
|
@@ -0,0 +1,1279 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Hustle Together - Tools for Builders</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=JetBrains+Mono:wght@300;400;500;700&family=Righteous&family=Bungee&family=Fredoka:wght@600;700&display=swap" rel="stylesheet">
|
|
10
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
|
11
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
|
|
12
|
+
<style>
|
|
13
|
+
/* ============================================
|
|
14
|
+
HUSTLE TOGETHER - RETRO TERMINAL AESTHETIC
|
|
15
|
+
Light/Dark Mode Support
|
|
16
|
+
============================================ */
|
|
17
|
+
|
|
18
|
+
* {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding: 0;
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
:root {
|
|
25
|
+
/* Dark Mode (default) - Bulls/Nike colorway: Red, White, Black */
|
|
26
|
+
--bg: #0a0a0a;
|
|
27
|
+
--bg-secondary: #111;
|
|
28
|
+
--text: #e0e0e0;
|
|
29
|
+
--text-muted: #888;
|
|
30
|
+
--text-dim: #444;
|
|
31
|
+
--accent: #fff;
|
|
32
|
+
--accent-red: #BA0C2F;
|
|
33
|
+
--accent-red-glow: rgba(186, 12, 47, 0.4);
|
|
34
|
+
--border: #333;
|
|
35
|
+
--glow: rgba(255, 255, 255, 0.3);
|
|
36
|
+
--pattern-opacity: 0.03;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[data-theme="light"] {
|
|
40
|
+
--bg: #f5f5f5;
|
|
41
|
+
--bg-secondary: #fff;
|
|
42
|
+
--text: #1a1a1a;
|
|
43
|
+
--text-muted: #666;
|
|
44
|
+
--text-dim: #aaa;
|
|
45
|
+
--accent: #000;
|
|
46
|
+
--accent-red: #BA0C2F;
|
|
47
|
+
--accent-red-glow: rgba(186, 12, 47, 0.3);
|
|
48
|
+
--border: #ccc;
|
|
49
|
+
--glow: rgba(0, 0, 0, 0.15);
|
|
50
|
+
--pattern-opacity: 0.05;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
body {
|
|
54
|
+
background: var(--bg);
|
|
55
|
+
color: var(--text);
|
|
56
|
+
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
|
57
|
+
line-height: 1.7;
|
|
58
|
+
overflow-x: hidden;
|
|
59
|
+
transition: background 0.3s, color 0.3s;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Animated Background Pattern */
|
|
63
|
+
.bg-pattern {
|
|
64
|
+
position: fixed;
|
|
65
|
+
top: 0;
|
|
66
|
+
left: 0;
|
|
67
|
+
width: 100%;
|
|
68
|
+
height: 100%;
|
|
69
|
+
pointer-events: none;
|
|
70
|
+
z-index: 0;
|
|
71
|
+
opacity: var(--pattern-opacity);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.bg-pattern svg {
|
|
75
|
+
width: 100%;
|
|
76
|
+
height: 100%;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.grid-line {
|
|
80
|
+
stroke: var(--text);
|
|
81
|
+
stroke-width: 0.5;
|
|
82
|
+
fill: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Navigation */
|
|
86
|
+
nav {
|
|
87
|
+
position: fixed;
|
|
88
|
+
top: 0;
|
|
89
|
+
left: 0;
|
|
90
|
+
right: 0;
|
|
91
|
+
z-index: 1000;
|
|
92
|
+
padding: 20px 40px;
|
|
93
|
+
display: flex;
|
|
94
|
+
justify-content: space-between;
|
|
95
|
+
align-items: center;
|
|
96
|
+
background: var(--bg);
|
|
97
|
+
border-bottom: 1px dashed var(--border);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.logo {
|
|
101
|
+
font-size: 1.2rem;
|
|
102
|
+
font-family: 'Fredoka', 'Bungee', sans-serif;
|
|
103
|
+
font-weight: 700;
|
|
104
|
+
letter-spacing: 2px;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: 10px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.logo-icon {
|
|
111
|
+
width: 30px;
|
|
112
|
+
height: 30px;
|
|
113
|
+
border: 2px solid var(--text);
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
font-size: 0.8rem;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.nav-links {
|
|
121
|
+
display: flex;
|
|
122
|
+
gap: 30px;
|
|
123
|
+
align-items: center;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.nav-links a {
|
|
127
|
+
color: var(--text-muted);
|
|
128
|
+
text-decoration: none;
|
|
129
|
+
font-size: 0.85rem;
|
|
130
|
+
letter-spacing: 1px;
|
|
131
|
+
transition: all 0.3s;
|
|
132
|
+
padding: 8px 0;
|
|
133
|
+
border-bottom: 1px solid transparent;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.nav-links a:hover {
|
|
137
|
+
color: var(--accent-red);
|
|
138
|
+
border-bottom-color: var(--accent-red);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.theme-toggle {
|
|
142
|
+
background: transparent;
|
|
143
|
+
border: 1px dashed var(--border);
|
|
144
|
+
color: var(--text);
|
|
145
|
+
padding: 8px 12px;
|
|
146
|
+
cursor: pointer;
|
|
147
|
+
font-family: inherit;
|
|
148
|
+
font-size: 0.8rem;
|
|
149
|
+
transition: all 0.3s;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.theme-toggle:hover {
|
|
153
|
+
background: var(--text);
|
|
154
|
+
color: var(--bg);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Main Content */
|
|
158
|
+
main {
|
|
159
|
+
position: relative;
|
|
160
|
+
z-index: 1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
section {
|
|
164
|
+
min-height: 100vh;
|
|
165
|
+
display: flex;
|
|
166
|
+
flex-direction: column;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
align-items: center;
|
|
169
|
+
padding: 120px 40px 80px;
|
|
170
|
+
position: relative;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Hero Section */
|
|
174
|
+
#hero {
|
|
175
|
+
text-align: center;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.hero-content {
|
|
179
|
+
max-width: 800px;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.hero-badge {
|
|
183
|
+
display: inline-block;
|
|
184
|
+
border: 1px dashed var(--border);
|
|
185
|
+
padding: 8px 20px;
|
|
186
|
+
font-size: 0.75rem;
|
|
187
|
+
letter-spacing: 3px;
|
|
188
|
+
color: var(--text-muted);
|
|
189
|
+
margin-bottom: 40px;
|
|
190
|
+
opacity: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
h1 {
|
|
194
|
+
font-size: 6.5rem;
|
|
195
|
+
font-family: 'Fredoka', 'Bungee', sans-serif;
|
|
196
|
+
font-weight: 700;
|
|
197
|
+
letter-spacing: 4px;
|
|
198
|
+
margin-bottom: 10px;
|
|
199
|
+
display: flex;
|
|
200
|
+
flex-wrap: wrap;
|
|
201
|
+
justify-content: center;
|
|
202
|
+
gap: 0 20px;
|
|
203
|
+
line-height: 1;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
h1 .word {
|
|
207
|
+
display: flex;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
h1 .letter {
|
|
211
|
+
display: inline-block;
|
|
212
|
+
opacity: 0;
|
|
213
|
+
transform: translateY(50px) rotateX(-90deg);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
h1 .highlight {
|
|
217
|
+
font-weight: 700;
|
|
218
|
+
color: var(--accent);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.hero-tagline {
|
|
222
|
+
font-size: 1.3rem;
|
|
223
|
+
color: var(--text-muted);
|
|
224
|
+
margin-top: 30px;
|
|
225
|
+
letter-spacing: 2px;
|
|
226
|
+
opacity: 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.hero-desc {
|
|
230
|
+
margin-top: 40px;
|
|
231
|
+
font-size: 1rem;
|
|
232
|
+
color: var(--text-muted);
|
|
233
|
+
line-height: 2;
|
|
234
|
+
max-width: 600px;
|
|
235
|
+
margin-left: auto;
|
|
236
|
+
margin-right: auto;
|
|
237
|
+
opacity: 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.hero-cta {
|
|
241
|
+
margin-top: 50px;
|
|
242
|
+
display: flex;
|
|
243
|
+
gap: 20px;
|
|
244
|
+
justify-content: center;
|
|
245
|
+
opacity: 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.btn {
|
|
249
|
+
display: inline-block;
|
|
250
|
+
padding: 15px 40px;
|
|
251
|
+
border: 1px solid var(--text);
|
|
252
|
+
color: var(--text);
|
|
253
|
+
text-decoration: none;
|
|
254
|
+
font-size: 0.9rem;
|
|
255
|
+
letter-spacing: 2px;
|
|
256
|
+
transition: all 0.3s;
|
|
257
|
+
background: transparent;
|
|
258
|
+
cursor: pointer;
|
|
259
|
+
font-family: inherit;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.btn:hover {
|
|
263
|
+
background: var(--text);
|
|
264
|
+
color: var(--bg);
|
|
265
|
+
box-shadow: 0 0 30px var(--glow);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.btn-primary {
|
|
269
|
+
background: var(--accent-red);
|
|
270
|
+
color: #fff;
|
|
271
|
+
border-color: var(--accent-red);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.btn-primary:hover {
|
|
275
|
+
background: transparent;
|
|
276
|
+
color: var(--accent-red);
|
|
277
|
+
box-shadow: 0 0 30px var(--accent-red-glow);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* Section Headers */
|
|
281
|
+
.section-header {
|
|
282
|
+
text-align: center;
|
|
283
|
+
margin-bottom: 60px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.section-label {
|
|
287
|
+
font-size: 0.75rem;
|
|
288
|
+
letter-spacing: 4px;
|
|
289
|
+
color: var(--text-muted);
|
|
290
|
+
margin-bottom: 15px;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
h2 {
|
|
294
|
+
font-size: 2.5rem;
|
|
295
|
+
font-family: 'Fredoka', 'Bungee', sans-serif;
|
|
296
|
+
font-weight: 600;
|
|
297
|
+
letter-spacing: 3px;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
h2 .highlight {
|
|
301
|
+
font-weight: 700;
|
|
302
|
+
color: var(--accent);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/* Philosophy Section */
|
|
306
|
+
#philosophy {
|
|
307
|
+
background: var(--bg-secondary);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.philosophy-grid {
|
|
311
|
+
display: grid;
|
|
312
|
+
grid-template-columns: repeat(3, 1fr);
|
|
313
|
+
gap: 30px;
|
|
314
|
+
max-width: 1000px;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.philosophy-card {
|
|
318
|
+
border: 1px dashed var(--border);
|
|
319
|
+
padding: 40px 30px;
|
|
320
|
+
text-align: center;
|
|
321
|
+
transition: all 0.3s;
|
|
322
|
+
opacity: 0;
|
|
323
|
+
transform: translateY(20px);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.philosophy-card:hover {
|
|
327
|
+
border-color: var(--accent-red);
|
|
328
|
+
box-shadow: 0 0 30px var(--accent-red-glow);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.philosophy-icon {
|
|
332
|
+
width: 60px;
|
|
333
|
+
height: 60px;
|
|
334
|
+
border: 2px solid var(--accent-red);
|
|
335
|
+
color: var(--accent-red);
|
|
336
|
+
margin: 0 auto 25px;
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
justify-content: center;
|
|
340
|
+
font-size: 1.5rem;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.philosophy-title {
|
|
344
|
+
font-size: 1.1rem;
|
|
345
|
+
letter-spacing: 2px;
|
|
346
|
+
margin-bottom: 15px;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.philosophy-desc {
|
|
350
|
+
font-size: 0.9rem;
|
|
351
|
+
color: var(--text-muted);
|
|
352
|
+
line-height: 1.8;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/* Tools Section */
|
|
356
|
+
.tools-grid {
|
|
357
|
+
display: grid;
|
|
358
|
+
grid-template-columns: repeat(2, 1fr);
|
|
359
|
+
gap: 40px;
|
|
360
|
+
max-width: 1000px;
|
|
361
|
+
width: 100%;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.tool-card {
|
|
365
|
+
border: 1px dashed var(--border);
|
|
366
|
+
padding: 40px;
|
|
367
|
+
transition: all 0.3s;
|
|
368
|
+
opacity: 0;
|
|
369
|
+
transform: translateY(20px);
|
|
370
|
+
position: relative;
|
|
371
|
+
overflow: hidden;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.tool-card::before {
|
|
375
|
+
content: '';
|
|
376
|
+
position: absolute;
|
|
377
|
+
top: 0;
|
|
378
|
+
left: 0;
|
|
379
|
+
width: 100%;
|
|
380
|
+
height: 3px;
|
|
381
|
+
background: var(--accent-red);
|
|
382
|
+
transform: scaleX(0);
|
|
383
|
+
transition: transform 0.3s;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.tool-card:hover {
|
|
387
|
+
border-color: var(--accent-red);
|
|
388
|
+
box-shadow: 0 0 40px var(--accent-red-glow);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.tool-card:hover::before {
|
|
392
|
+
transform: scaleX(1);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.tool-badge {
|
|
396
|
+
display: inline-block;
|
|
397
|
+
font-size: 0.7rem;
|
|
398
|
+
letter-spacing: 2px;
|
|
399
|
+
color: var(--text-muted);
|
|
400
|
+
border: 1px dashed var(--border);
|
|
401
|
+
padding: 5px 12px;
|
|
402
|
+
margin-bottom: 20px;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.tool-name {
|
|
406
|
+
font-size: 1.5rem;
|
|
407
|
+
letter-spacing: 2px;
|
|
408
|
+
margin-bottom: 15px;
|
|
409
|
+
display: flex;
|
|
410
|
+
align-items: center;
|
|
411
|
+
gap: 15px;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.tool-name .icon {
|
|
415
|
+
width: 40px;
|
|
416
|
+
height: 40px;
|
|
417
|
+
border: 1px solid var(--text);
|
|
418
|
+
display: flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
justify-content: center;
|
|
421
|
+
font-size: 1rem;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.tool-desc {
|
|
425
|
+
color: var(--text-muted);
|
|
426
|
+
font-size: 0.95rem;
|
|
427
|
+
line-height: 1.8;
|
|
428
|
+
margin-bottom: 25px;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.tool-features {
|
|
432
|
+
list-style: none;
|
|
433
|
+
margin-bottom: 30px;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.tool-features li {
|
|
437
|
+
font-size: 0.85rem;
|
|
438
|
+
color: var(--text-muted);
|
|
439
|
+
padding: 8px 0;
|
|
440
|
+
border-bottom: 1px dashed var(--border);
|
|
441
|
+
display: flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
gap: 10px;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.tool-features li::before {
|
|
447
|
+
content: '+';
|
|
448
|
+
color: var(--accent-red);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.tool-links {
|
|
452
|
+
display: flex;
|
|
453
|
+
gap: 15px;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.tool-link {
|
|
457
|
+
font-size: 0.8rem;
|
|
458
|
+
color: var(--text);
|
|
459
|
+
text-decoration: none;
|
|
460
|
+
border: 1px dashed var(--border);
|
|
461
|
+
padding: 10px 20px;
|
|
462
|
+
transition: all 0.3s;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.tool-link:hover {
|
|
466
|
+
background: var(--accent-red);
|
|
467
|
+
color: #fff;
|
|
468
|
+
border-color: var(--accent-red);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/* Shop Section */
|
|
472
|
+
#shop {
|
|
473
|
+
background: var(--bg-secondary);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.shop-preview {
|
|
477
|
+
max-width: 800px;
|
|
478
|
+
text-align: center;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.coming-soon-box {
|
|
482
|
+
border: 2px dashed var(--border);
|
|
483
|
+
padding: 80px 60px;
|
|
484
|
+
margin-top: 40px;
|
|
485
|
+
position: relative;
|
|
486
|
+
opacity: 0;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.coming-soon-box::before {
|
|
490
|
+
content: 'COMING SOON';
|
|
491
|
+
position: absolute;
|
|
492
|
+
top: -12px;
|
|
493
|
+
left: 50%;
|
|
494
|
+
transform: translateX(-50%);
|
|
495
|
+
background: var(--bg-secondary);
|
|
496
|
+
padding: 0 20px;
|
|
497
|
+
font-size: 0.75rem;
|
|
498
|
+
letter-spacing: 3px;
|
|
499
|
+
color: var(--text-muted);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.merch-grid {
|
|
503
|
+
display: grid;
|
|
504
|
+
grid-template-columns: repeat(3, 1fr);
|
|
505
|
+
gap: 30px;
|
|
506
|
+
margin-top: 40px;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.merch-placeholder {
|
|
510
|
+
aspect-ratio: 1;
|
|
511
|
+
border: 1px dashed var(--border);
|
|
512
|
+
display: flex;
|
|
513
|
+
flex-direction: column;
|
|
514
|
+
align-items: center;
|
|
515
|
+
justify-content: center;
|
|
516
|
+
color: var(--text-dim);
|
|
517
|
+
font-size: 0.8rem;
|
|
518
|
+
transition: all 0.3s;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.merch-placeholder:hover {
|
|
522
|
+
border-color: var(--text-muted);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
.merch-placeholder .icon {
|
|
526
|
+
font-size: 2rem;
|
|
527
|
+
margin-bottom: 15px;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.shop-notify {
|
|
531
|
+
margin-top: 50px;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.email-form {
|
|
535
|
+
display: flex;
|
|
536
|
+
gap: 10px;
|
|
537
|
+
justify-content: center;
|
|
538
|
+
max-width: 400px;
|
|
539
|
+
margin: 20px auto 0;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
.email-input {
|
|
543
|
+
flex: 1;
|
|
544
|
+
padding: 12px 20px;
|
|
545
|
+
border: 1px dashed var(--border);
|
|
546
|
+
background: transparent;
|
|
547
|
+
color: var(--text);
|
|
548
|
+
font-family: inherit;
|
|
549
|
+
font-size: 0.9rem;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
.email-input::placeholder {
|
|
553
|
+
color: var(--text-dim);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.email-input:focus {
|
|
557
|
+
outline: none;
|
|
558
|
+
border-color: var(--text);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* Blog Section */
|
|
562
|
+
.blog-grid {
|
|
563
|
+
display: grid;
|
|
564
|
+
grid-template-columns: repeat(3, 1fr);
|
|
565
|
+
gap: 30px;
|
|
566
|
+
max-width: 1100px;
|
|
567
|
+
width: 100%;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.blog-card {
|
|
571
|
+
border: 1px dashed var(--border);
|
|
572
|
+
transition: all 0.3s;
|
|
573
|
+
opacity: 0;
|
|
574
|
+
transform: translateY(20px);
|
|
575
|
+
overflow: hidden;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.blog-card:hover {
|
|
579
|
+
border-color: var(--accent-red);
|
|
580
|
+
box-shadow: 0 0 40px var(--accent-red-glow);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.blog-card-image {
|
|
584
|
+
width: 100%;
|
|
585
|
+
aspect-ratio: 16/9;
|
|
586
|
+
background: var(--bg-secondary);
|
|
587
|
+
border-bottom: 1px dashed var(--border);
|
|
588
|
+
display: flex;
|
|
589
|
+
align-items: center;
|
|
590
|
+
justify-content: center;
|
|
591
|
+
font-size: 3rem;
|
|
592
|
+
color: var(--text-dim);
|
|
593
|
+
text-decoration: none;
|
|
594
|
+
transition: all 0.3s;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.blog-card-image:hover {
|
|
598
|
+
background: var(--bg);
|
|
599
|
+
color: var(--text);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.blog-card-content {
|
|
603
|
+
padding: 25px;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.blog-card-meta {
|
|
607
|
+
display: flex;
|
|
608
|
+
gap: 15px;
|
|
609
|
+
margin-bottom: 15px;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.blog-tag {
|
|
613
|
+
font-size: 0.65rem;
|
|
614
|
+
letter-spacing: 2px;
|
|
615
|
+
color: var(--accent-red);
|
|
616
|
+
border: 1px dashed var(--accent-red);
|
|
617
|
+
padding: 4px 10px;
|
|
618
|
+
text-transform: uppercase;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.blog-date {
|
|
622
|
+
font-size: 0.75rem;
|
|
623
|
+
color: var(--text-dim);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
.blog-card-title {
|
|
627
|
+
font-size: 1.1rem;
|
|
628
|
+
font-family: 'Fredoka', sans-serif;
|
|
629
|
+
font-weight: 600;
|
|
630
|
+
margin-bottom: 12px;
|
|
631
|
+
line-height: 1.4;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
.blog-card-excerpt {
|
|
635
|
+
font-size: 0.85rem;
|
|
636
|
+
color: var(--text-muted);
|
|
637
|
+
line-height: 1.7;
|
|
638
|
+
margin-bottom: 20px;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
.blog-card-link {
|
|
642
|
+
font-size: 0.8rem;
|
|
643
|
+
color: var(--accent-red);
|
|
644
|
+
text-decoration: none;
|
|
645
|
+
display: inline-flex;
|
|
646
|
+
align-items: center;
|
|
647
|
+
gap: 8px;
|
|
648
|
+
transition: all 0.3s;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.blog-card-link:hover {
|
|
652
|
+
gap: 15px;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.blog-card-link::after {
|
|
656
|
+
content: '→';
|
|
657
|
+
color: var(--accent-red);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
.blog-featured {
|
|
661
|
+
grid-column: span 2;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.blog-featured .blog-card-image {
|
|
665
|
+
aspect-ratio: 21/9;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.blog-featured .blog-card-title {
|
|
669
|
+
font-size: 1.4rem;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
.blog-cta {
|
|
673
|
+
margin-top: 50px;
|
|
674
|
+
text-align: center;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
@media (max-width: 900px) {
|
|
678
|
+
.blog-grid {
|
|
679
|
+
grid-template-columns: 1fr;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
.blog-featured {
|
|
683
|
+
grid-column: span 1;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
.blog-featured .blog-card-image {
|
|
687
|
+
aspect-ratio: 16/9;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/* Footer */
|
|
692
|
+
footer {
|
|
693
|
+
border-top: 1px dashed var(--border);
|
|
694
|
+
padding: 60px 40px;
|
|
695
|
+
text-align: center;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.footer-logo {
|
|
699
|
+
font-size: 1.5rem;
|
|
700
|
+
font-family: 'Fredoka', 'Bungee', sans-serif;
|
|
701
|
+
font-weight: 700;
|
|
702
|
+
letter-spacing: 3px;
|
|
703
|
+
margin-bottom: 30px;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
.footer-links {
|
|
707
|
+
display: flex;
|
|
708
|
+
gap: 30px;
|
|
709
|
+
justify-content: center;
|
|
710
|
+
margin-bottom: 30px;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.footer-links a {
|
|
714
|
+
color: var(--text-muted);
|
|
715
|
+
text-decoration: none;
|
|
716
|
+
font-size: 0.85rem;
|
|
717
|
+
transition: color 0.3s;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
.footer-links a:hover {
|
|
721
|
+
color: var(--accent-red);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
.footer-copy {
|
|
725
|
+
color: var(--text-dim);
|
|
726
|
+
font-size: 0.8rem;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/* Animated Elements */
|
|
730
|
+
.float-element {
|
|
731
|
+
position: absolute;
|
|
732
|
+
border: 1px dashed var(--border);
|
|
733
|
+
opacity: 0.3;
|
|
734
|
+
pointer-events: none;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/* ASCII Art Decorations */
|
|
738
|
+
.ascii-corner {
|
|
739
|
+
position: absolute;
|
|
740
|
+
color: var(--text-dim);
|
|
741
|
+
font-size: 0.7rem;
|
|
742
|
+
pointer-events: none;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
.ascii-corner.top-left {
|
|
746
|
+
top: 20px;
|
|
747
|
+
left: 20px;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
.ascii-corner.bottom-right {
|
|
751
|
+
bottom: 20px;
|
|
752
|
+
right: 20px;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
/* Responsive */
|
|
756
|
+
@media (max-width: 900px) {
|
|
757
|
+
h1 {
|
|
758
|
+
font-size: 4rem;
|
|
759
|
+
letter-spacing: 2px;
|
|
760
|
+
gap: 0 12px;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.philosophy-grid {
|
|
764
|
+
grid-template-columns: 1fr;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
.tools-grid {
|
|
768
|
+
grid-template-columns: 1fr;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
.merch-grid {
|
|
772
|
+
grid-template-columns: repeat(2, 1fr);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
nav {
|
|
776
|
+
padding: 15px 20px;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.nav-links {
|
|
780
|
+
gap: 15px;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
.nav-links a {
|
|
784
|
+
font-size: 0.75rem;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
@media (max-width: 600px) {
|
|
789
|
+
.nav-links {
|
|
790
|
+
display: none;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
.hero-cta {
|
|
794
|
+
flex-direction: column;
|
|
795
|
+
align-items: center;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
.merch-grid {
|
|
799
|
+
grid-template-columns: 1fr;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
.email-form {
|
|
803
|
+
flex-direction: column;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/* Cursor effect */
|
|
808
|
+
.cursor-glow {
|
|
809
|
+
position: fixed;
|
|
810
|
+
width: 200px;
|
|
811
|
+
height: 200px;
|
|
812
|
+
border-radius: 50%;
|
|
813
|
+
background: radial-gradient(circle, var(--glow) 0%, transparent 70%);
|
|
814
|
+
pointer-events: none;
|
|
815
|
+
z-index: 9999;
|
|
816
|
+
opacity: 0.5;
|
|
817
|
+
transform: translate(-50%, -50%);
|
|
818
|
+
transition: opacity 0.3s;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/* Scroll indicator */
|
|
822
|
+
.scroll-indicator {
|
|
823
|
+
position: absolute;
|
|
824
|
+
bottom: 40px;
|
|
825
|
+
left: 50%;
|
|
826
|
+
transform: translateX(-50%);
|
|
827
|
+
color: var(--text-muted);
|
|
828
|
+
font-size: 0.75rem;
|
|
829
|
+
letter-spacing: 2px;
|
|
830
|
+
animation: bounce 2s infinite;
|
|
831
|
+
opacity: 0;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
@keyframes bounce {
|
|
835
|
+
0%, 100% { transform: translateX(-50%) translateY(0); }
|
|
836
|
+
50% { transform: translateX(-50%) translateY(10px); }
|
|
837
|
+
}
|
|
838
|
+
</style>
|
|
839
|
+
</head>
|
|
840
|
+
<body>
|
|
841
|
+
<!-- Animated Background Pattern -->
|
|
842
|
+
<div class="bg-pattern">
|
|
843
|
+
<svg id="gridPattern" xmlns="http://www.w3.org/2000/svg">
|
|
844
|
+
<defs>
|
|
845
|
+
<pattern id="grid" width="50" height="50" patternUnits="userSpaceOnUse">
|
|
846
|
+
<path d="M 50 0 L 0 0 0 50" fill="none" class="grid-line"/>
|
|
847
|
+
</pattern>
|
|
848
|
+
</defs>
|
|
849
|
+
<rect width="100%" height="100%" fill="url(#grid)"/>
|
|
850
|
+
</svg>
|
|
851
|
+
</div>
|
|
852
|
+
|
|
853
|
+
<!-- Cursor Glow Effect -->
|
|
854
|
+
<div class="cursor-glow" id="cursorGlow"></div>
|
|
855
|
+
|
|
856
|
+
<!-- Navigation -->
|
|
857
|
+
<nav>
|
|
858
|
+
<div class="logo">
|
|
859
|
+
<div class="logo-icon">HT</div>
|
|
860
|
+
HUSTLE TOGETHER
|
|
861
|
+
</div>
|
|
862
|
+
<div class="nav-links">
|
|
863
|
+
<a href="#hero">HOME</a>
|
|
864
|
+
<a href="#philosophy">PHILOSOPHY</a>
|
|
865
|
+
<a href="#tools">TOOLS</a>
|
|
866
|
+
<a href="#blog">BLOG</a>
|
|
867
|
+
<a href="#shop">SHOP</a>
|
|
868
|
+
<button class="theme-toggle" id="themeToggle">[ LIGHT ]</button>
|
|
869
|
+
</div>
|
|
870
|
+
</nav>
|
|
871
|
+
|
|
872
|
+
<main>
|
|
873
|
+
<!-- Hero Section -->
|
|
874
|
+
<section id="hero">
|
|
875
|
+
<div class="ascii-corner top-left">+--[HUSTLE]--+</div>
|
|
876
|
+
<div class="ascii-corner bottom-right">+--[2025]--+</div>
|
|
877
|
+
|
|
878
|
+
<div class="hero-content">
|
|
879
|
+
<div class="hero-badge">EXPERIMENT . BUILD . SHARE</div>
|
|
880
|
+
<h1 id="heroTitle">
|
|
881
|
+
<span class="word" data-text="HUSTLE"></span>
|
|
882
|
+
<span class="word highlight" data-text="TOGETHER"></span>
|
|
883
|
+
</h1>
|
|
884
|
+
<p class="hero-tagline">Tools for builders who like to try things</p>
|
|
885
|
+
<p class="hero-desc">
|
|
886
|
+
We're a small team obsessed with building tools that actually work.
|
|
887
|
+
We experiment, we iterate, and we share what we learn.
|
|
888
|
+
No corporate BS - just useful stuff for developers and creators.
|
|
889
|
+
</p>
|
|
890
|
+
<div class="hero-cta">
|
|
891
|
+
<a href="#tools" class="btn btn-primary">VIEW TOOLS</a>
|
|
892
|
+
<a href="#philosophy" class="btn">OUR PHILOSOPHY</a>
|
|
893
|
+
</div>
|
|
894
|
+
</div>
|
|
895
|
+
|
|
896
|
+
<div class="scroll-indicator">[ SCROLL ]</div>
|
|
897
|
+
</section>
|
|
898
|
+
|
|
899
|
+
<!-- Philosophy Section -->
|
|
900
|
+
<section id="philosophy">
|
|
901
|
+
<div class="section-header">
|
|
902
|
+
<div class="section-label">HOW WE WORK</div>
|
|
903
|
+
<h2>HUSTLE <span class="highlight">PHILOSOPHY</span></h2>
|
|
904
|
+
</div>
|
|
905
|
+
|
|
906
|
+
<div class="philosophy-grid">
|
|
907
|
+
<div class="philosophy-card">
|
|
908
|
+
<div class="philosophy-icon">[?]</div>
|
|
909
|
+
<div class="philosophy-title">EXPERIMENT</div>
|
|
910
|
+
<div class="philosophy-desc">
|
|
911
|
+
Try things before they're ready. Break stuff. Learn fast.
|
|
912
|
+
The best tools come from real problems, not perfect plans.
|
|
913
|
+
</div>
|
|
914
|
+
</div>
|
|
915
|
+
<div class="philosophy-card">
|
|
916
|
+
<div class="philosophy-icon">[*]</div>
|
|
917
|
+
<div class="philosophy-title">BUILD</div>
|
|
918
|
+
<div class="philosophy-desc">
|
|
919
|
+
Ship early, ship often. A working prototype beats a
|
|
920
|
+
perfect spec every time. Code is the best documentation.
|
|
921
|
+
</div>
|
|
922
|
+
</div>
|
|
923
|
+
<div class="philosophy-card">
|
|
924
|
+
<div class="philosophy-icon">[>]</div>
|
|
925
|
+
<div class="philosophy-title">SHARE</div>
|
|
926
|
+
<div class="philosophy-desc">
|
|
927
|
+
Open source everything. If it helped us, it might help you.
|
|
928
|
+
The community makes tools better than we ever could alone.
|
|
929
|
+
</div>
|
|
930
|
+
</div>
|
|
931
|
+
</div>
|
|
932
|
+
</section>
|
|
933
|
+
|
|
934
|
+
<!-- Tools Section -->
|
|
935
|
+
<section id="tools">
|
|
936
|
+
<div class="section-header">
|
|
937
|
+
<div class="section-label">WHAT WE MAKE</div>
|
|
938
|
+
<h2>HUSTLE <span class="highlight">TOOLS</span></h2>
|
|
939
|
+
</div>
|
|
940
|
+
|
|
941
|
+
<div class="tools-grid">
|
|
942
|
+
<div class="tool-card">
|
|
943
|
+
<div class="tool-badge">CLAUDE CODE EXTENSION</div>
|
|
944
|
+
<div class="tool-name">
|
|
945
|
+
<span class="icon">[A]</span>
|
|
946
|
+
API DEV TOOLS
|
|
947
|
+
</div>
|
|
948
|
+
<p class="tool-desc">
|
|
949
|
+
Interview-driven API development workflow for Claude Code.
|
|
950
|
+
Enforces research, testing, and documentation through Python hooks.
|
|
951
|
+
No more hallucinated APIs or skipped tests.
|
|
952
|
+
</p>
|
|
953
|
+
<ul class="tool-features">
|
|
954
|
+
<li>Structured interviews with multiple-choice options</li>
|
|
955
|
+
<li>Research enforcement via Context7 + WebSearch</li>
|
|
956
|
+
<li>TDD workflow (/red, /green, /refactor)</li>
|
|
957
|
+
<li>Decision tracking injected during implementation</li>
|
|
958
|
+
<li>10-phase workflow with state tracking</li>
|
|
959
|
+
</ul>
|
|
960
|
+
<div class="tool-links">
|
|
961
|
+
<a href="https://www.npmjs.com/package/@hustle-together/api-dev-tools" class="tool-link" target="_blank">NPM</a>
|
|
962
|
+
<a href="https://github.com/hustle-together/api-dev-tools" class="tool-link" target="_blank">GITHUB</a>
|
|
963
|
+
<a href="../workflow-demo.html" class="tool-link">DEMO</a>
|
|
964
|
+
</div>
|
|
965
|
+
</div>
|
|
966
|
+
|
|
967
|
+
<div class="tool-card">
|
|
968
|
+
<div class="tool-badge">WORDPRESS PLUGIN</div>
|
|
969
|
+
<div class="tool-name">
|
|
970
|
+
<span class="icon">[E]</span>
|
|
971
|
+
HUSTLE ELEMENTOR
|
|
972
|
+
</div>
|
|
973
|
+
<p class="tool-desc">
|
|
974
|
+
AI-powered widget generation for WordPress. Uses Gemini Pro 2.5
|
|
975
|
+
and Morph to create fully editable Elementor widgets from
|
|
976
|
+
natural language descriptions.
|
|
977
|
+
</p>
|
|
978
|
+
<ul class="tool-features">
|
|
979
|
+
<li>Gemini Pro 2.5 for intelligent generation</li>
|
|
980
|
+
<li>Morph integration for quick edits</li>
|
|
981
|
+
<li>Fully editable in WordPress admin</li>
|
|
982
|
+
<li>One-click widget creation</li>
|
|
983
|
+
<li>Style-aware generation</li>
|
|
984
|
+
</ul>
|
|
985
|
+
<div class="tool-links">
|
|
986
|
+
<a href="#" class="tool-link">COMING SOON</a>
|
|
987
|
+
</div>
|
|
988
|
+
</div>
|
|
989
|
+
</div>
|
|
990
|
+
</section>
|
|
991
|
+
|
|
992
|
+
<!-- Blog Section -->
|
|
993
|
+
<section id="blog">
|
|
994
|
+
<div class="section-header">
|
|
995
|
+
<div class="section-label">THOUGHTS & EXPERIMENTS</div>
|
|
996
|
+
<h2>HUSTLE <span class="highlight">BLOG</span></h2>
|
|
997
|
+
</div>
|
|
998
|
+
|
|
999
|
+
<div class="blog-grid">
|
|
1000
|
+
<!-- Featured Post -->
|
|
1001
|
+
<article class="blog-card blog-featured">
|
|
1002
|
+
<a href="blog/interview-driven-api-development.html" class="blog-card-image">[*]</a>
|
|
1003
|
+
<div class="blog-card-content">
|
|
1004
|
+
<div class="blog-card-meta">
|
|
1005
|
+
<span class="blog-tag">DEV TOOLS</span>
|
|
1006
|
+
<span class="blog-date">Dec 7, 2025</span>
|
|
1007
|
+
</div>
|
|
1008
|
+
<h3 class="blog-card-title">Why We Built Interview-Driven API Development</h3>
|
|
1009
|
+
<p class="blog-card-excerpt">
|
|
1010
|
+
Claude Code is incredible, but it has a problem: it skips steps. It hallucinates APIs.
|
|
1011
|
+
It marks things "done" without checking. We fixed that with Python hooks that enforce
|
|
1012
|
+
a 10-phase workflow. Here's why research-first beats code-first every time.
|
|
1013
|
+
</p>
|
|
1014
|
+
<a href="blog/interview-driven-api-development.html" class="blog-card-link">Read More</a>
|
|
1015
|
+
</div>
|
|
1016
|
+
</article>
|
|
1017
|
+
|
|
1018
|
+
<!-- Regular Post -->
|
|
1019
|
+
<article class="blog-card">
|
|
1020
|
+
<a href="blog/gemini-vs-claude-widgets.html" class="blog-card-image">[?]</a>
|
|
1021
|
+
<div class="blog-card-content">
|
|
1022
|
+
<div class="blog-card-meta">
|
|
1023
|
+
<span class="blog-tag">AI</span>
|
|
1024
|
+
<span class="blog-date">Dec 5, 2025</span>
|
|
1025
|
+
</div>
|
|
1026
|
+
<h3 class="blog-card-title">Gemini Pro 2.5 vs Claude for Widget Generation</h3>
|
|
1027
|
+
<p class="blog-card-excerpt">
|
|
1028
|
+
We tested both models for generating Elementor widgets. The results surprised us.
|
|
1029
|
+
</p>
|
|
1030
|
+
<a href="blog/gemini-vs-claude-widgets.html" class="blog-card-link">Read More</a>
|
|
1031
|
+
</div>
|
|
1032
|
+
</article>
|
|
1033
|
+
|
|
1034
|
+
<!-- Regular Post -->
|
|
1035
|
+
<article class="blog-card">
|
|
1036
|
+
<a href="blog/tdd-for-ai.html" class="blog-card-image">[+]</a>
|
|
1037
|
+
<div class="blog-card-content">
|
|
1038
|
+
<div class="blog-card-meta">
|
|
1039
|
+
<span class="blog-tag">WORKFLOW</span>
|
|
1040
|
+
<span class="blog-date">Dec 1, 2025</span>
|
|
1041
|
+
</div>
|
|
1042
|
+
<h3 class="blog-card-title">TDD is Dead, Long Live TDD</h3>
|
|
1043
|
+
<p class="blog-card-excerpt">
|
|
1044
|
+
The /red /green /refactor cycle isn't just for humans anymore. Here's how to enforce it.
|
|
1045
|
+
</p>
|
|
1046
|
+
<a href="blog/tdd-for-ai.html" class="blog-card-link">Read More</a>
|
|
1047
|
+
</div>
|
|
1048
|
+
</article>
|
|
1049
|
+
|
|
1050
|
+
<!-- Regular Post -->
|
|
1051
|
+
<article class="blog-card">
|
|
1052
|
+
<a href="blog/interview-driven-api-development.html" class="blog-card-image">[/]</a>
|
|
1053
|
+
<div class="blog-card-content">
|
|
1054
|
+
<div class="blog-card-meta">
|
|
1055
|
+
<span class="blog-tag">OPEN SOURCE</span>
|
|
1056
|
+
<span class="blog-date">Nov 28, 2025</span>
|
|
1057
|
+
</div>
|
|
1058
|
+
<h3 class="blog-card-title">Context7: The Best MCP Server You're Not Using</h3>
|
|
1059
|
+
<p class="blog-card-excerpt">
|
|
1060
|
+
Live documentation beats training data. Every time. Here's how to set it up.
|
|
1061
|
+
</p>
|
|
1062
|
+
<a href="blog/interview-driven-api-development.html" class="blog-card-link">Read More</a>
|
|
1063
|
+
</div>
|
|
1064
|
+
</article>
|
|
1065
|
+
</div>
|
|
1066
|
+
|
|
1067
|
+
<div class="blog-cta">
|
|
1068
|
+
<a href="blog/interview-driven-api-development.html" class="btn">VIEW ALL POSTS</a>
|
|
1069
|
+
</div>
|
|
1070
|
+
</section>
|
|
1071
|
+
|
|
1072
|
+
<!-- Shop Section -->
|
|
1073
|
+
<section id="shop">
|
|
1074
|
+
<div class="section-header">
|
|
1075
|
+
<div class="section-label">WEAR THE HUSTLE</div>
|
|
1076
|
+
<h2>HUSTLE <span class="highlight">MERCH</span></h2>
|
|
1077
|
+
</div>
|
|
1078
|
+
|
|
1079
|
+
<div class="shop-preview">
|
|
1080
|
+
<div class="coming-soon-box">
|
|
1081
|
+
<div class="merch-grid">
|
|
1082
|
+
<div class="merch-placeholder">
|
|
1083
|
+
<span class="icon">[T]</span>
|
|
1084
|
+
TEE
|
|
1085
|
+
</div>
|
|
1086
|
+
<div class="merch-placeholder">
|
|
1087
|
+
<span class="icon">[H]</span>
|
|
1088
|
+
HOODIE
|
|
1089
|
+
</div>
|
|
1090
|
+
<div class="merch-placeholder">
|
|
1091
|
+
<span class="icon">[C]</span>
|
|
1092
|
+
CAP
|
|
1093
|
+
</div>
|
|
1094
|
+
</div>
|
|
1095
|
+
|
|
1096
|
+
<div class="shop-notify">
|
|
1097
|
+
<p style="color: var(--text-muted); font-size: 0.9rem;">
|
|
1098
|
+
Get notified when the shop launches
|
|
1099
|
+
</p>
|
|
1100
|
+
<form class="email-form" onsubmit="return false;">
|
|
1101
|
+
<input type="email" class="email-input" placeholder="your@email.com">
|
|
1102
|
+
<button type="submit" class="btn">NOTIFY ME</button>
|
|
1103
|
+
</form>
|
|
1104
|
+
</div>
|
|
1105
|
+
</div>
|
|
1106
|
+
</div>
|
|
1107
|
+
</section>
|
|
1108
|
+
</main>
|
|
1109
|
+
|
|
1110
|
+
<!-- Footer -->
|
|
1111
|
+
<footer>
|
|
1112
|
+
<div class="footer-logo">HUSTLE TOGETHER</div>
|
|
1113
|
+
<div class="footer-links">
|
|
1114
|
+
<a href="https://github.com/hustle-together" target="_blank">GITHUB</a>
|
|
1115
|
+
<a href="https://www.npmjs.com/org/hustle-together" target="_blank">NPM</a>
|
|
1116
|
+
<a href="mailto:hello@hustletogether.dev">CONTACT</a>
|
|
1117
|
+
</div>
|
|
1118
|
+
<div class="footer-copy">
|
|
1119
|
+
2025 Hustle Together. Experiment. Build. Share.
|
|
1120
|
+
</div>
|
|
1121
|
+
</footer>
|
|
1122
|
+
|
|
1123
|
+
<script>
|
|
1124
|
+
// Register GSAP plugins
|
|
1125
|
+
gsap.registerPlugin(ScrollTrigger);
|
|
1126
|
+
|
|
1127
|
+
// Theme Toggle
|
|
1128
|
+
const themeToggle = document.getElementById('themeToggle');
|
|
1129
|
+
let isDark = true;
|
|
1130
|
+
|
|
1131
|
+
themeToggle.addEventListener('click', () => {
|
|
1132
|
+
isDark = !isDark;
|
|
1133
|
+
document.documentElement.setAttribute('data-theme', isDark ? '' : 'light');
|
|
1134
|
+
themeToggle.textContent = isDark ? '[ LIGHT ]' : '[ DARK ]';
|
|
1135
|
+
});
|
|
1136
|
+
|
|
1137
|
+
// Cursor Glow Effect
|
|
1138
|
+
const cursorGlow = document.getElementById('cursorGlow');
|
|
1139
|
+
document.addEventListener('mousemove', (e) => {
|
|
1140
|
+
cursorGlow.style.left = e.clientX + 'px';
|
|
1141
|
+
cursorGlow.style.top = e.clientY + 'px';
|
|
1142
|
+
});
|
|
1143
|
+
|
|
1144
|
+
// Split title into letters
|
|
1145
|
+
document.querySelectorAll('#heroTitle .word').forEach(word => {
|
|
1146
|
+
const text = word.getAttribute('data-text');
|
|
1147
|
+
word.innerHTML = text.split('').map(letter =>
|
|
1148
|
+
`<span class="letter">${letter}</span>`
|
|
1149
|
+
).join('');
|
|
1150
|
+
});
|
|
1151
|
+
|
|
1152
|
+
// Hero Animations with letter-by-letter reveal (slower, more dramatic)
|
|
1153
|
+
const heroTL = gsap.timeline({ delay: 0.5 });
|
|
1154
|
+
heroTL
|
|
1155
|
+
.to('.hero-badge', { opacity: 1, duration: 0.6 })
|
|
1156
|
+
.to('#heroTitle .letter', {
|
|
1157
|
+
opacity: 1,
|
|
1158
|
+
y: 0,
|
|
1159
|
+
rotateX: 0,
|
|
1160
|
+
duration: 0.15,
|
|
1161
|
+
stagger: 0.08,
|
|
1162
|
+
ease: 'back.out(1.7)'
|
|
1163
|
+
}, '-=0.2')
|
|
1164
|
+
.to('.hero-tagline', { opacity: 1, duration: 0.6 }, '-=0.4')
|
|
1165
|
+
.to('.hero-desc', { opacity: 1, duration: 0.6 }, '-=0.3')
|
|
1166
|
+
.to('.hero-cta', { opacity: 1, duration: 0.5 }, '-=0.2')
|
|
1167
|
+
.to('.scroll-indicator', { opacity: 1, duration: 0.4 });
|
|
1168
|
+
|
|
1169
|
+
// Philosophy Cards
|
|
1170
|
+
gsap.utils.toArray('.philosophy-card').forEach((card, i) => {
|
|
1171
|
+
gsap.to(card, {
|
|
1172
|
+
opacity: 1,
|
|
1173
|
+
y: 0,
|
|
1174
|
+
duration: 0.6,
|
|
1175
|
+
delay: i * 0.15,
|
|
1176
|
+
scrollTrigger: {
|
|
1177
|
+
trigger: card,
|
|
1178
|
+
start: 'top 80%',
|
|
1179
|
+
toggleActions: 'play none none reverse'
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
// Tool Cards
|
|
1185
|
+
gsap.utils.toArray('.tool-card').forEach((card, i) => {
|
|
1186
|
+
gsap.to(card, {
|
|
1187
|
+
opacity: 1,
|
|
1188
|
+
y: 0,
|
|
1189
|
+
duration: 0.6,
|
|
1190
|
+
delay: i * 0.2,
|
|
1191
|
+
scrollTrigger: {
|
|
1192
|
+
trigger: card,
|
|
1193
|
+
start: 'top 80%',
|
|
1194
|
+
toggleActions: 'play none none reverse'
|
|
1195
|
+
}
|
|
1196
|
+
});
|
|
1197
|
+
});
|
|
1198
|
+
|
|
1199
|
+
// Blog Cards
|
|
1200
|
+
gsap.utils.toArray('.blog-card').forEach((card, i) => {
|
|
1201
|
+
gsap.to(card, {
|
|
1202
|
+
opacity: 1,
|
|
1203
|
+
y: 0,
|
|
1204
|
+
duration: 0.6,
|
|
1205
|
+
delay: i * 0.15,
|
|
1206
|
+
scrollTrigger: {
|
|
1207
|
+
trigger: card,
|
|
1208
|
+
start: 'top 85%',
|
|
1209
|
+
toggleActions: 'play none none reverse'
|
|
1210
|
+
}
|
|
1211
|
+
});
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
// Coming Soon Box
|
|
1215
|
+
gsap.to('.coming-soon-box', {
|
|
1216
|
+
opacity: 1,
|
|
1217
|
+
duration: 0.8,
|
|
1218
|
+
scrollTrigger: {
|
|
1219
|
+
trigger: '.coming-soon-box',
|
|
1220
|
+
start: 'top 80%',
|
|
1221
|
+
toggleActions: 'play none none reverse'
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
|
|
1225
|
+
// Animated Background Pattern
|
|
1226
|
+
const pattern = document.querySelector('.bg-pattern');
|
|
1227
|
+
let offsetX = 0;
|
|
1228
|
+
let offsetY = 0;
|
|
1229
|
+
|
|
1230
|
+
function animatePattern() {
|
|
1231
|
+
offsetX += 0.1;
|
|
1232
|
+
offsetY += 0.05;
|
|
1233
|
+
pattern.style.transform = `translate(${Math.sin(offsetX) * 5}px, ${Math.cos(offsetY) * 5}px)`;
|
|
1234
|
+
requestAnimationFrame(animatePattern);
|
|
1235
|
+
}
|
|
1236
|
+
animatePattern();
|
|
1237
|
+
|
|
1238
|
+
// Smooth scroll for nav links
|
|
1239
|
+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
1240
|
+
anchor.addEventListener('click', function (e) {
|
|
1241
|
+
e.preventDefault();
|
|
1242
|
+
const target = document.querySelector(this.getAttribute('href'));
|
|
1243
|
+
if (target) {
|
|
1244
|
+
target.scrollIntoView({ behavior: 'smooth' });
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
});
|
|
1248
|
+
|
|
1249
|
+
// Add floating decorative elements
|
|
1250
|
+
function createFloatingElements() {
|
|
1251
|
+
const container = document.body;
|
|
1252
|
+
const symbols = ['+', '*', '/', '-', '=', '>', '<', '|'];
|
|
1253
|
+
|
|
1254
|
+
for (let i = 0; i < 15; i++) {
|
|
1255
|
+
const el = document.createElement('div');
|
|
1256
|
+
el.className = 'float-element';
|
|
1257
|
+
el.textContent = symbols[Math.floor(Math.random() * symbols.length)];
|
|
1258
|
+
el.style.left = Math.random() * 100 + 'vw';
|
|
1259
|
+
el.style.top = Math.random() * 100 + 'vh';
|
|
1260
|
+
el.style.fontSize = (Math.random() * 1.5 + 0.5) + 'rem';
|
|
1261
|
+
el.style.padding = '10px';
|
|
1262
|
+
container.appendChild(el);
|
|
1263
|
+
|
|
1264
|
+
// Animate floating
|
|
1265
|
+
gsap.to(el, {
|
|
1266
|
+
y: Math.random() * 100 - 50,
|
|
1267
|
+
x: Math.random() * 100 - 50,
|
|
1268
|
+
rotation: Math.random() * 360,
|
|
1269
|
+
duration: Math.random() * 10 + 10,
|
|
1270
|
+
repeat: -1,
|
|
1271
|
+
yoyo: true,
|
|
1272
|
+
ease: 'sine.inOut'
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
createFloatingElements();
|
|
1277
|
+
</script>
|
|
1278
|
+
</body>
|
|
1279
|
+
</html>
|