@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.
Files changed (89) hide show
  1. package/dist/{BeforeAfterSection-6QUJOBO2.js → BeforeAfterSection-6BHFLY4Y.js} +6 -6
  2. package/dist/BeforeAfterSection-6BHFLY4Y.js.map +1 -0
  3. package/dist/{BeforeAfterSection-DVAWWE4K.cjs → BeforeAfterSection-JTORBR3A.cjs} +6 -6
  4. package/dist/BeforeAfterSection-JTORBR3A.cjs.map +1 -0
  5. package/dist/DesignSystemSection-2R5BRBGO.js +172 -0
  6. package/dist/DesignSystemSection-2R5BRBGO.js.map +1 -0
  7. package/dist/DesignSystemSection-KXIQXITF.cjs +174 -0
  8. package/dist/DesignSystemSection-KXIQXITF.cjs.map +1 -0
  9. package/dist/{DetailsSection-FB763FS7.js → DetailsSection-A6PZQUQL.js} +14 -5
  10. package/dist/DetailsSection-A6PZQUQL.js.map +1 -0
  11. package/dist/{DetailsSection-OACJFGH7.cjs → DetailsSection-TTUZAPZZ.cjs} +14 -5
  12. package/dist/DetailsSection-TTUZAPZZ.cjs.map +1 -0
  13. package/dist/PerformanceSection-24TVVFZA.cjs +356 -0
  14. package/dist/PerformanceSection-24TVVFZA.cjs.map +1 -0
  15. package/dist/PerformanceSection-MGCEIXDX.js +351 -0
  16. package/dist/PerformanceSection-MGCEIXDX.js.map +1 -0
  17. package/dist/SiteArchitectureSection-EE6VQSXM.cjs +349 -0
  18. package/dist/SiteArchitectureSection-EE6VQSXM.cjs.map +1 -0
  19. package/dist/SiteArchitectureSection-PBBRTARV.js +344 -0
  20. package/dist/SiteArchitectureSection-PBBRTARV.js.map +1 -0
  21. package/dist/SpeedComparisonSection-EZKFQVGW.cjs +174 -0
  22. package/dist/SpeedComparisonSection-EZKFQVGW.cjs.map +1 -0
  23. package/dist/SpeedComparisonSection-Y3K7OFZQ.js +172 -0
  24. package/dist/SpeedComparisonSection-Y3K7OFZQ.js.map +1 -0
  25. package/dist/{StrategySection-3ED3QW4R.cjs → StrategySection-CJ7Y6OFQ.cjs} +18 -24
  26. package/dist/StrategySection-CJ7Y6OFQ.cjs.map +1 -0
  27. package/dist/{StrategySection-VUWMIYYP.js → StrategySection-DI5RSCJU.js} +18 -24
  28. package/dist/StrategySection-DI5RSCJU.js.map +1 -0
  29. package/dist/TechStackSection-2AQ7RGY3.js +93 -0
  30. package/dist/TechStackSection-2AQ7RGY3.js.map +1 -0
  31. package/dist/TechStackSection-VTNNZR5V.cjs +95 -0
  32. package/dist/TechStackSection-VTNNZR5V.cjs.map +1 -0
  33. package/dist/chunk-4GVC3D2X.js +606 -0
  34. package/dist/chunk-4GVC3D2X.js.map +1 -0
  35. package/dist/{chunk-XMC4DN6G.js → chunk-APG2QSMB.js} +8 -8
  36. package/dist/chunk-APG2QSMB.js.map +1 -0
  37. package/dist/chunk-BGM6A2RU.cjs +613 -0
  38. package/dist/chunk-BGM6A2RU.cjs.map +1 -0
  39. package/dist/{chunk-NAS4K5UR.cjs → chunk-OA5ZM4OA.cjs} +8 -8
  40. package/dist/chunk-OA5ZM4OA.cjs.map +1 -0
  41. package/dist/{chunk-QIC6JFFD.js → chunk-OMOF4VR5.js} +14 -14
  42. package/dist/chunk-OMOF4VR5.js.map +1 -0
  43. package/dist/{chunk-5FKOLIV6.cjs → chunk-XM2QD3AK.cjs} +14 -14
  44. package/dist/chunk-XM2QD3AK.cjs.map +1 -0
  45. package/dist/index.cjs +13 -13
  46. package/dist/index.d.cts +2 -2
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.js +3 -3
  49. package/dist/layout/index.cjs +2 -2
  50. package/dist/layout/index.d.cts +1 -1
  51. package/dist/layout/index.d.ts +1 -1
  52. package/dist/layout/index.js +1 -1
  53. package/dist/portfolio/client.cjs +3 -3
  54. package/dist/portfolio/client.d.cts +7 -3
  55. package/dist/portfolio/client.d.ts +7 -3
  56. package/dist/portfolio/client.js +1 -1
  57. package/dist/portfolio/index.cjs +6 -6
  58. package/dist/portfolio/index.d.cts +2 -2
  59. package/dist/portfolio/index.d.ts +2 -2
  60. package/dist/portfolio/index.js +2 -2
  61. package/dist/portfolio/sections.d.cts +1 -1
  62. package/dist/portfolio/sections.d.ts +1 -1
  63. package/dist/portfolio/server.cjs +1 -0
  64. package/dist/portfolio/server.cjs.map +1 -1
  65. package/dist/portfolio/server.d.cts +1 -1
  66. package/dist/portfolio/server.d.ts +1 -1
  67. package/dist/portfolio/server.js +1 -0
  68. package/dist/portfolio/server.js.map +1 -1
  69. package/dist/{types-BMUhBhWx.d.cts → types-DL4t_Cfa.d.cts} +3 -1
  70. package/dist/{types-BMUhBhWx.d.ts → types-DL4t_Cfa.d.ts} +3 -1
  71. package/package.json +1 -1
  72. package/dist/BeforeAfterSection-6QUJOBO2.js.map +0 -1
  73. package/dist/BeforeAfterSection-DVAWWE4K.cjs.map +0 -1
  74. package/dist/DetailsSection-FB763FS7.js.map +0 -1
  75. package/dist/DetailsSection-OACJFGH7.cjs.map +0 -1
  76. package/dist/StrategySection-3ED3QW4R.cjs.map +0 -1
  77. package/dist/StrategySection-VUWMIYYP.js.map +0 -1
  78. package/dist/TechStackSection-OCUYG4XT.js +0 -90
  79. package/dist/TechStackSection-OCUYG4XT.js.map +0 -1
  80. package/dist/TechStackSection-VKJK4KQB.cjs +0 -91
  81. package/dist/TechStackSection-VKJK4KQB.cjs.map +0 -1
  82. package/dist/chunk-2VNNFAG6.js +0 -415
  83. package/dist/chunk-2VNNFAG6.js.map +0 -1
  84. package/dist/chunk-5FKOLIV6.cjs.map +0 -1
  85. package/dist/chunk-NAS4K5UR.cjs.map +0 -1
  86. package/dist/chunk-QIC6JFFD.js.map +0 -1
  87. package/dist/chunk-TAPNXT7X.cjs +0 -422
  88. package/dist/chunk-TAPNXT7X.cjs.map +0 -1
  89. package/dist/chunk-XMC4DN6G.js.map +0 -1
