@sonordev/agency-site-kit 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BeforeAfterSection-6QUJOBO2.js → BeforeAfterSection-6BHFLY4Y.js} +6 -6
- package/dist/BeforeAfterSection-6BHFLY4Y.js.map +1 -0
- package/dist/{BeforeAfterSection-DVAWWE4K.cjs → BeforeAfterSection-JTORBR3A.cjs} +6 -6
- package/dist/BeforeAfterSection-JTORBR3A.cjs.map +1 -0
- package/dist/DesignSystemSection-2R5BRBGO.js +172 -0
- package/dist/DesignSystemSection-2R5BRBGO.js.map +1 -0
- package/dist/DesignSystemSection-KXIQXITF.cjs +174 -0
- package/dist/DesignSystemSection-KXIQXITF.cjs.map +1 -0
- package/dist/{DetailsSection-FB763FS7.js → DetailsSection-A6PZQUQL.js} +14 -5
- package/dist/DetailsSection-A6PZQUQL.js.map +1 -0
- package/dist/{DetailsSection-OACJFGH7.cjs → DetailsSection-TTUZAPZZ.cjs} +14 -5
- package/dist/DetailsSection-TTUZAPZZ.cjs.map +1 -0
- package/dist/PerformanceSection-24TVVFZA.cjs +356 -0
- package/dist/PerformanceSection-24TVVFZA.cjs.map +1 -0
- package/dist/PerformanceSection-MGCEIXDX.js +351 -0
- package/dist/PerformanceSection-MGCEIXDX.js.map +1 -0
- package/dist/SiteArchitectureSection-EE6VQSXM.cjs +349 -0
- package/dist/SiteArchitectureSection-EE6VQSXM.cjs.map +1 -0
- package/dist/SiteArchitectureSection-PBBRTARV.js +344 -0
- package/dist/SiteArchitectureSection-PBBRTARV.js.map +1 -0
- package/dist/SpeedComparisonSection-EZKFQVGW.cjs +174 -0
- package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +1 -0
- package/dist/SpeedComparisonSection-Y3K7OFZQ.js +172 -0
- package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +1 -0
- package/dist/{StrategySection-3ED3QW4R.cjs → StrategySection-CJ7Y6OFQ.cjs} +18 -24
- package/dist/StrategySection-CJ7Y6OFQ.cjs.map +1 -0
- package/dist/{StrategySection-VUWMIYYP.js → StrategySection-DI5RSCJU.js} +18 -24
- package/dist/StrategySection-DI5RSCJU.js.map +1 -0
- package/dist/TechStackSection-2AQ7RGY3.js +93 -0
- package/dist/TechStackSection-2AQ7RGY3.js.map +1 -0
- package/dist/TechStackSection-VTNNZR5V.cjs +95 -0
- package/dist/TechStackSection-VTNNZR5V.cjs.map +1 -0
- package/dist/chunk-4GVC3D2X.js +606 -0
- package/dist/chunk-4GVC3D2X.js.map +1 -0
- package/dist/{chunk-XMC4DN6G.js → chunk-APG2QSMB.js} +8 -8
- package/dist/chunk-APG2QSMB.js.map +1 -0
- package/dist/chunk-BGM6A2RU.cjs +613 -0
- package/dist/chunk-BGM6A2RU.cjs.map +1 -0
- package/dist/{chunk-NAS4K5UR.cjs → chunk-OA5ZM4OA.cjs} +8 -8
- package/dist/chunk-OA5ZM4OA.cjs.map +1 -0
- package/dist/{chunk-QIC6JFFD.js → chunk-OMOF4VR5.js} +14 -14
- package/dist/chunk-OMOF4VR5.js.map +1 -0
- package/dist/{chunk-5FKOLIV6.cjs → chunk-XM2QD3AK.cjs} +14 -14
- package/dist/chunk-XM2QD3AK.cjs.map +1 -0
- package/dist/index.cjs +13 -13
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/layout/index.cjs +2 -2
- package/dist/layout/index.d.cts +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/layout/index.js +1 -1
- package/dist/portfolio/client.cjs +3 -3
- package/dist/portfolio/client.d.cts +7 -3
- package/dist/portfolio/client.d.ts +7 -3
- package/dist/portfolio/client.js +1 -1
- package/dist/portfolio/index.cjs +6 -6
- package/dist/portfolio/index.d.cts +2 -2
- package/dist/portfolio/index.d.ts +2 -2
- package/dist/portfolio/index.js +2 -2
- package/dist/portfolio/sections.d.cts +1 -1
- package/dist/portfolio/sections.d.ts +1 -1
- package/dist/portfolio/server.cjs +1 -0
- package/dist/portfolio/server.cjs.map +1 -1
- package/dist/portfolio/server.d.cts +1 -1
- package/dist/portfolio/server.d.ts +1 -1
- package/dist/portfolio/server.js +1 -0
- package/dist/portfolio/server.js.map +1 -1
- package/dist/{types-BMUhBhWx.d.cts → types-DL4t_Cfa.d.cts} +3 -1
- package/dist/{types-BMUhBhWx.d.ts → types-DL4t_Cfa.d.ts} +3 -1
- package/package.json +1 -1
- package/dist/BeforeAfterSection-6QUJOBO2.js.map +0 -1
- package/dist/BeforeAfterSection-DVAWWE4K.cjs.map +0 -1
- package/dist/DetailsSection-FB763FS7.js.map +0 -1
- package/dist/DetailsSection-OACJFGH7.cjs.map +0 -1
- package/dist/StrategySection-3ED3QW4R.cjs.map +0 -1
- package/dist/StrategySection-VUWMIYYP.js.map +0 -1
- package/dist/TechStackSection-OCUYG4XT.js +0 -90
- package/dist/TechStackSection-OCUYG4XT.js.map +0 -1
- package/dist/TechStackSection-VKJK4KQB.cjs +0 -91
- package/dist/TechStackSection-VKJK4KQB.cjs.map +0 -1
- package/dist/chunk-2VNNFAG6.js +0 -415
- package/dist/chunk-2VNNFAG6.js.map +0 -1
- package/dist/chunk-5FKOLIV6.cjs.map +0 -1
- package/dist/chunk-NAS4K5UR.cjs.map +0 -1
- package/dist/chunk-QIC6JFFD.js.map +0 -1
- package/dist/chunk-TAPNXT7X.cjs +0 -422
- package/dist/chunk-TAPNXT7X.cjs.map +0 -1
- package/dist/chunk-XMC4DN6G.js.map +0 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { GlassCard } from './chunk-YB4B3OMC.js';
|
|
2
|
+
import { ScrollReveal } from './chunk-7CFFAKDM.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var CATEGORIES = [
|
|
6
|
+
{ key: "performance", label: "Performance", why: "Faster sites convert better \u2014 every 100ms of improvement increases conversions by up to 8%." },
|
|
7
|
+
{ key: "seo", label: "SEO", why: "Higher SEO scores mean better search rankings, more organic traffic, and lower customer acquisition costs." },
|
|
8
|
+
{ key: "accessibility", label: "Accessibility", why: "Accessible sites reach 15-20% more users and reduce legal liability." },
|
|
9
|
+
{ key: "bestPractices", label: "Best Practices", why: "Modern security headers, HTTPS, and optimized assets build trust and protect users." }
|
|
10
|
+
];
|
|
11
|
+
function getScoreColor(score) {
|
|
12
|
+
if (score >= 90) return "#10b981";
|
|
13
|
+
if (score >= 50) return "#f59e0b";
|
|
14
|
+
return "#ef4444";
|
|
15
|
+
}
|
|
16
|
+
function ScoreRing({ score, size = 72 }) {
|
|
17
|
+
const strokeWidth = 5;
|
|
18
|
+
const radius = (size - strokeWidth) / 2;
|
|
19
|
+
const circumference = 2 * Math.PI * radius;
|
|
20
|
+
const progress = score / 100 * circumference;
|
|
21
|
+
const color = getScoreColor(score);
|
|
22
|
+
return /* @__PURE__ */ jsxs("div", { className: "relative", style: { width: size, height: size }, children: [
|
|
23
|
+
/* @__PURE__ */ jsxs("svg", { width: size, height: size, className: "transform -rotate-90", children: [
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
"circle",
|
|
26
|
+
{
|
|
27
|
+
cx: size / 2,
|
|
28
|
+
cy: size / 2,
|
|
29
|
+
r: radius,
|
|
30
|
+
fill: "none",
|
|
31
|
+
stroke: "currentColor",
|
|
32
|
+
strokeWidth,
|
|
33
|
+
style: { color: "color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)" }
|
|
34
|
+
}
|
|
35
|
+
),
|
|
36
|
+
/* @__PURE__ */ jsx(
|
|
37
|
+
"circle",
|
|
38
|
+
{
|
|
39
|
+
cx: size / 2,
|
|
40
|
+
cy: size / 2,
|
|
41
|
+
r: radius,
|
|
42
|
+
fill: "none",
|
|
43
|
+
stroke: color,
|
|
44
|
+
strokeWidth,
|
|
45
|
+
strokeDasharray: `${progress} ${circumference - progress}`,
|
|
46
|
+
strokeLinecap: "round"
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsx(
|
|
51
|
+
"span",
|
|
52
|
+
{
|
|
53
|
+
className: "absolute inset-0 flex items-center justify-center text-lg font-bold",
|
|
54
|
+
style: { color },
|
|
55
|
+
children: score
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
] });
|
|
59
|
+
}
|
|
60
|
+
function SpeedComparisonSection({ data }) {
|
|
61
|
+
const { platformLabel, benchmarks, actual } = data;
|
|
62
|
+
return /* @__PURE__ */ jsx(
|
|
63
|
+
"section",
|
|
64
|
+
{
|
|
65
|
+
className: "w-full py-20 md:py-28",
|
|
66
|
+
style: { background: "var(--sk-bg, #0a0a0a)" },
|
|
67
|
+
children: /* @__PURE__ */ jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
|
|
68
|
+
/* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
"h2",
|
|
71
|
+
{
|
|
72
|
+
className: "text-3xl md:text-4xl font-bold mb-4",
|
|
73
|
+
style: {
|
|
74
|
+
color: "var(--sk-text-primary, #ffffff)",
|
|
75
|
+
fontFamily: "var(--sk-font-heading, inherit)"
|
|
76
|
+
},
|
|
77
|
+
children: "Why This Matters"
|
|
78
|
+
}
|
|
79
|
+
),
|
|
80
|
+
/* @__PURE__ */ jsx(
|
|
81
|
+
"p",
|
|
82
|
+
{
|
|
83
|
+
className: "text-lg mb-4 max-w-3xl",
|
|
84
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
85
|
+
children: "Lighthouse measures real-world site quality across performance, SEO, accessibility, and best practices. These scores directly impact search rankings, conversion rates, and user experience."
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
/* @__PURE__ */ jsxs(
|
|
89
|
+
"p",
|
|
90
|
+
{
|
|
91
|
+
className: "text-base mb-12 max-w-3xl",
|
|
92
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
93
|
+
children: [
|
|
94
|
+
"Here's how this Next.js build compares to the average ",
|
|
95
|
+
platformLabel,
|
|
96
|
+
" site."
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
] }),
|
|
101
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: CATEGORIES.map((cat, ci) => {
|
|
102
|
+
const ours = actual[cat.key];
|
|
103
|
+
const theirs = benchmarks[cat.key];
|
|
104
|
+
const diff = ours - theirs;
|
|
105
|
+
return /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: ci * 0.1, children: /* @__PURE__ */ jsx(GlassCard, { padding: "lg", hover: false, className: "h-full", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-5", children: [
|
|
106
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 shrink-0", children: [
|
|
107
|
+
/* @__PURE__ */ jsx(ScoreRing, { score: ours }),
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
"span",
|
|
110
|
+
{
|
|
111
|
+
className: "text-[10px] font-medium uppercase tracking-wider",
|
|
112
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
113
|
+
children: "Next.js"
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
] }),
|
|
117
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 shrink-0", children: [
|
|
118
|
+
/* @__PURE__ */ jsx(ScoreRing, { score: theirs }),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"span",
|
|
121
|
+
{
|
|
122
|
+
className: "text-[10px] font-medium uppercase tracking-wider",
|
|
123
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
124
|
+
children: platformLabel
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
] }),
|
|
128
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
129
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
"h3",
|
|
132
|
+
{
|
|
133
|
+
className: "text-base font-semibold",
|
|
134
|
+
style: { color: "var(--sk-text-primary, #ffffff)" },
|
|
135
|
+
children: cat.label
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
diff > 0 && /* @__PURE__ */ jsxs(
|
|
139
|
+
"span",
|
|
140
|
+
{
|
|
141
|
+
className: "text-xs font-bold px-2 py-0.5 rounded-full",
|
|
142
|
+
style: {
|
|
143
|
+
background: "color-mix(in srgb, #10b981 15%, transparent)",
|
|
144
|
+
color: "#10b981"
|
|
145
|
+
},
|
|
146
|
+
children: [
|
|
147
|
+
"+",
|
|
148
|
+
diff,
|
|
149
|
+
" pts"
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
] }),
|
|
154
|
+
/* @__PURE__ */ jsx(
|
|
155
|
+
"p",
|
|
156
|
+
{
|
|
157
|
+
className: "text-sm leading-relaxed",
|
|
158
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
159
|
+
children: cat.why
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
] })
|
|
163
|
+
] }) }) }, cat.key);
|
|
164
|
+
}) })
|
|
165
|
+
] })
|
|
166
|
+
}
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export { SpeedComparisonSection as default };
|
|
171
|
+
//# sourceMappingURL=SpeedComparisonSection-Y3K7OFZQ.js.map
|
|
172
|
+
//# sourceMappingURL=SpeedComparisonSection-Y3K7OFZQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portfolio/components/sections/SpeedComparisonSection.tsx"],"names":[],"mappings":"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","file":"SpeedComparisonSection-Y3K7OFZQ.js","sourcesContent":["'use client';\n\nimport React from 'react';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface Scores {\n performance: number;\n seo: number;\n accessibility: number;\n bestPractices: number;\n}\n\nexport interface SpeedComparisonData {\n platform: string;\n platformLabel: string;\n benchmarks: Scores;\n actual: Scores;\n}\n\ninterface SpeedComparisonSectionProps {\n data: SpeedComparisonData;\n}\n\nconst CATEGORIES: Array<{ key: keyof Scores; label: string; why: string }> = [\n { key: 'performance', label: 'Performance', why: 'Faster sites convert better — every 100ms of improvement increases conversions by up to 8%.' },\n { key: 'seo', label: 'SEO', why: 'Higher SEO scores mean better search rankings, more organic traffic, and lower customer acquisition costs.' },\n { key: 'accessibility', label: 'Accessibility', why: 'Accessible sites reach 15-20% more users and reduce legal liability.' },\n { key: 'bestPractices', label: 'Best Practices', why: 'Modern security headers, HTTPS, and optimized assets build trust and protect users.' },\n];\n\nfunction getScoreColor(score: number): string {\n if (score >= 90) return '#10b981';\n if (score >= 50) return '#f59e0b';\n return '#ef4444';\n}\n\n/** Circular score gauge */\nfunction ScoreRing({ score, size = 72 }: { score: number; size?: number }) {\n const strokeWidth = 5;\n const radius = (size - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const progress = (score / 100) * circumference;\n const color = getScoreColor(score);\n\n return (\n <div className=\"relative\" style={{ width: size, height: size }}>\n <svg width={size} height={size} className=\"transform -rotate-90\">\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n style={{ color: 'color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)' }}\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n fill=\"none\"\n stroke={color}\n strokeWidth={strokeWidth}\n strokeDasharray={`${progress} ${circumference - progress}`}\n strokeLinecap=\"round\"\n />\n </svg>\n <span\n className=\"absolute inset-0 flex items-center justify-center text-lg font-bold\"\n style={{ color }}\n >\n {score}\n </span>\n </div>\n );\n}\n\nexport default function SpeedComparisonSection({ data }: SpeedComparisonSectionProps) {\n const { platformLabel, benchmarks, actual } = data;\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Why This Matters\n </h2>\n <p\n className=\"text-lg mb-4 max-w-3xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n Lighthouse measures real-world site quality across performance, SEO, accessibility, and best practices.\n These scores directly impact search rankings, conversion rates, and user experience.\n </p>\n <p\n className=\"text-base mb-12 max-w-3xl\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Here's how this Next.js build compares to the average {platformLabel} site.\n </p>\n </ScrollReveal>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n {CATEGORIES.map((cat, ci) => {\n const ours = actual[cat.key];\n const theirs = benchmarks[cat.key];\n const diff = ours - theirs;\n\n return (\n <ScrollReveal key={cat.key} y={20} delay={ci * 0.1}>\n <GlassCard padding=\"lg\" hover={false} className=\"h-full\">\n <div className=\"flex items-start gap-5\">\n {/* Score rings side by side */}\n <div className=\"flex flex-col items-center gap-3 shrink-0\">\n <ScoreRing score={ours} />\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Next.js\n </span>\n </div>\n <div className=\"flex flex-col items-center gap-3 shrink-0\">\n <ScoreRing score={theirs} />\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {platformLabel}\n </span>\n </div>\n\n {/* Details */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-2\">\n <h3\n className=\"text-base font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {cat.label}\n </h3>\n {diff > 0 && (\n <span\n className=\"text-xs font-bold px-2 py-0.5 rounded-full\"\n style={{\n background: 'color-mix(in srgb, #10b981 15%, transparent)',\n color: '#10b981',\n }}\n >\n +{diff} pts\n </span>\n )}\n </div>\n <p\n className=\"text-sm leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {cat.why}\n </p>\n </div>\n </div>\n </GlassCard>\n </ScrollReveal>\n );\n })}\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -19,15 +19,11 @@ function StrategySection({ data }) {
|
|
|
19
19
|
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
20
20
|
if (prefersReducedMotion) return;
|
|
21
21
|
const ctx = gsap__default.default.context(() => {
|
|
22
|
-
const line = timelineRef.current
|
|
22
|
+
const line = timelineRef.current;
|
|
23
23
|
if (line) {
|
|
24
|
-
|
|
25
|
-
gsap__default.default.set(line, {
|
|
26
|
-
strokeDasharray: length,
|
|
27
|
-
strokeDashoffset: length
|
|
28
|
-
});
|
|
24
|
+
gsap__default.default.set(line, { scaleY: 0, transformOrigin: "top center" });
|
|
29
25
|
gsap__default.default.to(line, {
|
|
30
|
-
|
|
26
|
+
scaleY: 1,
|
|
31
27
|
ease: "none",
|
|
32
28
|
scrollTrigger: {
|
|
33
29
|
trigger: sectionRef.current,
|
|
@@ -69,30 +65,28 @@ function StrategySection({ data }) {
|
|
|
69
65
|
] }),
|
|
70
66
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: sectionRef, className: "relative", children: [
|
|
71
67
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
72
|
-
"
|
|
68
|
+
"div",
|
|
73
69
|
{
|
|
74
70
|
ref: timelineRef,
|
|
75
|
-
className: "absolute
|
|
76
|
-
|
|
77
|
-
height: "100%",
|
|
78
|
-
style: { overflow: "visible" },
|
|
71
|
+
className: "absolute top-0 bottom-0 hidden md:block pointer-events-none w-12 md:w-16",
|
|
72
|
+
style: { left: 0 },
|
|
79
73
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
80
|
-
"
|
|
74
|
+
"div",
|
|
81
75
|
{
|
|
82
|
-
className: "
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
className: "absolute top-0 bottom-0",
|
|
77
|
+
style: {
|
|
78
|
+
left: "50%",
|
|
79
|
+
transform: "translateX(-50%)",
|
|
80
|
+
width: "2px",
|
|
81
|
+
background: "var(--sk-primary, #6366f1)",
|
|
82
|
+
opacity: 0.3
|
|
83
|
+
}
|
|
90
84
|
}
|
|
91
85
|
)
|
|
92
86
|
}
|
|
93
87
|
),
|
|
94
88
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-12", children: data.phases.map((phase, index) => /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 40, delay: index * 0.15, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-6 md:gap-8", children: [
|
|
95
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center shrink-0 w-12 md:w-16", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
96
90
|
"div",
|
|
97
91
|
{
|
|
98
92
|
className: "flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full text-lg md:text-xl font-bold z-10",
|
|
@@ -176,5 +170,5 @@ function StrategySection({ data }) {
|
|
|
176
170
|
}
|
|
177
171
|
|
|
178
172
|
module.exports = StrategySection;
|
|
179
|
-
//# sourceMappingURL=StrategySection-
|
|
180
|
-
//# sourceMappingURL=StrategySection-
|
|
173
|
+
//# sourceMappingURL=StrategySection-CJ7Y6OFQ.cjs.map
|
|
174
|
+
//# sourceMappingURL=StrategySection-CJ7Y6OFQ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portfolio/components/sections/StrategySection.tsx"],"names":["useRef","useEffect","gsap","ScrollTrigger","jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"StrategySection-CJ7Y6OFQ.cjs","sourcesContent":["'use client';\n\nimport React, { useRef, useEffect } from 'react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport type { PortfolioStrategyData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface StrategySectionProps {\n data: PortfolioStrategyData;\n}\n\nexport default function StrategySection({ data }: StrategySectionProps) {\n const timelineRef = useRef<HTMLDivElement>(null);\n const sectionRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n gsap.registerPlugin(ScrollTrigger);\n\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n const ctx = gsap.context(() => {\n // Animate the vertical timeline line drawing in via scaleY\n const line = timelineRef.current;\n if (line) {\n gsap.set(line, { scaleY: 0, transformOrigin: 'top center' });\n gsap.to(line, {\n scaleY: 1,\n ease: 'none',\n scrollTrigger: {\n trigger: sectionRef.current,\n start: 'top 60%',\n end: 'bottom 40%',\n scrub: 1,\n },\n });\n }\n });\n\n return () => ctx.revert();\n }, [data.phases.length]);\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Our Strategy\n </h2>\n <p\n className=\"text-lg mb-16 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n A phased approach to delivering measurable results.\n </p>\n </ScrollReveal>\n\n <div ref={sectionRef} className=\"relative\">\n {/* Vertical timeline line — uses the circle column width to find center */}\n <div\n ref={timelineRef}\n className=\"absolute top-0 bottom-0 hidden md:block pointer-events-none w-12 md:w-16\"\n style={{ left: 0 }}\n >\n <div\n className=\"absolute top-0 bottom-0\"\n style={{\n left: '50%',\n transform: 'translateX(-50%)',\n width: '2px',\n background: 'var(--sk-primary, #6366f1)',\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"flex flex-col gap-12\">\n {data.phases.map((phase, index) => (\n <ScrollReveal key={index} y={40} delay={index * 0.15}>\n <div className=\"flex gap-6 md:gap-8\">\n {/* Number circle — fixed-width column so line can center on it */}\n <div className=\"flex flex-col items-center shrink-0 w-12 md:w-16\">\n <div\n className=\"flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full text-lg md:text-xl font-bold z-10\"\n style={{\n background: 'var(--sk-bg, #0a0a0a)',\n border: '3px solid var(--sk-primary, #6366f1)',\n color: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 0 20px color-mix(in srgb, var(--sk-primary, #6366f1) 30%, transparent)',\n }}\n >\n {phase.number}\n </div>\n </div>\n\n {/* Phase content */}\n <GlassCard padding=\"lg\" hover={false} className=\"flex-1\">\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <h3\n className=\"text-xl font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {phase.title}\n </h3>\n {phase.timeline && (\n <span\n className=\"px-3 py-0.5 rounded-full text-xs font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 12%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n }}\n >\n {phase.timeline}\n </span>\n )}\n </div>\n\n <p\n className=\"text-base leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {phase.description}\n </p>\n\n {/* Deliverables */}\n {phase.deliverables && phase.deliverables.length > 0 && (\n <ul className=\"flex flex-col gap-2 mt-2\">\n {phase.deliverables.map((deliverable, di) => (\n <li key={di} className=\"flex items-start gap-2\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n className=\"shrink-0 mt-0.5\"\n style={{ color: '#10b981' }}\n >\n <path\n d=\"M15 4.5L6.75 12.75 3 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span\n className=\"text-sm\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {deliverable}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -14,15 +14,11 @@ function StrategySection({ data }) {
|
|
|
14
14
|
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
15
15
|
if (prefersReducedMotion) return;
|
|
16
16
|
const ctx = gsap.context(() => {
|
|
17
|
-
const line = timelineRef.current
|
|
17
|
+
const line = timelineRef.current;
|
|
18
18
|
if (line) {
|
|
19
|
-
|
|
20
|
-
gsap.set(line, {
|
|
21
|
-
strokeDasharray: length,
|
|
22
|
-
strokeDashoffset: length
|
|
23
|
-
});
|
|
19
|
+
gsap.set(line, { scaleY: 0, transformOrigin: "top center" });
|
|
24
20
|
gsap.to(line, {
|
|
25
|
-
|
|
21
|
+
scaleY: 1,
|
|
26
22
|
ease: "none",
|
|
27
23
|
scrollTrigger: {
|
|
28
24
|
trigger: sectionRef.current,
|
|
@@ -64,30 +60,28 @@ function StrategySection({ data }) {
|
|
|
64
60
|
] }),
|
|
65
61
|
/* @__PURE__ */ jsxs("div", { ref: sectionRef, className: "relative", children: [
|
|
66
62
|
/* @__PURE__ */ jsx(
|
|
67
|
-
"
|
|
63
|
+
"div",
|
|
68
64
|
{
|
|
69
65
|
ref: timelineRef,
|
|
70
|
-
className: "absolute
|
|
71
|
-
|
|
72
|
-
height: "100%",
|
|
73
|
-
style: { overflow: "visible" },
|
|
66
|
+
className: "absolute top-0 bottom-0 hidden md:block pointer-events-none w-12 md:w-16",
|
|
67
|
+
style: { left: 0 },
|
|
74
68
|
children: /* @__PURE__ */ jsx(
|
|
75
|
-
"
|
|
69
|
+
"div",
|
|
76
70
|
{
|
|
77
|
-
className: "
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
className: "absolute top-0 bottom-0",
|
|
72
|
+
style: {
|
|
73
|
+
left: "50%",
|
|
74
|
+
transform: "translateX(-50%)",
|
|
75
|
+
width: "2px",
|
|
76
|
+
background: "var(--sk-primary, #6366f1)",
|
|
77
|
+
opacity: 0.3
|
|
78
|
+
}
|
|
85
79
|
}
|
|
86
80
|
)
|
|
87
81
|
}
|
|
88
82
|
),
|
|
89
83
|
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-12", children: data.phases.map((phase, index) => /* @__PURE__ */ jsx(ScrollReveal, { y: 40, delay: index * 0.15, children: /* @__PURE__ */ jsxs("div", { className: "flex gap-6 md:gap-8", children: [
|
|
90
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-col items-center shrink-0", children: /* @__PURE__ */ jsx(
|
|
84
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col items-center shrink-0 w-12 md:w-16", children: /* @__PURE__ */ jsx(
|
|
91
85
|
"div",
|
|
92
86
|
{
|
|
93
87
|
className: "flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full text-lg md:text-xl font-bold z-10",
|
|
@@ -171,5 +165,5 @@ function StrategySection({ data }) {
|
|
|
171
165
|
}
|
|
172
166
|
|
|
173
167
|
export { StrategySection as default };
|
|
174
|
-
//# sourceMappingURL=StrategySection-
|
|
175
|
-
//# sourceMappingURL=StrategySection-
|
|
168
|
+
//# sourceMappingURL=StrategySection-DI5RSCJU.js.map
|
|
169
|
+
//# sourceMappingURL=StrategySection-DI5RSCJU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portfolio/components/sections/StrategySection.tsx"],"names":[],"mappings":"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","file":"StrategySection-DI5RSCJU.js","sourcesContent":["'use client';\n\nimport React, { useRef, useEffect } from 'react';\nimport gsap from 'gsap';\nimport { ScrollTrigger } from 'gsap/ScrollTrigger';\nimport type { PortfolioStrategyData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface StrategySectionProps {\n data: PortfolioStrategyData;\n}\n\nexport default function StrategySection({ data }: StrategySectionProps) {\n const timelineRef = useRef<HTMLDivElement>(null);\n const sectionRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n gsap.registerPlugin(ScrollTrigger);\n\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion) return;\n\n const ctx = gsap.context(() => {\n // Animate the vertical timeline line drawing in via scaleY\n const line = timelineRef.current;\n if (line) {\n gsap.set(line, { scaleY: 0, transformOrigin: 'top center' });\n gsap.to(line, {\n scaleY: 1,\n ease: 'none',\n scrollTrigger: {\n trigger: sectionRef.current,\n start: 'top 60%',\n end: 'bottom 40%',\n scrub: 1,\n },\n });\n }\n });\n\n return () => ctx.revert();\n }, [data.phases.length]);\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Our Strategy\n </h2>\n <p\n className=\"text-lg mb-16 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n A phased approach to delivering measurable results.\n </p>\n </ScrollReveal>\n\n <div ref={sectionRef} className=\"relative\">\n {/* Vertical timeline line — uses the circle column width to find center */}\n <div\n ref={timelineRef}\n className=\"absolute top-0 bottom-0 hidden md:block pointer-events-none w-12 md:w-16\"\n style={{ left: 0 }}\n >\n <div\n className=\"absolute top-0 bottom-0\"\n style={{\n left: '50%',\n transform: 'translateX(-50%)',\n width: '2px',\n background: 'var(--sk-primary, #6366f1)',\n opacity: 0.3,\n }}\n />\n </div>\n\n <div className=\"flex flex-col gap-12\">\n {data.phases.map((phase, index) => (\n <ScrollReveal key={index} y={40} delay={index * 0.15}>\n <div className=\"flex gap-6 md:gap-8\">\n {/* Number circle — fixed-width column so line can center on it */}\n <div className=\"flex flex-col items-center shrink-0 w-12 md:w-16\">\n <div\n className=\"flex items-center justify-center w-12 h-12 md:w-16 md:h-16 rounded-full text-lg md:text-xl font-bold z-10\"\n style={{\n background: 'var(--sk-bg, #0a0a0a)',\n border: '3px solid var(--sk-primary, #6366f1)',\n color: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 0 20px color-mix(in srgb, var(--sk-primary, #6366f1) 30%, transparent)',\n }}\n >\n {phase.number}\n </div>\n </div>\n\n {/* Phase content */}\n <GlassCard padding=\"lg\" hover={false} className=\"flex-1\">\n <div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center gap-3 flex-wrap\">\n <h3\n className=\"text-xl font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {phase.title}\n </h3>\n {phase.timeline && (\n <span\n className=\"px-3 py-0.5 rounded-full text-xs font-medium\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 12%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '1px solid color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n }}\n >\n {phase.timeline}\n </span>\n )}\n </div>\n\n <p\n className=\"text-base leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {phase.description}\n </p>\n\n {/* Deliverables */}\n {phase.deliverables && phase.deliverables.length > 0 && (\n <ul className=\"flex flex-col gap-2 mt-2\">\n {phase.deliverables.map((deliverable, di) => (\n <li key={di} className=\"flex items-start gap-2\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n className=\"shrink-0 mt-0.5\"\n style={{ color: '#10b981' }}\n >\n <path\n d=\"M15 4.5L6.75 12.75 3 9\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span\n className=\"text-sm\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {deliverable}\n </span>\n </li>\n ))}\n </ul>\n )}\n </div>\n </GlassCard>\n </div>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { GlassCard } from './chunk-YB4B3OMC.js';
|
|
2
|
+
import { ScrollReveal } from './chunk-7CFFAKDM.js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
function TechStackSection({ data }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
"section",
|
|
8
|
+
{
|
|
9
|
+
className: "w-full py-20 md:py-28",
|
|
10
|
+
style: { background: "var(--sk-bg, #0a0a0a)" },
|
|
11
|
+
children: /* @__PURE__ */ jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
|
|
12
|
+
/* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
|
|
13
|
+
/* @__PURE__ */ jsx(
|
|
14
|
+
"h2",
|
|
15
|
+
{
|
|
16
|
+
className: "text-3xl md:text-4xl font-bold mb-4",
|
|
17
|
+
style: {
|
|
18
|
+
color: "var(--sk-text-primary, #ffffff)",
|
|
19
|
+
fontFamily: "var(--sk-font-heading, inherit)"
|
|
20
|
+
},
|
|
21
|
+
children: "Tech Stack"
|
|
22
|
+
}
|
|
23
|
+
),
|
|
24
|
+
/* @__PURE__ */ jsx(
|
|
25
|
+
"p",
|
|
26
|
+
{
|
|
27
|
+
className: "text-lg mb-12 max-w-2xl",
|
|
28
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
29
|
+
children: "The technologies and tools powering this project."
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
] }),
|
|
33
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-4", children: data.technologies.map((tech, ti) => /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: ti * 0.05, children: /* @__PURE__ */ jsxs(GlassCard, { padding: "md", hover: true, className: "flex items-start gap-3 h-full", children: [
|
|
34
|
+
tech.icon ? /* @__PURE__ */ jsx(
|
|
35
|
+
"img",
|
|
36
|
+
{
|
|
37
|
+
src: tech.icon,
|
|
38
|
+
alt: tech.name,
|
|
39
|
+
width: 28,
|
|
40
|
+
height: 28,
|
|
41
|
+
className: "w-7 h-7 object-contain shrink-0 mt-0.5"
|
|
42
|
+
}
|
|
43
|
+
) : /* @__PURE__ */ jsx(
|
|
44
|
+
"div",
|
|
45
|
+
{
|
|
46
|
+
className: "w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5",
|
|
47
|
+
style: {
|
|
48
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
|
|
49
|
+
color: "var(--sk-primary, #6366f1)"
|
|
50
|
+
},
|
|
51
|
+
children: tech.name.charAt(0)
|
|
52
|
+
}
|
|
53
|
+
),
|
|
54
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
55
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-0.5", children: [
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
"span",
|
|
58
|
+
{
|
|
59
|
+
className: "text-sm font-semibold",
|
|
60
|
+
style: { color: "var(--sk-text-primary, #ffffff)" },
|
|
61
|
+
children: tech.name
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
/* @__PURE__ */ jsx(
|
|
65
|
+
"span",
|
|
66
|
+
{
|
|
67
|
+
className: "text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded",
|
|
68
|
+
style: {
|
|
69
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)",
|
|
70
|
+
color: "var(--sk-primary, #6366f1)"
|
|
71
|
+
},
|
|
72
|
+
children: tech.category
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
] }),
|
|
76
|
+
tech.description && /* @__PURE__ */ jsx(
|
|
77
|
+
"p",
|
|
78
|
+
{
|
|
79
|
+
className: "text-xs leading-relaxed",
|
|
80
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
81
|
+
children: tech.description
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
] })
|
|
85
|
+
] }) }, ti)) })
|
|
86
|
+
] })
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { TechStackSection as default };
|
|
92
|
+
//# sourceMappingURL=TechStackSection-2AQ7RGY3.js.map
|
|
93
|
+
//# sourceMappingURL=TechStackSection-2AQ7RGY3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portfolio/components/sections/TechStackSection.tsx"],"names":[],"mappings":"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","file":"TechStackSection-2AQ7RGY3.js","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { PortfolioTechStackData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface TechStackSectionProps {\n data: PortfolioTechStackData;\n}\n\nexport default function TechStackSection({ data }: TechStackSectionProps) {\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Tech Stack\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The technologies and tools powering this project.\n </p>\n </ScrollReveal>\n\n {/* All technologies in a 2-3 column grid — never single column */}\n <div className=\"grid grid-cols-2 lg:grid-cols-3 gap-4\">\n {data.technologies.map((tech, ti) => (\n <ScrollReveal key={ti} y={20} delay={ti * 0.05}>\n <GlassCard padding=\"md\" hover className=\"flex items-start gap-3 h-full\">\n {tech.icon ? (\n <img\n src={tech.icon}\n alt={tech.name}\n width={28}\n height={28}\n className=\"w-7 h-7 object-contain shrink-0 mt-0.5\"\n />\n ) : (\n <div\n className=\"w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.name.charAt(0)}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span\n className=\"text-sm font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.category}\n </span>\n </div>\n {tech.description && (\n <p\n className=\"text-xs leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {tech.description}\n </p>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkKEOHORIH_cjs = require('./chunk-KEOHORIH.cjs');
|
|
4
|
+
var chunkIKBK7HYX_cjs = require('./chunk-IKBK7HYX.cjs');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
function TechStackSection({ data }) {
|
|
8
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9
|
+
"section",
|
|
10
|
+
{
|
|
11
|
+
className: "w-full py-20 md:py-28",
|
|
12
|
+
style: { background: "var(--sk-bg, #0a0a0a)" },
|
|
13
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
|
|
14
|
+
/* @__PURE__ */ jsxRuntime.jsxs(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: [
|
|
15
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
16
|
+
"h2",
|
|
17
|
+
{
|
|
18
|
+
className: "text-3xl md:text-4xl font-bold mb-4",
|
|
19
|
+
style: {
|
|
20
|
+
color: "var(--sk-text-primary, #ffffff)",
|
|
21
|
+
fontFamily: "var(--sk-font-heading, inherit)"
|
|
22
|
+
},
|
|
23
|
+
children: "Tech Stack"
|
|
24
|
+
}
|
|
25
|
+
),
|
|
26
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
27
|
+
"p",
|
|
28
|
+
{
|
|
29
|
+
className: "text-lg mb-12 max-w-2xl",
|
|
30
|
+
style: { color: "var(--sk-text-secondary, #a1a1aa)" },
|
|
31
|
+
children: "The technologies and tools powering this project."
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
] }),
|
|
35
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-4", children: data.technologies.map((tech, ti) => /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, delay: ti * 0.05, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkKEOHORIH_cjs.GlassCard, { padding: "md", hover: true, className: "flex items-start gap-3 h-full", children: [
|
|
36
|
+
tech.icon ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
37
|
+
"img",
|
|
38
|
+
{
|
|
39
|
+
src: tech.icon,
|
|
40
|
+
alt: tech.name,
|
|
41
|
+
width: 28,
|
|
42
|
+
height: 28,
|
|
43
|
+
className: "w-7 h-7 object-contain shrink-0 mt-0.5"
|
|
44
|
+
}
|
|
45
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
className: "w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5",
|
|
49
|
+
style: {
|
|
50
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)",
|
|
51
|
+
color: "var(--sk-primary, #6366f1)"
|
|
52
|
+
},
|
|
53
|
+
children: tech.name.charAt(0)
|
|
54
|
+
}
|
|
55
|
+
),
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mb-0.5", children: [
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
59
|
+
"span",
|
|
60
|
+
{
|
|
61
|
+
className: "text-sm font-semibold",
|
|
62
|
+
style: { color: "var(--sk-text-primary, #ffffff)" },
|
|
63
|
+
children: tech.name
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
+
"span",
|
|
68
|
+
{
|
|
69
|
+
className: "text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded",
|
|
70
|
+
style: {
|
|
71
|
+
background: "color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)",
|
|
72
|
+
color: "var(--sk-primary, #6366f1)"
|
|
73
|
+
},
|
|
74
|
+
children: tech.category
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
] }),
|
|
78
|
+
tech.description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
79
|
+
"p",
|
|
80
|
+
{
|
|
81
|
+
className: "text-xs leading-relaxed",
|
|
82
|
+
style: { color: "var(--sk-text-tertiary, #71717a)" },
|
|
83
|
+
children: tech.description
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
] })
|
|
87
|
+
] }) }, ti)) })
|
|
88
|
+
] })
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = TechStackSection;
|
|
94
|
+
//# sourceMappingURL=TechStackSection-VTNNZR5V.cjs.map
|
|
95
|
+
//# sourceMappingURL=TechStackSection-VTNNZR5V.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/portfolio/components/sections/TechStackSection.tsx"],"names":["jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"TechStackSection-VTNNZR5V.cjs","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { PortfolioTechStackData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface TechStackSectionProps {\n data: PortfolioTechStackData;\n}\n\nexport default function TechStackSection({ data }: TechStackSectionProps) {\n\n return (\n <section\n className=\"w-full py-20 md:py-28\"\n style={{ background: 'var(--sk-bg, #0a0a0a)' }}\n >\n <div className=\"max-w-5xl mx-auto px-6\">\n <ScrollReveal y={30}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-4\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Tech Stack\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The technologies and tools powering this project.\n </p>\n </ScrollReveal>\n\n {/* All technologies in a 2-3 column grid — never single column */}\n <div className=\"grid grid-cols-2 lg:grid-cols-3 gap-4\">\n {data.technologies.map((tech, ti) => (\n <ScrollReveal key={ti} y={20} delay={ti * 0.05}>\n <GlassCard padding=\"md\" hover className=\"flex items-start gap-3 h-full\">\n {tech.icon ? (\n <img\n src={tech.icon}\n alt={tech.name}\n width={28}\n height={28}\n className=\"w-7 h-7 object-contain shrink-0 mt-0.5\"\n />\n ) : (\n <div\n className=\"w-7 h-7 rounded-md flex items-center justify-center text-xs font-bold shrink-0 mt-0.5\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 15%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.name.charAt(0)}\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2 mb-0.5\">\n <span\n className=\"text-sm font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider px-1.5 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 10%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {tech.category}\n </span>\n </div>\n {tech.description && (\n <p\n className=\"text-xs leading-relaxed\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {tech.description}\n </p>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"]}
|