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