@@ -10,8 +10,8 @@ function BeforeAfterSection({ data }) {
10
10
  const sliderRef = useRef(null);
11
11
  const [position, setPosition] = useState(data.defaultPosition ?? 50);
12
12
  const isDragging = useRef(false);
13
- const beforeUrl = data.before?.asset?._ref || "";
14
- const afterUrl = data.after?.asset?._ref || "";
13
+ const beforeUrl = data.beforeUrl || data.before?.asset?._ref || "";
14
+ const afterUrl = data.afterUrl || data.after?.asset?._ref || "";
15
15
  useEffect(() => {
16
16
  const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
17
17
  if (prefersReducedMotion || !sliderRef.current) return;
@@ -148,7 +148,7 @@ function BeforeAfterSection({ data }) {
148
148
  color: "#ffffff",
149
149
  backdropFilter: "blur(4px)"
150
150
  },
151
- children: "Before"
151
+ children: data.beforeLabel || "Before"
152
152
  }
153
153
  ),
154
154
  /* @__PURE__ */ jsx(
@@ -160,7 +160,7 @@ function BeforeAfterSection({ data }) {
160
160
  color: "#ffffff",
161
161
  backdropFilter: "blur(4px)"
162
162
  },
163
- children: "After"
163
+ children: data.afterLabel || "After"
164
164
  }
165
165
  )
166
166
  ]
@@ -172,5 +172,5 @@ function BeforeAfterSection({ data }) {
172
172
  }
173
173
 
174
174
  export { BeforeAfterSection as default };
175
- //# sourceMappingURL=BeforeAfterSection-6QUJOBO2.js.map
176
- //# sourceMappingURL=BeforeAfterSection-6QUJOBO2.js.map
175
+ //# sourceMappingURL=BeforeAfterSection-6BHFLY4Y.js.map
176
+ //# sourceMappingURL=BeforeAfterSection-6BHFLY4Y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/BeforeAfterSection.tsx"],"names":[],"mappings":"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","file":"BeforeAfterSection-6BHFLY4Y.js","sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioBeforeAfterData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface BeforeAfterSectionProps {\n data: PortfolioBeforeAfterData;\n}\n\nexport default function BeforeAfterSection({ data }: BeforeAfterSectionProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState(data.defaultPosition ?? 50);\n const isDragging = useRef(false);\n\n // Support both Sanity image refs and direct URL strings\n const beforeUrl = (data as any).beforeUrl || data.before?.asset?._ref || '';\n const afterUrl = (data as any).afterUrl || data.after?.asset?._ref || '';\n\n // Animate slider handle entrance\n useEffect(() => {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion || !sliderRef.current) return;\n\n gsap.fromTo(\n sliderRef.current,\n { opacity: 0, scale: 0.8 },\n { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: 'back.out(2)' },\n );\n }, []);\n\n const updatePosition = useCallback((clientX: number) => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const x = clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (x / rect.width) * 100));\n setPosition(percent);\n }, []);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n isDragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!isDragging.current) return;\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerUp = useCallback(() => {\n isDragging.current = false;\n }, []);\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 {(data.title || data.description) && (\n <ScrollReveal y={30}>\n {data.title && (\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 {data.title}\n </h2>\n )}\n {data.description && (\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.description}\n </p>\n )}\n </ScrollReveal>\n )}\n\n <ScrollReveal y={40}>\n <GlassCard padding=\"sm\" hover={false}>\n <div\n ref={containerRef}\n className=\"relative w-full overflow-hidden rounded-xl cursor-col-resize select-none\"\n style={{ aspectRatio: '16/10' }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {/* After image (full background) */}\n <img\n src={afterUrl}\n alt=\"After\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n draggable={false}\n />\n\n {/* Before image (clipped) */}\n <div\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: `${position}%` }}\n >\n <img\n src={beforeUrl}\n alt=\"Before\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n style={{ minWidth: containerRef.current?.offsetWidth || '100%' }}\n draggable={false}\n />\n </div>\n\n {/* Slider line */}\n <div\n className=\"absolute top-0 bottom-0 w-0.5\"\n style={{\n left: `${position}%`,\n transform: 'translateX(-50%)',\n background: '#ffffff',\n boxShadow: '0 0 8px rgba(0,0,0,0.5)',\n }}\n />\n\n {/* Slider handle */}\n <div\n ref={sliderRef}\n className=\"absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full\"\n style={{\n left: `${position}%`,\n transform: 'translate(-50%, -50%)',\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 4px 16px rgba(0,0,0,0.3)',\n border: '3px solid #ffffff',\n zIndex: 5,\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 3l-4 5 4 5M11 3l4 5-4 5\" stroke=\"#ffffff\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n {/* Before / After labels */}\n <span\n className=\"absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {(data as any).beforeLabel || 'Before'}\n </span>\n <span\n className=\"absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {(data as any).afterLabel || 'After'}\n </span>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -15,8 +15,8 @@ function BeforeAfterSection({ data }) {
15
15
  const sliderRef = react.useRef(null);
