@prosophia/lab-minimal 0.0.2 → 0.0.4

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/index.js CHANGED
@@ -30,241 +30,125 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ AnimatedCard: () => AnimatedCard,
34
+ AnimatedGalleryGrid: () => AnimatedGalleryGrid,
35
+ AnimatedGalleryHeader: () => AnimatedGalleryHeader,
36
+ AnimatedGrid: () => AnimatedGrid,
37
+ AnimatedHeader: () => AnimatedHeader,
33
38
  AnimatedHero: () => AnimatedHero,
39
+ AnimatedHeroContent: () => AnimatedHeroContent,
40
+ AnimatedImage: () => AnimatedImage,
41
+ AnimatedItem: () => AnimatedItem,
42
+ AnimatedList: () => AnimatedList,
43
+ AnimatedMain: () => AnimatedMain,
44
+ AnimatedPage: () => AnimatedPage,
45
+ AnimatedSection: () => AnimatedSection,
46
+ AnimatedSectionHeader: () => AnimatedSectionHeader,
47
+ AnimatedStats: () => AnimatedStats,
34
48
  ClientLayout: () => ClientLayout,
35
49
  ContactCTA: () => ContactCTA,
36
50
  Footer: () => Footer,
37
51
  Header: () => Header,
38
- ThemeToggle: () => ThemeToggle
52
+ ScrollRevealSection: () => ScrollRevealSection,
53
+ StaggeredGrid: () => StaggeredGrid,
54
+ ThemeToggle: () => ThemeToggle,
55
+ cardHover: () => cardHover,
56
+ client: () => client,
57
+ defineConfig: () => defineConfig,
58
+ escapeHtml: () => escapeHtml,
59
+ fadeIn: () => fadeIn,
60
+ fadeInUp: () => fadeInUp,
61
+ fadeInUpShort: () => fadeInUpShort,
62
+ getClient: () => getClient,
63
+ imageZoom: () => imageZoom,
64
+ isValidEmail: () => isValidEmail,
65
+ isValidExternalUrl: () => isValidExternalUrl,
66
+ isValidGoogleMapsEmbedUrl: () => isValidGoogleMapsEmbedUrl,
67
+ isValidSlug: () => isValidSlug,
68
+ pageTransition: () => pageTransition,
69
+ reducedMotion: () => reducedMotion,
70
+ sanitizeUrl: () => sanitizeUrl,
71
+ scaleIn: () => scaleIn,
72
+ scrollReveal: () => scrollReveal,
73
+ slideInLeft: () => slideInLeft,
74
+ slideInRight: () => slideInRight,
75
+ staggerContainer: () => staggerContainer,
76
+ staggerItem: () => staggerItem,
77
+ urlFor: () => urlFor,
78
+ viewportSettings: () => viewportSettings
39
79
  });
40
80
  module.exports = __toCommonJS(index_exports);
41
81
 
42
- // src/components/AnimatedCard.tsx
43
- var import_framer_motion = require("framer-motion");
44
-
45
- // src/lib/animations.ts
46
- var fadeInUp = {
47
- hidden: { opacity: 0, y: 30 },
48
- visible: {
49
- opacity: 1,
50
- y: 0,
51
- transition: {
52
- duration: 0.8,
53
- ease: [0.65, 0, 0.35, 1]
54
- }
55
- }
56
- };
57
- var scaleIn = {
58
- hidden: { opacity: 0, scale: 0.9 },
59
- visible: {
60
- opacity: 1,
61
- scale: 1,
62
- transition: {
63
- duration: 0.8,
64
- ease: [0.65, 0, 0.35, 1]
65
- }
66
- }
67
- };
68
-
69
- // src/components/AnimatedCard.tsx
70
- var import_jsx_runtime = require("react/jsx-runtime");
71
-
72
- // src/components/AnimatedGallery.tsx
73
- var import_framer_motion2 = require("framer-motion");
74
- var import_image = __toESM(require("next/image"));
75
- var import_react = require("react");
76
- var import_PicturesPage = __toESM(require("./PicturesPage.module.css"));
77
- var import_jsx_runtime2 = require("react/jsx-runtime");
78
-
79
- // src/components/AnimatedHero.tsx
80
- var import_framer_motion3 = require("framer-motion");
81
- var import_react2 = require("react");
82
- var import_image2 = __toESM(require("next/image"));
83
- var import_link = __toESM(require("next/link"));
84
- var import_HomePage = __toESM(require("./HomePage.module.css"));
85
- var import_jsx_runtime3 = require("react/jsx-runtime");
86
- function AnimatedHero({ heroData, ArrowRightIcon }) {
87
- const ref = (0, import_react2.useRef)(null);
88
- const { scrollY } = (0, import_framer_motion3.useScroll)();
89
- const y = (0, import_framer_motion3.useTransform)(scrollY, [0, 500], [0, 150]);
90
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("section", { className: import_HomePage.default.heroSection, ref, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: import_HomePage.default.heroContainer, children: [
91
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
92
- import_framer_motion3.motion.div,
93
- {
94
- className: import_HomePage.default.heroContent,
95
- initial: "hidden",
96
- animate: "visible",
97
- variants: fadeInUp,
98
- children: [
99
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
100
- import_framer_motion3.motion.span,
101
- {
102
- className: import_HomePage.default.heroTagline,
103
- initial: { opacity: 0 },
104
- animate: { opacity: 1 },
105
- transition: { duration: 0.6, delay: 0.2 },
106
- children: heroData.tagline
107
- }
108
- ),
109
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
110
- import_framer_motion3.motion.h1,
111
- {
112
- className: import_HomePage.default.heroHeading,
113
- initial: { opacity: 0, y: 20 },
114
- animate: { opacity: 1, y: 0 },
115
- transition: { duration: 0.8, delay: 0.3 },
116
- children: [
117
- heroData.heading,
118
- " ",
119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: import_HomePage.default.heroHeadingAccent, children: heroData.headingAccent })
120
- ]
121
- }
122
- ),
123
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
124
- import_framer_motion3.motion.p,
125
- {
126
- className: import_HomePage.default.heroDescription,
127
- initial: { opacity: 0, y: 20 },
128
- animate: { opacity: 1, y: 0 },
129
- transition: { duration: 0.8, delay: 0.4 },
130
- children: heroData.description
131
- }
132
- ),
133
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
134
- import_framer_motion3.motion.div,
135
- {
136
- className: import_HomePage.default.heroCtas,
137
- initial: { opacity: 0, y: 20 },
138
- animate: { opacity: 1, y: 0 },
139
- transition: { duration: 0.8, delay: 0.5 },
140
- children: [
141
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_link.default, { href: heroData.ctaLink, className: import_HomePage.default.heroPrimaryCta, children: [
142
- heroData.ctaText,
143
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowRightIcon, {})
144
- ] }),
145
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link.default, { href: "/publications", className: import_HomePage.default.heroSecondaryCta, children: "View Publications" })
146
- ]
147
- }
148
- )
149
- ]
150
- }
151
- ),
152
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
153
- import_framer_motion3.motion.div,
154
- {
155
- className: import_HomePage.default.heroImageWrapper,
156
- style: { y },
157
- initial: "hidden",
158
- animate: "visible",
159
- variants: scaleIn,
160
- transition: { duration: 0.8, delay: 0.6 },
161
- children: heroData.image ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
162
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
163
- import_image2.default,
164
- {
165
- src: heroData.image,
166
- alt: "Research lab",
167
- width: 800,
168
- height: 600,
169
- className: import_HomePage.default.heroImage,
170
- priority: true
171
- }
172
- ),
173
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: import_HomePage.default.heroImageOverlay })
174
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: import_HomePage.default.heroImagePlaceholder, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
175
- "svg",
176
- {
177
- width: "120",
178
- height: "120",
179
- viewBox: "0 0 24 24",
180
- fill: "none",
181
- stroke: "currentColor",
182
- strokeWidth: "1",
183
- children: [
184
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
185
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
186
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 15l-5-5L5 21" })
187
- ]
188
- }
189
- ) })
190
- }
191
- )
192
- ] }) });
193
- }
194
-
195
- // src/components/AnimatedPage.tsx
196
- var import_framer_motion4 = require("framer-motion");
197
- var import_react3 = require("react");
198
- var import_jsx_runtime4 = require("react/jsx-runtime");
199
-
200
- // src/components/AnimatedSections.tsx
201
- var import_framer_motion5 = require("framer-motion");
202
- var import_jsx_runtime5 = require("react/jsx-runtime");
203
-
204
82
  // src/components/ClientLayout.tsx
