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