16
16
  const [position, setPosition] = react.useState(data.defaultPosition ?? 50);
17
17
  const isDragging = react.useRef(false);
18
- const beforeUrl = data.before?.asset?._ref || "";
19
- const afterUrl = data.after?.asset?._ref || "";
18
+ const beforeUrl = data.beforeUrl || data.before?.asset?._ref || "";
19
+ const afterUrl = data.afterUrl || data.after?.asset?._ref || "";
20
20
  react.useEffect(() => {
21
21
  const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
22
22
  if (prefersReducedMotion || !sliderRef.current) return;
@@ -153,7 +153,7 @@ function BeforeAfterSection({ data }) {
153
153
  color: "#ffffff",
154
154
  backdropFilter: "blur(4px)"
155
155
  },
156
- children: "Before"
156
+ children: data.beforeLabel || "Before"
157
157
  }
158
158
  ),
159
159
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -165,7 +165,7 @@ function BeforeAfterSection({ data }) {
165
165
  color: "#ffffff",
166
166
  backdropFilter: "blur(4px)"
167
167
  },
168
- children: "After"
168
+ children: data.afterLabel || "After"
169
169
  }
170
170
  )
171
171
  ]
@@ -177,5 +177,5 @@ function BeforeAfterSection({ data }) {
177
177
  }
178
178
 
179
179
  module.exports = BeforeAfterSection;