205
- var import_react6 = require("react");
83
+ var import_react3 = require("react");
206
84
  var import_next_themes2 = require("next-themes");
207
85
 
208
86
  // src/components/Header.tsx
209
- var import_link2 = __toESM(require("next/link"));
210
- var import_react5 = require("react");
87
+ var import_link = __toESM(require("next/link"));
88
+ var import_react2 = require("react");
211
89
  var import_navigation = require("next/navigation");
212
- var import_Layout = __toESM(require("./Layout.module.css"));
90
+
91
+ // src/components/Layout.module.css
92
+ var Layout_default = {};
213
93
 
214
94
  // src/components/ThemeToggle.tsx
215
95
  var import_next_themes = require("next-themes");
216
- var import_react4 = require("react");
217
- var import_framer_motion6 = require("framer-motion");
218
- var import_ThemeToggle = __toESM(require("./ThemeToggle.module.css"));
219
- var import_jsx_runtime6 = require("react/jsx-runtime");
96
+ var import_react = require("react");
97
+ var import_framer_motion = require("framer-motion");
98
+
99
+ // src/components/ThemeToggle.module.css
100
+ var ThemeToggle_default = {};
101
+
102
+ // src/components/ThemeToggle.tsx
103
+ var import_jsx_runtime = require("react/jsx-runtime");
220
104
  function ThemeToggle() {
221
105
  const { theme, setTheme, resolvedTheme } = (0, import_next_themes.useTheme)();
222
- const [mounted, setMounted] = (0, import_react4.useState)(false);
223
- (0, import_react4.useEffect)(() => {
106
+ const [mounted, setMounted] = (0, import_react.useState)(false);
107
+ (0, import_react.useEffect)(() => {
224
108
  setMounted(true);
225
109
  }, []);
226
110
  if (!mounted) {
227
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: import_ThemeToggle.default.togglePlaceholder });
111
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: ThemeToggle_default.togglePlaceholder });
228
112
  }
229
113
  const isDark = resolvedTheme === "dark";
230
114
  const toggleTheme = () => {
231
115
  setTheme(isDark ? "light" : "dark");
232
116
  };
233
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
234
- import_framer_motion6.motion.button,
117
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
118
+ import_framer_motion.motion.button,
235
119
  {
236
- className: import_ThemeToggle.default.toggle,
120
+ className: ThemeToggle_default.toggle,
237
121
  onClick: toggleTheme,
238
122
  "aria-label": `Switch to ${isDark ? "light" : "dark"} mode`,
239
123
  whileTap: { scale: 0.95 },
240
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: import_ThemeToggle.default.track, children: [
241
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `${import_ThemeToggle.default.icon} ${import_ThemeToggle.default.sunIcon} ${!isDark ? import_ThemeToggle.default.iconActive : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
242
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "12", cy: "12", r: "5" }),
243
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
244
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
245
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
246
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
247
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
248
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
249
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
250
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
124
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: ThemeToggle_default.track, children: [
125
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `${ThemeToggle_default.icon} ${ThemeToggle_default.sunIcon} ${!isDark ? ThemeToggle_default.iconActive : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "5" }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
132
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
133
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
251
135
  ] }) }),
252
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
253
- import_framer_motion6.motion.span,
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
137
+ import_framer_motion.motion.span,
254
138
  {
255
- className: import_ThemeToggle.default.thumb,
139
+ className: ThemeToggle_default.thumb,
256
140
  animate: { x: isDark ? 26 : 0 },
257
141
  transition: { type: "spring", stiffness: 500, damping: 30 }
258
142
  }
259
143
  ),
260
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `${import_ThemeToggle.default.icon} ${import_ThemeToggle.default.moonIcon} ${isDark ? import_ThemeToggle.default.iconActive : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }) })
144
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: `${ThemeToggle_default.icon} ${ThemeToggle_default.moonIcon} ${isDark ? ThemeToggle_default.iconActive : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) }) })
261
145
  ] })
262
146
  }
263
147
  );
264
148
  }
265
149
 
266
150
  // src/components/Header.tsx
