@hustle-together/api-dev-tools 1.9.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 +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 +740 -45
- package/package.json +1 -1
|
@@ -0,0 +1,957 @@
|
|
|
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>Gemini Pro 2.5 vs Claude for Widget Generation - Hustle Together Blog</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=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
|
+
<style>
|
|
12
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
13
|
+
|
|
14
|
+
:root {
|
|
15
|
+
--bg: #0a0a0a;
|
|
16
|
+
--bg-secondary: #111;
|
|
17
|
+
--bg-tertiary: #1a1a1a;
|
|
18
|
+
--text: #e0e0e0;
|
|
19
|
+
--text-muted: #888;
|
|
20
|
+
--text-dim: #444;
|
|
21
|
+
--accent: #fff;
|
|
22
|
+
--accent-red: #BA0C2F;
|
|
23
|
+
--accent-red-glow: rgba(186, 12, 47, 0.4);
|
|
24
|
+
--border: #333;
|
|
25
|
+
--glow: rgba(255, 255, 255, 0.3);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[data-theme="light"] {
|
|
29
|
+
--bg: #f5f5f5;
|
|
30
|
+
--bg-secondary: #fff;
|
|
31
|
+
--bg-tertiary: #e5e5e5;
|
|
32
|
+
--text: #1a1a1a;
|
|
33
|
+
--text-muted: #666;
|
|
34
|
+
--text-dim: #aaa;
|
|
35
|
+
--accent: #000;
|
|
36
|
+
--accent-red: #BA0C2F;
|
|
37
|
+
--accent-red-glow: rgba(186, 12, 47, 0.3);
|
|
38
|
+
--border: #ccc;
|
|
39
|
+
--glow: rgba(0, 0, 0, 0.15);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
body {
|
|
43
|
+
background: var(--bg);
|
|
44
|
+
color: var(--text);
|
|
45
|
+
font-family: 'JetBrains Mono', 'Courier New', monospace;
|
|
46
|
+
line-height: 1.8;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
nav {
|
|
50
|
+
position: fixed;
|
|
51
|
+
top: 0;
|
|
52
|
+
left: 0;
|
|
53
|
+
right: 0;
|
|
54
|
+
z-index: 1000;
|
|
55
|
+
padding: 20px 40px;
|
|
56
|
+
display: flex;
|
|
57
|
+
justify-content: space-between;
|
|
58
|
+
align-items: center;
|
|
59
|
+
background: var(--bg);
|
|
60
|
+
border-bottom: 1px dashed var(--border);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.logo {
|
|
64
|
+
font-size: 1.1rem;
|
|
65
|
+
font-family: 'Fredoka', sans-serif;
|
|
66
|
+
font-weight: 700;
|
|
67
|
+
letter-spacing: 2px;
|
|
68
|
+
text-decoration: none;
|
|
69
|
+
color: var(--text);
|
|
70
|
+
display: flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
gap: 10px;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.logo-icon {
|
|
76
|
+
width: 28px;
|
|
77
|
+
height: 28px;
|
|
78
|
+
border: 2px solid var(--text);
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
justify-content: center;
|
|
82
|
+
font-size: 0.7rem;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.nav-links {
|
|
86
|
+
display: flex;
|
|
87
|
+
gap: 25px;
|
|
88
|
+
align-items: center;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.nav-links a {
|
|
92
|
+
color: var(--text-muted);
|
|
93
|
+
text-decoration: none;
|
|
94
|
+
font-size: 0.8rem;
|
|
95
|
+
letter-spacing: 1px;
|
|
96
|
+
transition: color 0.3s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.nav-links a:hover { color: var(--accent-red); }
|
|
100
|
+
|
|
101
|
+
.theme-toggle {
|
|
102
|
+
background: transparent;
|
|
103
|
+
border: 1px dashed var(--border);
|
|
104
|
+
color: var(--text);
|
|
105
|
+
padding: 6px 12px;
|
|
106
|
+
cursor: pointer;
|
|
107
|
+
font-family: inherit;
|
|
108
|
+
font-size: 0.75rem;
|
|
109
|
+
transition: all 0.3s;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.theme-toggle:hover {
|
|
113
|
+
background: var(--text);
|
|
114
|
+
color: var(--bg);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
main {
|
|
118
|
+
max-width: 900px;
|
|
119
|
+
margin: 0 auto;
|
|
120
|
+
padding: 120px 40px 80px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.article-header {
|
|
124
|
+
margin-bottom: 50px;
|
|
125
|
+
opacity: 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.article-meta {
|
|
129
|
+
display: flex;
|
|
130
|
+
gap: 20px;
|
|
131
|
+
margin-bottom: 20px;
|
|
132
|
+
flex-wrap: wrap;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.article-tag {
|
|
136
|
+
font-size: 0.7rem;
|
|
137
|
+
letter-spacing: 2px;
|
|
138
|
+
color: var(--accent-red);
|
|
139
|
+
border: 1px dashed var(--accent-red);
|
|
140
|
+
padding: 5px 12px;
|
|
141
|
+
text-transform: uppercase;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.article-date {
|
|
145
|
+
font-size: 0.8rem;
|
|
146
|
+
color: var(--text-dim);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.article-title {
|
|
150
|
+
font-size: 2.8rem;
|
|
151
|
+
font-family: 'Fredoka', sans-serif;
|
|
152
|
+
font-weight: 700;
|
|
153
|
+
line-height: 1.2;
|
|
154
|
+
margin-bottom: 25px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.article-excerpt {
|
|
158
|
+
font-size: 1.1rem;
|
|
159
|
+
color: var(--text-muted);
|
|
160
|
+
line-height: 1.8;
|
|
161
|
+
border-left: 3px solid var(--border);
|
|
162
|
+
padding-left: 20px;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.audio-player {
|
|
166
|
+
background: var(--bg-secondary);
|
|
167
|
+
border: 1px dashed var(--border);
|
|
168
|
+
padding: 25px;
|
|
169
|
+
margin: 40px 0;
|
|
170
|
+
opacity: 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.audio-header {
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: center;
|
|
176
|
+
gap: 15px;
|
|
177
|
+
margin-bottom: 20px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.audio-icon {
|
|
181
|
+
width: 50px;
|
|
182
|
+
height: 50px;
|
|
183
|
+
border: 2px solid var(--text);
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
justify-content: center;
|
|
187
|
+
font-size: 1.2rem;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.audio-info h4 { font-size: 0.9rem; font-weight: 600; margin-bottom: 5px; }
|
|
191
|
+
.audio-info p { font-size: 0.75rem; color: var(--text-muted); }
|
|
192
|
+
|
|
193
|
+
.audio-controls {
|
|
194
|
+
display: flex;
|
|
195
|
+
align-items: center;
|
|
196
|
+
gap: 20px;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.play-btn {
|
|
200
|
+
width: 50px;
|
|
201
|
+
height: 50px;
|
|
202
|
+
border: 2px solid var(--text);
|
|
203
|
+
background: transparent;
|
|
204
|
+
color: var(--text);
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
font-size: 1.2rem;
|
|
207
|
+
display: flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
justify-content: center;
|
|
210
|
+
transition: all 0.3s;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.play-btn:hover { background: var(--accent-red); color: #fff; border-color: var(--accent-red); }
|
|
214
|
+
|
|
215
|
+
.progress-bar {
|
|
216
|
+
flex: 1;
|
|
217
|
+
height: 4px;
|
|
218
|
+
background: var(--border);
|
|
219
|
+
position: relative;
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.progress-fill {
|
|
224
|
+
height: 100%;
|
|
225
|
+
background: var(--accent-red);
|
|
226
|
+
width: 0%;
|
|
227
|
+
transition: width 0.1s;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.audio-time {
|
|
231
|
+
font-size: 0.8rem;
|
|
232
|
+
color: var(--text-muted);
|
|
233
|
+
min-width: 90px;
|
|
234
|
+
text-align: right;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.comparison-table {
|
|
238
|
+
margin: 40px 0;
|
|
239
|
+
border: 1px dashed var(--border);
|
|
240
|
+
opacity: 0;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.comparison-header {
|
|
244
|
+
display: grid;
|
|
245
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
246
|
+
background: var(--bg-secondary);
|
|
247
|
+
border-bottom: 1px dashed var(--border);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.comparison-header div {
|
|
251
|
+
padding: 20px;
|
|
252
|
+
font-size: 0.85rem;
|
|
253
|
+
font-weight: 600;
|
|
254
|
+
text-align: center;
|
|
255
|
+
letter-spacing: 1px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.comparison-header div:not(:last-child) {
|
|
259
|
+
border-right: 1px dashed var(--border);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.comparison-row {
|
|
263
|
+
display: grid;
|
|
264
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
265
|
+
border-bottom: 1px dashed var(--border);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.comparison-row:last-child { border-bottom: none; }
|
|
269
|
+
|
|
270
|
+
.comparison-row div {
|
|
271
|
+
padding: 15px 20px;
|
|
272
|
+
font-size: 0.85rem;
|
|
273
|
+
text-align: center;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.comparison-row div:not(:last-child) {
|
|
277
|
+
border-right: 1px dashed var(--border);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.comparison-row div:first-child {
|
|
281
|
+
text-align: left;
|
|
282
|
+
color: var(--text-muted);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.winner { color: var(--accent-red); font-weight: 600; }
|
|
286
|
+
|
|
287
|
+
.featured-media {
|
|
288
|
+
margin: 40px 0;
|
|
289
|
+
border: 1px dashed var(--border);
|
|
290
|
+
opacity: 0;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.media-container {
|
|
294
|
+
aspect-ratio: 16/9;
|
|
295
|
+
background: var(--bg-tertiary);
|
|
296
|
+
display: flex;
|
|
297
|
+
align-items: center;
|
|
298
|
+
justify-content: center;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.media-placeholder {
|
|
302
|
+
text-align: center;
|
|
303
|
+
color: var(--text-dim);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.media-placeholder .icon {
|
|
307
|
+
font-size: 4rem;
|
|
308
|
+
margin-bottom: 15px;
|
|
309
|
+
display: block;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.media-caption {
|
|
313
|
+
padding: 15px;
|
|
314
|
+
font-size: 0.8rem;
|
|
315
|
+
color: var(--text-muted);
|
|
316
|
+
border-top: 1px dashed var(--border);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.article-content { opacity: 0; }
|
|
320
|
+
|
|
321
|
+
.article-content h2 {
|
|
322
|
+
font-size: 1.6rem;
|
|
323
|
+
font-family: 'Fredoka', sans-serif;
|
|
324
|
+
margin: 50px 0 20px;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.article-content h3 {
|
|
328
|
+
font-size: 1.2rem;
|
|
329
|
+
margin: 35px 0 15px;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.article-content p { margin-bottom: 20px; font-size: 1rem; }
|
|
333
|
+
|
|
334
|
+
.article-content ul, .article-content ol { margin: 20px 0 20px 30px; }
|
|
335
|
+
.article-content li { margin-bottom: 10px; }
|
|
336
|
+
|
|
337
|
+
.article-content code {
|
|
338
|
+
background: var(--bg-secondary);
|
|
339
|
+
padding: 2px 8px;
|
|
340
|
+
border: 1px dashed var(--border);
|
|
341
|
+
font-size: 0.9em;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.article-content pre {
|
|
345
|
+
background: var(--bg-secondary);
|
|
346
|
+
border: 1px dashed var(--border);
|
|
347
|
+
padding: 20px;
|
|
348
|
+
margin: 25px 0;
|
|
349
|
+
overflow-x: auto;
|
|
350
|
+
font-size: 0.85rem;
|
|
351
|
+
line-height: 1.6;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.article-content blockquote {
|
|
355
|
+
border-left: 3px solid var(--text);
|
|
356
|
+
padding-left: 20px;
|
|
357
|
+
margin: 30px 0;
|
|
358
|
+
font-style: italic;
|
|
359
|
+
color: var(--text-muted);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.callout {
|
|
363
|
+
background: var(--bg-secondary);
|
|
364
|
+
border: 1px dashed var(--border);
|
|
365
|
+
border-left: 3px solid var(--text);
|
|
366
|
+
padding: 25px;
|
|
367
|
+
margin: 30px 0;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.callout-title {
|
|
371
|
+
font-size: 0.8rem;
|
|
372
|
+
letter-spacing: 2px;
|
|
373
|
+
text-transform: uppercase;
|
|
374
|
+
margin-bottom: 10px;
|
|
375
|
+
display: flex;
|
|
376
|
+
align-items: center;
|
|
377
|
+
gap: 10px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.callout-title::before {
|
|
381
|
+
content: '!';
|
|
382
|
+
width: 20px;
|
|
383
|
+
height: 20px;
|
|
384
|
+
border: 1px dashed var(--text);
|
|
385
|
+
display: flex;
|
|
386
|
+
align-items: center;
|
|
387
|
+
justify-content: center;
|
|
388
|
+
font-size: 0.75rem;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.ai-chat {
|
|
392
|
+
background: var(--bg-secondary);
|
|
393
|
+
border: 1px dashed var(--border);
|
|
394
|
+
margin: 50px 0;
|
|
395
|
+
opacity: 0;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.ai-chat-header {
|
|
399
|
+
padding: 20px;
|
|
400
|
+
border-bottom: 1px dashed var(--border);
|
|
401
|
+
display: flex;
|
|
402
|
+
align-items: center;
|
|
403
|
+
gap: 15px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.ai-chat-icon {
|
|
407
|
+
width: 40px;
|
|
408
|
+
height: 40px;
|
|
409
|
+
border: 2px solid var(--text);
|
|
410
|
+
display: flex;
|
|
411
|
+
align-items: center;
|
|
412
|
+
justify-content: center;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.ai-chat-title h4 { font-size: 0.9rem; font-weight: 600; }
|
|
416
|
+
.ai-chat-title p { font-size: 0.75rem; color: var(--text-muted); }
|
|
417
|
+
|
|
418
|
+
.ai-chat-body {
|
|
419
|
+
padding: 20px;
|
|
420
|
+
max-height: 400px;
|
|
421
|
+
overflow-y: auto;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.chat-message {
|
|
425
|
+
margin-bottom: 20px;
|
|
426
|
+
display: flex;
|
|
427
|
+
gap: 12px;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.chat-message.user { flex-direction: row-reverse; }
|
|
431
|
+
|
|
432
|
+
.chat-avatar {
|
|
433
|
+
width: 30px;
|
|
434
|
+
height: 30px;
|
|
435
|
+
border: 1px dashed var(--border);
|
|
436
|
+
display: flex;
|
|
437
|
+
align-items: center;
|
|
438
|
+
justify-content: center;
|
|
439
|
+
font-size: 0.7rem;
|
|
440
|
+
flex-shrink: 0;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.chat-bubble {
|
|
444
|
+
background: var(--bg-tertiary);
|
|
445
|
+
border: 1px dashed var(--border);
|
|
446
|
+
padding: 12px 16px;
|
|
447
|
+
max-width: 80%;
|
|
448
|
+
font-size: 0.9rem;
|
|
449
|
+
line-height: 1.6;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
.chat-message.user .chat-bubble { background: var(--bg); }
|
|
453
|
+
|
|
454
|
+
.quick-questions { padding: 0 20px 20px; }
|
|
455
|
+
|
|
456
|
+
.quick-questions-label {
|
|
457
|
+
font-size: 0.7rem;
|
|
458
|
+
letter-spacing: 2px;
|
|
459
|
+
color: var(--text-muted);
|
|
460
|
+
margin-bottom: 12px;
|
|
461
|
+
text-transform: uppercase;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.quick-btns { display: flex; flex-wrap: wrap; gap: 10px; }
|
|
465
|
+
|
|
466
|
+
.quick-btn {
|
|
467
|
+
background: transparent;
|
|
468
|
+
border: 1px dashed var(--border);
|
|
469
|
+
color: var(--text);
|
|
470
|
+
padding: 8px 16px;
|
|
471
|
+
font-family: inherit;
|
|
472
|
+
font-size: 0.8rem;
|
|
473
|
+
cursor: pointer;
|
|
474
|
+
transition: all 0.3s;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.quick-btn:hover { background: var(--accent-red); color: #fff; }
|
|
478
|
+
|
|
479
|
+
.ai-chat-input {
|
|
480
|
+
display: flex;
|
|
481
|
+
gap: 10px;
|
|
482
|
+
padding: 15px 20px;
|
|
483
|
+
border-top: 1px dashed var(--border);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.ai-chat-input input {
|
|
487
|
+
flex: 1;
|
|
488
|
+
background: transparent;
|
|
489
|
+
border: 1px dashed var(--border);
|
|
490
|
+
color: var(--text);
|
|
491
|
+
padding: 12px 15px;
|
|
492
|
+
font-family: inherit;
|
|
493
|
+
font-size: 0.9rem;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.ai-chat-input input::placeholder { color: var(--text-dim); }
|
|
497
|
+
.ai-chat-input input:focus { outline: none; border-color: var(--text); }
|
|
498
|
+
|
|
499
|
+
.ai-chat-input button {
|
|
500
|
+
background: var(--accent-red);
|
|
501
|
+
color: #fff;
|
|
502
|
+
border: none;
|
|
503
|
+
padding: 12px 20px;
|
|
504
|
+
font-family: inherit;
|
|
505
|
+
font-size: 0.8rem;
|
|
506
|
+
cursor: pointer;
|
|
507
|
+
letter-spacing: 1px;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.feedback-section {
|
|
511
|
+
background: var(--bg-secondary);
|
|
512
|
+
border: 1px dashed var(--border);
|
|
513
|
+
padding: 30px;
|
|
514
|
+
margin: 50px 0;
|
|
515
|
+
text-align: center;
|
|
516
|
+
opacity: 0;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
.feedback-title { font-size: 1.1rem; margin-bottom: 8px; }
|
|
520
|
+
.feedback-subtitle { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 25px; }
|
|
521
|
+
|
|
522
|
+
.feedback-buttons {
|
|
523
|
+
display: flex;
|
|
524
|
+
gap: 15px;
|
|
525
|
+
justify-content: center;
|
|
526
|
+
flex-wrap: wrap;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.feedback-btn {
|
|
530
|
+
background: transparent;
|
|
531
|
+
border: 2px solid var(--border);
|
|
532
|
+
color: var(--text);
|
|
533
|
+
padding: 15px 30px;
|
|
534
|
+
font-family: inherit;
|
|
535
|
+
font-size: 0.9rem;
|
|
536
|
+
cursor: pointer;
|
|
537
|
+
transition: all 0.3s;
|
|
538
|
+
display: flex;
|
|
539
|
+
align-items: center;
|
|
540
|
+
gap: 10px;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.feedback-btn:hover { border-color: var(--accent-red); box-shadow: 0 0 20px var(--accent-red-glow); }
|
|
544
|
+
.feedback-btn.active { background: var(--accent-red); color: #fff; }
|
|
545
|
+
.feedback-btn .icon { font-size: 1.2rem; }
|
|
546
|
+
|
|
547
|
+
.feedback-count { font-size: 0.75rem; color: var(--text-muted); margin-top: 20px; }
|
|
548
|
+
|
|
549
|
+
.related-posts { margin: 60px 0; }
|
|
550
|
+
|
|
551
|
+
.related-posts h3 {
|
|
552
|
+
font-size: 1.2rem;
|
|
553
|
+
font-family: 'Fredoka', sans-serif;
|
|
554
|
+
margin-bottom: 25px;
|
|
555
|
+
letter-spacing: 2px;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.related-grid {
|
|
559
|
+
display: grid;
|
|
560
|
+
grid-template-columns: repeat(2, 1fr);
|
|
561
|
+
gap: 25px;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.related-card {
|
|
565
|
+
border: 1px dashed var(--border);
|
|
566
|
+
padding: 25px;
|
|
567
|
+
text-decoration: none;
|
|
568
|
+
color: var(--text);
|
|
569
|
+
transition: all 0.3s;
|
|
570
|
+
opacity: 0;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
.related-card:hover { border-color: var(--accent-red); box-shadow: 0 0 30px var(--accent-red-glow); }
|
|
574
|
+
|
|
575
|
+
.related-card-tag {
|
|
576
|
+
font-size: 0.65rem;
|
|
577
|
+
letter-spacing: 2px;
|
|
578
|
+
color: var(--accent-red);
|
|
579
|
+
text-transform: uppercase;
|
|
580
|
+
margin-bottom: 12px;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.related-card-title {
|
|
584
|
+
font-size: 1rem;
|
|
585
|
+
font-family: 'Fredoka', sans-serif;
|
|
586
|
+
font-weight: 600;
|
|
587
|
+
line-height: 1.4;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
footer {
|
|
591
|
+
border-top: 1px dashed var(--border);
|
|
592
|
+
padding: 40px;
|
|
593
|
+
text-align: center;
|
|
594
|
+
margin-top: 60px;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.footer-logo {
|
|
598
|
+
font-size: 1.2rem;
|
|
599
|
+
font-family: 'Fredoka', sans-serif;
|
|
600
|
+
font-weight: 700;
|
|
601
|
+
letter-spacing: 2px;
|
|
602
|
+
margin-bottom: 20px;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.footer-links {
|
|
606
|
+
display: flex;
|
|
607
|
+
gap: 25px;
|
|
608
|
+
justify-content: center;
|
|
609
|
+
margin-bottom: 20px;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
.footer-links a {
|
|
613
|
+
color: var(--text-muted);
|
|
614
|
+
text-decoration: none;
|
|
615
|
+
font-size: 0.8rem;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.footer-links a:hover { color: var(--accent-red); }
|
|
619
|
+
.footer-copy { color: var(--text-dim); font-size: 0.75rem; }
|
|
620
|
+
|
|
621
|
+
@media (max-width: 768px) {
|
|
622
|
+
main { padding: 100px 20px 60px; }
|
|
623
|
+
.article-title { font-size: 2rem; }
|
|
624
|
+
.comparison-header, .comparison-row { grid-template-columns: 1fr; }
|
|
625
|
+
.comparison-header div:not(:last-child),
|
|
626
|
+
.comparison-row div:not(:last-child) { border-right: none; border-bottom: 1px dashed var(--border); }
|
|
627
|
+
.related-grid { grid-template-columns: 1fr; }
|
|
628
|
+
nav { padding: 15px 20px; }
|
|
629
|
+
.nav-links { display: none; }
|
|
630
|
+
}
|
|
631
|
+
</style>
|
|
632
|
+
</head>
|
|
633
|
+
<body>
|
|
634
|
+
<nav>
|
|
635
|
+
<a href="../index.html" class="logo">
|
|
636
|
+
<div class="logo-icon">HT</div>
|
|
637
|
+
HUSTLE TOGETHER
|
|
638
|
+
</a>
|
|
639
|
+
<div class="nav-links">
|
|
640
|
+
<a href="../index.html">HOME</a>
|
|
641
|
+
<a href="../index.html#tools">TOOLS</a>
|
|
642
|
+
<a href="../index.html#blog">BLOG</a>
|
|
643
|
+
<button class="theme-toggle" id="themeToggle">[ LIGHT ]</button>
|
|
644
|
+
</div>
|
|
645
|
+
</nav>
|
|
646
|
+
|
|
647
|
+
<main>
|
|
648
|
+
<header class="article-header">
|
|
649
|
+
<div class="article-meta">
|
|
650
|
+
<span class="article-tag">AI</span>
|
|
651
|
+
<span class="article-date">December 5, 2025</span>
|
|
652
|
+
</div>
|
|
653
|
+
<h1 class="article-title">Gemini Pro 2.5 vs Claude for Widget Generation</h1>
|
|
654
|
+
<p class="article-excerpt">
|
|
655
|
+
We tested both models for generating Elementor widgets from natural language.
|
|
656
|
+
The results challenged our assumptions about which AI is "best" for code generation.
|
|
657
|
+
Spoiler: context matters more than raw capability.
|
|
658
|
+
</p>
|
|
659
|
+
</header>
|
|
660
|
+
|
|
661
|
+
<div class="audio-player">
|
|
662
|
+
<div class="audio-header">
|
|
663
|
+
<div class="audio-icon">[>]</div>
|
|
664
|
+
<div class="audio-info">
|
|
665
|
+
<h4>Listen to this article</h4>
|
|
666
|
+
<p>AI-generated audio - 6 min read</p>
|
|
667
|
+
</div>
|
|
668
|
+
</div>
|
|
669
|
+
<div class="audio-controls">
|
|
670
|
+
<button class="play-btn" id="playBtn">[>]</button>
|
|
671
|
+
<div class="progress-bar">
|
|
672
|
+
<div class="progress-fill" id="progressFill"></div>
|
|
673
|
+
</div>
|
|
674
|
+
<span class="audio-time">0:00 / 6:12</span>
|
|
675
|
+
</div>
|
|
676
|
+
</div>
|
|
677
|
+
|
|
678
|
+
<div class="comparison-table">
|
|
679
|
+
<div class="comparison-header">
|
|
680
|
+
<div>METRIC</div>
|
|
681
|
+
<div>GEMINI PRO 2.5</div>
|
|
682
|
+
<div>CLAUDE</div>
|
|
683
|
+
</div>
|
|
684
|
+
<div class="comparison-row">
|
|
685
|
+
<div>Initial Code Quality</div>
|
|
686
|
+
<div class="winner">9/10</div>
|
|
687
|
+
<div>8/10</div>
|
|
688
|
+
</div>
|
|
689
|
+
<div class="comparison-row">
|
|
690
|
+
<div>WordPress Conventions</div>
|
|
691
|
+
<div>7/10</div>
|
|
692
|
+
<div class="winner">9/10</div>
|
|
693
|
+
</div>
|
|
694
|
+
<div class="comparison-row">
|
|
695
|
+
<div>Elementor API Accuracy</div>
|
|
696
|
+
<div>6/10</div>
|
|
697
|
+
<div class="winner">8/10</div>
|
|
698
|
+
</div>
|
|
699
|
+
<div class="comparison-row">
|
|
700
|
+
<div>Iteration Speed</div>
|
|
701
|
+
<div class="winner">10/10</div>
|
|
702
|
+
<div>7/10</div>
|
|
703
|
+
</div>
|
|
704
|
+
<div class="comparison-row">
|
|
705
|
+
<div>Context Window Usage</div>
|
|
706
|
+
<div class="winner">Excellent</div>
|
|
707
|
+
<div>Good</div>
|
|
708
|
+
</div>
|
|
709
|
+
</div>
|
|
710
|
+
|
|
711
|
+
<div class="featured-media">
|
|
712
|
+
<div class="media-container">
|
|
713
|
+
<div class="media-placeholder">
|
|
714
|
+
<span class="icon">[?]</span>
|
|
715
|
+
<p>SIDE-BY-SIDE COMPARISON VIDEO</p>
|
|
716
|
+
</div>
|
|
717
|
+
</div>
|
|
718
|
+
<p class="media-caption">Watch both models generate the same testimonial widget from identical prompts</p>
|
|
719
|
+
</div>
|
|
720
|
+
|
|
721
|
+
<article class="article-content">
|
|
722
|
+
<h2>The Test Setup</h2>
|
|
723
|
+
|
|
724
|
+
<p>We gave both models the same task: generate a fully functional Elementor widget for displaying customer testimonials. The widget needed:</p>
|
|
725
|
+
|
|
726
|
+
<ul>
|
|
727
|
+
<li>Editable customer name, title, and quote fields</li>
|
|
728
|
+
<li>Image upload for avatar</li>
|
|
729
|
+
<li>Star rating control (1-5)</li>
|
|
730
|
+
<li>Responsive styling with Elementor controls</li>
|
|
731
|
+
<li>Proper WordPress i18n support</li>
|
|
732
|
+
</ul>
|
|
733
|
+
|
|
734
|
+
<p>Same prompt. Same requirements. Different results.</p>
|
|
735
|
+
|
|
736
|
+
<h2>Round 1: Initial Generation</h2>
|
|
737
|
+
|
|
738
|
+
<p>Gemini Pro 2.5 produced cleaner code out of the gate. The structure was elegant, the naming conventions were consistent, and it even added comments explaining what each section did.</p>
|
|
739
|
+
|
|
740
|
+
<pre>// Gemini's output
|
|
741
|
+
class Testimonial_Widget extends \Elementor\Widget_Base {
|
|
742
|
+
public function get_name() { return 'ht_testimonial'; }
|
|
743
|
+
public function get_title() { return esc_html__('Testimonial', 'hustle-elementor'); }
|
|
744
|
+
// ... well-structured code continues</pre>
|
|
745
|
+
|
|
746
|
+
<p>Claude's initial output was functional but verbose. It included more edge case handling but at the cost of readability.</p>
|
|
747
|
+
|
|
748
|
+
<div class="callout">
|
|
749
|
+
<div class="callout-title">Key Observation</div>
|
|
750
|
+
<p>Gemini's code was prettier. Claude's code was more defensive. For a WordPress plugin that could be installed on any server, Claude's paranoia might actually be the better choice.</p>
|
|
751
|
+
</div>
|
|
752
|
+
|
|
753
|
+
<h2>Round 2: WordPress Integration</h2>
|
|
754
|
+
|
|
755
|
+
<p>This is where things got interesting. Gemini's beautiful code had a problem: it didn't follow WordPress coding standards. The escaping was inconsistent, the text domains were sometimes missing, and the action hooks were in the wrong order.</p>
|
|
756
|
+
|
|
757
|
+
<p>Claude, despite its verbose style, got the WordPress stuff right. Every output was escaped. Every string was translatable. The hooks fired in the correct sequence.</p>
|
|
758
|
+
|
|
759
|
+
<h2>Round 3: Elementor API Accuracy</h2>
|
|
760
|
+
|
|
761
|
+
<p>Both models hallucinated some Elementor controls that don't exist. But Claude was more likely to stick to core controls, while Gemini invented creative-but-nonexistent options.</p>
|
|
762
|
+
|
|
763
|
+
<pre>// Gemini invented this (it doesn't exist)
|
|
764
|
+
$this->add_control('avatar_shape', [
|
|
765
|
+
'type' => \Elementor\Controls_Manager::SHAPE, // NOT A THING
|
|
766
|
+
]);
|
|
767
|
+
|
|
768
|
+
// Claude used this (it does exist)
|
|
769
|
+
$this->add_control('avatar_radius', [
|
|
770
|
+
'type' => \Elementor\Controls_Manager::SLIDER,
|
|
771
|
+
]);</pre>
|
|
772
|
+
|
|
773
|
+
<h2>Round 4: Iteration Speed</h2>
|
|
774
|
+
|
|
775
|
+
<p>Here's where Gemini crushed it. When we asked for changes, Gemini responded with full updated code in about 3 seconds. Claude took 8-10 seconds and often gave partial updates that required follow-up prompts.</p>
|
|
776
|
+
|
|
777
|
+
<p>For rapid prototyping and live demos, Gemini's speed is a genuine advantage.</p>
|
|
778
|
+
|
|
779
|
+
<h2>Our Recommendation</h2>
|
|
780
|
+
|
|
781
|
+
<p>Use both. Seriously.</p>
|
|
782
|
+
|
|
783
|
+
<ol>
|
|
784
|
+
<li><strong>Prototype with Gemini</strong> - Get the structure right fast</li>
|
|
785
|
+
<li><strong>Refine with Claude</strong> - Fix the WordPress integration</li>
|
|
786
|
+
<li><strong>Ship with Morph</strong> - Make quick edits without regenerating</li>
|
|
787
|
+
</ol>
|
|
788
|
+
|
|
789
|
+
<p>That's exactly how Hustle Elementor works. Gemini for generation, Claude for review, Morph for edits. The best tool for each job.</p>
|
|
790
|
+
|
|
791
|
+
<div class="callout">
|
|
792
|
+
<div class="callout-title">The Real Winner</div>
|
|
793
|
+
<p>The model that works best is the one with the most context about your specific codebase. Our interview-driven workflow from api-dev-tools helps both models perform better by giving them real requirements instead of vague prompts.</p>
|
|
794
|
+
</div>
|
|
795
|
+
</article>
|
|
796
|
+
|
|
797
|
+
<div class="ai-chat">
|
|
798
|
+
<div class="ai-chat-header">
|
|
799
|
+
<div class="ai-chat-icon">[?]</div>
|
|
800
|
+
<div class="ai-chat-title">
|
|
801
|
+
<h4>Quick Answers</h4>
|
|
802
|
+
<p>Ask questions about this comparison</p>
|
|
803
|
+
</div>
|
|
804
|
+
</div>
|
|
805
|
+
<div class="ai-chat-body">
|
|
806
|
+
<div class="chat-message">
|
|
807
|
+
<div class="chat-avatar">AI</div>
|
|
808
|
+
<div class="chat-bubble">
|
|
809
|
+
Got questions about Gemini vs Claude for code generation? I can help clarify our testing methodology or explain specific results.
|
|
810
|
+
</div>
|
|
811
|
+
</div>
|
|
812
|
+
</div>
|
|
813
|
+
<div class="quick-questions">
|
|
814
|
+
<div class="quick-questions-label">Quick Questions</div>
|
|
815
|
+
<div class="quick-btns">
|
|
816
|
+
<button class="quick-btn" data-question="Which model is faster?">Which is faster?</button>
|
|
817
|
+
<button class="quick-btn" data-question="What about cost?">What about cost?</button>
|
|
818
|
+
<button class="quick-btn" data-question="Can I use both together?">Use both together?</button>
|
|
819
|
+
</div>
|
|
820
|
+
</div>
|
|
821
|
+
<div class="ai-chat-input">
|
|
822
|
+
<input type="text" placeholder="Ask about the comparison..." id="chatInput">
|
|
823
|
+
<button id="chatSend">SEND</button>
|
|
824
|
+
</div>
|
|
825
|
+
</div>
|
|
826
|
+
|
|
827
|
+
<div class="feedback-section">
|
|
828
|
+
<h3 class="feedback-title">Was this comparison helpful?</h3>
|
|
829
|
+
<p class="feedback-subtitle">We test so you don't have to</p>
|
|
830
|
+
<div class="feedback-buttons">
|
|
831
|
+
<button class="feedback-btn" data-reaction="very-nice">
|
|
832
|
+
<span class="icon">[+]</span>
|
|
833
|
+
Very Nice
|
|
834
|
+
</button>
|
|
835
|
+
<button class="feedback-btn" data-reaction="helpful">
|
|
836
|
+
<span class="icon">[*]</span>
|
|
837
|
+
Helpful
|
|
838
|
+
</button>
|
|
839
|
+
<button class="feedback-btn" data-reaction="more-tests">
|
|
840
|
+
<span class="icon">[?]</span>
|
|
841
|
+
More Tests
|
|
842
|
+
</button>
|
|
843
|
+
</div>
|
|
844
|
+
<p class="feedback-count">38 developers found this helpful</p>
|
|
845
|
+
</div>
|
|
846
|
+
|
|
847
|
+
<div class="related-posts">
|
|
848
|
+
<h3>RELATED POSTS</h3>
|
|
849
|
+
<div class="related-grid">
|
|
850
|
+
<a href="interview-driven-api-development.html" class="related-card">
|
|
851
|
+
<div class="related-card-tag">DEV TOOLS</div>
|
|
852
|
+
<h4 class="related-card-title">Why We Built Interview-Driven API Development</h4>
|
|
853
|
+
</a>
|
|
854
|
+
<a href="tdd-for-ai.html" class="related-card">
|
|
855
|
+
<div class="related-card-tag">WORKFLOW</div>
|
|
856
|
+
<h4 class="related-card-title">TDD is Dead, Long Live TDD</h4>
|
|
857
|
+
</a>
|
|
858
|
+
</div>
|
|
859
|
+
</div>
|
|
860
|
+
</main>
|
|
861
|
+
|
|
862
|
+
<footer>
|
|
863
|
+
<div class="footer-logo">HUSTLE TOGETHER</div>
|
|
864
|
+
<div class="footer-links">
|
|
865
|
+
<a href="https://github.com/hustle-together" target="_blank">GITHUB</a>
|
|
866
|
+
<a href="https://www.npmjs.com/org/hustle-together" target="_blank">NPM</a>
|
|
867
|
+
<a href="mailto:hello@hustletogether.dev">CONTACT</a>
|
|
868
|
+
</div>
|
|
869
|
+
<div class="footer-copy">2025 Hustle Together. Experiment. Build. Share.</div>
|
|
870
|
+
</footer>
|
|
871
|
+
|
|
872
|
+
<script>
|
|
873
|
+
const themeToggle = document.getElementById('themeToggle');
|
|
874
|
+
let isDark = true;
|
|
875
|
+
themeToggle.addEventListener('click', () => {
|
|
876
|
+
isDark = !isDark;
|
|
877
|
+
document.documentElement.setAttribute('data-theme', isDark ? '' : 'light');
|
|
878
|
+
themeToggle.textContent = isDark ? '[ LIGHT ]' : '[ DARK ]';
|
|
879
|
+
});
|
|
880
|
+
|
|
881
|
+
gsap.to('.article-header', { opacity: 1, duration: 0.8, delay: 0.3 });
|
|
882
|
+
gsap.to('.audio-player', { opacity: 1, duration: 0.6, delay: 0.5 });
|
|
883
|
+
gsap.to('.comparison-table', { opacity: 1, duration: 0.6, delay: 0.7 });
|
|
884
|
+
gsap.to('.featured-media', { opacity: 1, duration: 0.6, delay: 0.9 });
|
|
885
|
+
gsap.to('.article-content', { opacity: 1, duration: 0.8, delay: 1.1 });
|
|
886
|
+
gsap.to('.ai-chat', { opacity: 1, duration: 0.6, delay: 1.3 });
|
|
887
|
+
gsap.to('.feedback-section', { opacity: 1, duration: 0.6, delay: 1.5 });
|
|
888
|
+
gsap.to('.related-card', { opacity: 1, duration: 0.5, stagger: 0.15, delay: 1.7 });
|
|
889
|
+
|
|
890
|
+
const playBtn = document.getElementById('playBtn');
|
|
891
|
+
const progressFill = document.getElementById('progressFill');
|
|
892
|
+
let isPlaying = false, progress = 0, playInterval;
|
|
893
|
+
|
|
894
|
+
playBtn.addEventListener('click', () => {
|
|
895
|
+
isPlaying = !isPlaying;
|
|
896
|
+
playBtn.textContent = isPlaying ? '[||]' : '[>]';
|
|
897
|
+
if (isPlaying) {
|
|
898
|
+
playInterval = setInterval(() => {
|
|
899
|
+
progress += 0.25;
|
|
900
|
+
if (progress >= 100) { progress = 0; isPlaying = false; playBtn.textContent = '[>]'; clearInterval(playInterval); }
|
|
901
|
+
progressFill.style.width = progress + '%';
|
|
902
|
+
}, 100);
|
|
903
|
+
} else { clearInterval(playInterval); }
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
const quickBtns = document.querySelectorAll('.quick-btn');
|
|
907
|
+
const chatBody = document.querySelector('.ai-chat-body');
|
|
908
|
+
const answers = {
|
|
909
|
+
"Which model is faster?": "Gemini Pro 2.5 is significantly faster - about 3x faster for code generation. It responds in 2-4 seconds while Claude takes 8-12 seconds for similar tasks.",
|
|
910
|
+
"What about cost?": "Gemini Pro 2.5 is cheaper per token, but Claude's longer context window means fewer calls for complex projects. For widget generation, Gemini wins on cost.",
|
|
911
|
+
"Can I use both together?": "Absolutely! That's our recommended approach. Use Gemini for fast prototyping, Claude for WordPress-specific validation, and Morph for quick edits."
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
quickBtns.forEach(btn => {
|
|
915
|
+
btn.addEventListener('click', () => {
|
|
916
|
+
const q = btn.dataset.question;
|
|
917
|
+
chatBody.innerHTML += `<div class="chat-message user"><div class="chat-avatar">U</div><div class="chat-bubble">${q}</div></div>`;
|
|
918
|
+
setTimeout(() => {
|
|
919
|
+
chatBody.innerHTML += `<div class="chat-message"><div class="chat-avatar">AI</div><div class="chat-bubble">${answers[q] || "Let me look into that for you."}</div></div>`;
|
|
920
|
+
chatBody.scrollTop = chatBody.scrollHeight;
|
|
921
|
+
}, 500);
|
|
922
|
+
chatBody.scrollTop = chatBody.scrollHeight;
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
|
|
926
|
+
const chatInput = document.getElementById('chatInput');
|
|
927
|
+
const chatSend = document.getElementById('chatSend');
|
|
928
|
+
chatSend.addEventListener('click', sendMessage);
|
|
929
|
+
chatInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); });
|
|
930
|
+
|
|
931
|
+
function sendMessage() {
|
|
932
|
+
const msg = chatInput.value.trim();
|
|
933
|
+
if (!msg) return;
|
|
934
|
+
chatBody.innerHTML += `<div class="chat-message user"><div class="chat-avatar">U</div><div class="chat-bubble">${msg}</div></div>`;
|
|
935
|
+
chatInput.value = '';
|
|
936
|
+
setTimeout(() => {
|
|
937
|
+
chatBody.innerHTML += `<div class="chat-message"><div class="chat-avatar">AI</div><div class="chat-bubble">Great question! This demo chat shows how we'd add AI Q&A to every article.</div></div>`;
|
|
938
|
+
chatBody.scrollTop = chatBody.scrollHeight;
|
|
939
|
+
}, 500);
|
|
940
|
+
chatBody.scrollTop = chatBody.scrollHeight;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
const feedbackBtns = document.querySelectorAll('.feedback-btn');
|
|
944
|
+
const feedbackCount = document.querySelector('.feedback-count');
|
|
945
|
+
let count = 38;
|
|
946
|
+
feedbackBtns.forEach(btn => {
|
|
947
|
+
btn.addEventListener('click', () => {
|
|
948
|
+
feedbackBtns.forEach(b => b.classList.remove('active'));
|
|
949
|
+
btn.classList.add('active');
|
|
950
|
+
count++;
|
|
951
|
+
feedbackCount.textContent = `${count} developers found this helpful`;
|
|
952
|
+
gsap.to(btn, { scale: 1.1, duration: 0.1, yoyo: true, repeat: 1 });
|
|
953
|
+
});
|
|
954
|
+
});
|
|
955
|
+
</script>
|
|
956
|
+
</body>
|
|
957
|
+
</html>
|