180
- //# sourceMappingURL=BeforeAfterSection-DVAWWE4K.cjs.map
181
- //# sourceMappingURL=BeforeAfterSection-DVAWWE4K.cjs.map
180
+ //# sourceMappingURL=BeforeAfterSection-JTORBR3A.cjs.map
181
+ //# sourceMappingURL=BeforeAfterSection-JTORBR3A.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/BeforeAfterSection.tsx"],"names":["useRef","useState","useEffect","gsap","useCallback","jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"BeforeAfterSection-JTORBR3A.cjs","sourcesContent":["'use client';\n\nimport React, { useRef, useState, useCallback, useEffect } from 'react';\nimport gsap from 'gsap';\nimport type { PortfolioBeforeAfterData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface BeforeAfterSectionProps {\n data: PortfolioBeforeAfterData;\n}\n\nexport default function BeforeAfterSection({ data }: BeforeAfterSectionProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const sliderRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState(data.defaultPosition ?? 50);\n const isDragging = useRef(false);\n\n // Support both Sanity image refs and direct URL strings\n const beforeUrl = (data as any).beforeUrl || data.before?.asset?._ref || '';\n const afterUrl = (data as any).afterUrl || data.after?.asset?._ref || '';\n\n // Animate slider handle entrance\n useEffect(() => {\n const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n if (prefersReducedMotion || !sliderRef.current) return;\n\n gsap.fromTo(\n sliderRef.current,\n { opacity: 0, scale: 0.8 },\n { opacity: 1, scale: 1, duration: 0.6, delay: 0.5, ease: 'back.out(2)' },\n );\n }, []);\n\n const updatePosition = useCallback((clientX: number) => {\n const container = containerRef.current;\n if (!container) return;\n\n const rect = container.getBoundingClientRect();\n const x = clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (x / rect.width) * 100));\n setPosition(percent);\n }, []);\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent) => {\n isDragging.current = true;\n (e.target as HTMLElement).setPointerCapture(e.pointerId);\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent) => {\n if (!isDragging.current) return;\n updatePosition(e.clientX);\n },\n [updatePosition],\n );\n\n const handlePointerUp = useCallback(() => {\n isDragging.current = false;\n }, []);\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 {(data.title || data.description) && (\n <ScrollReveal y={30}>\n {data.title && (\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 {data.title}\n </h2>\n )}\n {data.description && (\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n {data.description}\n </p>\n )}\n </ScrollReveal>\n )}\n\n <ScrollReveal y={40}>\n <GlassCard padding=\"sm\" hover={false}>\n <div\n ref={containerRef}\n className=\"relative w-full overflow-hidden rounded-xl cursor-col-resize select-none\"\n style={{ aspectRatio: '16/10' }}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n {/* After image (full background) */}\n <img\n src={afterUrl}\n alt=\"After\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n draggable={false}\n />\n\n {/* Before image (clipped) */}\n <div\n className=\"absolute inset-0 overflow-hidden\"\n style={{ width: `${position}%` }}\n >\n <img\n src={beforeUrl}\n alt=\"Before\"\n className=\"absolute inset-0 w-full h-full object-cover\"\n style={{ minWidth: containerRef.current?.offsetWidth || '100%' }}\n draggable={false}\n />\n </div>\n\n {/* Slider line */}\n <div\n className=\"absolute top-0 bottom-0 w-0.5\"\n style={{\n left: `${position}%`,\n transform: 'translateX(-50%)',\n background: '#ffffff',\n boxShadow: '0 0 8px rgba(0,0,0,0.5)',\n }}\n />\n\n {/* Slider handle */}\n <div\n ref={sliderRef}\n className=\"absolute top-1/2 flex items-center justify-center w-10 h-10 rounded-full\"\n style={{\n left: `${position}%`,\n transform: 'translate(-50%, -50%)',\n background: 'var(--sk-primary, #6366f1)',\n boxShadow: '0 4px 16px rgba(0,0,0,0.3)',\n border: '3px solid #ffffff',\n zIndex: 5,\n }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 3l-4 5 4 5M11 3l4 5-4 5\" stroke=\"#ffffff\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n\n {/* Before / After labels */}\n <span\n className=\"absolute top-4 left-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {(data as any).beforeLabel || 'Before'}\n </span>\n <span\n className=\"absolute top-4 right-4 px-3 py-1 rounded-lg text-xs font-semibold uppercase tracking-wider\"\n style={{\n background: 'rgba(0,0,0,0.6)',\n color: '#ffffff',\n backdropFilter: 'blur(4px)',\n }}\n >\n {(data as any).afterLabel || 'After'}\n </span>\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}
@@ -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
+ function isLightColor(hex) {
6
+ const c = hex.replace("#", "");
7
+ const r = parseInt(c.substring(0, 2), 16);
8
+ const g = parseInt(c.substring(2, 4), 16);
9
+ const b = parseInt(c.substring(4, 6), 16);
10
+ return (r * 299 + g * 587 + b * 114) / 1e3 > 140;
11
+ }
12
+ function DesignSystemSection({ data }) {
13
+ const { colors, fonts } = data;
14
+ const headingFont = fonts.find((f) => f.usage === "heading") || fonts[0];
15
+ const bodyFont = fonts.find((f) => f.usage === "body") || fonts[1] || fonts[0];
16
+ if (!colors.length && !fonts.length) return null;
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-5xl 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: "Design System"
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 visual language we crafted for this project."
41
+ }
42
+ )
43
+ ] }),
44
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [
45
+ colors.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 20, children: /* @__PURE__ */ jsxs(GlassCard, { padding: "lg", hover: false, children: [
46
+ /* @__PURE__ */ jsx(
47
+ "h3",
48
+ {
49
+ className: "text-base font-semibold mb-4",
50
+ style: { color: "var(--sk-text-primary, #ffffff)" },
51
+ children: "Color Palette"
52
+ }
53
+ ),
54
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-3 gap-3", children: colors.map((color, ci) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
55
+ /* @__PURE__ */ jsx(
56
+ "div",
57
+ {
58
+ className: "w-full aspect-square rounded-lg border flex items-end justify-center pb-2",
59
+ style: {
60
+ background: color.hex,
61
+ borderColor: "color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)"
62
+ },
63
+ children: /* @__PURE__ */ jsx(
64
+ "span",
65
+ {
66
+ className: "text-[10px] font-mono font-medium px-1.5 py-0.5 rounded",
67
+ style: {
68
+ color: isLightColor(color.hex) ? "#000" : "#fff",
69
+ background: isLightColor(color.hex) ? "rgba(0,0,0,0.15)" : "rgba(255,255,255,0.15)"
70
+ },
71
+ children: color.hex
72
+ }
73
+ )
74
+ }
75
+ ),
76
+ color.context && /* @__PURE__ */ jsx(
77
+ "span",
78
+ {
79
+ className: "text-[10px] capitalize",
80
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
81
+ children: color.context
82
+ }
83
+ )
84
+ ] }, ci)) })
85
+ ] }) }),
86
+ fonts.length > 0 && /* @__PURE__ */ jsx(ScrollReveal, { y: 20, delay: 0.1, children: /* @__PURE__ */ jsxs(GlassCard, { padding: "lg", hover: false, children: [
87
+ /* @__PURE__ */ jsx(
88
+ "h3",
89
+ {
90
+ className: "text-base font-semibold mb-4",
91
+ style: { color: "var(--sk-text-primary, #ffffff)" },
92
+ children: "Typography"
93
+ }
94
+ ),
95
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6", children: [
96
+ headingFont && /* @__PURE__ */ jsxs("div", { children: [
97
+ /* @__PURE__ */ jsx(
98
+ "span",
99
+ {
100
+ className: "text-[10px] font-medium uppercase tracking-wider block mb-2",
101
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
102
+ children: "Headings"
103
+ }
104
+ ),
105
+ /* @__PURE__ */ jsx(
106
+ "p",
107
+ {
108
+ className: "text-2xl font-bold",
109
+ style: {
110
+ color: "var(--sk-text-primary, #ffffff)",
111
+ fontFamily: headingFont.family
112
+ },
113
+ children: headingFont.family
114
+ }
115
+ ),
116
+ headingFont.weights && headingFont.weights.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex gap-2 mt-2", children: headingFont.weights.map((w) => /* @__PURE__ */ jsx(
117
+ "span",
118
+ {
119
+ className: "text-xs px-2 py-0.5 rounded",
120
+ style: {
121
+ background: "color-mix(in srgb, var(--sk-text-tertiary, #71717a) 15%, transparent)",
122
+ color: "var(--sk-text-tertiary, #71717a)",
123
+ fontWeight: w
124
+ },
125
+ children: w
126
+ },
127
+ w
128
+ )) })
129
+ ] }),
130
+ bodyFont && bodyFont.family !== headingFont?.family && /* @__PURE__ */ jsxs("div", { children: [
131
+ /* @__PURE__ */ jsx(
132
+ "span",
133
+ {
134
+ className: "text-[10px] font-medium uppercase tracking-wider block mb-2",
135
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
136
+ children: "Body"
137
+ }
138
+ ),
139
+ /* @__PURE__ */ jsx(
140
+ "p",
141
+ {
142
+ className: "text-lg",
143
+ style: {
144
+ color: "var(--sk-text-primary, #ffffff)",
145
+ fontFamily: bodyFont.family
146
+ },
147
+ children: bodyFont.family
148
+ }
149
+ ),
150
+ /* @__PURE__ */ jsx(
151
+ "p",
152
+ {
153
+ className: "text-sm mt-2 leading-relaxed",
154
+ style: {
155
+ color: "var(--sk-text-tertiary, #71717a)",
156
+ fontFamily: bodyFont.family
157
+ },
158
+ children: "The quick brown fox jumps over the lazy dog. Clean, readable type that puts content first."
159
+ }
160
+ )
161
+ ] })
162
+ ] })
163
+ ] }) })
164
+ ] })
165
+ ] })
166
+ }
167
+ );
168
+ }
169
+
170
+ export { DesignSystemSection as default };
171
+ //# sourceMappingURL=DesignSystemSection-2R5BRBGO.js.map
172
+ //# sourceMappingURL=DesignSystemSection-2R5BRBGO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/DesignSystemSection.tsx"],"names":[],"mappings":"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","file":"DesignSystemSection-2R5BRBGO.js","sourcesContent":["'use client';\n\nimport React from 'react';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface ColorEntry {\n hex: string;\n usageCount?: number;\n context?: string;\n}\n\ninterface FontEntry {\n family: string;\n weights?: number[];\n usage?: string; // 'heading' | 'body' | 'accent'\n}\n\nexport interface DesignSystemData {\n colors: ColorEntry[];\n fonts: FontEntry[];\n headingStyles?: { font?: string; size?: string; weight?: string | number };\n bodyStyles?: { font?: string; size?: string; lineHeight?: string };\n}\n\ninterface DesignSystemSectionProps {\n data: DesignSystemData;\n}\n\n/** Determine if a hex color is light (needs dark text label) */\nfunction isLightColor(hex: string): boolean {\n const c = hex.replace('#', '');\n const r = parseInt(c.substring(0, 2), 16);\n const g = parseInt(c.substring(2, 4), 16);\n const b = parseInt(c.substring(4, 6), 16);\n return (r * 299 + g * 587 + b * 114) / 1000 > 140;\n}\n\nexport default function DesignSystemSection({ data }: DesignSystemSectionProps) {\n const { colors, fonts } = data;\n const headingFont = fonts.find((f) => f.usage === 'heading') || fonts[0];\n const bodyFont = fonts.find((f) => f.usage === 'body') || fonts[1] || fonts[0];\n\n if (!colors.length && !fonts.length) return null;\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 Design System\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The visual language we crafted for this project.\n </p>\n </ScrollReveal>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-8\">\n {/* Color Palette */}\n {colors.length > 0 && (\n <ScrollReveal y={20}>\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-base font-semibold mb-4\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n Color Palette\n </h3>\n <div className=\"grid grid-cols-3 gap-3\">\n {colors.map((color, ci) => (\n <div key={ci} className=\"flex flex-col items-center gap-2\">\n <div\n className=\"w-full aspect-square rounded-lg border flex items-end justify-center pb-2\"\n style={{\n background: color.hex,\n borderColor: 'color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)',\n }}\n >\n <span\n className=\"text-[10px] font-mono font-medium px-1.5 py-0.5 rounded\"\n style={{\n color: isLightColor(color.hex) ? '#000' : '#fff',\n background: isLightColor(color.hex) ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.15)',\n }}\n >\n {color.hex}\n </span>\n </div>\n {color.context && (\n <span\n className=\"text-[10px] capitalize\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {color.context}\n </span>\n )}\n </div>\n ))}\n </div>\n </GlassCard>\n </ScrollReveal>\n )}\n\n {/* Typography */}\n {fonts.length > 0 && (\n <ScrollReveal y={20} delay={0.1}>\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-base font-semibold mb-4\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n Typography\n </h3>\n <div className=\"flex flex-col gap-6\">\n {headingFont && (\n <div>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider block mb-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Headings\n </span>\n <p\n className=\"text-2xl font-bold\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: headingFont.family,\n }}\n >\n {headingFont.family}\n </p>\n {headingFont.weights && headingFont.weights.length > 0 && (\n <div className=\"flex gap-2 mt-2\">\n {headingFont.weights.map((w) => (\n <span\n key={w}\n className=\"text-xs px-2 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-text-tertiary, #71717a) 15%, transparent)',\n color: 'var(--sk-text-tertiary, #71717a)',\n fontWeight: w,\n }}\n >\n {w}\n </span>\n ))}\n </div>\n )}\n </div>\n )}\n {bodyFont && bodyFont.family !== headingFont?.family && (\n <div>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider block mb-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Body\n </span>\n <p\n className=\"text-lg\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: bodyFont.family,\n }}\n >\n {bodyFont.family}\n </p>\n <p\n className=\"text-sm mt-2 leading-relaxed\"\n style={{\n color: 'var(--sk-text-tertiary, #71717a)',\n fontFamily: bodyFont.family,\n }}\n >\n The quick brown fox jumps over the lazy dog. Clean, readable type that puts content first.\n </p>\n </div>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n )}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -0,0 +1,174 @@
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 isLightColor(hex) {
8
+ const c = hex.replace("#", "");
9
+ const r = parseInt(c.substring(0, 2), 16);
10
+ const g = parseInt(c.substring(2, 4), 16);
11
+ const b = parseInt(c.substring(4, 6), 16);
12
+ return (r * 299 + g * 587 + b * 114) / 1e3 > 140;
13
+ }
14
+ function DesignSystemSection({ data }) {
15
+ const { colors, fonts } = data;
16
+ const headingFont = fonts.find((f) => f.usage === "heading") || fonts[0];
17
+ const bodyFont = fonts.find((f) => f.usage === "body") || fonts[1] || fonts[0];
18
+ if (!colors.length && !fonts.length) return null;
19
+ return /* @__PURE__ */ jsxRuntime.jsx(
20
+ "section",
21
+ {
22
+ className: "w-full py-20 md:py-28",
23
+ style: { background: "var(--sk-bg, #0a0a0a)" },
24
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto px-6", children: [
25
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkIKBK7HYX_cjs.ScrollReveal, { y: 30, children: [
26
+ /* @__PURE__ */ jsxRuntime.jsx(
27
+ "h2",
28
+ {
29
+ className: "text-3xl md:text-4xl font-bold mb-4",
30
+ style: {
31
+ color: "var(--sk-text-primary, #ffffff)",
32
+ fontFamily: "var(--sk-font-heading, inherit)"
33
+ },
34
+ children: "Design System"
35
+ }
36
+ ),
37
+ /* @__PURE__ */ jsxRuntime.jsx(
38
+ "p",
39
+ {
40
+ className: "text-lg mb-12 max-w-2xl",
41
+ style: { color: "var(--sk-text-secondary, #a1a1aa)" },
42
+ children: "The visual language we crafted for this project."
43
+ }
44
+ )
45
+ ] }),
46
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [
47
+ colors.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkKEOHORIH_cjs.GlassCard, { padding: "lg", hover: false, children: [
48
+ /* @__PURE__ */ jsxRuntime.jsx(
49
+ "h3",
50
+ {
51
+ className: "text-base font-semibold mb-4",
52
+ style: { color: "var(--sk-text-primary, #ffffff)" },
53
+ children: "Color Palette"
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-3 gap-3", children: colors.map((color, ci) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
57
+ /* @__PURE__ */ jsxRuntime.jsx(
58
+ "div",
59
+ {
60
+ className: "w-full aspect-square rounded-lg border flex items-end justify-center pb-2",
61
+ style: {
62
+ background: color.hex,
63
+ borderColor: "color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)"
64
+ },
65
+ children: /* @__PURE__ */ jsxRuntime.jsx(
66
+ "span",
67
+ {
68
+ className: "text-[10px] font-mono font-medium px-1.5 py-0.5 rounded",
69
+ style: {
70
+ color: isLightColor(color.hex) ? "#000" : "#fff",
71
+ background: isLightColor(color.hex) ? "rgba(0,0,0,0.15)" : "rgba(255,255,255,0.15)"
72
+ },
73
+ children: color.hex
74
+ }
75
+ )
76
+ }
77
+ ),
78
+ color.context && /* @__PURE__ */ jsxRuntime.jsx(
79
+ "span",
80
+ {
81
+ className: "text-[10px] capitalize",
82
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
83
+ children: color.context
84
+ }
85
+ )
86
+ ] }, ci)) })
87
+ ] }) }),
88
+ fonts.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(chunkIKBK7HYX_cjs.ScrollReveal, { y: 20, delay: 0.1, children: /* @__PURE__ */ jsxRuntime.jsxs(chunkKEOHORIH_cjs.GlassCard, { padding: "lg", hover: false, children: [
89
+ /* @__PURE__ */ jsxRuntime.jsx(
90
+ "h3",
91
+ {
92
+ className: "text-base font-semibold mb-4",
93
+ style: { color: "var(--sk-text-primary, #ffffff)" },
94
+ children: "Typography"
95
+ }
96
+ ),
97
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-6", children: [
98
+ headingFont && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
99
+ /* @__PURE__ */ jsxRuntime.jsx(
100
+ "span",
101
+ {
102
+ className: "text-[10px] font-medium uppercase tracking-wider block mb-2",
103
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
104
+ children: "Headings"
105
+ }
106
+ ),
107
+ /* @__PURE__ */ jsxRuntime.jsx(
108
+ "p",
109
+ {
110
+ className: "text-2xl font-bold",
111
+ style: {
112
+ color: "var(--sk-text-primary, #ffffff)",
113
+ fontFamily: headingFont.family
114
+ },
115
+ children: headingFont.family
116
+ }
117
+ ),
118
+ headingFont.weights && headingFont.weights.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-2 mt-2", children: headingFont.weights.map((w) => /* @__PURE__ */ jsxRuntime.jsx(
119
+ "span",
120
+ {
121
+ className: "text-xs px-2 py-0.5 rounded",
122
+ style: {
123
+ background: "color-mix(in srgb, var(--sk-text-tertiary, #71717a) 15%, transparent)",
124
+ color: "var(--sk-text-tertiary, #71717a)",
125
+ fontWeight: w
126
+ },
127
+ children: w
128
+ },
129
+ w
130
+ )) })
131
+ ] }),
132
+ bodyFont && bodyFont.family !== headingFont?.family && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
133
+ /* @__PURE__ */ jsxRuntime.jsx(
134
+ "span",
135
+ {
136
+ className: "text-[10px] font-medium uppercase tracking-wider block mb-2",
137
+ style: { color: "var(--sk-text-tertiary, #71717a)" },
138
+ children: "Body"
139
+ }
140
+ ),
141
+ /* @__PURE__ */ jsxRuntime.jsx(
142
+ "p",
143
+ {
144
+ className: "text-lg",
145
+ style: {
146
+ color: "var(--sk-text-primary, #ffffff)",
147
+ fontFamily: bodyFont.family
148
+ },
149
+ children: bodyFont.family
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsxRuntime.jsx(
153
+ "p",
154
+ {
155
+ className: "text-sm mt-2 leading-relaxed",
156
+ style: {
157
+ color: "var(--sk-text-tertiary, #71717a)",
158
+ fontFamily: bodyFont.family
159
+ },
160
+ children: "The quick brown fox jumps over the lazy dog. Clean, readable type that puts content first."
161
+ }
162
+ )
163
+ ] })
164
+ ] })
165
+ ] }) })
166
+ ] })
167
+ ] })
168
+ }
169
+ );
170
+ }
171
+
172
+ module.exports = DesignSystemSection;
173
+ //# sourceMappingURL=DesignSystemSection-KXIQXITF.cjs.map
174
+ //# sourceMappingURL=DesignSystemSection-KXIQXITF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/DesignSystemSection.tsx"],"names":["jsx","jsxs","ScrollReveal","GlassCard"],"mappings":"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","file":"DesignSystemSection-KXIQXITF.cjs","sourcesContent":["'use client';\n\nimport React from 'react';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface ColorEntry {\n hex: string;\n usageCount?: number;\n context?: string;\n}\n\ninterface FontEntry {\n family: string;\n weights?: number[];\n usage?: string; // 'heading' | 'body' | 'accent'\n}\n\nexport interface DesignSystemData {\n colors: ColorEntry[];\n fonts: FontEntry[];\n headingStyles?: { font?: string; size?: string; weight?: string | number };\n bodyStyles?: { font?: string; size?: string; lineHeight?: string };\n}\n\ninterface DesignSystemSectionProps {\n data: DesignSystemData;\n}\n\n/** Determine if a hex color is light (needs dark text label) */\nfunction isLightColor(hex: string): boolean {\n const c = hex.replace('#', '');\n const r = parseInt(c.substring(0, 2), 16);\n const g = parseInt(c.substring(2, 4), 16);\n const b = parseInt(c.substring(4, 6), 16);\n return (r * 299 + g * 587 + b * 114) / 1000 > 140;\n}\n\nexport default function DesignSystemSection({ data }: DesignSystemSectionProps) {\n const { colors, fonts } = data;\n const headingFont = fonts.find((f) => f.usage === 'heading') || fonts[0];\n const bodyFont = fonts.find((f) => f.usage === 'body') || fonts[1] || fonts[0];\n\n if (!colors.length && !fonts.length) return null;\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 Design System\n </h2>\n <p\n className=\"text-lg mb-12 max-w-2xl\"\n style={{ color: 'var(--sk-text-secondary, #a1a1aa)' }}\n >\n The visual language we crafted for this project.\n </p>\n </ScrollReveal>\n\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-8\">\n {/* Color Palette */}\n {colors.length > 0 && (\n <ScrollReveal y={20}>\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-base font-semibold mb-4\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n Color Palette\n </h3>\n <div className=\"grid grid-cols-3 gap-3\">\n {colors.map((color, ci) => (\n <div key={ci} className=\"flex flex-col items-center gap-2\">\n <div\n className=\"w-full aspect-square rounded-lg border flex items-end justify-center pb-2\"\n style={{\n background: color.hex,\n borderColor: 'color-mix(in srgb, var(--sk-text-tertiary, #71717a) 20%, transparent)',\n }}\n >\n <span\n className=\"text-[10px] font-mono font-medium px-1.5 py-0.5 rounded\"\n style={{\n color: isLightColor(color.hex) ? '#000' : '#fff',\n background: isLightColor(color.hex) ? 'rgba(0,0,0,0.15)' : 'rgba(255,255,255,0.15)',\n }}\n >\n {color.hex}\n </span>\n </div>\n {color.context && (\n <span\n className=\"text-[10px] capitalize\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {color.context}\n </span>\n )}\n </div>\n ))}\n </div>\n </GlassCard>\n </ScrollReveal>\n )}\n\n {/* Typography */}\n {fonts.length > 0 && (\n <ScrollReveal y={20} delay={0.1}>\n <GlassCard padding=\"lg\" hover={false}>\n <h3\n className=\"text-base font-semibold mb-4\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n Typography\n </h3>\n <div className=\"flex flex-col gap-6\">\n {headingFont && (\n <div>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider block mb-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Headings\n </span>\n <p\n className=\"text-2xl font-bold\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: headingFont.family,\n }}\n >\n {headingFont.family}\n </p>\n {headingFont.weights && headingFont.weights.length > 0 && (\n <div className=\"flex gap-2 mt-2\">\n {headingFont.weights.map((w) => (\n <span\n key={w}\n className=\"text-xs px-2 py-0.5 rounded\"\n style={{\n background: 'color-mix(in srgb, var(--sk-text-tertiary, #71717a) 15%, transparent)',\n color: 'var(--sk-text-tertiary, #71717a)',\n fontWeight: w,\n }}\n >\n {w}\n </span>\n ))}\n </div>\n )}\n </div>\n )}\n {bodyFont && bodyFont.family !== headingFont?.family && (\n <div>\n <span\n className=\"text-[10px] font-medium uppercase tracking-wider block mb-2\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n Body\n </span>\n <p\n className=\"text-lg\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: bodyFont.family,\n }}\n >\n {bodyFont.family}\n </p>\n <p\n className=\"text-sm mt-2 leading-relaxed\"\n style={{\n color: 'var(--sk-text-tertiary, #71717a)',\n fontFamily: bodyFont.family,\n }}\n >\n The quick brown fox jumps over the lazy dog. Clean, readable type that puts content first.\n </p>\n </div>\n )}\n </div>\n </GlassCard>\n </ScrollReveal>\n )}\n </div>\n </div>\n </section>\n );\n}\n"]}
@@ -22,9 +22,10 @@ function DetailsSection({ data }) {
22
22
  });