267
- var import_jsx_runtime7 = require("react/jsx-runtime");
151
+ var import_jsx_runtime2 = require("react/jsx-runtime");
268
152
  var navLinks = [
269
153
  { href: "/research", label: "Research" },
270
154
  { href: "/publications", label: "Publications" },
@@ -273,17 +157,17 @@ var navLinks = [
273
157
  { href: "/pictures", label: "Gallery" }
274
158
  ];
275
159
  function Header({ settings }) {
276
- const [menuOpen, setMenuOpen] = (0, import_react5.useState)(false);
277
- const [scrolled, setScrolled] = (0, import_react5.useState)(false);
160
+ const [menuOpen, setMenuOpen] = (0, import_react2.useState)(false);
161
+ const [scrolled, setScrolled] = (0, import_react2.useState)(false);
278
162
  const pathname = (0, import_navigation.usePathname)();
279
- (0, import_react5.useEffect)(() => {
163
+ (0, import_react2.useEffect)(() => {
280
164
  const handleScroll = () => {
281
165
  setScrolled(window.scrollY > 20);
282
166
  };
283
167
  window.addEventListener("scroll", handleScroll, { passive: true });
284
168
  return () => window.removeEventListener("scroll", handleScroll);
285
169
  }, []);
286
- (0, import_react5.useEffect)(() => {
170
+ (0, import_react2.useEffect)(() => {
287
171
  if (menuOpen) {
288
172
  document.body.style.overflow = "hidden";
289
173
  } else {
@@ -293,15 +177,15 @@ function Header({ settings }) {
293
177
  document.body.style.overflow = "";
294
178
  };
295
179
  }, [menuOpen]);
296
- (0, import_react5.useEffect)(() => {
180
+ (0, import_react2.useEffect)(() => {
297
181
  setMenuOpen(false);
298
182
  }, [pathname]);
299
- const handleKeyDown = (0, import_react5.useCallback)((e) => {
183
+ const handleKeyDown = (0, import_react2.useCallback)((e) => {
300
184
  if (e.key === "Escape" && menuOpen) {
301
185
  setMenuOpen(false);
302
186
  }
303
187
  }, [menuOpen]);
304
- (0, import_react5.useEffect)(() => {
188
+ (0, import_react2.useEffect)(() => {
305
189
  document.addEventListener("keydown", handleKeyDown);
306
190
  return () => document.removeEventListener("keydown", handleKeyDown);
307
191
  }, [handleKeyDown]);
@@ -309,9 +193,9 @@ function Header({ settings }) {
309
193
  if (href === "/") return pathname === "/";
310
194
  return pathname.startsWith(href);
311
195
  };
312
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("header", { className: `${import_Layout.default.header} ${scrolled ? import_Layout.default.headerScrolled : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: import_Layout.default.navContainer, children: [
313
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_link2.default, { href: "/", className: import_Layout.default.navLogo, "aria-label": "Go to homepage", children: [
314
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
196
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("header", { className: `${Layout_default.header} ${scrolled ? Layout_default.headerScrolled : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: Layout_default.navContainer, children: [
197
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_link.default, { href: "/", className: Layout_default.navLogo, "aria-label": "Go to homepage", children: [
198
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
315
199
  "svg",
316
200
  {
317
201
  width: "32",
@@ -321,7 +205,7 @@ function Header({ settings }) {
321
205
  xmlns: "http://www.w3.org/2000/svg",
322
206
  "aria-hidden": "true",
323
207
  children: [
324
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
208
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
325
209
  "path",
326
210
  {
327
211
  d: "M12 2L2 7L12 12L22 7L12 2Z",
@@ -331,7 +215,7 @@ function Header({ settings }) {
331
215
  strokeLinejoin: "round"
332
216
  }
333
217
  ),
334
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
218
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
335
219
  "path",
336
220
  {
337
221
  d: "M2 17L12 22L22 17",
@@ -341,7 +225,7 @@ function Header({ settings }) {
341
225
  strokeLinejoin: "round"
342
226
  }
343
227
  ),
344
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
228
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
345
229
  "path",
346
230
  {
347
231
  d: "M2 12L12 17L22 12",
@@ -354,79 +238,79 @@ function Header({ settings }) {
354
238
  ]
355
239
  }
356
240
  ),
357
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
241
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
358
242
  settings.labName || "Research",
359
- settings.labNameAccent && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: import_Layout.default.navLogoAccent, children: [
243
+ settings.labNameAccent && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: Layout_default.navLogoAccent, children: [
360
244
  " ",
361
245
  settings.labNameAccent
362
246
  ] })
363
247
  ] })
364
248
  ] }),
365
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { className: import_Layout.default.desktopNav, "aria-label": "Main navigation", children: navLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
366
- import_link2.default,
249
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("nav", { className: Layout_default.desktopNav, "aria-label": "Main navigation", children: navLinks.map((link) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
250
+ import_link.default,
367
251
  {
368
252
  href: link.href,
369
- className: `${import_Layout.default.navLink} ${isActive(link.href) ? import_Layout.default.navLinkActive : ""}`,
253
+ className: `${Layout_default.navLink} ${isActive(link.href) ? Layout_default.navLinkActive : ""}`,
370
254
  children: link.label
371
255
  },
372
256
  link.href
373
257
  )) }),
374
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: import_Layout.default.navActions, children: [
375
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ThemeToggle, {}),
376
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_link2.default, { href: "/contact", className: import_Layout.default.navCta, children: "Contact Us" })
258
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: Layout_default.navActions, children: [
259
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ThemeToggle, {}),
260
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_link.default, { href: "/contact", className: Layout_default.navCta, children: "Contact Us" })
377
261
  ] }),
378
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
262
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
379
263
  "button",
380
264
  {
381
- className: import_Layout.default.menuButton,
265
+ className: Layout_default.menuButton,
382
266
  onClick: () => setMenuOpen(!menuOpen),
383
267
  "aria-label": menuOpen ? "Close menu" : "Open menu",
384
268
  "aria-expanded": menuOpen,
385
269
  "aria-controls": "mobile-menu",
386
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: import_Layout.default.menuButtonLines, children: [
387
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `${import_Layout.default.menuLine} ${menuOpen ? import_Layout.default.menuLineOpen1 : ""}` }),
388
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `${import_Layout.default.menuLine} ${menuOpen ? import_Layout.default.menuLineOpen2 : ""}` }),
389
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: `${import_Layout.default.menuLine} ${menuOpen ? import_Layout.default.menuLineOpen3 : ""}` })
270
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: Layout_default.menuButtonLines, children: [
271
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${Layout_default.menuLine} ${menuOpen ? Layout_default.menuLineOpen1 : ""}` }),
272
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${Layout_default.menuLine} ${menuOpen ? Layout_default.menuLineOpen2 : ""}` }),
273
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: `${Layout_default.menuLine} ${menuOpen ? Layout_default.menuLineOpen3 : ""}` })
390
274
  ] })
391
275
  }
392
276
  ),
393
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
277
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
394
278
  "div",
