@sonordev/agency-site-kit 0.1.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.
Files changed (131) hide show
  1. package/dist/BeforeAfterSection-6QUJOBO2.js +176 -0
  2. package/dist/BeforeAfterSection-6QUJOBO2.js.map +1 -0
  3. package/dist/BeforeAfterSection-DVAWWE4K.cjs +181 -0
  4. package/dist/BeforeAfterSection-DVAWWE4K.cjs.map +1 -0
  5. package/dist/CTASection-4JKLXEUF.cjs +111 -0
  6. package/dist/CTASection-4JKLXEUF.cjs.map +1 -0
  7. package/dist/CTASection-BJA72XIL.js +106 -0
  8. package/dist/CTASection-BJA72XIL.js.map +1 -0
  9. package/dist/ChallengesSection-GEQGVSJN.js +180 -0
  10. package/dist/ChallengesSection-GEQGVSJN.js.map +1 -0
  11. package/dist/ChallengesSection-IZ3DHECS.cjs +182 -0
  12. package/dist/ChallengesSection-IZ3DHECS.cjs.map +1 -0
  13. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs +209 -0
  14. package/dist/ConversionFunnelSection-AUUSJ5HQ.cjs.map +1 -0
  15. package/dist/ConversionFunnelSection-D3GE4NKE.js +203 -0
  16. package/dist/ConversionFunnelSection-D3GE4NKE.js.map +1 -0
  17. package/dist/DetailsSection-FB763FS7.js +135 -0
  18. package/dist/DetailsSection-FB763FS7.js.map +1 -0
  19. package/dist/DetailsSection-OACJFGH7.cjs +137 -0
  20. package/dist/DetailsSection-OACJFGH7.cjs.map +1 -0
  21. package/dist/FeatureSpotlightSection-B7P3JGNL.js +205 -0
  22. package/dist/FeatureSpotlightSection-B7P3JGNL.js.map +1 -0
  23. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs +210 -0
  24. package/dist/FeatureSpotlightSection-WRHXS7TU.cjs.map +1 -0
  25. package/dist/GallerySection-VMKORC47.js +218 -0
  26. package/dist/GallerySection-VMKORC47.js.map +1 -0
  27. package/dist/GallerySection-WJ4PQDBI.cjs +219 -0
  28. package/dist/GallerySection-WJ4PQDBI.cjs.map +1 -0
  29. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs +258 -0
  30. package/dist/MetricsTimelineSection-4L6DUHJ5.cjs.map +1 -0
  31. package/dist/MetricsTimelineSection-6BT5GNFV.js +253 -0
  32. package/dist/MetricsTimelineSection-6BT5GNFV.js.map +1 -0
  33. package/dist/ResultsSection-DFUJ5U6M.js +93 -0
  34. package/dist/ResultsSection-DFUJ5U6M.js.map +1 -0
  35. package/dist/ResultsSection-XLGMMQKY.cjs +95 -0
  36. package/dist/ResultsSection-XLGMMQKY.cjs.map +1 -0
  37. package/dist/ServicesSection-D5V3Q4GR.js +118 -0
  38. package/dist/ServicesSection-D5V3Q4GR.js.map +1 -0
  39. package/dist/ServicesSection-WJMGK2MF.cjs +120 -0
  40. package/dist/ServicesSection-WJMGK2MF.cjs.map +1 -0
  41. package/dist/StrategySection-3ED3QW4R.cjs +180 -0
  42. package/dist/StrategySection-3ED3QW4R.cjs.map +1 -0
  43. package/dist/StrategySection-VUWMIYYP.js +175 -0
  44. package/dist/StrategySection-VUWMIYYP.js.map +1 -0
  45. package/dist/TeamSection-DZVSNZE6.cjs +112 -0
  46. package/dist/TeamSection-DZVSNZE6.cjs.map +1 -0
  47. package/dist/TeamSection-HGKFW6PQ.js +107 -0
  48. package/dist/TeamSection-HGKFW6PQ.js.map +1 -0
  49. package/dist/TechStackSection-OCUYG4XT.js +90 -0
  50. package/dist/TechStackSection-OCUYG4XT.js.map +1 -0
  51. package/dist/TechStackSection-VKJK4KQB.cjs +91 -0
  52. package/dist/TechStackSection-VKJK4KQB.cjs.map +1 -0
  53. package/dist/TestimonialSection-6RGSMXQB.js +122 -0
  54. package/dist/TestimonialSection-6RGSMXQB.js.map +1 -0
  55. package/dist/TestimonialSection-XPTFUQIN.cjs +124 -0
  56. package/dist/TestimonialSection-XPTFUQIN.cjs.map +1 -0
  57. package/dist/VideoSection-4A2HC6K6.js +117 -0
  58. package/dist/VideoSection-4A2HC6K6.js.map +1 -0
  59. package/dist/VideoSection-G3DFS7UH.cjs +118 -0
  60. package/dist/VideoSection-G3DFS7UH.cjs.map +1 -0
  61. package/dist/chunk-2VNNFAG6.js +415 -0
  62. package/dist/chunk-2VNNFAG6.js.map +1 -0
  63. package/dist/chunk-2Y4O3LWM.js +53 -0
  64. package/dist/chunk-2Y4O3LWM.js.map +1 -0
  65. package/dist/chunk-5FKOLIV6.cjs +221 -0
  66. package/dist/chunk-5FKOLIV6.cjs.map +1 -0
  67. package/dist/chunk-7CFFAKDM.js +74 -0
  68. package/dist/chunk-7CFFAKDM.js.map +1 -0
  69. package/dist/chunk-A4I4IK7V.js +69 -0
  70. package/dist/chunk-A4I4IK7V.js.map +1 -0
  71. package/dist/chunk-IKBK7HYX.cjs +79 -0
  72. package/dist/chunk-IKBK7HYX.cjs.map +1 -0
  73. package/dist/chunk-KEOHORIH.cjs +79 -0
  74. package/dist/chunk-KEOHORIH.cjs.map +1 -0
  75. package/dist/chunk-NAS4K5UR.cjs +139 -0
  76. package/dist/chunk-NAS4K5UR.cjs.map +1 -0
  77. package/dist/chunk-QBLWP25X.cjs +73 -0
  78. package/dist/chunk-QBLWP25X.cjs.map +1 -0
  79. package/dist/chunk-QIC6JFFD.js +210 -0
  80. package/dist/chunk-QIC6JFFD.js.map +1 -0
  81. package/dist/chunk-TAPNXT7X.cjs +422 -0
  82. package/dist/chunk-TAPNXT7X.cjs.map +1 -0
  83. package/dist/chunk-XCKXHK44.js +15 -0
  84. package/dist/chunk-XCKXHK44.js.map +1 -0
  85. package/dist/chunk-XMC4DN6G.js +131 -0
  86. package/dist/chunk-XMC4DN6G.js.map +1 -0
  87. package/dist/chunk-XONXEFJY.cjs +58 -0
  88. package/dist/chunk-XONXEFJY.cjs.map +1 -0
  89. package/dist/chunk-XQNJED46.cjs +19 -0
  90. package/dist/chunk-XQNJED46.cjs.map +1 -0
  91. package/dist/chunk-YB4B3OMC.js +74 -0
  92. package/dist/chunk-YB4B3OMC.js.map +1 -0
  93. package/dist/index.cjs +271 -0
  94. package/dist/index.cjs.map +1 -0
  95. package/dist/index.d.cts +137 -0
  96. package/dist/index.d.ts +137 -0
  97. package/dist/index.js +197 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/layout/index.cjs +13 -0
  100. package/dist/layout/index.cjs.map +1 -0
  101. package/dist/layout/index.d.cts +54 -0
  102. package/dist/layout/index.d.ts +54 -0
  103. package/dist/layout/index.js +4 -0
  104. package/dist/layout/index.js.map +1 -0
  105. package/dist/portfolio/client.cjs +18 -0
  106. package/dist/portfolio/client.cjs.map +1 -0
  107. package/dist/portfolio/client.d.cts +97 -0
  108. package/dist/portfolio/client.d.ts +97 -0
  109. package/dist/portfolio/client.js +6 -0
  110. package/dist/portfolio/client.js.map +1 -0
  111. package/dist/portfolio/index.cjs +41 -0
  112. package/dist/portfolio/index.cjs.map +1 -0
  113. package/dist/portfolio/index.d.cts +12 -0
  114. package/dist/portfolio/index.d.ts +12 -0
  115. package/dist/portfolio/index.js +8 -0
  116. package/dist/portfolio/index.js.map +1 -0
  117. package/dist/portfolio/sections.cjs +20 -0
  118. package/dist/portfolio/sections.cjs.map +1 -0
  119. package/dist/portfolio/sections.d.cts +42 -0
  120. package/dist/portfolio/sections.d.ts +42 -0
  121. package/dist/portfolio/sections.js +4 -0
  122. package/dist/portfolio/sections.js.map +1 -0
  123. package/dist/portfolio/server.cjs +141 -0
  124. package/dist/portfolio/server.cjs.map +1 -0
  125. package/dist/portfolio/server.d.cts +68 -0
  126. package/dist/portfolio/server.d.ts +68 -0
  127. package/dist/portfolio/server.js +134 -0
  128. package/dist/portfolio/server.js.map +1 -0
  129. package/dist/types-BMUhBhWx.d.cts +346 -0
  130. package/dist/types-BMUhBhWx.d.ts +346 -0
  131. package/package.json +71 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/TeamSection.tsx"],"names":[],"mappings":"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","file":"TeamSection-HGKFW6PQ.js","sourcesContent":["'use client';\n\nimport React, { useRef, useCallback } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioTeamData, PortfolioTeamMember } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface TeamSectionProps {\n data: PortfolioTeamData;\n}\n\nfunction TeamCard({ member }: { member: PortfolioTeamMember }) {\n const cardRef = useRef<HTMLDivElement>(null);\n\n const handleMouseEnter = useCallback(() => {\n if (!cardRef.current) return;\n const avatar = cardRef.current.querySelector('.team-avatar');\n if (avatar) {\n gsap.to(avatar, { scale: 1.08, duration: 0.3, ease: 'power2.out' });\n }\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n if (!cardRef.current) return;\n const avatar = cardRef.current.querySelector('.team-avatar');\n if (avatar) {\n gsap.to(avatar, { scale: 1, duration: 0.3, ease: 'power2.out' });\n }\n }, []);\n\n const avatarUrl = member.avatar?.asset?._ref;\n const initials = member.name\n .split(' ')\n .map((w: string) => w[0])\n .join('')\n .slice(0, 2)\n .toUpperCase();\n\n return (\n <div ref={cardRef} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>\n <GlassCard padding=\"md\" hover className=\"text-center\">\n <div className=\"flex flex-col items-center gap-4\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={member.name}\n className=\"team-avatar w-20 h-20 rounded-full object-cover\"\n style={{\n border: '3px solid var(--sk-border, rgba(255,255,255,0.1))',\n willChange: 'transform',\n }}\n />\n ) : (\n <div\n className=\"team-avatar flex items-center justify-center w-20 h-20 rounded-full text-xl font-bold\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n border: '3px solid color-mix(in srgb, var(--sk-primary, #6366f1) 25%, transparent)',\n willChange: 'transform',\n }}\n >\n {initials}\n </div>\n )}\n\n <div>\n <h3\n className=\"text-base font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {member.name}\n </h3>\n <p\n className=\"text-sm mt-1\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {member.role}\n </p>\n </div>\n </div>\n </GlassCard>\n </div>\n );\n}\n\nexport default function TeamSection({ data }: TeamSectionProps) {\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-7xl 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 The Team\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The people who brought this project to life.\n </p>\n </ScrollReveal>\n\n <ScrollReveal stagger={0.1}>\n <div className=\"grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6\">\n {data.members.map((member, index) => (\n <TeamCard key={index} member={member} />\n ))}\n </div>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+ import { GlassCard } from './chunk-YB4B3OMC.js';
3
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
4
+ import { useMemo } from 'react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function TechStackSection({ data }) {
8
+ const grouped = useMemo(() => {
9
+ const groups = {};
10
+ for (const tech of data.technologies) {
11
+ const cat = tech.category || "Other";
12
+ if (!groups[cat]) groups[cat] = [];
13
+ groups[cat].push(tech);
14
+ }
15
+ return Object.entries(groups);
16
+ }, [data.technologies]);
17
+ return /* @__PURE__ */ jsx(
18
+ "section",
19
+ {
20
+ className: "w-full py-20 md:py-28",
21
+ style: { background: "var(--sk-bg, #0a0a0a)" },
22
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-7xl mx-auto px-6", children: [
23
+ /* @__PURE__ */ jsxs(ScrollReveal, { y: 30, children: [
24
+ /* @__PURE__ */ jsx(
25
+ "h2",
26
+ {
27
+ className: "text-3xl md:text-4xl font-bold mb-4",
28
+ style: {
29
+ color: "var(--sk-text-primary, #ffffff)",
30
+ fontFamily: "var(--sk-font-heading, inherit)"
31
+ },
32
+ children: "Tech Stack"
33
+ }
34
+ ),
35
+ /* @__PURE__ */ jsx(
36
+ "p",
37
+ {
38
+ className: "text-lg mb-12 max-w-2xl",
39
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
40
+ children: "The technologies and tools powering this project."
41
+ }
42
+ )
43
+ ] }),
44
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-10", children: grouped.map(([category, techs], gi) => /* @__PURE__ */ jsx(ScrollReveal, { y: 30, delay: gi * 0.1, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
45
+ /* @__PURE__ */ jsx(
46
+ "h3",
47
+ {
48
+ className: "text-sm font-semibold uppercase tracking-wider",
49
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
50
+ children: category
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsx(ScrollReveal, { stagger: 0.06, children: /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-3", children: techs.map((tech, ti) => /* @__PURE__ */ jsxs(
54
+ GlassCard,
55
+ {
56
+ padding: "sm",
57
+ hover: true,
58
+ className: "inline-flex items-center gap-2",
59
+ children: [
60
+ tech.icon && /* @__PURE__ */ jsx(
61
+ "img",
62
+ {
63
+ src: tech.icon,
64
+ alt: tech.name,
65
+ width: 20,
66
+ height: 20,
67
+ className: "w-5 h-5 object-contain"
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsx(
71
+ "span",
72
+ {
73
+ className: "text-sm font-medium whitespace-nowrap",
74
+ style: { color: "var(--sk-text-primary, #ffffff)" },
75
+ children: tech.name
76
+ }
77
+ )
78
+ ]
79
+ },
80
+ ti
81
+ )) }) })
82
+ ] }) }, category)) })
83
+ ] })
84
+ }
85
+ );
86
+ }
87
+
88
+ export { TechStackSection as default };
89
+ //# sourceMappingURL=TechStackSection-OCUYG4XT.js.map
90
+ //# sourceMappingURL=TechStackSection-OCUYG4XT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/TechStackSection.tsx"],"names":[],"mappings":"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","file":"TechStackSection-OCUYG4XT.js","sourcesContent":["'use client';\n\nimport React, { useMemo } 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 // Group technologies by category\n const grouped = useMemo(() => {\n const groups: Record<string, typeof data.technologies> = {};\n for (const tech of data.technologies) {\n const cat = tech.category || 'Other';\n if (!groups[cat]) groups[cat] = [];\n groups[cat].push(tech);\n }\n return Object.entries(groups);\n }, [data.technologies]);\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-7xl 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 <div className=\"flex flex-col gap-10\">\n {grouped.map(([category, techs], gi) => (\n <ScrollReveal key={category} y={30} delay={gi * 0.1}>\n <div className=\"flex flex-col gap-4\">\n <h3\n className=\"text-sm font-semibold uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {category}\n </h3>\n <ScrollReveal stagger={0.06}>\n <div className=\"flex flex-wrap gap-3\">\n {techs.map((tech, ti) => (\n <GlassCard\n key={ti}\n padding=\"sm\"\n hover\n className=\"inline-flex items-center gap-2\"\n >\n {tech.icon && (\n <img\n src={tech.icon}\n alt={tech.name}\n width={20}\n height={20}\n className=\"w-5 h-5 object-contain\"\n />\n )}\n <span\n className=\"text-sm font-medium whitespace-nowrap\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n </div>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ var chunkKEOHORIH_cjs = require('./chunk-KEOHORIH.cjs');
4
+ var chunkIKBK7HYX_cjs = require('./chunk-IKBK7HYX.cjs');
5
+ var react = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function TechStackSection({ data }) {
9
+ const grouped = react.useMemo(() => {
10
+ const groups = {};
11
+ for (const tech of data.technologies) {
12
+ const cat = tech.category || "Other";
13
+ if (!groups[cat]) groups[cat] = [];
14
+ groups[cat].push(tech);
15
+ }
16
+ return Object.entries(groups);
17
+ }, [data.technologies]);
18
+ return /* @__PURE__ */ jsxRuntime.jsx(
19
+ "section",
20
+ {
21
+ className: "w-full py-20 md:py-28",
22
+ style: { background: "var(--sk-bg, #0a0a0a)" },
23
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-7xl mx-auto px-6", children: [
24
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: [
25
+ /* @__PURE__ */ jsxRuntime.jsx(
26
+ "h2",
27
+ {
28
+ className: "text-3xl md:text-4xl font-bold mb-4",
29
+ style: {
30
+ color: "var(--sk-text-primary, #ffffff)",
31
+ fontFamily: "var(--sk-font-heading, inherit)"
32
+ },
33
+ children: "Tech Stack"
34
+ }
35
+ ),
36
+ /* @__PURE__ */ jsxRuntime.jsx(
37
+ "p",
38
+ {
39
+ className: "text-lg mb-12 max-w-2xl",
40
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
41
+ children: "The technologies and tools powering this project."
42
+ }
43
+ )
44
+ ] }),
45
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-10", children: grouped.map(([category, techs], gi) => /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, delay: gi * 0.1, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
46
+ /* @__PURE__ */ jsxRuntime.jsx(
47
+ "h3",
48
+ {
49
+ className: "text-sm font-semibold uppercase tracking-wider",
50
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
51
+ children: category
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { stagger: 0.06, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-3", children: techs.map((tech, ti) => /* @__PURE__ */ jsxRuntime.jsxs(
55
+ chunkKEOHORIH_cjs.GlassCard,
56
+ {
57
+ padding: "sm",
58
+ hover: true,
59
+ className: "inline-flex items-center gap-2",
60
+ children: [
61
+ tech.icon && /* @__PURE__ */ jsxRuntime.jsx(
62
+ "img",
63
+ {
64
+ src: tech.icon,
65
+ alt: tech.name,
66
+ width: 20,
67
+ height: 20,
68
+ className: "w-5 h-5 object-contain"
69
+ }
70
+ ),
71
+ /* @__PURE__ */ jsxRuntime.jsx(
72
+ "span",
73
+ {
74
+ className: "text-sm font-medium whitespace-nowrap",
75
+ style: { color: "var(--sk-text-primary, #ffffff)" },
76
+ children: tech.name
77
+ }
78
+ )
79
+ ]
80
+ },
81
+ ti
82
+ )) }) })
83
+ ] }) }, category)) })
84
+ ] })
85
+ }
86
+ );
87
+ }
88
+
89
+ module.exports = TechStackSection;
90
+ //# sourceMappingURL=TechStackSection-VKJK4KQB.cjs.map
91
+ //# sourceMappingURL=TechStackSection-VKJK4KQB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/TechStackSection.tsx"],"names":["useMemo","jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"TechStackSection-VKJK4KQB.cjs","sourcesContent":["'use client';\n\nimport React, { useMemo } 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 // Group technologies by category\n const grouped = useMemo(() => {\n const groups: Record<string, typeof data.technologies> = {};\n for (const tech of data.technologies) {\n const cat = tech.category || 'Other';\n if (!groups[cat]) groups[cat] = [];\n groups[cat].push(tech);\n }\n return Object.entries(groups);\n }, [data.technologies]);\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-7xl 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 <div className=\"flex flex-col gap-10\">\n {grouped.map(([category, techs], gi) => (\n <ScrollReveal key={category} y={30} delay={gi * 0.1}>\n <div className=\"flex flex-col gap-4\">\n <h3\n className=\"text-sm font-semibold uppercase tracking-wider\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {category}\n </h3>\n <ScrollReveal stagger={0.06}>\n <div className=\"flex flex-wrap gap-3\">\n {techs.map((tech, ti) => (\n <GlassCard\n key={ti}\n padding=\"sm\"\n hover\n className=\"inline-flex items-center gap-2\"\n >\n {tech.icon && (\n <img\n src={tech.icon}\n alt={tech.name}\n width={20}\n height={20}\n className=\"w-5 h-5 object-contain\"\n />\n )}\n <span\n className=\"text-sm font-medium whitespace-nowrap\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {tech.name}\n </span>\n </GlassCard>\n ))}\n </div>\n </ScrollReveal>\n </div>\n </ScrollReveal>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,122 @@
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 StarRating({ rating }) {
6
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx(
7
+ "svg",
8
+ {
9
+ width: "20",
10
+ height: "20",
11
+ viewBox: "0 0 20 20",
12
+ fill: i < rating ? "var(--sk-primary, #6366f1)" : "none",
13
+ xmlns: "http://www.w3.org/2000/svg",
14
+ children: /* @__PURE__ */ jsx(
15
+ "path",
16
+ {
17
+ d: "M10 1.667l2.575 5.216 5.758.84-4.166 4.06.983 5.734L10 14.808l-5.15 2.709.983-5.734-4.166-4.06 5.758-.84L10 1.667z",
18
+ stroke: i < rating ? "var(--sk-primary, #6366f1)" : "var(--sk-text-tertiary, #71717a)",
19
+ strokeWidth: "1.5",
20
+ strokeLinecap: "round",
21
+ strokeLinejoin: "round"
22
+ }
23
+ )
24
+ },
25
+ i
26
+ )) });
27
+ }
28
+ function TestimonialSection({ data }) {
29
+ const avatarUrl = data.avatar?.asset?._ref;
30
+ return /* @__PURE__ */ jsx(
31
+ "section",
32
+ {
33
+ className: "w-full py-20 md:py-28",
34
+ style: { background: "var(--sk-bg, #0a0a0a)" },
35
+ children: /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto px-6", children: /* @__PURE__ */ jsx(ScrollReveal, { y: 30, duration: 1, children: /* @__PURE__ */ jsx(GlassCard, { padding: "lg", hover: false, className: "text-center", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-6 py-8 px-4 md:px-12", children: [
36
+ /* @__PURE__ */ jsx(
37
+ "svg",
38
+ {
39
+ width: "48",
40
+ height: "48",
41
+ viewBox: "0 0 48 48",
42
+ fill: "none",
43
+ xmlns: "http://www.w3.org/2000/svg",
44
+ style: { color: "var(--sk-primary, #6366f1)", opacity: 0.4 },
45
+ children: /* @__PURE__ */ jsx(
46
+ "path",
47
+ {
48
+ d: "M14 28c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6zm20 0c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6z",
49
+ fill: "currentColor"
50
+ }
51
+ )
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsxs(
55
+ "blockquote",
56
+ {
57
+ className: "text-xl md:text-2xl lg:text-3xl font-medium leading-relaxed italic",
58
+ style: {
59
+ color: "var(--sk-text-primary, #ffffff)",
60
+ fontFamily: "var(--sk-font-heading, inherit)"
61
+ },
62
+ children: [
63
+ "\u201C",
64
+ data.quote,
65
+ "\u201D"
66
+ ]
67
+ }
68
+ ),
69
+ data.rating !== void 0 && data.rating > 0 && /* @__PURE__ */ jsx(StarRating, { rating: data.rating }),
70
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 mt-2", children: [
71
+ avatarUrl ? /* @__PURE__ */ jsx(
72
+ "img",
73
+ {
74
+ src: avatarUrl,
75
+ alt: data.author,
76
+ className: "w-12 h-12 rounded-full object-cover",
77
+ style: {
78
+ border: "2px solid var(--sk-border, rgba(255,255,255,0.1))"
79
+ }
80
+ }
81
+ ) : /* @__PURE__ */ jsx(
82
+ "div",
83
+ {
84
+ className: "flex items-center justify-center w-12 h-12 rounded-full text-sm font-bold",
85
+ style: {
86
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)",
87
+ color: "var(--sk-primary, #6366f1)"
88
+ },
89
+ children: data.author.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase()
90
+ }
91
+ ),
92
+ /* @__PURE__ */ jsxs("div", { className: "text-left", children: [
93
+ /* @__PURE__ */ jsx(
94
+ "div",
95
+ {
96
+ className: "font-semibold",
97
+ style: { color: "var(--sk-text-primary, #ffffff)" },
98
+ children: data.author
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsxs(
102
+ "div",
103
+ {
104
+ className: "text-sm",
105
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
106
+ children: [
107
+ data.title,
108
+ ", ",
109
+ data.company
110
+ ]
111
+ }
112
+ )
113
+ ] })
114
+ ] })
115
+ ] }) }) }) })
116
+ }
117
+ );
118
+ }
119
+
120
+ export { TestimonialSection as default };
121
+ //# sourceMappingURL=TestimonialSection-6RGSMXQB.js.map
122
+ //# sourceMappingURL=TestimonialSection-6RGSMXQB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/TestimonialSection.tsx"],"names":[],"mappings":"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","file":"TestimonialSection-6RGSMXQB.js","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { PortfolioTestimonialData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface TestimonialSectionProps {\n data: PortfolioTestimonialData;\n}\n\nfunction StarRating({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-1\">\n {Array.from({ length: 5 }).map((_, i) => (\n <svg\n key={i}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill={i < rating ? 'var(--sk-primary, #6366f1)' : 'none'}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 1.667l2.575 5.216 5.758.84-4.166 4.06.983 5.734L10 14.808l-5.15 2.709.983-5.734-4.166-4.06 5.758-.84L10 1.667z\"\n stroke={i < rating ? 'var(--sk-primary, #6366f1)' : 'var(--sk-text-tertiary, #71717a)'}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n ))}\n </div>\n );\n}\n\nexport default function TestimonialSection({ data }: TestimonialSectionProps) {\n const avatarUrl = data.avatar?.asset?._ref;\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-4xl mx-auto px-6\">\n <ScrollReveal y={30} duration={1}>\n <GlassCard padding=\"lg\" hover={false} className=\"text-center\">\n <div className=\"flex flex-col items-center gap-6 py-8 px-4 md:px-12\">\n {/* Quote icon */}\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ color: 'var(--sk-primary, #6366f1)', opacity: 0.4 }}\n >\n <path\n d=\"M14 28c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6zm20 0c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6z\"\n fill=\"currentColor\"\n />\n </svg>\n\n {/* Quote text */}\n <blockquote\n className=\"text-xl md:text-2xl lg:text-3xl font-medium leading-relaxed italic\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n &ldquo;{data.quote}&rdquo;\n </blockquote>\n\n {/* Rating */}\n {data.rating !== undefined && data.rating > 0 && (\n <StarRating rating={data.rating} />\n )}\n\n {/* Author */}\n <div className=\"flex items-center gap-4 mt-2\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={data.author}\n className=\"w-12 h-12 rounded-full object-cover\"\n style={{\n border: '2px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n />\n ) : (\n <div\n className=\"flex items-center justify-center w-12 h-12 rounded-full text-sm font-bold\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {data.author\n .split(' ')\n .map((w) => w[0])\n .join('')\n .slice(0, 2)\n .toUpperCase()}\n </div>\n )}\n <div className=\"text-left\">\n <div\n className=\"font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {data.author}\n </div>\n <div\n className=\"text-sm\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.title}, {data.company}\n </div>\n </div>\n </div>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,124 @@
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 StarRating({ rating }) {
8
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
9
+ "svg",
10
+ {
11
+ width: "20",
12
+ height: "20",
13
+ viewBox: "0 0 20 20",
14
+ fill: i < rating ? "var(--sk-primary, #6366f1)" : "none",
15
+ xmlns: "http://www.w3.org/2000/svg",
16
+ children: /* @__PURE__ */ jsxRuntime.jsx(
17
+ "path",
18
+ {
19
+ d: "M10 1.667l2.575 5.216 5.758.84-4.166 4.06.983 5.734L10 14.808l-5.15 2.709.983-5.734-4.166-4.06 5.758-.84L10 1.667z",
20
+ stroke: i < rating ? "var(--sk-primary, #6366f1)" : "var(--sk-text-tertiary, #71717a)",
21
+ strokeWidth: "1.5",
22
+ strokeLinecap: "round",
23
+ strokeLinejoin: "round"
24
+ }
25
+ )
26
+ },
27
+ i
28
+ )) });
29
+ }
30
+ function TestimonialSection({ data }) {
31
+ const avatarUrl = data.avatar?.asset?._ref;
32
+ return /* @__PURE__ */ jsxRuntime.jsx(
33
+ "section",
34
+ {
35
+ className: "w-full py-20 md:py-28",
36
+ style: { background: "var(--sk-bg, #0a0a0a)" },
37
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-6", children: /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, duration: 1, children: /* @__PURE__ */ jsxRuntime.jsx(chunkKEOHORIH_cjs.GlassCard, { padding: "lg", hover: false, className: "text-center", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-6 py-8 px-4 md:px-12", children: [
38
+ /* @__PURE__ */ jsxRuntime.jsx(
39
+ "svg",
40
+ {
41
+ width: "48",
42
+ height: "48",
43
+ viewBox: "0 0 48 48",
44
+ fill: "none",
45
+ xmlns: "http://www.w3.org/2000/svg",
46
+ style: { color: "var(--sk-primary, #6366f1)", opacity: 0.4 },
47
+ children: /* @__PURE__ */ jsxRuntime.jsx(
48
+ "path",
49
+ {
50
+ d: "M14 28c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6zm20 0c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6z",
51
+ fill: "currentColor"
52
+ }
53
+ )
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsxRuntime.jsxs(
57
+ "blockquote",
58
+ {
59
+ className: "text-xl md:text-2xl lg:text-3xl font-medium leading-relaxed italic",
60
+ style: {
61
+ color: "var(--sk-text-primary, #ffffff)",
62
+ fontFamily: "var(--sk-font-heading, inherit)"
63
+ },
64
+ children: [
65
+ "\u201C",
66
+ data.quote,
67
+ "\u201D"
68
+ ]
69
+ }
70
+ ),
71
+ data.rating !== void 0 && data.rating > 0 && /* @__PURE__ */ jsxRuntime.jsx(StarRating, { rating: data.rating }),
72
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 mt-2", children: [
73
+ avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(
74
+ "img",
75
+ {
76
+ src: avatarUrl,
77
+ alt: data.author,
78
+ className: "w-12 h-12 rounded-full object-cover",
79
+ style: {
80
+ border: "2px solid var(--sk-border, rgba(255,255,255,0.1))"
81
+ }
82
+ }
83
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
84
+ "div",
85
+ {
86
+ className: "flex items-center justify-center w-12 h-12 rounded-full text-sm font-bold",
87
+ style: {
88
+ background: "color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)",
89
+ color: "var(--sk-primary, #6366f1)"
90
+ },
91
+ children: data.author.split(" ").map((w) => w[0]).join("").slice(0, 2).toUpperCase()
92
+ }
93
+ ),
94
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-left", children: [
95
+ /* @__PURE__ */ jsxRuntime.jsx(
96
+ "div",
97
+ {
98
+ className: "font-semibold",
99
+ style: { color: "var(--sk-text-primary, #ffffff)" },
100
+ children: data.author
101
+ }
102
+ ),
103
+ /* @__PURE__ */ jsxRuntime.jsxs(
104
+ "div",
105
+ {
106
+ className: "text-sm",
107
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
108
+ children: [
109
+ data.title,
110
+ ", ",
111
+ data.company
112
+ ]
113
+ }
114
+ )
115
+ ] })
116
+ ] })
117
+ ] }) }) }) })
118
+ }
119
+ );
120
+ }
121
+
122
+ module.exports = TestimonialSection;
123
+ //# sourceMappingURL=TestimonialSection-XPTFUQIN.cjs.map
124
+ //# sourceMappingURL=TestimonialSection-XPTFUQIN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/TestimonialSection.tsx"],"names":["jsx","ScrollReveal","GlassCard","jsxs"],"mappings":"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","file":"TestimonialSection-XPTFUQIN.cjs","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { PortfolioTestimonialData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface TestimonialSectionProps {\n data: PortfolioTestimonialData;\n}\n\nfunction StarRating({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-1\">\n {Array.from({ length: 5 }).map((_, i) => (\n <svg\n key={i}\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill={i < rating ? 'var(--sk-primary, #6366f1)' : 'none'}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 1.667l2.575 5.216 5.758.84-4.166 4.06.983 5.734L10 14.808l-5.15 2.709.983-5.734-4.166-4.06 5.758-.84L10 1.667z\"\n stroke={i < rating ? 'var(--sk-primary, #6366f1)' : 'var(--sk-text-tertiary, #71717a)'}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n ))}\n </div>\n );\n}\n\nexport default function TestimonialSection({ data }: TestimonialSectionProps) {\n const avatarUrl = data.avatar?.asset?._ref;\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-4xl mx-auto px-6\">\n <ScrollReveal y={30} duration={1}>\n <GlassCard padding=\"lg\" hover={false} className=\"text-center\">\n <div className=\"flex flex-col items-center gap-6 py-8 px-4 md:px-12\">\n {/* Quote icon */}\n <svg\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{ color: 'var(--sk-primary, #6366f1)', opacity: 0.4 }}\n >\n <path\n d=\"M14 28c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6zm20 0c-3.314 0-6-2.686-6-6 0-6.627 5.373-12 12-12v4c-4.418 0-8 3.582-8 8h2c3.314 0 6 2.686 6 6s-2.686 6-6 6z\"\n fill=\"currentColor\"\n />\n </svg>\n\n {/* Quote text */}\n <blockquote\n className=\"text-xl md:text-2xl lg:text-3xl font-medium leading-relaxed italic\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n &ldquo;{data.quote}&rdquo;\n </blockquote>\n\n {/* Rating */}\n {data.rating !== undefined && data.rating > 0 && (\n <StarRating rating={data.rating} />\n )}\n\n {/* Author */}\n <div className=\"flex items-center gap-4 mt-2\">\n {avatarUrl ? (\n <img\n src={avatarUrl}\n alt={data.author}\n className=\"w-12 h-12 rounded-full object-cover\"\n style={{\n border: '2px solid var(--sk-border, rgba(255,255,255,0.1))',\n }}\n />\n ) : (\n <div\n className=\"flex items-center justify-center w-12 h-12 rounded-full text-sm font-bold\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 20%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {data.author\n .split(' ')\n .map((w) => w[0])\n .join('')\n .slice(0, 2)\n .toUpperCase()}\n </div>\n )}\n <div className=\"text-left\">\n <div\n className=\"font-semibold\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {data.author}\n </div>\n <div\n className=\"text-sm\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {data.title}, {data.company}\n </div>\n </div>\n </div>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,117 @@
1
+ 'use client';
2
+ import { GlassCard } from './chunk-YB4B3OMC.js';
3
+ import { ScrollReveal } from './chunk-7CFFAKDM.js';
4
+ import { useState, useCallback } from 'react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ function getEmbedUrl(data) {
8
+ if (data.embedUrl) return data.embedUrl;
9
+ if (!data.url) return "";
10
+ const ytMatch = data.url.match(
11
+ /(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/
12
+ );
13
+ if (ytMatch) return `https://www.youtube.com/embed/${ytMatch[1]}?autoplay=1`;
14
+ const vimeoMatch = data.url.match(/vimeo\.com\/(\d+)/);
15
+ if (vimeoMatch) return `https://player.vimeo.com/video/${vimeoMatch[1]}?autoplay=1`;
16
+ return data.url;
17
+ }
18
+ function VideoSection({ data }) {
19
+ const [playing, setPlaying] = useState(false);
20
+ const thumbnailUrl = data.thumbnail?.asset?._ref || "";
21
+ const embedUrl = getEmbedUrl(data);
22
+ const handlePlay = useCallback(() => {
23
+ if (embedUrl) setPlaying(true);
24
+ }, [embedUrl]);
25
+ return /* @__PURE__ */ jsx(
26
+ "section",
27
+ {
28
+ className: "w-full py-20 md:py-28",
29
+ style: { background: "var(--sk-bg, #0a0a0a)" },
30
+ children: /* @__PURE__ */ jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
31
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 30, children: /* @__PURE__ */ jsx(
32
+ "h2",
33
+ {
34
+ className: "text-3xl md:text-4xl font-bold mb-4",
35
+ style: {
36
+ color: "var(--sk-text-primary, #ffffff)",
37
+ fontFamily: "var(--sk-font-heading, inherit)"
38
+ },
39
+ children: data.title
40
+ }
41
+ ) }),
42
+ /* @__PURE__ */ jsx(ScrollReveal, { y: 40, delay: 0.15, children: /* @__PURE__ */ jsx(GlassCard, { padding: "sm", hover: false, children: /* @__PURE__ */ jsx("div", { className: "relative w-full overflow-hidden rounded-xl", style: { aspectRatio: "16/9" }, children: playing ? /* @__PURE__ */ jsx(
43
+ "iframe",
44
+ {
45
+ src: embedUrl,
46
+ className: "absolute inset-0 w-full h-full",
47
+ allow: "autoplay; fullscreen; picture-in-picture",
48
+ allowFullScreen: true,
49
+ title: data.title,
50
+ style: { border: "none" }
51
+ }
52
+ ) : /* @__PURE__ */ jsxs(
53
+ "button",
54
+ {
55
+ onClick: handlePlay,
56
+ className: "absolute inset-0 w-full h-full group cursor-pointer",
57
+ "aria-label": `Play ${data.title}`,
58
+ children: [
59
+ thumbnailUrl && /* @__PURE__ */ jsx(
60
+ "img",
61
+ {
62
+ src: thumbnailUrl,
63
+ alt: data.title,
64
+ className: "w-full h-full object-cover"
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx(
68
+ "div",
69
+ {
70
+ className: "absolute inset-0 transition-opacity duration-300 group-hover:opacity-60",
71
+ style: { background: "rgba(0,0,0,0.4)", opacity: 0.5 }
72
+ }
73
+ ),
74
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx(
75
+ "div",
76
+ {
77
+ className: "flex items-center justify-center w-20 h-20 rounded-full transition-transform duration-300 group-hover:scale-110",
78
+ style: {
79
+ background: "var(--sk-primary, #6366f1)",
80
+ boxShadow: "0 8px 32px color-mix(in srgb, var(--sk-primary, #6366f1) 40%, transparent)"
81
+ },
82
+ children: /* @__PURE__ */ jsx(
83
+ "svg",
84
+ {
85
+ width: "32",
86
+ height: "32",
87
+ viewBox: "0 0 32 32",
88
+ fill: "none",
89
+ xmlns: "http://www.w3.org/2000/svg",
90
+ children: /* @__PURE__ */ jsx("path", { d: "M12 8l14 8-14 8V8z", fill: "#ffffff" })
91
+ }
92
+ )
93
+ }
94
+ ) }),
95
+ data.duration && /* @__PURE__ */ jsx(
96
+ "span",
97
+ {
98
+ className: "absolute bottom-4 right-4 px-3 py-1 rounded-lg text-xs font-medium",
99
+ style: {
100
+ background: "rgba(0,0,0,0.6)",
101
+ color: "#ffffff",
102
+ backdropFilter: "blur(4px)"
103
+ },
104
+ children: data.duration
105
+ }
106
+ )
107
+ ]
108
+ }
109
+ ) }) }) })
110
+ ] })
111
+ }
112
+ );
113
+ }
114
+
115
+ export { VideoSection as default };
116
+ //# sourceMappingURL=VideoSection-4A2HC6K6.js.map
117
+ //# sourceMappingURL=VideoSection-4A2HC6K6.js.map