23
23
  }
24
24
  if (data.website) {
25
+ const cleanUrl = data.website.replace(/^https?:\/\/https?:\/\//, "https://");
25
26
  rows.push({
26
27
  label: "Website",
27
- value: data.website,
28
+ value: cleanUrl,
28
29
  icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
29
30
  /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
30
31
  /* @__PURE__ */ jsx("path", { d: "M1.5 9h15M9 1.5a11.25 11.25 0 013 7.5 11.25 11.25 0 01-3 7.5 11.25 11.25 0 01-3-7.5 11.25 11.25 0 013-7.5z", stroke: "currentColor", strokeWidth: "1.5" })
@@ -33,7 +34,7 @@ function DetailsSection({ data }) {
33
34
  }
34
35
  if (data.timeline) {
35
36
  rows.push({
36
- label: "Timeline",
37
+ label: "Delivered In",
37
38
  value: data.timeline,
38
39
  icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
39
40
  /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "7.5", stroke: "currentColor", strokeWidth: "1.5" }),
@@ -42,9 +43,17 @@ function DetailsSection({ data }) {
42
43
  });
43
44
  }
44
45
  if (data.launchDate) {
46
+ let formattedDate = data.launchDate;
47
+ try {
48
+ const d = new Date(data.launchDate);
49
+ if (!isNaN(d.getTime())) {
50
+ formattedDate = d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
51
+ }
52
+ } catch {
53
+ }
45
54
  rows.push({
46
55
  label: "Launch Date",
47
- value: data.launchDate,
56
+ value: formattedDate,
48
57
  icon: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", children: [
49
58
  /* @__PURE__ */ jsx("rect", { x: "2.25", y: "3", width: "13.5", height: "12.75", rx: "2", stroke: "currentColor", strokeWidth: "1.5" }),
50
59
  /* @__PURE__ */ jsx("path", { d: "M12 1.5v3M6 1.5v3M2.25 7.5h13.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
@@ -131,5 +140,5 @@ function DetailsSection({ data }) {
131
140
  }
132
141
 
133
142
  export { DetailsSection as default };
134
- //# sourceMappingURL=DetailsSection-FB763FS7.js.map
135
- //# sourceMappingURL=DetailsSection-FB763FS7.js.map
143
+ //# sourceMappingURL=DetailsSection-A6PZQUQL.js.map
144
+ //# sourceMappingURL=DetailsSection-A6PZQUQL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/portfolio/components/sections/DetailsSection.tsx"],"names":[],"mappings":"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","file":"DetailsSection-A6PZQUQL.js","sourcesContent":["'use client';\n\nimport React from 'react';\nimport type { PortfolioDetailsData } from '../../../types';\nimport ScrollReveal from '../primitives/ScrollReveal';\nimport GlassCard from '../primitives/GlassCard';\n\ninterface DetailsSectionProps {\n data: PortfolioDetailsData;\n}\n\ninterface DetailRow {\n icon: React.ReactNode;\n label: string;\n value: string;\n}\n\nexport default function DetailsSection({ data }: DetailsSectionProps) {\n const rows: DetailRow[] = [];\n\n if (data.industry) {\n rows.push({\n label: 'Industry',\n value: data.industry,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M3 16.5h12M4.5 1.5h9l1.5 6H3l1.5-6zM6 7.5v9M12 7.5v9M9 7.5v9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ),\n });\n }\n\n if (data.location) {\n rows.push({\n label: 'Location',\n value: data.location,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M15 7.5c0 4.5-6 9-6 9s-6-4.5-6-9a6 6 0 1112 0z\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <circle cx=\"9\" cy=\"7.5\" r=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n ),\n });\n }\n\n if (data.website) {\n // Normalize — strip any double protocol prefix\n const cleanUrl = data.website.replace(/^https?:\\/\\/https?:\\/\\//, 'https://');\n rows.push({\n label: 'Website',\n value: cleanUrl,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M1.5 9h15M9 1.5a11.25 11.25 0 013 7.5 11.25 11.25 0 01-3 7.5 11.25 11.25 0 01-3-7.5 11.25 11.25 0 013-7.5z\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n ),\n });\n }\n\n if (data.timeline) {\n rows.push({\n label: 'Delivered In',\n value: data.timeline,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <circle cx=\"9\" cy=\"9\" r=\"7.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M9 4.5V9l3 1.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ),\n });\n }\n\n if (data.launchDate) {\n // Format ISO date to readable string (e.g. \"January 16, 2026\")\n let formattedDate = data.launchDate;\n try {\n const d = new Date(data.launchDate);\n if (!isNaN(d.getTime())) {\n formattedDate = d.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\n }\n } catch { /* keep raw value */ }\n rows.push({\n label: 'Launch Date',\n value: formattedDate,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <rect x=\"2.25\" y=\"3\" width=\"13.5\" height=\"12.75\" rx=\"2\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M12 1.5v3M6 1.5v3M2.25 7.5h13.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n ),\n });\n }\n\n if (data.budgetRange) {\n rows.push({\n label: 'Budget Range',\n value: data.budgetRange,\n icon: (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\n <path d=\"M9 1.5v15M13.5 4.5H6.75a2.625 2.625 0 000 5.25h4.5a2.625 2.625 0 010 5.25H4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n ),\n });\n }\n\n if (rows.length === 0) return null;\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}>\n <h2\n className=\"text-3xl md:text-4xl font-bold mb-8\"\n style={{\n color: 'var(--sk-text-primary, #ffffff)',\n fontFamily: 'var(--sk-font-heading, inherit)',\n }}\n >\n Project Details\n </h2>\n </ScrollReveal>\n\n <ScrollReveal y={40} delay={0.1}>\n <GlassCard padding=\"lg\" hover={false}>\n <div className=\"flex flex-col divide-y\" style={{ borderColor: 'var(--sk-border, rgba(255,255,255,0.1))' }}>\n {rows.map((row, index) => (\n <div\n key={index}\n className=\"flex items-center gap-4 py-4 first:pt-0 last:pb-0\"\n style={{\n borderColor: 'var(--sk-border, rgba(255,255,255,0.1))',\n }}\n >\n <span\n className=\"flex items-center justify-center w-9 h-9 rounded-lg shrink-0\"\n style={{\n background: 'color-mix(in srgb, var(--sk-primary, #6366f1) 12%, transparent)',\n color: 'var(--sk-primary, #6366f1)',\n }}\n >\n {row.icon}\n </span>\n <span\n className=\"text-sm font-medium w-32 shrink-0\"\n style={{ color: 'var(--sk-text-tertiary, #71717a)' }}\n >\n {row.label}\n </span>\n {row.label === 'Website' ? (\n <a\n href={row.value.startsWith('http') ? row.value : `https://${row.value}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-sm font-medium hover:underline\"\n style={{ color: 'var(--sk-primary, #6366f1)' }}\n >\n {row.value}\n </a>\n ) : (\n <span\n className=\"text-sm font-medium\"\n style={{ color: 'var(--sk-text-primary, #ffffff)' }}\n >\n {row.value}\n </span>\n )}\n </div>\n ))}\n </div>\n </GlassCard>\n </ScrollReveal>\n </div>\n </section>\n );\n}\n"]}