395
279
  {
396
280
  id: "mobile-menu",
397
- className: `${import_Layout.default.mobileMenu} ${menuOpen ? import_Layout.default.mobileMenuOpen : ""}`,
281
+ className: `${Layout_default.mobileMenu} ${menuOpen ? Layout_default.mobileMenuOpen : ""}`,
398
282
  "aria-hidden": !menuOpen,
399
283
  children: [
400
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
284
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
401
285
  "div",
402
286
  {
403
- className: import_Layout.default.mobileMenuOverlay,
287
+ className: Layout_default.mobileMenuOverlay,
404
288
  onClick: () => setMenuOpen(false),
405
289
  "aria-hidden": "true"
406
290
  }
407
291
  ),
408
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
292
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
409
293
  "nav",
410
294
  {
411
- className: import_Layout.default.mobileMenuContent,
295
+ className: Layout_default.mobileMenuContent,
412
296
  "aria-label": "Mobile navigation",
413
297
  children: [
414
- navLinks.map((link, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
415
- import_link2.default,
298
+ navLinks.map((link, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
299
+ import_link.default,
416
300
  {
417
301
  href: link.href,
418
- className: `${import_Layout.default.mobileNavLink} ${isActive(link.href) ? import_Layout.default.mobileNavLinkActive : ""}`,
302
+ className: `${Layout_default.mobileNavLink} ${isActive(link.href) ? Layout_default.mobileNavLinkActive : ""}`,
419
303
  style: { animationDelay: `${index * 50}ms` },
420
304
  tabIndex: menuOpen ? 0 : -1,
421
305
  children: link.label
422
306
  },
423
307
  link.href
424
308
  )),
425
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
426
- import_link2.default,
309
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
310
+ import_link.default,
427
311
  {
428
312
  href: "/contact",
429
- className: import_Layout.default.mobileNavCta,
313
+ className: Layout_default.mobileNavCta,
430
314
  style: { animationDelay: `${navLinks.length * 50}ms` },
431
315
  tabIndex: menuOpen ? 0 : -1,
432
316
  children: "Contact Us"
@@ -442,8 +326,10 @@ function Header({ settings }) {
442
326
  }
443
327
 
444
328
  // src/components/Footer.tsx
445
- var import_link3 = __toESM(require("next/link"));
446
- var import_Footer = __toESM(require("./Footer.module.css"));
329
+ var import_link2 = __toESM(require("next/link"));
330
+
331
+ // src/components/Footer.module.css
332
+ var Footer_default = {};
447
333
 
448
334
  // src/lib/utils.ts
449
335
  function isValidExternalUrl(url) {
@@ -455,64 +341,104 @@ function isValidExternalUrl(url) {
455
341
  return false;
456
342
  }
457
343
  }
344
+ function isValidGoogleMapsEmbedUrl(url) {
345
+ if (!url || typeof url !== "string") return false;
346
+ try {
347
+ const parsed = new URL(url);
348
+ const allowedHosts = [
349
+ "www.google.com",
350
+ "google.com",
351
+ "maps.google.com"
352
+ ];
353
+ return parsed.protocol === "https:" && allowedHosts.includes(parsed.hostname) && parsed.pathname.startsWith("/maps/embed");
354
+ } catch {
355
+ return false;
356
+ }
357
+ }
358
+ function sanitizeUrl(url) {
359
+ if (isValidExternalUrl(url)) {
360
+ return url;
361
+ }
362
+ return void 0;
363
+ }
364
+ function isValidEmail(email) {
365
+ if (!email || typeof email !== "string") return false;
366
+ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
367
+ return emailPattern.test(email) && email.length <= 254;
368
+ }
369
+ function escapeHtml(text) {
370
+ const htmlEntities = {
371
+ "&": "&amp;",
372
+ "<": "&lt;",
373
+ ">": "&gt;",
374
+ '"': "&quot;",
375
+ "'": "&#39;"
376
+ };
377
+ return text.replace(/[&<>"']/g, (char) => htmlEntities[char]);
378
+ }
379
+ function isValidSlug(slug) {
380
+ if (!slug || typeof slug !== "string") return false;
381
+ const slugPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
382
+ return slugPattern.test(slug) && slug.length <= 200;
383
+ }
458
384
 
459
385
  // src/components/Footer.tsx
460
- var import_jsx_runtime8 = require("react/jsx-runtime");
461
- var SocialIcon = ({ href, children }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: import_Footer.default.socialIcon, children });
386
+ var import_jsx_runtime3 = require("react/jsx-runtime");
387
+ var SocialIcon = ({ href, children }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", className: Footer_default.socialIcon, children });
462
388
  function Footer({ settings }) {
463
389
  const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
464
390
  const showPrivacy = settings?.showPrivacyPolicy !== false;
465
391
  const showTerms = settings?.showTerms !== false;
466
392
  const hasLegalLinks = showPrivacy || showTerms;
467
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { className: import_Footer.default.footerWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerContainer, children: [
468
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.mainFooter, children: [
469
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerAbout, children: [
470
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_link3.default, { href: "/", className: import_Footer.default.footerLogo, children: [
393
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("footer", { className: Footer_default.footerWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerContainer, children: [
394
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.mainFooter, children: [
395
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerAbout, children: [
396
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_link2.default, { href: "/", className: Footer_default.footerLogo, children: [
471
397
  settings?.labName || "Cavendish",
472
398
  " ",
473
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: import_Footer.default.logoAccent, children: settings?.labNameAccent || "Lab" })
399
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: Footer_default.logoAccent, children: settings?.labNameAccent || "Lab" })
474
400
  ] }),
475
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: import_Footer.default.footerDescription, children: settings?.labNameDescription || "Advancing the frontiers of physics and our understanding of the universe." }),
476
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.socials, children: [
477
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SocialIcon, { href: "#", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" }) }) }),
478
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SocialIcon, { href: "#", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.617l-5.21-6.817-6.044 6.817h-3.308l7.73-8.835-7.73-10.668h6.78l4.522 6.312 5.59-6.312z" }) }) })
401
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: Footer_default.footerDescription, children: settings?.labNameDescription || "Advancing the frontiers of physics and our understanding of the universe." }),
402
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.socials, children: [
403
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SocialIcon, { href: "#", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" }) }) }),
404
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SocialIcon, { href: "#", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24h-6.617l-5.21-6.817-6.044 6.817h-3.308l7.73-8.835-7.73-10.668h6.78l4.522 6.312 5.59-6.312z" }) }) })
479
405
  ] })
480
406
  ] }),
481
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerLinksGrid, children: [
482
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerColumn, children: [
483
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Quick Links" }),
484
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/research", children: "Research" }),
485
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/publications", children: "Publications" }),
486
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/pictures", children: "Gallery" })
407
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerLinksGrid, children: [
408
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerColumn, children: [
409
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h4", { children: "Quick Links" }),
410
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/research", children: "Research" }),
411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/publications", children: "Publications" }),
412
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/pictures", children: "Gallery" })
487
413
  ] }),
488
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerColumn, children: [
489
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "About" }),
490
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/news", children: "News" }),
491
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/people", children: "Our Team" }),
492
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/contact", children: "Contact" })
414
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerColumn, children: [
415
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h4", { children: "About" }),
416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/news", children: "News" }),
417
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/people", children: "Our Team" }),
418
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/contact", children: "Contact" })
493
419
  ] }),
494
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerColumn, children: [
495
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Resources" }),
496
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "https://www.cam.ac.uk/", children: "University" }),
497
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "#", children: "Careers" })
420
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerColumn, children: [
421
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h4", { children: "Resources" }),
422
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "https://www.cam.ac.uk/", children: "University" }),
423
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "#", children: "Careers" })
498
424
  ] })
499
425
  ] })
500
426
  ] }),
501
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.footerBottomBar, children: [
502
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: settings?.footerText || `\xA9 ${currentYear} The Research Group. All Rights Reserved.` }),
503
- hasLegalLinks && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: import_Footer.default.legalLinks, children: [
504
- showPrivacy && (settings?.privacyPolicyUrl && isValidExternalUrl(settings.privacyPolicyUrl) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: settings.privacyPolicyUrl, target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/privacy", children: "Privacy Policy" })),
505
- showTerms && (settings?.termsUrl && isValidExternalUrl(settings.termsUrl) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href: settings.termsUrl, target: "_blank", rel: "noopener noreferrer", children: "Terms & Conditions" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_link3.default, { href: "/terms", children: "Terms & Conditions" }))
427
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.footerBottomBar, children: [
428
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: settings?.footerText || `\xA9 ${currentYear} The Research Group. All Rights Reserved.` }),
429
+ hasLegalLinks && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Footer_default.legalLinks, children: [
430
+ showPrivacy && (settings?.privacyPolicyUrl && isValidExternalUrl(settings.privacyPolicyUrl) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: settings.privacyPolicyUrl, target: "_blank", rel: "noopener noreferrer", children: "Privacy Policy" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/privacy", children: "Privacy Policy" })),
431
+ showTerms && (settings?.termsUrl && isValidExternalUrl(settings.termsUrl) ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("a", { href: settings.termsUrl, target: "_blank", rel: "noopener noreferrer", children: "Terms & Conditions" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_link2.default, { href: "/terms", children: "Terms & Conditions" }))
506
432
  ] })
507
433
  ] })
508
434
  ] }) });
509
435
  }
510
436
 
511
437
  // src/components/ClientLayout.tsx
