@hustle-together/api-dev-tools 2.0.0 → 2.0.2
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/demo/workflow-demo.html +266 -40
- package/package.json +1 -1
package/demo/workflow-demo.html
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>API Dev Tools -
|
|
6
|
+
<title>Hustle API Dev Tools - Build APIs the Right Way</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=Fredoka:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
7
10
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
|
|
8
11
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
|
|
9
12
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/TextPlugin.min.js"></script>
|
|
@@ -711,6 +714,170 @@
|
|
|
711
714
|
font-size: 1.1rem;
|
|
712
715
|
}
|
|
713
716
|
|
|
717
|
+
/* ============================================
|
|
718
|
+
HUSTLE BRAND TITLE - Matching Home Page Style
|
|
719
|
+
============================================ */
|
|
720
|
+
.hustle-brand {
|
|
721
|
+
display: flex;
|
|
722
|
+
justify-content: center;
|
|
723
|
+
align-items: center;
|
|
724
|
+
gap: 15px;
|
|
725
|
+
margin-bottom: 15px;
|
|
726
|
+
flex-wrap: wrap;
|
|
727
|
+
text-align: center;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
.hustle-word {
|
|
731
|
+
font-size: 5rem;
|
|
732
|
+
font-family: 'Fredoka', sans-serif;
|
|
733
|
+
font-weight: 700;
|
|
734
|
+
letter-spacing: 4px;
|
|
735
|
+
opacity: 0;
|
|
736
|
+
transform: translateY(30px);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.hustle-highlight {
|
|
740
|
+
color: var(--accent-red);
|
|
741
|
+
text-shadow: 0 0 30px var(--accent-red-glow), 0 0 60px var(--accent-red-glow);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
.text-red {
|
|
745
|
+
color: var(--accent-red);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
/* Intro section centering */
|
|
749
|
+
#intro {
|
|
750
|
+
text-align: center;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
#intro .ascii-border {
|
|
754
|
+
display: flex;
|
|
755
|
+
flex-direction: column;
|
|
756
|
+
align-items: center;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.package-name {
|
|
760
|
+
text-align: center;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
.version {
|
|
764
|
+
text-align: center;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
.tagline {
|
|
768
|
+
text-align: center;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
.scroll-hint {
|
|
772
|
+
text-align: center;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/* ============================================
|
|
776
|
+
PHASE FLOW - LIGHTING UP SEQUENCE
|
|
777
|
+
============================================ */
|
|
778
|
+
.phase-flow {
|
|
779
|
+
display: flex;
|
|
780
|
+
align-items: center;
|
|
781
|
+
justify-content: center;
|
|
782
|
+
gap: 15px;
|
|
783
|
+
margin-top: 50px;
|
|
784
|
+
flex-wrap: wrap;
|
|
785
|
+
opacity: 0;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
.phase-node {
|
|
789
|
+
position: relative;
|
|
790
|
+
border: 2px solid var(--dark-grey);
|
|
791
|
+
padding: 20px 25px;
|
|
792
|
+
text-align: center;
|
|
793
|
+
min-width: 100px;
|
|
794
|
+
transition: all 0.4s ease;
|
|
795
|
+
opacity: 0;
|
|
796
|
+
transform: translateY(20px);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.phase-node .phase-glow {
|
|
800
|
+
position: absolute;
|
|
801
|
+
top: -2px;
|
|
802
|
+
left: -2px;
|
|
803
|
+
right: -2px;
|
|
804
|
+
bottom: -2px;
|
|
805
|
+
border: 2px solid var(--accent-red);
|
|
806
|
+
opacity: 0;
|
|
807
|
+
box-shadow: 0 0 20px var(--accent-red-glow), inset 0 0 20px var(--accent-red-glow);
|
|
808
|
+
transition: opacity 0.4s ease;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
.phase-node.active {
|
|
812
|
+
border-color: var(--accent-red);
|
|
813
|
+
background: rgba(186, 12, 47, 0.1);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.phase-node.active .phase-glow {
|
|
817
|
+
opacity: 1;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.phase-node.active .phase-icon {
|
|
821
|
+
color: var(--accent-red);
|
|
822
|
+
text-shadow: 0 0 10px var(--accent-red);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.phase-node.active .phase-label {
|
|
826
|
+
color: var(--white);
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
.phase-icon {
|
|
830
|
+
display: block;
|
|
831
|
+
font-size: 1.8rem;
|
|
832
|
+
font-weight: bold;
|
|
833
|
+
margin-bottom: 8px;
|
|
834
|
+
color: var(--grey);
|
|
835
|
+
transition: all 0.4s ease;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.phase-label {
|
|
839
|
+
font-size: 0.7rem;
|
|
840
|
+
text-transform: uppercase;
|
|
841
|
+
letter-spacing: 2px;
|
|
842
|
+
color: var(--dark-grey);
|
|
843
|
+
transition: all 0.4s ease;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
.phase-connector-arrow {
|
|
847
|
+
color: var(--dark-grey);
|
|
848
|
+
font-size: 1.5rem;
|
|
849
|
+
opacity: 0;
|
|
850
|
+
transition: all 0.3s ease;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.phase-connector-arrow.active {
|
|
854
|
+
color: var(--accent-red);
|
|
855
|
+
text-shadow: 0 0 10px var(--accent-red-glow);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
@media (max-width: 768px) {
|
|
859
|
+
.hustle-word {
|
|
860
|
+
font-size: 2.5rem;
|
|
861
|
+
letter-spacing: 4px;
|
|
862
|
+
}
|
|
863
|
+
.hustle-brand {
|
|
864
|
+
gap: 10px;
|
|
865
|
+
}
|
|
866
|
+
.phase-flow {
|
|
867
|
+
gap: 10px;
|
|
868
|
+
}
|
|
869
|
+
.phase-node {
|
|
870
|
+
padding: 15px 18px;
|
|
871
|
+
min-width: 70px;
|
|
872
|
+
}
|
|
873
|
+
.phase-icon {
|
|
874
|
+
font-size: 1.4rem;
|
|
875
|
+
}
|
|
876
|
+
.phase-connector-arrow {
|
|
877
|
+
font-size: 1rem;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
714
881
|
.intro-text {
|
|
715
882
|
max-width: 700px;
|
|
716
883
|
margin: 40px auto 0;
|
|
@@ -1432,48 +1599,53 @@
|
|
|
1432
1599
|
============================================ -->
|
|
1433
1600
|
<section id="intro">
|
|
1434
1601
|
<div class="ascii-border">
|
|
1435
|
-
<
|
|
1602
|
+
<div class="hustle-brand" id="hustleBrand">
|
|
1603
|
+
<span class="hustle-word">HUSTLE</span>
|
|
1604
|
+
<span class="hustle-word hustle-highlight">API</span>
|
|
1605
|
+
<span class="hustle-word hustle-highlight">DEV</span>
|
|
1606
|
+
<span class="hustle-word">TOOLS</span>
|
|
1607
|
+
</div>
|
|
1436
1608
|
<div class="package-name" id="packageName">@hustle-together/api-dev-tools</div>
|
|
1437
|
-
<div class="version" id="versionText">
|
|
1438
|
-
<p class="tagline">"
|
|
1609
|
+
<div class="version" id="versionText">v2.0.2</div>
|
|
1610
|
+
<p class="tagline">"Hustle together. Share resources. Build stronger."<span class="cursor"></span></p>
|
|
1439
1611
|
|
|
1440
1612
|
<div class="intro-text">
|
|
1441
1613
|
<p>
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
then ask YOU questions with <strong>multiple-choice options</strong> based on what they found.
|
|
1445
|
-
</p>
|
|
1446
|
-
<p style="margin-top: 20px;">
|
|
1447
|
-
<strong>Scroll down</strong> to see how it works, step by step, using a real example:
|
|
1448
|
-
creating a <strong>Brandfetch API endpoint</strong> from scratch.
|
|
1614
|
+
<strong>Enforced workflows</strong> for AI-assisted API development.
|
|
1615
|
+
Research first. Interview second. <span class="text-red">No shortcuts.</span>
|
|
1449
1616
|
</p>
|
|
1450
1617
|
</div>
|
|
1451
1618
|
|
|
1452
|
-
<!-- Visual Quick Overview -->
|
|
1453
|
-
<div class="
|
|
1454
|
-
<div class="
|
|
1455
|
-
<span class="
|
|
1456
|
-
<span class="
|
|
1619
|
+
<!-- Visual Quick Overview - Phases Light Up -->
|
|
1620
|
+
<div class="phase-flow" id="introFlow">
|
|
1621
|
+
<div class="phase-node" data-phase="research">
|
|
1622
|
+
<span class="phase-icon">R</span>
|
|
1623
|
+
<span class="phase-label">Research</span>
|
|
1624
|
+
<div class="phase-glow"></div>
|
|
1457
1625
|
</div>
|
|
1458
|
-
<span class="
|
|
1459
|
-
<div class="
|
|
1460
|
-
<span class="
|
|
1461
|
-
<span class="
|
|
1626
|
+
<span class="phase-connector-arrow">→</span>
|
|
1627
|
+
<div class="phase-node" data-phase="interview">
|
|
1628
|
+
<span class="phase-icon">?</span>
|
|
1629
|
+
<span class="phase-label">Interview</span>
|
|
1630
|
+
<div class="phase-glow"></div>
|
|
1462
1631
|
</div>
|
|
1463
|
-
<span class="
|
|
1464
|
-
<div class="
|
|
1465
|
-
<span class="
|
|
1466
|
-
<span class="
|
|
1632
|
+
<span class="phase-connector-arrow">→</span>
|
|
1633
|
+
<div class="phase-node" data-phase="test">
|
|
1634
|
+
<span class="phase-icon">T</span>
|
|
1635
|
+
<span class="phase-label">Test</span>
|
|
1636
|
+
<div class="phase-glow"></div>
|
|
1467
1637
|
</div>
|
|
1468
|
-
<span class="
|
|
1469
|
-
<div class="
|
|
1470
|
-
<span class="
|
|
1471
|
-
<span class="
|
|
1638
|
+
<span class="phase-connector-arrow">→</span>
|
|
1639
|
+
<div class="phase-node" data-phase="code">
|
|
1640
|
+
<span class="phase-icon">C</span>
|
|
1641
|
+
<span class="phase-label">Code</span>
|
|
1642
|
+
<div class="phase-glow"></div>
|
|
1472
1643
|
</div>
|
|
1473
|
-
<span class="
|
|
1474
|
-
<div class="
|
|
1475
|
-
<span class="
|
|
1476
|
-
<span class="
|
|
1644
|
+
<span class="phase-connector-arrow">→</span>
|
|
1645
|
+
<div class="phase-node" data-phase="docs">
|
|
1646
|
+
<span class="phase-icon">D</span>
|
|
1647
|
+
<span class="phase-label">Docs</span>
|
|
1648
|
+
<div class="phase-glow"></div>
|
|
1477
1649
|
</div>
|
|
1478
1650
|
</div>
|
|
1479
1651
|
|
|
@@ -2222,7 +2394,7 @@
|
|
|
2222
2394
|
});
|
|
2223
2395
|
|
|
2224
2396
|
// ============================================
|
|
2225
|
-
// SECTION 1: INTRO ANIMATION
|
|
2397
|
+
// SECTION 1: INTRO ANIMATION - HUSTLE BRAND + PHASE LIGHTING
|
|
2226
2398
|
// ============================================
|
|
2227
2399
|
const introTL = gsap.timeline({
|
|
2228
2400
|
scrollTrigger: {
|
|
@@ -2232,15 +2404,69 @@
|
|
|
2232
2404
|
}
|
|
2233
2405
|
});
|
|
2234
2406
|
|
|
2407
|
+
// Hustle brand title animation
|
|
2235
2408
|
introTL
|
|
2236
|
-
.to('
|
|
2237
|
-
|
|
2409
|
+
.to('.hustle-word', {
|
|
2410
|
+
opacity: 1,
|
|
2411
|
+
y: 0,
|
|
2412
|
+
duration: 0.5,
|
|
2413
|
+
stagger: 0.15,
|
|
2414
|
+
ease: 'back.out(1.7)'
|
|
2415
|
+
})
|
|
2416
|
+
.to('#packageName', { opacity: 1, duration: 0.4 }, '-=0.2')
|
|
2238
2417
|
.to('#versionText', { opacity: 1, duration: 0.3 })
|
|
2239
|
-
.to('.
|
|
2240
|
-
.to('
|
|
2241
|
-
.to('#introFlow
|
|
2242
|
-
|
|
2243
|
-
.to('.
|
|
2418
|
+
.to('.tagline', { opacity: 1, duration: 0.4 })
|
|
2419
|
+
.to('.intro-text', { opacity: 1, duration: 0.5 }, '-=0.2')
|
|
2420
|
+
.to('#introFlow', { opacity: 1, duration: 0.3 })
|
|
2421
|
+
// Phase nodes appear one by one
|
|
2422
|
+
.to('#introFlow .phase-node', {
|
|
2423
|
+
opacity: 1,
|
|
2424
|
+
y: 0,
|
|
2425
|
+
duration: 0.3,
|
|
2426
|
+
stagger: 0.12,
|
|
2427
|
+
ease: 'power2.out'
|
|
2428
|
+
})
|
|
2429
|
+
// Arrows appear between nodes
|
|
2430
|
+
.to('#introFlow .phase-connector-arrow', {
|
|
2431
|
+
opacity: 1,
|
|
2432
|
+
duration: 0.2,
|
|
2433
|
+
stagger: 0.1
|
|
2434
|
+
}, '-=0.4')
|
|
2435
|
+
.to('.scroll-hint', { opacity: 1, duration: 0.4 }, '-=0.2');
|
|
2436
|
+
|
|
2437
|
+
// Phase lighting sequence - lights up each phase with red glow
|
|
2438
|
+
const phaseNodes = document.querySelectorAll('#introFlow .phase-node');
|
|
2439
|
+
const phaseArrows = document.querySelectorAll('#introFlow .phase-connector-arrow');
|
|
2440
|
+
|
|
2441
|
+
// Create a separate timeline for the lighting sequence that loops
|
|
2442
|
+
const lightingTL = gsap.timeline({
|
|
2443
|
+
repeat: -1,
|
|
2444
|
+
repeatDelay: 1,
|
|
2445
|
+
delay: 3 // Wait for intro animation to complete
|
|
2446
|
+
});
|
|
2447
|
+
|
|
2448
|
+
phaseNodes.forEach((node, i) => {
|
|
2449
|
+
lightingTL
|
|
2450
|
+
.call(() => {
|
|
2451
|
+
// Light up current node
|
|
2452
|
+
node.classList.add('active');
|
|
2453
|
+
// Light up the arrow before this node (if any)
|
|
2454
|
+
if (i > 0 && phaseArrows[i-1]) {
|
|
2455
|
+
phaseArrows[i-1].classList.add('active');
|
|
2456
|
+
}
|
|
2457
|
+
})
|
|
2458
|
+
.to({}, { duration: 0.5 }); // Pause to show the lit state
|
|
2459
|
+
});
|
|
2460
|
+
|
|
2461
|
+
// Keep all lit for a moment, then reset
|
|
2462
|
+
lightingTL
|
|
2463
|
+
.to({}, { duration: 1.5 })
|
|
2464
|
+
.call(() => {
|
|
2465
|
+
// Reset all
|
|
2466
|
+
phaseNodes.forEach(node => node.classList.remove('active'));
|
|
2467
|
+
phaseArrows.forEach(arrow => arrow.classList.remove('active'));
|
|
2468
|
+
})
|
|
2469
|
+
.to({}, { duration: 0.5 }); // Brief pause before restart
|
|
2244
2470
|
|
|
2245
2471
|
// ============================================
|
|
2246
2472
|
// SECTION 2: PROBLEMS ANIMATION
|
package/package.json
CHANGED