512
- var import_jsx_runtime9 = require("react/jsx-runtime");
438
+ var import_jsx_runtime4 = require("react/jsx-runtime");
513
439
  function ThemeBodySync() {
514
440
  const { resolvedTheme } = (0, import_next_themes2.useTheme)();
515
- (0, import_react6.useEffect)(() => {
441
+ (0, import_react3.useEffect)(() => {
516
442
  if (resolvedTheme === "dark") {
517
443
  document.body.classList.add("dark-mode");
518
444
  document.body.classList.remove("light-mode");
@@ -524,33 +450,848 @@ function ThemeBodySync() {
524
450
  return null;
525
451
  }
526
452
  function ClientLayout({ children, settings }) {
527
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_next_themes2.ThemeProvider, { attribute: "class", defaultTheme: "light", enableSystem: false, children: [
528
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ThemeBodySync, {}),
529
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "pageWrapper", children: [
530
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Header, { settings }),
531
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("main", { children }),
532
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Footer, { settings })
453
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_next_themes2.ThemeProvider, { attribute: "class", defaultTheme: "light", enableSystem: false, children: [
454
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ThemeBodySync, {}),
455
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "pageWrapper", children: [
456
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Header, { settings }),
457
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("main", { children }),
458
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Footer, { settings })
533
459
  ] })
534
460
  ] });
535
461
  }
536
462
 
537
463
  // src/components/ContactCTA.tsx
538
- var import_link4 = __toESM(require("next/link"));
539
- var import_ContactCTA = __toESM(require("./ContactCTA.module.css"));
540
- var import_jsx_runtime10 = require("react/jsx-runtime");
464
+ var import_link3 = __toESM(require("next/link"));
465
+
466
+ // src/components/ContactCTA.module.css
467
+ var ContactCTA_default = {};
468
+
469
+ // src/components/ContactCTA.tsx
470
+ var import_jsx_runtime5 = require("react/jsx-runtime");
541
471
  function ContactCTA() {
542
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("section", { className: import_ContactCTA.default.ctaContainer, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: import_ContactCTA.default.ctaContent, children: [
543
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: import_ContactCTA.default.ctaHeading, children: "Interested in Our Research?" }),
544
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: import_ContactCTA.default.ctaText, children: "Follow our work, explore our publications, or get in touch to discuss potential collaborations." }),
545
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_link4.default, { href: "/contact", className: import_ContactCTA.default.ctaButton, children: "Contact Us" })
472
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("section", { className: ContactCTA_default.ctaContainer, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: ContactCTA_default.ctaContent, children: [
473
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: ContactCTA_default.ctaHeading, children: "Interested in Our Research?" }),
474
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: ContactCTA_default.ctaText, children: "Follow our work, explore our publications, or get in touch to discuss potential collaborations." }),
475
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_link3.default, { href: "/contact", className: ContactCTA_default.ctaButton, children: "Contact Us" })
546
476
  ] }) });
547
477
  }
478
+
479
+ // src/components/AnimatedHero.tsx
480
+ var import_framer_motion2 = require("framer-motion");
481
+ var import_react4 = require("react");
482
+ var import_image = __toESM(require("next/image"));
483
+ var import_link4 = __toESM(require("next/link"));
484
+
485
+ // src/components/HomePage.module.css
486
+ var HomePage_default = {};
487
+
488
+ // src/lib/animations.ts
489
+ var fadeIn = {
490
+ hidden: { opacity: 0 },
491
+ visible: {
492
+ opacity: 1,
493
+ transition: {
494
+ duration: 0.6,
495
+ ease: [0.65, 0, 0.35, 1]
496
+ }
497
+ }
498
+ };
499
+ var fadeInUp = {
500
+ hidden: { opacity: 0, y: 30 },
501
+ visible: {
502
+ opacity: 1,
503
+ y: 0,
504
+ transition: {
505
+ duration: 0.8,
506
+ ease: [0.65, 0, 0.35, 1]
507
+ }
508
+ }
509
+ };
510
+ var fadeInUpShort = {
511
+ hidden: { opacity: 0, y: 20 },
512
+ visible: {
513
+ opacity: 1,
514
+ y: 0,
515
+ transition: {
516
+ duration: 0.6,
517
+ ease: [0.4, 0, 0.2, 1]
518
+ }
519
+ }
520
+ };
521
+ var scaleIn = {
522
+ hidden: { opacity: 0, scale: 0.9 },
523
+ visible: {
524
+ opacity: 1,
525
+ scale: 1,
526
+ transition: {
527
+ duration: 0.8,
528
+ ease: [0.65, 0, 0.35, 1]
529
+ }
530
+ }
531
+ };
532
+ var slideInRight = {
533
+ hidden: { opacity: 0, x: 20 },
534
+ visible: {
535
+ opacity: 1,
536
+ x: 0,
537
+ transition: {
538
+ duration: 0.6,
539
+ ease: [0.4, 0, 0.2, 1]
540
+ }
541
+ }
542
+ };
543
+ var slideInLeft = {
544
+ hidden: { opacity: 0, x: -20 },
545
+ visible: {
546
+ opacity: 1,
547
+ x: 0,
548
+ transition: {
549
+ duration: 0.6,
550
+ ease: [0.4, 0, 0.2, 1]
551
+ }
552
+ }
553
+ };
554
+ var staggerContainer = {
555
+ hidden: { opacity: 0 },
556
+ visible: {
557
+ opacity: 1,
558
+ transition: {
559
+ staggerChildren: 0.1,
560
+ delayChildren: 0.2
561
+ }
562
+ }
563
+ };
564
+ var staggerItem = {
565
+ hidden: { opacity: 0, y: 20 },
566
+ visible: {
567
+ opacity: 1,
568
+ y: 0,
569
+ transition: {
570
+ duration: 0.5,
571
+ ease: [0.4, 0, 0.2, 1]
572
+ }
573
+ }
574
+ };
575
+ var cardHover = {
576
+ hover: {
577
+ y: -8,
578
+ transition: {
579
+ duration: 0.3,
580
+ ease: [0.4, 0, 0.2, 1]
581
+ }
582
+ }
583
+ };
584
+ var imageZoom = {
585
+ hover: {
586
+ scale: 1.08,
587
+ transition: {
588
+ duration: 0.5,
589
+ ease: [0.65, 0, 0.35, 1]
590
+ }
591
+ }
592
+ };
593
+ var pageTransition = {
594
+ hidden: { opacity: 0, y: 20 },
595
+ visible: {
596
+ opacity: 1,
597
+ y: 0,
598
+ transition: {
599
+ duration: 0.6,
600
+ ease: [0.4, 0, 0.2, 1]
601
+ }
602
+ },
603
+ exit: {
604
+ opacity: 0,
605
+ y: -20,
606
+ transition: {
607
+ duration: 0.4,
608
+ ease: [0.4, 0, 0.2, 1]
609
+ }
610
+ }
611
+ };
612
+ var viewportSettings = {
613
+ once: true,
614
+ amount: 0.3,
615
+ margin: "0px 0px -100px 0px"
616
+ };
617
+ var scrollReveal = {
618
+ hidden: { opacity: 0, y: 50 },
619
+ visible: {
620
+ opacity: 1,
621
+ y: 0,
622
+ transition: {
623
+ duration: 0.8,
624
+ ease: [0.65, 0, 0.35, 1]
625
+ }
626
+ }
627
+ };
628
+ var reducedMotion = {
629
+ hidden: { opacity: 0 },
630
+ visible: {
631
+ opacity: 1,
632
+ transition: {
633
+ duration: 0.01
634
+ }
635
+ }
636
+ };
637
+
638
+ // src/components/AnimatedHero.tsx
639
+ var import_jsx_runtime6 = require("react/jsx-runtime");
640
+ function AnimatedHero({ heroData, ArrowRightIcon }) {
641
+ const ref = (0, import_react4.useRef)(null);
642
+ const { scrollY } = (0, import_framer_motion2.useScroll)();
643
+ const y = (0, import_framer_motion2.useTransform)(scrollY, [0, 500], [0, 150]);
644
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("section", { className: HomePage_default.heroSection, ref, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: HomePage_default.heroContainer, children: [
645
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
646
+ import_framer_motion2.motion.div,
647
+ {
648
+ className: HomePage_default.heroContent,
649
+ initial: "hidden",
650
+ animate: "visible",
651
+ variants: fadeInUp,
652
+ children: [
653
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
654
+ import_framer_motion2.motion.span,
655
+ {
656
+ className: HomePage_default.heroTagline,
657
+ initial: { opacity: 0 },
658
+ animate: { opacity: 1 },
659
+ transition: { duration: 0.6, delay: 0.2 },
660
+ children: heroData.tagline
661
+ }
662
+ ),
663
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
664
+ import_framer_motion2.motion.h1,
665
+ {
666
+ className: HomePage_default.heroHeading,
667
+ initial: { opacity: 0, y: 20 },
668
+ animate: { opacity: 1, y: 0 },
669
+ transition: { duration: 0.8, delay: 0.3 },
670
+ children: [
671
+ heroData.heading,
672
+ " ",
673
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: HomePage_default.heroHeadingAccent, children: heroData.headingAccent })
674
+ ]
675
+ }
676
+ ),
677
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
678
+ import_framer_motion2.motion.p,
679
+ {
680
+ className: HomePage_default.heroDescription,
681
+ initial: { opacity: 0, y: 20 },
682
+ animate: { opacity: 1, y: 0 },
683
+ transition: { duration: 0.8, delay: 0.4 },
684
+ children: heroData.description
685
+ }
686
+ ),
687
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
688
+ import_framer_motion2.motion.div,
689
+ {
690
+ className: HomePage_default.heroCtas,
691
+ initial: { opacity: 0, y: 20 },
692
+ animate: { opacity: 1, y: 0 },
693
+ transition: { duration: 0.8, delay: 0.5 },
694
+ children: [
695
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_link4.default, { href: heroData.ctaLink, className: HomePage_default.heroPrimaryCta, children: [
696
+ heroData.ctaText,
697
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ArrowRightIcon, {})
698
+ ] }),
699
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_link4.default, { href: "/publications", className: HomePage_default.heroSecondaryCta, children: "View Publications" })
700
+ ]
701
+ }
702
+ )
703
+ ]
704
+ }
705
+ ),
706
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
707
+ import_framer_motion2.motion.div,
708
+ {
709
+ className: HomePage_default.heroImageWrapper,
710
+ style: { y },
711
+ initial: "hidden",
712
+ animate: "visible",
713
+ variants: scaleIn,
714
+ transition: { duration: 0.8, delay: 0.6 },
715
+ children: heroData.image ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
716
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
717
+ import_image.default,
718
+ {
719
+ src: heroData.image,
720
+ alt: "Research lab",
721
+ width: 800,
722
+ height: 600,
723
+ className: HomePage_default.heroImage,
724
+ priority: true
725
+ }
726
+ ),
727
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: HomePage_default.heroImageOverlay })
728
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: HomePage_default.heroImagePlaceholder, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
729
+ "svg",
730
+ {
731
+ width: "120",
732
+ height: "120",
733
+ viewBox: "0 0 24 24",
734
+ fill: "none",
735
+ stroke: "currentColor",
736
+ strokeWidth: "1",
737
+ children: [
738
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
739
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
740
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M21 15l-5-5L5 21" })
741
+ ]
742
+ }
743
+ ) })
744
+ }
745
+ )
746
+ ] }) });
747
+ }
748
+
749
+ // src/components/AnimatedCard.tsx
750
+ var import_framer_motion3 = require("framer-motion");
751
+ var import_jsx_runtime7 = require("react/jsx-runtime");
752
+ function AnimatedCard({ children, className, delay = 0 }) {
753
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
754
+ import_framer_motion3.motion.div,
755
+ {
756
+ className,
757
+ initial: "hidden",
758
+ whileInView: "visible",
759
+ viewport: viewportSettings,
760
+ variants: {
761
+ hidden: { opacity: 0, y: 30 },
762
+ visible: {
763
+ opacity: 1,
764
+ y: 0,
765
+ transition: {
766
+ duration: 0.6,
767
+ delay,
768
+ ease: [0.4, 0, 0.2, 1]
769
+ }
770
+ }
771
+ },
772
+ whileHover: "hover",
773
+ children
774
+ }
775
+ );
776
+ }
777
+ function AnimatedImage({ children, className }) {
778
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_framer_motion3.motion.div, { className, variants: imageZoom, children });
779
+ }
780
+ function AnimatedSection({ children, className }) {
781
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
782
+ import_framer_motion3.motion.section,
783
+ {
784
+ className,
785
+ initial: "hidden",
786
+ whileInView: "visible",
787
+ viewport: viewportSettings,
788
+ variants: fadeInUpShort,
789
+ children
790
+ }
791
+ );
792
+ }
793
+
794
+ // src/components/AnimatedGallery.tsx
795
+ var import_framer_motion4 = require("framer-motion");
796
+ var import_image2 = __toESM(require("next/image"));
797
+ var import_react5 = require("react");
798
+
799
+ // src/components/PicturesPage.module.css
800
+ var PicturesPage_default = {};
801
+
802
+ // src/components/AnimatedGallery.tsx
803
+ var import_jsx_runtime8 = require("react/jsx-runtime");
804
+ function useMounted() {
805
+ const [mounted, setMounted] = (0, import_react5.useState)(false);
806
+ (0, import_react5.useEffect)(() => {
807
+ setMounted(true);
808
+ }, []);
809
+ return mounted;
810
+ }
811
+ function AnimatedGalleryHeader({ children, className }) {
812
+ const mounted = useMounted();
813
+ if (!mounted) {
814
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("header", { className, children });
815
+ }
816
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
817
+ import_framer_motion4.motion.header,
818
+ {
819
+ className,
820
+ initial: { opacity: 0, y: 30 },
821
+ animate: { opacity: 1, y: 0 },
822
+ transition: { duration: 0.8, ease: [0.4, 0, 0.2, 1] },
823
+ children
824
+ }
825
+ );
826
+ }
827
+ function AnimatedGalleryGrid({ images }) {
828
+ const mounted = useMounted();
829
+ if (!mounted) {
830
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: PicturesPage_default.photosGrid, children: images.map((pic) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: PicturesPage_default.photoCard, children: [
831
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: PicturesPage_default.photoImageWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
832
+ import_image2.default,
833
+ {
834
+ src: pic.imageUrl,
835
+ alt: pic.altText,
836
+ width: pic.width,
837
+ height: pic.height,
838
+ sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw",
839
+ className: PicturesPage_default.photoImage
840
+ }
841
+ ) }),
842
+ pic.caption && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: PicturesPage_default.photoCaption, children: pic.caption })
843
+ ] }, pic._id)) });
844
+ }
845
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
846
+ import_framer_motion4.motion.div,
847
+ {
848
+ className: PicturesPage_default.photosGrid,
849
+ initial: "hidden",
850
+ animate: "visible",
851
+ variants: {
852
+ hidden: { opacity: 0 },
853
+ visible: {
854
+ opacity: 1,
855
+ transition: {
856
+ staggerChildren: 0.08,
857
+ delayChildren: 0.2
858
+ }
859
+ }
860
+ },
861
+ children: images.map((pic) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
862
+ import_framer_motion4.motion.div,
863
+ {
864
+ className: PicturesPage_default.photoCard,
865
+ variants: {
866
+ hidden: { opacity: 0, y: 40, scale: 0.95 },
867
+ visible: {
868
+ opacity: 1,
869
+ y: 0,
870
+ scale: 1,
871
+ transition: {
872
+ duration: 0.6,
873
+ ease: [0.4, 0, 0.2, 1]
874
+ }
875
+ }
876
+ },
877
+ whileHover: {
878
+ scale: 1.05,
879
+ transition: { duration: 0.3 }
880
+ },
881
+ children: [
882
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: PicturesPage_default.photoImageWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
883
+ import_image2.default,
884
+ {
885
+ src: pic.imageUrl,
886
+ alt: pic.altText,
887
+ width: pic.width,
888
+ height: pic.height,
889
+ sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw",
890
+ className: PicturesPage_default.photoImage
891
+ }
892
+ ) }),
893
+ pic.caption && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: PicturesPage_default.photoCaption, children: pic.caption })
894
+ ]
895
+ },
896
+ pic._id
897
+ ))
898
+ }
899
+ );
900
+ }
901
+
902
+ // src/components/AnimatedPage.tsx
903
+ var import_framer_motion5 = require("framer-motion");
904
+ var import_react6 = require("react");
905
+ var import_jsx_runtime9 = require("react/jsx-runtime");
906
+ function useMounted2() {
907
+ const [mounted, setMounted] = (0, import_react6.useState)(false);
908
+ (0, import_react6.useEffect)(() => {
909
+ setMounted(true);
910
+ }, []);
911
+ return mounted;
912
+ }
913
+ function AnimatedPage({ children, className }) {
914
+ const mounted = useMounted2();
915
+ if (!mounted) {
916
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, children });
917
+ }
918
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
919
+ import_framer_motion5.motion.div,
920
+ {
921
+ className,
922
+ initial: { opacity: 0 },
923
+ animate: { opacity: 1 },
924
+ transition: { duration: 0.6, ease: [0.4, 0, 0.2, 1] },
925
+ children
926
+ }
927
+ );
928
+ }
929
+ function AnimatedHeader({ children, className }) {
930
+ const mounted = useMounted2();
931
+ if (!mounted) {
932
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("header", { className, children });
933
+ }
934
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
935
+ import_framer_motion5.motion.header,
936
+ {
937
+ className,
938
+ initial: { opacity: 0, y: 15 },
939
+ animate: { opacity: 1, y: 0 },
940
+ transition: { duration: 0.5, ease: [0.4, 0, 0.2, 1] },
941
+ children
942
+ }
943
+ );
944
+ }
945
+ function AnimatedMain({ children, className }) {
946
+ const mounted = useMounted2();
947
+ if (!mounted) {
948
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("main", { className, children });
949
+ }
950
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
951
+ import_framer_motion5.motion.main,
952
+ {
953
+ className,
954
+ initial: { opacity: 0, y: 10 },
955
+ animate: { opacity: 1, y: 0 },
956
+ transition: { duration: 0.5, delay: 0.1, ease: [0.4, 0, 0.2, 1] },
957
+ children
958
+ }
959
+ );
960
+ }
961
+ function StaggeredGrid({ children, className }) {
962
+ const mounted = useMounted2();
963
+ const childArray = Array.isArray(children) ? children : [children];
964
+ if (!mounted) {
965
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, children });
966
+ }
967
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
968
+ import_framer_motion5.motion.div,
969
+ {
970
+ className,
971
+ initial: "hidden",
972
+ whileInView: "visible",
973
+ viewport: { once: true, amount: 0.1 },
974
+ variants: {
975
+ hidden: { opacity: 0 },
976
+ visible: {
977
+ opacity: 1,
978
+ transition: {
979
+ staggerChildren: 0.05,
980
+ delayChildren: 0.05
981
+ }
982
+ }
983
+ },
984
+ children: childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
985
+ import_framer_motion5.motion.div,
986
+ {
987
+ variants: {
988
+ hidden: { opacity: 0, y: 15 },
989
+ visible: {
990
+ opacity: 1,
991
+ y: 0,
992
+ transition: {
993
+ duration: 0.5,
994
+ ease: [0.4, 0, 0.2, 1]
995
+ }
996
+ }
997
+ },
998
+ children: child
999
+ },
1000
+ index
1001
+ ))
1002
+ }
1003
+ );
1004
+ }
1005
+ function AnimatedItem({ children, className, delay = 0, index = 0 }) {
1006
+ const mounted = useMounted2();
1007
+ if (!mounted) {
1008
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, children });
1009
+ }
1010
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1011
+ import_framer_motion5.motion.div,
1012
+ {
1013
+ className,
1014
+ initial: { opacity: 0, y: 15 },
1015
+ whileInView: { opacity: 1, y: 0 },
1016
+ viewport: { once: true, amount: 0.2 },
1017
+ transition: {
1018
+ duration: 0.5,
1019
+ delay: delay || index * 0.05,
1020
+ ease: [0.4, 0, 0.2, 1]
1021
+ },
1022
+ children
1023
+ }
1024
+ );
1025
+ }
1026
+ function ScrollRevealSection({ children, className }) {
1027
+ const mounted = useMounted2();
1028
+ if (!mounted) {
1029
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("section", { className, children });
1030
+ }
1031
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1032
+ import_framer_motion5.motion.section,
1033
+ {
1034
+ className,
1035
+ initial: { opacity: 0, y: 20 },
1036
+ whileInView: { opacity: 1, y: 0 },
1037
+ viewport: { once: true, amount: 0.15 },
1038
+ transition: { duration: 0.5, ease: [0.4, 0, 0.2, 1] },
1039
+ children
1040
+ }
1041
+ );
1042
+ }
1043
+ function AnimatedHeroContent({ children, className }) {
1044
+ const mounted = useMounted2();
1045
+ const childArray = Array.isArray(children) ? children : [children];
1046
+ if (!mounted) {
1047
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className, children });
1048
+ }
1049
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1050
+ import_framer_motion5.motion.div,
1051
+ {
1052
+ className,
1053
+ initial: "hidden",
1054
+ animate: "visible",
1055
+ variants: {
1056
+ hidden: { opacity: 0 },
1057
+ visible: {
1058
+ opacity: 1,
1059
+ transition: {
1060
+ staggerChildren: 0.08,
1061
+ delayChildren: 0.05
1062
+ }
1063
+ }
1064
+ },
1065
+ children: childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1066
+ import_framer_motion5.motion.div,
1067
+ {
1068
+ variants: {
1069
+ hidden: { opacity: 0, y: 10 },
1070
+ visible: {
1071
+ opacity: 1,
1072
+ y: 0,
1073
+ transition: {
1074
+ duration: 0.5,
1075
+ ease: [0.4, 0, 0.2, 1]
1076
+ }
1077
+ }
1078
+ },
1079
+ children: child
1080
+ },
1081
+ index
1082
+ ))
1083
+ }
1084
+ );
1085
+ }
1086
+
1087
+ // src/components/AnimatedSections.tsx
1088
+ var import_framer_motion6 = require("framer-motion");
1089
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1090
+ function AnimatedGrid({ children, className }) {
1091
+ const childArray = Array.isArray(children) ? children : [children];
1092
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1093
+ import_framer_motion6.motion.div,
1094
+ {
1095
+ className,
1096
+ initial: "hidden",
1097
+ whileInView: "visible",
1098
+ viewport: viewportSettings,
1099
+ variants: staggerContainer,
1100
+ children: childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_framer_motion6.motion.div, { variants: staggerItem, children: child }, index))
1101
+ }
1102
+ );
1103
+ }
1104
+ function AnimatedStats({ children, className }) {
1105
+ const childArray = Array.isArray(children) ? children : [children];
1106
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1107
+ import_framer_motion6.motion.div,
1108
+ {
1109
+ className,
1110
+ initial: "hidden",
1111
+ whileInView: "visible",
1112
+ viewport: { once: true, amount: 0.3 },
1113
+ variants: {
1114
+ hidden: { opacity: 0 },
1115
+ visible: {
1116
+ opacity: 1,
1117
+ transition: {
1118
+ staggerChildren: 0.15,
1119
+ delayChildren: 0.1
1120
+ }
1121
+ }
1122
+ },
1123
+ children: childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1124
+ import_framer_motion6.motion.div,
1125
+ {
1126
+ variants: {
1127
+ hidden: { opacity: 0, scale: 0.8 },
1128
+ visible: {
1129
+ opacity: 1,
1130
+ scale: 1,
1131
+ transition: {
1132
+ duration: 0.5,
1133
+ ease: [0.4, 0, 0.2, 1]
1134
+ }
1135
+ }
1136
+ },
1137
+ children: child
1138
+ },
1139
+ index
1140
+ ))
1141
+ }
1142
+ );
1143
+ }
1144
+ function AnimatedSectionHeader({ children, className }) {
1145
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1146
+ import_framer_motion6.motion.header,
1147
+ {
1148
+ className,
1149
+ initial: "hidden",
1150
+ whileInView: "visible",
1151
+ viewport: viewportSettings,
1152
+ variants: fadeInUpShort,
1153
+ children
1154
+ }
1155
+ );
1156
+ }
1157
+ function AnimatedList({ children, className }) {
1158
+ const childArray = Array.isArray(children) ? children : [children];
1159
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1160
+ import_framer_motion6.motion.div,
1161
+ {
1162
+ className,
1163
+ initial: "hidden",
1164
+ whileInView: "visible",
1165
+ viewport: viewportSettings,
1166
+ variants: {
1167
+ hidden: { opacity: 0 },
1168
+ visible: {
1169
+ opacity: 1,
1170
+ transition: {
1171
+ staggerChildren: 0.08,
1172
+ delayChildren: 0.1
1173
+ }
1174
+ }
1175
+ },
1176
+ children: childArray.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1177
+ import_framer_motion6.motion.div,
1178
+ {
1179
+ variants: {
1180
+ hidden: { opacity: 0, x: -20 },
1181
+ visible: {
1182
+ opacity: 1,
1183
+ x: 0,
1184
+ transition: {
1185
+ duration: 0.5,
1186
+ ease: [0.4, 0, 0.2, 1]
1187
+ }
1188
+ }
1189
+ },
1190
+ children: child
1191
+ },
1192
+ index
1193
+ ))
1194
+ }
1195
+ );
1196
+ }
1197
+
1198
+ // src/config.ts
1199
+ function defineConfig(config) {
1200
+ return config;
1201
+ }
1202
+
1203
+ // src/lib/sanity.ts
1204
+ var import_next_sanity = require("next-sanity");
1205
+ var import_image_url = __toESM(require("@sanity/image-url"));
1206
+ var projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
1207
+ var dataset = process.env.NEXT_PUBLIC_SANITY_DATASET || "production";
1208
+ var apiVersion = "2023-05-03";
1209
+ var _client = null;
1210
+ function getClient() {
1211
+ if (!_client) {
1212
+ if (!projectId) {
1213
+ throw new Error(
1214
+ "Sanity Project ID is not defined. Please set NEXT_PUBLIC_SANITY_PROJECT_ID in your environment."
1215
+ );
1216
+ }
1217
+ _client = (0, import_next_sanity.createClient)({
1218
+ projectId,
1219
+ dataset,
1220
+ apiVersion,
1221
+ useCdn: process.env.NODE_ENV === "production"
1222
+ });
1223
+ }
1224
+ return _client;
1225
+ }
1226
+ var client = {
1227
+ get projectId() {
1228
+ return projectId;
1229
+ },
1230
+ get dataset() {
1231
+ return dataset;
1232
+ },
1233
+ fetch: (...args) => getClient().fetch(...args)
1234
+ };
1235
+ var _builder = null;
1236
+ function urlFor(source) {
1237
+ if (!_builder) {
1238
+ if (!projectId) {
1239
+ return {
1240
+ width: () => ({ height: () => ({ url: () => "" }), url: () => "" }),
1241
+ height: () => ({ width: () => ({ url: () => "" }), url: () => "" }),
1242
+ url: () => ""
1243
+ };
1244
+ }
1245
+ _builder = (0, import_image_url.default)({ projectId, dataset });
1246
+ }
1247
+ return _builder.image(source);
1248
+ }
548
1249
  // Annotate the CommonJS export names for ESM import in node:
549
1250
  0 && (module.exports = {
1251
+ AnimatedCard,
1252
+ AnimatedGalleryGrid,
1253
+ AnimatedGalleryHeader,
1254
+ AnimatedGrid,
1255
+ AnimatedHeader,
550
1256
  AnimatedHero,
1257
+ AnimatedHeroContent,
1258
+ AnimatedImage,
1259
+ AnimatedItem,
1260
+ AnimatedList,
1261
+ AnimatedMain,
1262
+ AnimatedPage,
1263
+ AnimatedSection,
1264
+ AnimatedSectionHeader,
1265
+ AnimatedStats,
551
1266
  ClientLayout,
552
1267
  ContactCTA,
553
1268
  Footer,
554
1269
  Header,
555
- ThemeToggle
1270
+ ScrollRevealSection,
1271
+ StaggeredGrid,
1272
+ ThemeToggle,
1273
+ cardHover,
1274
+ client,
1275
+ defineConfig,
1276
+ escapeHtml,
1277
+ fadeIn,
1278
+ fadeInUp,
1279
+ fadeInUpShort,
1280
+ getClient,
1281
+ imageZoom,
1282
+ isValidEmail,
1283
+ isValidExternalUrl,
1284
+ isValidGoogleMapsEmbedUrl,
1285
+ isValidSlug,
1286
+ pageTransition,
1287
+ reducedMotion,
1288
+ sanitizeUrl,
1289
+ scaleIn,
1290
+ scrollReveal,
1291
+ slideInLeft,
1292
+ slideInRight,
1293
+ staggerContainer,
1294
+ staggerItem,
1295
+ urlFor,
1296
+ viewportSettings
556
1297
  });