├── .gitignore
├── .vscode
└── settings.json
├── CHANGELOG.md
├── README.md
├── app
├── (auth)
│ ├── layout.tsx
│ ├── reset-password
│ │ └── page.tsx
│ ├── signin
│ │ └── page.tsx
│ └── signup
│ │ └── page.tsx
├── (default)
│ ├── layout.tsx
│ └── page.tsx
├── api
│ └── hello
│ │ └── route.ts
├── css
│ ├── additional-styles
│ │ ├── theme.css
│ │ └── utility-patterns.css
│ └── style.css
└── layout.tsx
├── components
├── cta.tsx
├── features.tsx
├── hero-home.tsx
├── modal-video.tsx
├── page-illustration.tsx
├── spotlight.tsx
├── testimonials.tsx
├── ui
│ ├── footer.tsx
│ ├── header.tsx
│ └── logo.tsx
└── workflows.tsx
├── next.config.js
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── public
├── favicon.ico
├── fonts
│ ├── nacelle-italic.woff2
│ ├── nacelle-regular.woff2
│ ├── nacelle-semibold.woff2
│ └── nacelle-semibolditalic.woff2
├── images
│ ├── blurred-shape-gray.svg
│ ├── blurred-shape.svg
│ ├── client-logo-01.svg
│ ├── client-logo-02.svg
│ ├── client-logo-03.svg
│ ├── client-logo-04.svg
│ ├── client-logo-05.svg
│ ├── client-logo-06.svg
│ ├── client-logo-07.svg
│ ├── client-logo-08.svg
│ ├── client-logo-09.svg
│ ├── features.png
│ ├── footer-illustration.svg
│ ├── hero-image-01.jpg
│ ├── logo.svg
│ ├── page-illustration.svg
│ ├── secondary-illustration.svg
│ ├── testimonial-01.jpg
│ ├── testimonial-02.jpg
│ ├── testimonial-03.jpg
│ ├── testimonial-04.jpg
│ ├── testimonial-05.jpg
│ ├── testimonial-06.jpg
│ ├── testimonial-07.jpg
│ ├── testimonial-08.jpg
│ ├── testimonial-09.jpg
│ ├── workflow-01.png
│ ├── workflow-02.png
│ └── workflow-03.png
└── videos
│ └── video.mp4
├── tsconfig.json
└── utils
├── useMasonry.tsx
└── useMousePosition.tsx
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # contentlayer
39 | .contentlayer
40 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true
4 | }
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG.md
2 |
3 | ## [5.0.0] - 2025-02-04
4 |
5 | - Updgrade to Tailwind v4
6 | - Update dependencies
7 |
8 | ## [4.1.0] - 2024-12-08
9 |
10 | - Update dependencies + Upgrade to Next.js 15
11 |
12 | ## [4.0.0] - 2024-09-11
13 |
14 | Redesign the entire template
15 |
16 | ## [3.3.0] - 2023-12-08
17 |
18 | Update to Next.js 14
19 | Update dependencies
20 |
21 | ## [3.2.2] - 2023-10-04
22 |
23 | Update Twitter icon
24 | Update dependencies
25 |
26 | ## [3.2.0] - 2023-05-31
27 |
28 | Update dependencies and fix some issues
29 |
30 | ## [3.1.0] - 2023-05-07
31 |
32 | Modal video improvements
33 |
34 | ## [3.0.0] - 2023-04-12
35 |
36 | Conversion to Next.js
37 |
38 | ## [2.0.3] - 2023-03-28
39 |
40 | Fix video
41 |
42 | ## [2.0.2] - 2023-03-28
43 |
44 | Add self-hosted video
45 |
46 | ## [2.0.1] - 2023-02-16
47 |
48 | Remove header links
49 |
50 | ## [2.0.0] - 2023-02-16
51 |
52 | Replace Cruip CSS with Tailwind CSS
53 |
54 | ## [1.0.0] - 2020-04-07
55 |
56 | First release
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Free React / Next.js landing page template
2 |
3 | 
4 |
5 | **Open** is a **free React / Next.js landing page template built with Tailwind CSS** for developers/makers who want to create a quick and professional landing page for their open source projects, SaaS products, online services, and more.
6 |
7 | **UPDATE 2025-02-04** Added Tailwind v4 support!
8 |
9 | Use it for whatever you want, and be sure to reach us out on [Twitter](https://twitter.com/Cruip_com) if you build anything cool/useful with it.
10 |
11 | Created and maintained with ❤️ by [Cruip.com](https://cruip.com).
12 |
13 | _Version 1.0.0 built with the Cruip CSS is available [here](https://github.com/cruip/open-react-template/releases/tag/1.0.0)._
14 | _Version 2.0.3 built with Tailwind CSS and React + Vite is available [here](https://github.com/cruip/open-react-template/releases/tag/2.0.3)._
15 | _Version 3.3.0 (before redesign) built with Tailwind CSS and Next.js is available [here](https://github.com/cruip/open-react-template/releases/tag/3.3.0)._
16 |
17 | ## Live demo
18 |
19 | Check the live demo here 👉️ [https://open.cruip.com/](https://open.cruip.com/)
20 |
21 | ## Open PRO
22 |
23 | [](https://cruip.com/)
24 |
25 | ## Design files
26 |
27 | If you need the design files, you can download them from Figma's Community 👉 https://bit.ly/401KSUS
28 |
29 | ## Usage
30 |
31 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
32 |
33 | ### Getting Started
34 |
35 | First, run the development server:
36 |
37 | ```bash
38 | npm run dev
39 | # or
40 | pnpm dev (recommended)
41 | # or
42 | yarn dev
43 | ```
44 |
45 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
46 |
47 | You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
48 |
49 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
50 |
51 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
52 |
53 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
54 |
55 | ### Learn More
56 |
57 | To learn more about Next.js, take a look at the following resources:
58 |
59 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
60 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
61 |
62 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
63 |
64 | ### Deploy on Vercel
65 |
66 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
67 |
68 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
69 |
70 | ### Support notes
71 |
72 | This template has been developed with the App Router (`app`) and React Server Components. If you’re unfamiliar with these beta features, you can find more information about them on the Next.js beta documentation page. So, please note that any request dealing with React (e.g. extra features, customisations, et cetera) is to be considered out of the support scope.
73 |
74 | For more information about what support covers, please see our (FAQs)[https://cruip.com/faq/].
75 |
76 | ## Credits
77 |
78 | - [Nucleo](https://nucleoapp.com/)
79 |
80 | ## Terms and License
81 |
82 | - Released under the [GPL](https://www.gnu.org/licenses/gpl-3.0.html).
83 | - Copyright 2024 [Cruip](https://cruip.com/).
84 | - Use it for personal and commercial projects, but please don’t republish, redistribute, or resell the template.
85 | - Attribution is not required, although it is really appreciated.
86 |
87 | ## About Us
88 |
89 | We're an Italian developer/designer duo creating high-quality design/code resources for developers, makers, and startups.
90 |
91 | ## Stay in the loop
92 |
93 | If you would like to know when we release new resources, you can follow [@pacovitiello](https://x.com/pacovitiello) and [@DavidePacilio](https://x.com/DavidePacilio) on X, or you can subscribe to our [newsletter](https://cruip.com/newsletter/).
94 |
--------------------------------------------------------------------------------
/app/(auth)/layout.tsx:
--------------------------------------------------------------------------------
1 | import PageIllustration from "@/components/page-illustration";
2 |
3 | export default function AuthLayout({
4 | children,
5 | }: {
6 | children: React.ReactNode;
7 | }) {
8 | return (
9 |
10 |
11 |
12 | {children}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/app/(auth)/reset-password/page.tsx:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "Reset Password - Open PRO",
3 | description: "Page description",
4 | };
5 |
6 | import Link from "next/link";
7 |
8 | export default function ResetPassword() {
9 | return (
10 |
11 |
12 |
13 | {/* Section header */}
14 |
15 |
16 | Reset your password
17 |
18 |
19 | {/* Contact form */}
20 |
41 |
42 |
43 |
44 | );
45 | }
46 |
--------------------------------------------------------------------------------
/app/(auth)/signin/page.tsx:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "Sign In - Open PRO",
3 | description: "Page description",
4 | };
5 |
6 | import Link from "next/link";
7 |
8 | export default function SignIn() {
9 | return (
10 |
11 |
12 |
13 | {/* Section header */}
14 |
15 |
16 | Welcome back
17 |
18 |
19 | {/* Contact form */}
20 |
71 | {/* Bottom link */}
72 |
73 | Don't you have an account?{" "}
74 |
75 | Sign Up
76 |
77 |
78 |
79 |
80 |
81 | );
82 | }
83 |
--------------------------------------------------------------------------------
/app/(auth)/signup/page.tsx:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "Sign Up - Open PRO",
3 | description: "Page description",
4 | };
5 |
6 | import Link from "next/link";
7 |
8 | export default function SignUp() {
9 | return (
10 |
11 |
12 |
13 | {/* Section header */}
14 |
15 |
16 | Create an account
17 |
18 |
19 | {/* Contact form */}
20 |
93 | {/* Bottom link */}
94 |
95 | Already have an account?{" "}
96 |
97 | Sign in
98 |
99 |
100 |
101 |
102 |
103 | );
104 | }
105 |
--------------------------------------------------------------------------------
/app/(default)/layout.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useEffect } from "react";
4 |
5 | import AOS from "aos";
6 | import "aos/dist/aos.css";
7 |
8 | import Footer from "@/components/ui/footer";
9 |
10 | export default function DefaultLayout({
11 | children,
12 | }: {
13 | children: React.ReactNode;
14 | }) {
15 | useEffect(() => {
16 | AOS.init({
17 | once: true,
18 | disable: "phone",
19 | duration: 600,
20 | easing: "ease-out-sine",
21 | });
22 | });
23 |
24 | return (
25 | <>
26 | {children}
27 |
28 |
29 | >
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/app/(default)/page.tsx:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "Home - Open PRO",
3 | description: "Page description",
4 | };
5 |
6 | import PageIllustration from "@/components/page-illustration";
7 | import Hero from "@/components/hero-home";
8 | import Workflows from "@/components/workflows";
9 | import Features from "@/components/features";
10 | import Testimonials from "@/components/testimonials";
11 | import Cta from "@/components/cta";
12 |
13 | export default function Home() {
14 | return (
15 | <>
16 |
17 |
18 |
19 |
20 |
21 |
22 | >
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/app/api/hello/route.ts:
--------------------------------------------------------------------------------
1 | export async function GET(request: Request) {
2 | return new Response("Hello, Next.js!");
3 | }
4 |
--------------------------------------------------------------------------------
/app/css/additional-styles/theme.css:
--------------------------------------------------------------------------------
1 | /* Custom AOS animations */
2 | @media screen {
3 | html:not(.no-js) body [data-aos="fade-up"] {
4 | -webkit-transform: translate3d(0, 10px, 0);
5 | transform: translate3d(0, 10px, 0);
6 | }
7 |
8 | html:not(.no-js) body [data-aos="fade-down"] {
9 | -webkit-transform: translate3d(0, -10px, 0);
10 | transform: translate3d(0, -10px, 0);
11 | }
12 |
13 | html:not(.no-js) body [data-aos="fade-right"] {
14 | -webkit-transform: translate3d(-10px, 0, 0);
15 | transform: translate3d(-10px, 0, 0);
16 | }
17 |
18 | html:not(.no-js) body [data-aos="fade-left"] {
19 | -webkit-transform: translate3d(10px, 0, 0);
20 | transform: translate3d(10px, 0, 0);
21 | }
22 |
23 | html:not(.no-js) body [data-aos="fade-up-right"] {
24 | -webkit-transform: translate3d(-10px, 10px, 0);
25 | transform: translate3d(-10px, 10px, 0);
26 | }
27 |
28 | html:not(.no-js) body [data-aos="fade-up-left"] {
29 | -webkit-transform: translate3d(10px, 10px, 0);
30 | transform: translate3d(10px, 10px, 0);
31 | }
32 |
33 | html:not(.no-js) body [data-aos="fade-down-right"] {
34 | -webkit-transform: translate3d(-10px, -10px, 0);
35 | transform: translate3d(-10px, -10px, 0);
36 | }
37 |
38 | html:not(.no-js) body [data-aos="fade-down-left"] {
39 | -webkit-transform: translate3d(10px, -10px, 0);
40 | transform: translate3d(10px, -10px, 0);
41 | }
42 |
43 | html:not(.no-js) body [data-aos="zoom-in-up"] {
44 | -webkit-transform: translate3d(0, 10px, 0) scale(0.6);
45 | transform: translate3d(0, 10px, 0) scale(0.6);
46 | }
47 |
48 | html:not(.no-js) body [data-aos="zoom-in-down"] {
49 | -webkit-transform: translate3d(0, -10px, 0) scale(0.6);
50 | transform: translate3d(0, -10px, 0) scale(0.6);
51 | }
52 |
53 | html:not(.no-js) body [data-aos="zoom-in-right"] {
54 | -webkit-transform: translate3d(-10px, 0, 0) scale(0.6);
55 | transform: translate3d(-10px, 0, 0) scale(0.6);
56 | }
57 |
58 | html:not(.no-js) body [data-aos="zoom-in-left"] {
59 | -webkit-transform: translate3d(10px, 0, 0) scale(0.6);
60 | transform: translate3d(10px, 0, 0) scale(0.6);
61 | }
62 |
63 | html:not(.no-js) body [data-aos="zoom-out-up"] {
64 | -webkit-transform: translate3d(0, 10px, 0) scale(1.2);
65 | transform: translate3d(0, 10px, 0) scale(1.2);
66 | }
67 |
68 | html:not(.no-js) body [data-aos="zoom-out-down"] {
69 | -webkit-transform: translate3d(0, -10px, 0) scale(1.2);
70 | transform: translate3d(0, -10px, 0) scale(1.2);
71 | }
72 |
73 | html:not(.no-js) body [data-aos="zoom-out-right"] {
74 | -webkit-transform: translate3d(-10px, 0, 0) scale(1.2);
75 | transform: translate3d(-10px, 0, 0) scale(1.2);
76 | }
77 |
78 | html:not(.no-js) body [data-aos="zoom-out-left"] {
79 | -webkit-transform: translate3d(10px, 0, 0) scale(1.2);
80 | transform: translate3d(10px, 0, 0) scale(1.2);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/css/additional-styles/utility-patterns.css:
--------------------------------------------------------------------------------
1 | /* Buttons */
2 | .btn,
3 | .btn-sm {
4 | @apply inline-flex items-center justify-center whitespace-nowrap rounded-lg text-sm font-medium transition-all;
5 | }
6 |
7 | .btn {
8 | @apply px-4 py-[11px];
9 | }
10 |
11 | .btn-sm {
12 | @apply px-3 py-[7px];
13 | }
14 |
15 | /* Forms */
16 | input[type='search']::-webkit-search-decoration,
17 | input[type='search']::-webkit-search-cancel-button,
18 | input[type='search']::-webkit-search-results-button,
19 | input[type='search']::-webkit-search-results-decoration {
20 | -webkit-appearance: none;
21 | }
22 |
23 | .form-input,
24 | .form-textarea,
25 | .form-multiselect,
26 | .form-select,
27 | .form-checkbox,
28 | .form-radio {
29 | @apply border border-gray-700 bg-gray-900/50 focus:border-gray-600 focus:ring-0 focus:ring-offset-0;
30 | }
31 |
32 | .form-input,
33 | .form-textarea,
34 | .form-multiselect,
35 | .form-select {
36 | @apply rounded-lg px-4 py-2.5 text-sm text-gray-200;
37 | }
38 |
39 | .form-input,
40 | .form-textarea {
41 | @apply placeholder-gray-600;
42 | }
43 |
44 | .form-select {
45 | @apply pr-10;
46 | }
47 |
48 | .form-checkbox,
49 | .form-radio {
50 | @apply text-indigo-500;
51 | }
52 |
53 | .form-checkbox {
54 | @apply rounded-xs;
55 | }
56 |
--------------------------------------------------------------------------------
/app/css/style.css:
--------------------------------------------------------------------------------
1 | @import 'tailwindcss';
2 |
3 | /* Additional styles */
4 | @import './additional-styles/utility-patterns.css' layer(components);
5 | @import './additional-styles/theme.css';
6 |
7 | @plugin "@tailwindcss/forms" {
8 | strategy: base;
9 | }
10 |
11 | @theme {
12 | --font-inter: var(--font-inter), sans-serif;
13 | --font-nacelle: var(--font-nacelle), sans-serif;
14 |
15 | --text-xs: 0.8125rem;
16 | --text-xs--line-height: 1.5384;
17 | --text-sm: 0.875rem;
18 | --text-sm--line-height: 1.5715;
19 | --text-base: 0.9375rem;
20 | --text-base--line-height: 1.5333;
21 | --text-base--letter-spacing: -0.0125em;
22 | --text-lg: 1.125rem;
23 | --text-lg--line-height: 1.5;
24 | --text-lg--letter-spacing: -0.0125em;
25 | --text-xl: 1.25rem;
26 | --text-xl--line-height: 1.5;
27 | --text-xl--letter-spacing: -0.0125em;
28 | --text-2xl: 1.5rem;
29 | --text-2xl--line-height: 1.415;
30 | --text-2xl--letter-spacing: -0.0268em;
31 | --text-3xl: 1.75rem;
32 | --text-3xl--line-height: 1.3571;
33 | --text-3xl--letter-spacing: -0.0268em;
34 | --text-4xl: 2.5rem;
35 | --text-4xl--line-height: 1.1;
36 | --text-4xl--letter-spacing: -0.0268em;
37 | --text-5xl: 3.5rem;
38 | --text-5xl--line-height: 1;
39 | --text-5xl--letter-spacing: -0.0268em;
40 | --text-6xl: 4rem;
41 | --text-6xl--line-height: 1;
42 | --text-6xl--letter-spacing: -0.0268em;
43 | --text-7xl: 4.5rem;
44 | --text-7xl--line-height: 1;
45 | --text-7xl--letter-spacing: -0.0268em;
46 |
47 | --animate-shine: shine 5s ease-in-out 500ms infinite;
48 | --animate-gradient: gradient 6s linear infinite;
49 |
50 | @keyframes shine {
51 | 0% {
52 | top: 0;
53 | transform: scaleY(5);
54 | opacity: 0;
55 | }
56 | 10% {
57 | opacity: 0.8;
58 | }
59 | 20% {
60 | top: 100%;
61 | transform: scaleY(10);
62 | opacity: 0;
63 | }
64 | 100% {
65 | top: 100%;
66 | transform: scaleY(1);
67 | opacity: 0;
68 | }
69 | }
70 | @keyframes gradient {
71 | to {
72 | background-position: 200% center;
73 | }
74 | }
75 | }
76 |
77 | /*
78 | The default border color has changed to `currentColor` in Tailwind CSS v4,
79 | so we've added these compatibility styles to make sure everything still
80 | looks the same as it did with Tailwind CSS v3.
81 |
82 | If we ever want to remove these styles, we need to add an explicit border
83 | color utility to any element that depends on these defaults.
84 | */
85 | @layer base {
86 | *,
87 | ::after,
88 | ::before,
89 | ::backdrop,
90 | ::file-selector-button {
91 | border-color: var(--color-gray-200, currentColor);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "./css/style.css";
2 |
3 | import { Inter } from "next/font/google";
4 | import localFont from "next/font/local";
5 |
6 | import Header from "@/components/ui/header";
7 |
8 | const inter = Inter({
9 | subsets: ["latin"],
10 | variable: "--font-inter",
11 | display: "swap",
12 | });
13 |
14 | const nacelle = localFont({
15 | src: [
16 | {
17 | path: "../public/fonts/nacelle-regular.woff2",
18 | weight: "400",
19 | style: "normal",
20 | },
21 | {
22 | path: "../public/fonts/nacelle-italic.woff2",
23 | weight: "400",
24 | style: "italic",
25 | },
26 | {
27 | path: "../public/fonts/nacelle-semibold.woff2",
28 | weight: "600",
29 | style: "normal",
30 | },
31 | {
32 | path: "../public/fonts/nacelle-semibolditalic.woff2",
33 | weight: "600",
34 | style: "italic",
35 | },
36 | ],
37 | variable: "--font-nacelle",
38 | display: "swap",
39 | });
40 |
41 | export const metadata = {
42 | title: "Create Next App",
43 | description: "Generated by create next app",
44 | };
45 |
46 | export default function RootLayout({
47 | children,
48 | }: {
49 | children: React.ReactNode;
50 | }) {
51 | return (
52 |
53 |
56 |
57 |
58 | {children}
59 |
60 |
61 |
62 | );
63 | }
64 |
--------------------------------------------------------------------------------
/components/cta.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import BlurredShape from "@/public/images/blurred-shape.svg";
3 |
4 | export default function Cta() {
5 | return (
6 |
7 |
11 |
18 |
19 |
20 |
21 |
22 |
26 | Join the content-first platform
27 |
28 |
51 |
52 |
53 |
54 |
55 | );
56 | }
57 |
--------------------------------------------------------------------------------
/components/features.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import BlurredShapeGray from "@/public/images/blurred-shape-gray.svg";
3 | import BlurredShape from "@/public/images/blurred-shape.svg";
4 | import FeaturesImage from "@/public/images/features.png";
5 |
6 | export default function Features() {
7 | return (
8 |
9 |
13 |
20 |
21 |
25 |
32 |
33 |
34 |
35 | {/* Section header */}
36 |
37 |
38 |
39 | Advanced Controls
40 |
41 |
42 |
43 | Built for modern product teams
44 |
45 |
46 | Open AI reads and understands your files, and with nothing more
47 | than a single line of feedback, so you can go further than the
48 | speed of thought.
49 |
50 |
51 |
52 |
59 |
60 | {/* Items */}
61 |
62 |
63 |
69 |
70 |
74 |
75 |
76 | Project Milestones
77 |
78 |
79 | Track progress across custom flows for your team. Find the right
80 | balance for the user, privacy and security.
81 |
82 |
83 |
84 |
90 |
91 |
92 |
93 |
94 | Team Views
95 |
96 |
97 | Track progress across custom flows for your team. Find the right
98 | balance for the user, privacy and security.
99 |
100 |
101 |
102 |
108 |
109 |
113 |
114 |
115 | Advanced Search
116 |
117 |
118 | Track progress across custom flows for your team. Find the right
119 | balance for the user, privacy and security.
120 |
121 |
122 |
123 |
129 |
133 |
134 |
138 |
139 |
140 |
141 | Strategic Initiatives
142 |
143 |
144 | Track progress across custom flows for your team. Find the right
145 | balance for the user, privacy and security.
146 |
147 |
148 |
149 |
155 |
159 |
160 |
161 |
162 | Flexible Workflows
163 |
164 |
165 | Track progress across custom flows for your team. Find the right
166 | balance for the user, privacy and security.
167 |
168 |
169 |
170 |
176 |
180 |
181 |
182 |
183 | Unified Timeline
184 |
185 |
186 | Track progress across custom flows for your team. Find the right
187 | balance for the user, privacy and security.
188 |
189 |
190 |
191 |
192 |
193 |
194 | );
195 | }
196 |
--------------------------------------------------------------------------------
/components/hero-home.tsx:
--------------------------------------------------------------------------------
1 | import VideoThumb from "@/public/images/hero-image-01.jpg";
2 | import ModalVideo from "@/components/modal-video";
3 |
4 | export default function HeroHome() {
5 | return (
6 |
7 |
8 | {/* Hero content */}
9 |
10 | {/* Section header */}
11 |
12 |
16 | AI-driven tools for product teams
17 |
18 |
19 |
24 | Our landing page template works on all devices, so you only have
25 | to set it up once, and get beautiful results forever.
26 |
27 |
50 |
51 |
52 |
53 |
62 |
63 |
64 |
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/components/modal-video.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState, useRef } from "react";
4 | import type { StaticImageData } from "next/image";
5 | import { Dialog, DialogBackdrop, DialogPanel } from "@headlessui/react";
6 | import Image from "next/image";
7 | import SecondaryIllustration from "@/public/images/secondary-illustration.svg";
8 |
9 | interface ModalVideoProps {
10 | thumb: StaticImageData;
11 | thumbWidth: number;
12 | thumbHeight: number;
13 | thumbAlt: string;
14 | video: string;
15 | videoWidth: number;
16 | videoHeight: number;
17 | }
18 |
19 | export default function ModalVideo({
20 | thumb,
21 | thumbWidth,
22 | thumbHeight,
23 | thumbAlt,
24 | video,
25 | videoWidth,
26 | videoHeight,
27 | }: ModalVideoProps) {
28 | const [modalOpen, setModalOpen] = useState(false);
29 | const videoRef = useRef(null);
30 |
31 | return (
32 |
33 | {/* Secondary illustration */}
34 |
38 |
45 |
46 |
47 | {/* Video thumbnail */}
48 |
{
51 | setModalOpen(true);
52 | }}
53 | aria-label="Watch the video"
54 | data-aos="fade-up"
55 | data-aos-delay={200}
56 | >
57 |
58 |
66 |
67 | {/* Play icon */}
68 |
69 |
70 |
76 |
82 |
83 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | Watch Demo
98 | -
99 | 3:47
100 |
101 |
102 |
103 |
104 | {/* End: Video thumbnail */}
105 |
106 |
setModalOpen(false)}
110 | >
111 |
115 |
116 |
117 |
121 |
128 |
129 | Your browser does not support the video tag.
130 |
131 |
132 |
133 |
134 |
135 |
136 | );
137 | }
138 |
--------------------------------------------------------------------------------
/components/page-illustration.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import Illustration from "@/public/images/page-illustration.svg";
3 | import BlurredShapeGray from "@/public/images/blurred-shape-gray.svg";
4 | import BlurredShape from "@/public/images/blurred-shape.svg";
5 |
6 | export default function PageIllustration({
7 | multiple = false,
8 | }: {
9 | multiple?: boolean;
10 | }) {
11 | return (
12 | <>
13 |
17 |
24 |
25 | {multiple && (
26 | <>
27 |
31 |
38 |
39 |
43 |
50 |
51 | >
52 | )}
53 | >
54 | );
55 | }
56 |
--------------------------------------------------------------------------------
/components/spotlight.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import React, { useRef, useState, useEffect } from "react";
4 | import useMousePosition from "@/utils/useMousePosition";
5 |
6 | type SpotlightProps = {
7 | children: React.ReactNode;
8 | className?: string;
9 | };
10 |
11 | export default function Spotlight({
12 | children,
13 | className = "",
14 | }: SpotlightProps) {
15 | const containerRef = useRef(null);
16 | const mousePosition = useMousePosition();
17 | const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 });
18 | const containerSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 });
19 | const [boxes, setBoxes] = useState>([]);
20 |
21 | useEffect(() => {
22 | containerRef.current &&
23 | setBoxes(
24 | Array.from(containerRef.current.children).map(
25 | (el) => el as HTMLElement,
26 | ),
27 | );
28 | }, []);
29 |
30 | useEffect(() => {
31 | initContainer();
32 | window.addEventListener("resize", initContainer);
33 |
34 | return () => {
35 | window.removeEventListener("resize", initContainer);
36 | };
37 | }, [boxes]);
38 |
39 | useEffect(() => {
40 | onMouseMove();
41 | }, [mousePosition]);
42 |
43 | const initContainer = () => {
44 | if (containerRef.current) {
45 | containerSize.current.w = containerRef.current.offsetWidth;
46 | containerSize.current.h = containerRef.current.offsetHeight;
47 | }
48 | };
49 |
50 | const onMouseMove = () => {
51 | if (containerRef.current) {
52 | const rect = containerRef.current.getBoundingClientRect();
53 | const { w, h } = containerSize.current;
54 | const x = mousePosition.x - rect.left;
55 | const y = mousePosition.y - rect.top;
56 | const inside = x < w && x > 0 && y < h && y > 0;
57 | if (inside) {
58 | mouse.current.x = x;
59 | mouse.current.y = y;
60 | boxes.forEach((box) => {
61 | const boxX =
62 | -(box.getBoundingClientRect().left - rect.left) + mouse.current.x;
63 | const boxY =
64 | -(box.getBoundingClientRect().top - rect.top) + mouse.current.y;
65 | box.style.setProperty("--mouse-x", `${boxX}px`);
66 | box.style.setProperty("--mouse-y", `${boxY}px`);
67 | });
68 | }
69 | }
70 | };
71 |
72 | return (
73 |
74 | {children}
75 |
76 | );
77 | }
78 |
--------------------------------------------------------------------------------
/components/testimonials.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useState } from "react";
4 | import useMasonry from "@/utils/useMasonry";
5 | import Image, { StaticImageData } from "next/image";
6 | import TestimonialImg01 from "@/public/images/testimonial-01.jpg";
7 | import TestimonialImg02 from "@/public/images/testimonial-02.jpg";
8 | import TestimonialImg03 from "@/public/images/testimonial-03.jpg";
9 | import TestimonialImg04 from "@/public/images/testimonial-04.jpg";
10 | import TestimonialImg05 from "@/public/images/testimonial-05.jpg";
11 | import TestimonialImg06 from "@/public/images/testimonial-06.jpg";
12 | import TestimonialImg07 from "@/public/images/testimonial-07.jpg";
13 | import TestimonialImg08 from "@/public/images/testimonial-08.jpg";
14 | import TestimonialImg09 from "@/public/images/testimonial-09.jpg";
15 | import ClientImg01 from "@/public/images/client-logo-01.svg";
16 | import ClientImg02 from "@/public/images/client-logo-02.svg";
17 | import ClientImg03 from "@/public/images/client-logo-03.svg";
18 | import ClientImg04 from "@/public/images/client-logo-04.svg";
19 | import ClientImg05 from "@/public/images/client-logo-05.svg";
20 | import ClientImg06 from "@/public/images/client-logo-06.svg";
21 | import ClientImg07 from "@/public/images/client-logo-07.svg";
22 | import ClientImg08 from "@/public/images/client-logo-08.svg";
23 | import ClientImg09 from "@/public/images/client-logo-09.svg";
24 |
25 | const testimonials = [
26 | {
27 | img: TestimonialImg01,
28 | clientImg: ClientImg01,
29 | name: "MaKayla P.",
30 | company: "Disney",
31 | content:
32 | "As a content creator, I was always on the lookout for a tool that could help me keep up with the demand. The AI-driven content tool has been a game-changer. It generates high-quality content in a fraction of the time it used to take me.",
33 | categories: [1, 3, 5],
34 | },
35 | {
36 | img: TestimonialImg02,
37 | clientImg: ClientImg02,
38 | name: "Andrew K.",
39 | company: "Samsung",
40 | content:
41 | "I've tried several content generation tools, but this AI-driven tool is by far the best. It understands my brand's voice and consistently produces content that resonates with my audience!",
42 | categories: [1, 2, 4],
43 | },
44 | {
45 | img: TestimonialImg03,
46 | clientImg: ClientImg03,
47 | name: "Lucy D.",
48 | company: "Rio",
49 | content:
50 | "Content creation used to be a bottleneck in our workflow, but not anymore. This AI tool is intuitive and produces top-notch content every time. It's like having an extra team member who never sleeps! Definitely recommend.",
51 | categories: [1, 2, 5],
52 | },
53 | {
54 | img: TestimonialImg04,
55 | clientImg: ClientImg04,
56 | name: "Pavel M.",
57 | company: "Canon",
58 | content:
59 | "The quality of the content generated by this AI tool is outstanding. It has taken our content marketing to new heights, allowing us to publish more frequently without compromising on quality. Highly recommended for anyone.",
60 | categories: [1, 4],
61 | },
62 | {
63 | img: TestimonialImg05,
64 | clientImg: ClientImg05,
65 | name: "Miriam E.",
66 | company: "Cadbury",
67 | content:
68 | "The AI-driven content tool has been a lifesaver for my marketing agency. We can now produce high-quality content for multiple clients quickly and efficiently. It's an invaluable asset to our team.",
69 | categories: [1, 3, 5],
70 | },
71 | {
72 | img: TestimonialImg06,
73 | clientImg: ClientImg06,
74 | name: "Eloise V.",
75 | company: "Maffell",
76 | content:
77 | "I'm amazed at how well this AI-driven content tool performs. It's incredibly versatile and can generate content for blogs, social media, and even product descriptions effortlessly. It's fantastic!",
78 | categories: [1, 3],
79 | },
80 | {
81 | img: TestimonialImg07,
82 | clientImg: ClientImg07,
83 | name: "Pierre-Gilles L.",
84 | company: "Binance",
85 | content:
86 | "I was blown away by how easy it was to create my content using this tool! Within a few hours, I had a professional-looking platform up and running, and my client could not believe it.",
87 | categories: [1, 2, 5],
88 | },
89 | {
90 | img: TestimonialImg08,
91 | clientImg: ClientImg08,
92 | name: "Danielle K.",
93 | company: "Forbes Inc.",
94 | content:
95 | "I've never been a fan of complicated website AI tools, which is why Open PRO is perfect for me. Its minimalist design and simple functionality make staying organized feel like second nature.",
96 | categories: [1, 4],
97 | },
98 | {
99 | img: TestimonialImg09,
100 | clientImg: ClientImg09,
101 | name: "Mary P.",
102 | company: "Ray Ban",
103 | content:
104 | "I've never been one for coding, so finding an AI tool that doesn't require any technical skills was a dream come true. This tool exceeded my expectations, and I'm proud to show off my new stuff to friends.",
105 | categories: [1, 2],
106 | },
107 | ];
108 |
109 | export default function Testimonials() {
110 | const masonryContainer = useMasonry();
111 | const [category, setCategory] = useState(1);
112 |
113 | return (
114 |
115 |
116 | {/* Section header */}
117 |
118 |
119 | Don't take our word for it
120 |
121 |
122 | We provide tech-first solutions that empower decision-makers to
123 | build healthier and happier workspaces from anywhere in the world.
124 |
125 |
126 |
127 |
128 | {/* Buttons */}
129 |
130 |
131 | {/* Button #1 */}
132 |
setCategory(1)}
136 | >
137 |
143 |
144 |
145 | View All
146 |
147 | {/* Button #2 */}
148 |
setCategory(2)}
152 | >
153 |
159 |
160 |
161 | Web Apps
162 |
163 | {/* Button #3 */}
164 |
setCategory(3)}
168 | >
169 |
175 |
176 |
177 | eCommerce
178 |
179 | {/* Button #4 */}
180 |
setCategory(4)}
184 | >
185 |
191 |
192 |
193 | Enteprise
194 |
195 | {/* Button #5 */}
196 |
setCategory(5)}
200 | >
201 |
207 |
208 |
209 | Enteprise
210 |
211 |
212 |
213 |
214 | {/* Cards */}
215 |
219 | {testimonials.map((testimonial, index) => (
220 |
221 |
222 | {testimonial.content}
223 |
224 |
225 | ))}
226 |
227 |
228 |
229 |
230 | );
231 | }
232 |
233 | export function Testimonial({
234 | testimonial,
235 | category,
236 | children,
237 | }: {
238 | testimonial: {
239 | img: StaticImageData;
240 | clientImg: StaticImageData;
241 | name: string;
242 | company: string;
243 | content: string;
244 | categories: number[];
245 | };
246 | category: number;
247 | children: React.ReactNode;
248 | }) {
249 | return (
250 |
253 |
254 |
255 |
256 |
257 |
258 | {children}
259 |
260 |
279 |
280 |
281 | );
282 | }
283 |
--------------------------------------------------------------------------------
/components/ui/footer.tsx:
--------------------------------------------------------------------------------
1 | import Logo from "./logo";
2 | import Image from "next/image";
3 | import FooterIllustration from "@/public/images/footer-illustration.svg";
4 |
5 | export default function Footer() {
6 | return (
7 |
269 | );
270 | }
271 |
--------------------------------------------------------------------------------
/components/ui/header.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import Link from "next/link";
4 | import Logo from "./logo";
5 |
6 | export default function Header() {
7 | return (
8 |
9 |
10 |
11 | {/* Site branding */}
12 |
13 |
14 |
15 |
16 | {/* Desktop sign in links */}
17 |
18 |
19 |
23 | Sign In
24 |
25 |
26 |
27 |
31 | Register
32 |
33 |
34 |
35 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/components/ui/logo.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 | import Image from "next/image";
3 | import logo from "@/public/images/logo.svg";
4 |
5 | export default function Logo() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/components/workflows.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | import WorflowImg01 from "@/public/images/workflow-01.png";
3 | import WorflowImg02 from "@/public/images/workflow-02.png";
4 | import WorflowImg03 from "@/public/images/workflow-03.png";
5 | import Spotlight from "@/components/spotlight";
6 |
7 | export default function Workflows() {
8 | return (
9 |
175 | );
176 | }
177 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | module.exports = nextConfig;
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "open-pro-next",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev --turbopack",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@headlessui/react": "^2.2.0",
13 | "@types/node": "^22.13.0",
14 | "@types/react": "19.0.8",
15 | "@types/react-dom": "19.0.3",
16 | "aos": "3.0.0-beta.6",
17 | "next": "15.1.6",
18 | "react": "19.0.0",
19 | "react-dom": "19.0.0",
20 | "typescript": "^5.7.3"
21 | },
22 | "devDependencies": {
23 | "@tailwindcss/forms": "^0.5.10",
24 | "@tailwindcss/postcss": "^4.0.3",
25 | "@types/aos": "^3.0.7",
26 | "postcss": "^8.5.1",
27 | "tailwindcss": "^4.0.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@headlessui/react':
12 | specifier: ^2.2.0
13 | version: 2.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
14 | '@types/node':
15 | specifier: ^22.13.0
16 | version: 22.13.0
17 | '@types/react':
18 | specifier: 19.0.8
19 | version: 19.0.8
20 | '@types/react-dom':
21 | specifier: 19.0.3
22 | version: 19.0.3(@types/react@19.0.8)
23 | aos:
24 | specifier: 3.0.0-beta.6
25 | version: 3.0.0-beta.6
26 | next:
27 | specifier: 15.1.6
28 | version: 15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
29 | react:
30 | specifier: 19.0.0
31 | version: 19.0.0
32 | react-dom:
33 | specifier: 19.0.0
34 | version: 19.0.0(react@19.0.0)
35 | typescript:
36 | specifier: ^5.7.3
37 | version: 5.7.3
38 | devDependencies:
39 | '@tailwindcss/forms':
40 | specifier: ^0.5.10
41 | version: 0.5.10(tailwindcss@4.0.3)
42 | '@tailwindcss/postcss':
43 | specifier: ^4.0.3
44 | version: 4.0.3
45 | '@types/aos':
46 | specifier: ^3.0.7
47 | version: 3.0.7
48 | postcss:
49 | specifier: ^8.5.1
50 | version: 8.5.1
51 | tailwindcss:
52 | specifier: ^4.0.3
53 | version: 4.0.3
54 |
55 | packages:
56 |
57 | '@alloc/quick-lru@5.2.0':
58 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
59 | engines: {node: '>=10'}
60 |
61 | '@emnapi/runtime@1.3.1':
62 | resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
63 |
64 | '@floating-ui/core@1.6.9':
65 | resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==}
66 |
67 | '@floating-ui/dom@1.6.13':
68 | resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
69 |
70 | '@floating-ui/react-dom@2.1.2':
71 | resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
72 | peerDependencies:
73 | react: '>=16.8.0'
74 | react-dom: '>=16.8.0'
75 |
76 | '@floating-ui/react@0.26.28':
77 | resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==}
78 | peerDependencies:
79 | react: '>=16.8.0'
80 | react-dom: '>=16.8.0'
81 |
82 | '@floating-ui/utils@0.2.9':
83 | resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
84 |
85 | '@headlessui/react@2.2.0':
86 | resolution: {integrity: sha512-RzCEg+LXsuI7mHiSomsu/gBJSjpupm6A1qIZ5sWjd7JhARNlMiSA4kKfJpCKwU9tE+zMRterhhrP74PvfJrpXQ==}
87 | engines: {node: '>=10'}
88 | peerDependencies:
89 | react: ^18 || ^19 || ^19.0.0-rc
90 | react-dom: ^18 || ^19 || ^19.0.0-rc
91 |
92 | '@img/sharp-darwin-arm64@0.33.5':
93 | resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
94 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
95 | cpu: [arm64]
96 | os: [darwin]
97 |
98 | '@img/sharp-darwin-x64@0.33.5':
99 | resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
100 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
101 | cpu: [x64]
102 | os: [darwin]
103 |
104 | '@img/sharp-libvips-darwin-arm64@1.0.4':
105 | resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
106 | cpu: [arm64]
107 | os: [darwin]
108 |
109 | '@img/sharp-libvips-darwin-x64@1.0.4':
110 | resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
111 | cpu: [x64]
112 | os: [darwin]
113 |
114 | '@img/sharp-libvips-linux-arm64@1.0.4':
115 | resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
116 | cpu: [arm64]
117 | os: [linux]
118 |
119 | '@img/sharp-libvips-linux-arm@1.0.5':
120 | resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
121 | cpu: [arm]
122 | os: [linux]
123 |
124 | '@img/sharp-libvips-linux-s390x@1.0.4':
125 | resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
126 | cpu: [s390x]
127 | os: [linux]
128 |
129 | '@img/sharp-libvips-linux-x64@1.0.4':
130 | resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
131 | cpu: [x64]
132 | os: [linux]
133 |
134 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
135 | resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
136 | cpu: [arm64]
137 | os: [linux]
138 |
139 | '@img/sharp-libvips-linuxmusl-x64@1.0.4':
140 | resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
141 | cpu: [x64]
142 | os: [linux]
143 |
144 | '@img/sharp-linux-arm64@0.33.5':
145 | resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
146 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
147 | cpu: [arm64]
148 | os: [linux]
149 |
150 | '@img/sharp-linux-arm@0.33.5':
151 | resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
152 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
153 | cpu: [arm]
154 | os: [linux]
155 |
156 | '@img/sharp-linux-s390x@0.33.5':
157 | resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
158 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
159 | cpu: [s390x]
160 | os: [linux]
161 |
162 | '@img/sharp-linux-x64@0.33.5':
163 | resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
164 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
165 | cpu: [x64]
166 | os: [linux]
167 |
168 | '@img/sharp-linuxmusl-arm64@0.33.5':
169 | resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
170 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
171 | cpu: [arm64]
172 | os: [linux]
173 |
174 | '@img/sharp-linuxmusl-x64@0.33.5':
175 | resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
176 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
177 | cpu: [x64]
178 | os: [linux]
179 |
180 | '@img/sharp-wasm32@0.33.5':
181 | resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
182 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
183 | cpu: [wasm32]
184 |
185 | '@img/sharp-win32-ia32@0.33.5':
186 | resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
187 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
188 | cpu: [ia32]
189 | os: [win32]
190 |
191 | '@img/sharp-win32-x64@0.33.5':
192 | resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
193 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
194 | cpu: [x64]
195 | os: [win32]
196 |
197 | '@next/env@15.1.6':
198 | resolution: {integrity: sha512-d9AFQVPEYNr+aqokIiPLNK/MTyt3DWa/dpKveiAaVccUadFbhFEvY6FXYX2LJO2Hv7PHnLBu2oWwB4uBuHjr/w==}
199 |
200 | '@next/swc-darwin-arm64@15.1.6':
201 | resolution: {integrity: sha512-u7lg4Mpl9qWpKgy6NzEkz/w0/keEHtOybmIl0ykgItBxEM5mYotS5PmqTpo+Rhg8FiOiWgwr8USxmKQkqLBCrw==}
202 | engines: {node: '>= 10'}
203 | cpu: [arm64]
204 | os: [darwin]
205 |
206 | '@next/swc-darwin-x64@15.1.6':
207 | resolution: {integrity: sha512-x1jGpbHbZoZ69nRuogGL2MYPLqohlhnT9OCU6E6QFewwup+z+M6r8oU47BTeJcWsF2sdBahp5cKiAcDbwwK/lg==}
208 | engines: {node: '>= 10'}
209 | cpu: [x64]
210 | os: [darwin]
211 |
212 | '@next/swc-linux-arm64-gnu@15.1.6':
213 | resolution: {integrity: sha512-jar9sFw0XewXsBzPf9runGzoivajeWJUc/JkfbLTC4it9EhU8v7tCRLH7l5Y1ReTMN6zKJO0kKAGqDk8YSO2bg==}
214 | engines: {node: '>= 10'}
215 | cpu: [arm64]
216 | os: [linux]
217 |
218 | '@next/swc-linux-arm64-musl@15.1.6':
219 | resolution: {integrity: sha512-+n3u//bfsrIaZch4cgOJ3tXCTbSxz0s6brJtU3SzLOvkJlPQMJ+eHVRi6qM2kKKKLuMY+tcau8XD9CJ1OjeSQQ==}
220 | engines: {node: '>= 10'}
221 | cpu: [arm64]
222 | os: [linux]
223 |
224 | '@next/swc-linux-x64-gnu@15.1.6':
225 | resolution: {integrity: sha512-SpuDEXixM3PycniL4iVCLyUyvcl6Lt0mtv3am08sucskpG0tYkW1KlRhTgj4LI5ehyxriVVcfdoxuuP8csi3kQ==}
226 | engines: {node: '>= 10'}
227 | cpu: [x64]
228 | os: [linux]
229 |
230 | '@next/swc-linux-x64-musl@15.1.6':
231 | resolution: {integrity: sha512-L4druWmdFSZIIRhF+G60API5sFB7suTbDRhYWSjiw0RbE+15igQvE2g2+S973pMGvwN3guw7cJUjA/TmbPWTHQ==}
232 | engines: {node: '>= 10'}
233 | cpu: [x64]
234 | os: [linux]
235 |
236 | '@next/swc-win32-arm64-msvc@15.1.6':
237 | resolution: {integrity: sha512-s8w6EeqNmi6gdvM19tqKKWbCyOBvXFbndkGHl+c9YrzsLARRdCHsD9S1fMj8gsXm9v8vhC8s3N8rjuC/XrtkEg==}
238 | engines: {node: '>= 10'}
239 | cpu: [arm64]
240 | os: [win32]
241 |
242 | '@next/swc-win32-x64-msvc@15.1.6':
243 | resolution: {integrity: sha512-6xomMuu54FAFxttYr5PJbEfu96godcxBTRk1OhAvJq0/EnmFU/Ybiax30Snis4vdWZ9LGpf7Roy5fSs7v/5ROQ==}
244 | engines: {node: '>= 10'}
245 | cpu: [x64]
246 | os: [win32]
247 |
248 | '@react-aria/focus@3.19.1':
249 | resolution: {integrity: sha512-bix9Bu1Ue7RPcYmjwcjhB14BMu2qzfJ3tMQLqDc9pweJA66nOw8DThy3IfVr8Z7j2PHktOLf9kcbiZpydKHqzg==}
250 | peerDependencies:
251 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
252 | react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
253 |
254 | '@react-aria/interactions@3.23.0':
255 | resolution: {integrity: sha512-0qR1atBIWrb7FzQ+Tmr3s8uH5mQdyRH78n0krYaG8tng9+u1JlSi8DGRSaC9ezKyNB84m7vHT207xnHXGeJ3Fg==}
256 | peerDependencies:
257 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
258 | react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
259 |
260 | '@react-aria/ssr@3.9.7':
261 | resolution: {integrity: sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==}
262 | engines: {node: '>= 12'}
263 | peerDependencies:
264 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
265 |
266 | '@react-aria/utils@3.27.0':
267 | resolution: {integrity: sha512-p681OtApnKOdbeN8ITfnnYqfdHS0z7GE+4l8EXlfLnr70Rp/9xicBO6d2rU+V/B3JujDw2gPWxYKEnEeh0CGCw==}
268 | peerDependencies:
269 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
270 | react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
271 |
272 | '@react-stately/utils@3.10.5':
273 | resolution: {integrity: sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==}
274 | peerDependencies:
275 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
276 |
277 | '@react-types/shared@3.27.0':
278 | resolution: {integrity: sha512-gvznmLhi6JPEf0bsq7SwRYTHAKKq/wcmKqFez9sRdbED+SPMUmK5omfZ6w3EwUFQHbYUa4zPBYedQ7Knv70RMw==}
279 | peerDependencies:
280 | react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
281 |
282 | '@swc/counter@0.1.3':
283 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
284 |
285 | '@swc/helpers@0.5.15':
286 | resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
287 |
288 | '@tailwindcss/forms@0.5.10':
289 | resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==}
290 | peerDependencies:
291 | tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
292 |
293 | '@tailwindcss/node@4.0.3':
294 | resolution: {integrity: sha512-QsVJokOl0pJ4AbJV33D2npvLcHGPWi5MOSZtrtE0GT3tSx+3D0JE2lokLA8yHS1x3oCY/3IyRyy7XX6tmzid7A==}
295 |
296 | '@tailwindcss/oxide-android-arm64@4.0.3':
297 | resolution: {integrity: sha512-S8XOTQuMnpijZRlPm5HBzPJjZ28quB+40LSRHjRnQF6rRYKsvpr1qkY7dfwsetNdd+kMLOMDsvmuT8WnqqETvg==}
298 | engines: {node: '>= 10'}
299 | cpu: [arm64]
300 | os: [android]
301 |
302 | '@tailwindcss/oxide-darwin-arm64@4.0.3':
303 | resolution: {integrity: sha512-smrY2DpzhXvgDhZtQlYAl8+vxJ04lv2/64C1eiRxvsRT2nkw/q+zA1/eAYKvUHat6cIuwqDku3QucmrUT6pCeg==}
304 | engines: {node: '>= 10'}
305 | cpu: [arm64]
306 | os: [darwin]
307 |
308 | '@tailwindcss/oxide-darwin-x64@4.0.3':
309 | resolution: {integrity: sha512-NTz8x/LcGUjpZAWUxz0ZuzHao90Wj9spoQgomwB+/hgceh5gcJDfvaBYqxLFpKzVglpnbDSq1Fg0p0zI4oa5Pg==}
310 | engines: {node: '>= 10'}
311 | cpu: [x64]
312 | os: [darwin]
313 |
314 | '@tailwindcss/oxide-freebsd-x64@4.0.3':
315 | resolution: {integrity: sha512-yQc9Q0JCOp3kkAV8gKgDctXO60IkQhHpqGB+KgOccDtD5UmN6Q5+gd+lcsDyQ7N8dRuK1fAud51xQpZJgKfm7g==}
316 | engines: {node: '>= 10'}
317 | cpu: [x64]
318 | os: [freebsd]
319 |
320 | '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.3':
321 | resolution: {integrity: sha512-e1ivVMLSnxTOU1O3npnxN16FEyWM/g3SuH2pP6udxXwa0/SnSAijRwcAYRpqIlhVKujr158S8UeHxQjC4fGl4w==}
322 | engines: {node: '>= 10'}
323 | cpu: [arm]
324 | os: [linux]
325 |
326 | '@tailwindcss/oxide-linux-arm64-gnu@4.0.3':
327 | resolution: {integrity: sha512-PLrToqQqX6sdJ9DmMi8IxZWWrfjc9pdi9AEEPTrtMts3Jm9HBi1WqEeF1VwZZ2aW9TXloE5OwA35zuuq1Bhb/Q==}
328 | engines: {node: '>= 10'}
329 | cpu: [arm64]
330 | os: [linux]
331 |
332 | '@tailwindcss/oxide-linux-arm64-musl@4.0.3':
333 | resolution: {integrity: sha512-YlzRxx7N1ampfgSKzEDw0iwDkJXUInR4cgNEqmR4TzHkU2Vhg59CGPJrTI7dxOBofD8+O35R13Nk9Ytyv0JUFg==}
334 | engines: {node: '>= 10'}
335 | cpu: [arm64]
336 | os: [linux]
337 |
338 | '@tailwindcss/oxide-linux-x64-gnu@4.0.3':
339 | resolution: {integrity: sha512-Xfc3z/li6XkuD7Hs+Uk6pjyCXnfnd9zuQTKOyDTZJ544xc2yoMKUkuDw6Et9wb31MzU2/c0CIUpTDa71lL9KHw==}
340 | engines: {node: '>= 10'}
341 | cpu: [x64]
342 | os: [linux]
343 |
344 | '@tailwindcss/oxide-linux-x64-musl@4.0.3':
345 | resolution: {integrity: sha512-ugKVqKzwa/cjmqSQG17aS9DYrEcQ/a5NITcgmOr3JLW4Iz64C37eoDlkC8tIepD3S/Td/ywKAolTQ8fKbjEL4g==}
346 | engines: {node: '>= 10'}
347 | cpu: [x64]
348 | os: [linux]
349 |
350 | '@tailwindcss/oxide-win32-arm64-msvc@4.0.3':
351 | resolution: {integrity: sha512-qHPDMl+UUwsk1RMJMgAXvhraWqUUT+LR/tkXix5RA39UGxtTrHwsLIN1AhNxI5i2RFXAXfmFXDqZCdyQ4dWmAQ==}
352 | engines: {node: '>= 10'}
353 | cpu: [arm64]
354 | os: [win32]
355 |
356 | '@tailwindcss/oxide-win32-x64-msvc@4.0.3':
357 | resolution: {integrity: sha512-+ujwN4phBGyOsPyLgGgeCyUm4Mul+gqWVCIGuSXWgrx9xVUnf6LVXrw0BDBc9Aq1S2qMyOTX4OkCGbZeoIo8Qw==}
358 | engines: {node: '>= 10'}
359 | cpu: [x64]
360 | os: [win32]
361 |
362 | '@tailwindcss/oxide@4.0.3':
363 | resolution: {integrity: sha512-FFcp3VNvRjjmFA39ORM27g2mbflMQljhvM7gxBAujHxUy4LXlKa6yMF9wbHdTbPqTONiCyyOYxccvJyVyI/XBg==}
364 | engines: {node: '>= 10'}
365 |
366 | '@tailwindcss/postcss@4.0.3':
367 | resolution: {integrity: sha512-qUyxuhuI2eTgRJ+qfCQRAr69Cw7BdSz+PoNFUNoRuhPjikNC8+sxK+Mi/chaXAXewjv/zbf6if6z6ItVLh+e9Q==}
368 |
369 | '@tanstack/react-virtual@3.12.0':
370 | resolution: {integrity: sha512-6krceiPN07kpxXmU6m8AY7EL0X1gHLu8m3nJdh4phvktzVNxkQfBmSwnRUpoUjGQO1PAn8wSAhYaL8hY1cS1vw==}
371 | peerDependencies:
372 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
373 | react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
374 |
375 | '@tanstack/virtual-core@3.12.0':
376 | resolution: {integrity: sha512-7mDINtua3v/pOnn6WUmuT9dPXYSO7WidFej7JzoAfqEOcbbpt/iZ1WPqd+eg+FnrL9nUJK8radqj4iAU51Zchg==}
377 |
378 | '@types/aos@3.0.7':
379 | resolution: {integrity: sha512-sEhyFqvKauUJZDbvAB3Pggynrq6g+2PS4XB3tmUr+mDL1gfDJnwslUC4QQ7/l8UD+LWpr3RxZVR/rHoZrLqZVg==}
380 |
381 | '@types/node@22.13.0':
382 | resolution: {integrity: sha512-ClIbNe36lawluuvq3+YYhnIN2CELi+6q8NpnM7PYp4hBn/TatfboPgVSm2rwKRfnV2M+Ty9GWDFI64KEe+kysA==}
383 |
384 | '@types/react-dom@19.0.3':
385 | resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==}
386 | peerDependencies:
387 | '@types/react': ^19.0.0
388 |
389 | '@types/react@19.0.8':
390 | resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==}
391 |
392 | aos@3.0.0-beta.6:
393 | resolution: {integrity: sha512-VLWrpq8bfAWcetynVHMMrqdC+89Qq/Ym6UBJbHB4crIwp3RR8uq1dNGgsFzoDl03S43rlVMK+na3r5+oUCZsYw==}
394 |
395 | busboy@1.6.0:
396 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
397 | engines: {node: '>=10.16.0'}
398 |
399 | caniuse-lite@1.0.30001696:
400 | resolution: {integrity: sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==}
401 |
402 | classlist-polyfill@1.2.0:
403 | resolution: {integrity: sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ==}
404 |
405 | client-only@0.0.1:
406 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
407 |
408 | clsx@2.1.1:
409 | resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
410 | engines: {node: '>=6'}
411 |
412 | color-convert@2.0.1:
413 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
414 | engines: {node: '>=7.0.0'}
415 |
416 | color-name@1.1.4:
417 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
418 |
419 | color-string@1.9.1:
420 | resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
421 |
422 | color@4.2.3:
423 | resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
424 | engines: {node: '>=12.5.0'}
425 |
426 | csstype@3.1.3:
427 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
428 |
429 | detect-libc@1.0.3:
430 | resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==}
431 | engines: {node: '>=0.10'}
432 | hasBin: true
433 |
434 | detect-libc@2.0.3:
435 | resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
436 | engines: {node: '>=8'}
437 |
438 | enhanced-resolve@5.18.0:
439 | resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==}
440 | engines: {node: '>=10.13.0'}
441 |
442 | graceful-fs@4.2.11:
443 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
444 |
445 | is-arrayish@0.3.2:
446 | resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
447 |
448 | jiti@2.4.2:
449 | resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
450 | hasBin: true
451 |
452 | lightningcss-darwin-arm64@1.29.1:
453 | resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==}
454 | engines: {node: '>= 12.0.0'}
455 | cpu: [arm64]
456 | os: [darwin]
457 |
458 | lightningcss-darwin-x64@1.29.1:
459 | resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==}
460 | engines: {node: '>= 12.0.0'}
461 | cpu: [x64]
462 | os: [darwin]
463 |
464 | lightningcss-freebsd-x64@1.29.1:
465 | resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==}
466 | engines: {node: '>= 12.0.0'}
467 | cpu: [x64]
468 | os: [freebsd]
469 |
470 | lightningcss-linux-arm-gnueabihf@1.29.1:
471 | resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==}
472 | engines: {node: '>= 12.0.0'}
473 | cpu: [arm]
474 | os: [linux]
475 |
476 | lightningcss-linux-arm64-gnu@1.29.1:
477 | resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==}
478 | engines: {node: '>= 12.0.0'}
479 | cpu: [arm64]
480 | os: [linux]
481 |
482 | lightningcss-linux-arm64-musl@1.29.1:
483 | resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==}
484 | engines: {node: '>= 12.0.0'}
485 | cpu: [arm64]
486 | os: [linux]
487 |
488 | lightningcss-linux-x64-gnu@1.29.1:
489 | resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==}
490 | engines: {node: '>= 12.0.0'}
491 | cpu: [x64]
492 | os: [linux]
493 |
494 | lightningcss-linux-x64-musl@1.29.1:
495 | resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==}
496 | engines: {node: '>= 12.0.0'}
497 | cpu: [x64]
498 | os: [linux]
499 |
500 | lightningcss-win32-arm64-msvc@1.29.1:
501 | resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==}
502 | engines: {node: '>= 12.0.0'}
503 | cpu: [arm64]
504 | os: [win32]
505 |
506 | lightningcss-win32-x64-msvc@1.29.1:
507 | resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==}
508 | engines: {node: '>= 12.0.0'}
509 | cpu: [x64]
510 | os: [win32]
511 |
512 | lightningcss@1.29.1:
513 | resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==}
514 | engines: {node: '>= 12.0.0'}
515 |
516 | lodash.debounce@4.0.8:
517 | resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
518 |
519 | lodash.throttle@4.1.1:
520 | resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
521 |
522 | mini-svg-data-uri@1.4.4:
523 | resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==}
524 | hasBin: true
525 |
526 | nanoid@3.3.8:
527 | resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
528 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
529 | hasBin: true
530 |
531 | next@15.1.6:
532 | resolution: {integrity: sha512-Hch4wzbaX0vKQtalpXvUiw5sYivBy4cm5rzUKrBnUB/y436LGrvOUqYvlSeNVCWFO/770gDlltR9gqZH62ct4Q==}
533 | engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
534 | hasBin: true
535 | peerDependencies:
536 | '@opentelemetry/api': ^1.1.0
537 | '@playwright/test': ^1.41.2
538 | babel-plugin-react-compiler: '*'
539 | react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
540 | react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
541 | sass: ^1.3.0
542 | peerDependenciesMeta:
543 | '@opentelemetry/api':
544 | optional: true
545 | '@playwright/test':
546 | optional: true
547 | babel-plugin-react-compiler:
548 | optional: true
549 | sass:
550 | optional: true
551 |
552 | picocolors@1.1.1:
553 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
554 |
555 | postcss@8.4.31:
556 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
557 | engines: {node: ^10 || ^12 || >=14}
558 |
559 | postcss@8.5.1:
560 | resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
561 | engines: {node: ^10 || ^12 || >=14}
562 |
563 | react-dom@19.0.0:
564 | resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
565 | peerDependencies:
566 | react: ^19.0.0
567 |
568 | react@19.0.0:
569 | resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
570 | engines: {node: '>=0.10.0'}
571 |
572 | scheduler@0.25.0:
573 | resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
574 |
575 | semver@7.7.1:
576 | resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==}
577 | engines: {node: '>=10'}
578 | hasBin: true
579 |
580 | sharp@0.33.5:
581 | resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
582 | engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
583 |
584 | simple-swizzle@0.2.2:
585 | resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
586 |
587 | source-map-js@1.2.1:
588 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
589 | engines: {node: '>=0.10.0'}
590 |
591 | streamsearch@1.1.0:
592 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
593 | engines: {node: '>=10.0.0'}
594 |
595 | styled-jsx@5.1.6:
596 | resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==}
597 | engines: {node: '>= 12.0.0'}
598 | peerDependencies:
599 | '@babel/core': '*'
600 | babel-plugin-macros: '*'
601 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0'
602 | peerDependenciesMeta:
603 | '@babel/core':
604 | optional: true
605 | babel-plugin-macros:
606 | optional: true
607 |
608 | tabbable@6.2.0:
609 | resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
610 |
611 | tailwindcss@4.0.3:
612 | resolution: {integrity: sha512-ImmZF0Lon5RrQpsEAKGxRvHwCvMgSC4XVlFRqmbzTEDb/3wvin9zfEZrMwgsa3yqBbPqahYcVI6lulM2S7IZAA==}
613 |
614 | tapable@2.2.1:
615 | resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
616 | engines: {node: '>=6'}
617 |
618 | tslib@2.8.1:
619 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
620 |
621 | typescript@5.7.3:
622 | resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
623 | engines: {node: '>=14.17'}
624 | hasBin: true
625 |
626 | undici-types@6.20.0:
627 | resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
628 |
629 | snapshots:
630 |
631 | '@alloc/quick-lru@5.2.0': {}
632 |
633 | '@emnapi/runtime@1.3.1':
634 | dependencies:
635 | tslib: 2.8.1
636 | optional: true
637 |
638 | '@floating-ui/core@1.6.9':
639 | dependencies:
640 | '@floating-ui/utils': 0.2.9
641 |
642 | '@floating-ui/dom@1.6.13':
643 | dependencies:
644 | '@floating-ui/core': 1.6.9
645 | '@floating-ui/utils': 0.2.9
646 |
647 | '@floating-ui/react-dom@2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
648 | dependencies:
649 | '@floating-ui/dom': 1.6.13
650 | react: 19.0.0
651 | react-dom: 19.0.0(react@19.0.0)
652 |
653 | '@floating-ui/react@0.26.28(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
654 | dependencies:
655 | '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
656 | '@floating-ui/utils': 0.2.9
657 | react: 19.0.0
658 | react-dom: 19.0.0(react@19.0.0)
659 | tabbable: 6.2.0
660 |
661 | '@floating-ui/utils@0.2.9': {}
662 |
663 | '@headlessui/react@2.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
664 | dependencies:
665 | '@floating-ui/react': 0.26.28(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
666 | '@react-aria/focus': 3.19.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
667 | '@react-aria/interactions': 3.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
668 | '@tanstack/react-virtual': 3.12.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
669 | react: 19.0.0
670 | react-dom: 19.0.0(react@19.0.0)
671 |
672 | '@img/sharp-darwin-arm64@0.33.5':
673 | optionalDependencies:
674 | '@img/sharp-libvips-darwin-arm64': 1.0.4
675 | optional: true
676 |
677 | '@img/sharp-darwin-x64@0.33.5':
678 | optionalDependencies:
679 | '@img/sharp-libvips-darwin-x64': 1.0.4
680 | optional: true
681 |
682 | '@img/sharp-libvips-darwin-arm64@1.0.4':
683 | optional: true
684 |
685 | '@img/sharp-libvips-darwin-x64@1.0.4':
686 | optional: true
687 |
688 | '@img/sharp-libvips-linux-arm64@1.0.4':
689 | optional: true
690 |
691 | '@img/sharp-libvips-linux-arm@1.0.5':
692 | optional: true
693 |
694 | '@img/sharp-libvips-linux-s390x@1.0.4':
695 | optional: true
696 |
697 | '@img/sharp-libvips-linux-x64@1.0.4':
698 | optional: true
699 |
700 | '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
701 | optional: true
702 |
703 | '@img/sharp-libvips-linuxmusl-x64@1.0.4':
704 | optional: true
705 |
706 | '@img/sharp-linux-arm64@0.33.5':
707 | optionalDependencies:
708 | '@img/sharp-libvips-linux-arm64': 1.0.4
709 | optional: true
710 |
711 | '@img/sharp-linux-arm@0.33.5':
712 | optionalDependencies:
713 | '@img/sharp-libvips-linux-arm': 1.0.5
714 | optional: true
715 |
716 | '@img/sharp-linux-s390x@0.33.5':
717 | optionalDependencies:
718 | '@img/sharp-libvips-linux-s390x': 1.0.4
719 | optional: true
720 |
721 | '@img/sharp-linux-x64@0.33.5':
722 | optionalDependencies:
723 | '@img/sharp-libvips-linux-x64': 1.0.4
724 | optional: true
725 |
726 | '@img/sharp-linuxmusl-arm64@0.33.5':
727 | optionalDependencies:
728 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
729 | optional: true
730 |
731 | '@img/sharp-linuxmusl-x64@0.33.5':
732 | optionalDependencies:
733 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4
734 | optional: true
735 |
736 | '@img/sharp-wasm32@0.33.5':
737 | dependencies:
738 | '@emnapi/runtime': 1.3.1
739 | optional: true
740 |
741 | '@img/sharp-win32-ia32@0.33.5':
742 | optional: true
743 |
744 | '@img/sharp-win32-x64@0.33.5':
745 | optional: true
746 |
747 | '@next/env@15.1.6': {}
748 |
749 | '@next/swc-darwin-arm64@15.1.6':
750 | optional: true
751 |
752 | '@next/swc-darwin-x64@15.1.6':
753 | optional: true
754 |
755 | '@next/swc-linux-arm64-gnu@15.1.6':
756 | optional: true
757 |
758 | '@next/swc-linux-arm64-musl@15.1.6':
759 | optional: true
760 |
761 | '@next/swc-linux-x64-gnu@15.1.6':
762 | optional: true
763 |
764 | '@next/swc-linux-x64-musl@15.1.6':
765 | optional: true
766 |
767 | '@next/swc-win32-arm64-msvc@15.1.6':
768 | optional: true
769 |
770 | '@next/swc-win32-x64-msvc@15.1.6':
771 | optional: true
772 |
773 | '@react-aria/focus@3.19.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
774 | dependencies:
775 | '@react-aria/interactions': 3.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
776 | '@react-aria/utils': 3.27.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
777 | '@react-types/shared': 3.27.0(react@19.0.0)
778 | '@swc/helpers': 0.5.15
779 | clsx: 2.1.1
780 | react: 19.0.0
781 | react-dom: 19.0.0(react@19.0.0)
782 |
783 | '@react-aria/interactions@3.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
784 | dependencies:
785 | '@react-aria/ssr': 3.9.7(react@19.0.0)
786 | '@react-aria/utils': 3.27.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
787 | '@react-types/shared': 3.27.0(react@19.0.0)
788 | '@swc/helpers': 0.5.15
789 | react: 19.0.0
790 | react-dom: 19.0.0(react@19.0.0)
791 |
792 | '@react-aria/ssr@3.9.7(react@19.0.0)':
793 | dependencies:
794 | '@swc/helpers': 0.5.15
795 | react: 19.0.0
796 |
797 | '@react-aria/utils@3.27.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
798 | dependencies:
799 | '@react-aria/ssr': 3.9.7(react@19.0.0)
800 | '@react-stately/utils': 3.10.5(react@19.0.0)
801 | '@react-types/shared': 3.27.0(react@19.0.0)
802 | '@swc/helpers': 0.5.15
803 | clsx: 2.1.1
804 | react: 19.0.0
805 | react-dom: 19.0.0(react@19.0.0)
806 |
807 | '@react-stately/utils@3.10.5(react@19.0.0)':
808 | dependencies:
809 | '@swc/helpers': 0.5.15
810 | react: 19.0.0
811 |
812 | '@react-types/shared@3.27.0(react@19.0.0)':
813 | dependencies:
814 | react: 19.0.0
815 |
816 | '@swc/counter@0.1.3': {}
817 |
818 | '@swc/helpers@0.5.15':
819 | dependencies:
820 | tslib: 2.8.1
821 |
822 | '@tailwindcss/forms@0.5.10(tailwindcss@4.0.3)':
823 | dependencies:
824 | mini-svg-data-uri: 1.4.4
825 | tailwindcss: 4.0.3
826 |
827 | '@tailwindcss/node@4.0.3':
828 | dependencies:
829 | enhanced-resolve: 5.18.0
830 | jiti: 2.4.2
831 | tailwindcss: 4.0.3
832 |
833 | '@tailwindcss/oxide-android-arm64@4.0.3':
834 | optional: true
835 |
836 | '@tailwindcss/oxide-darwin-arm64@4.0.3':
837 | optional: true
838 |
839 | '@tailwindcss/oxide-darwin-x64@4.0.3':
840 | optional: true
841 |
842 | '@tailwindcss/oxide-freebsd-x64@4.0.3':
843 | optional: true
844 |
845 | '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.3':
846 | optional: true
847 |
848 | '@tailwindcss/oxide-linux-arm64-gnu@4.0.3':
849 | optional: true
850 |
851 | '@tailwindcss/oxide-linux-arm64-musl@4.0.3':
852 | optional: true
853 |
854 | '@tailwindcss/oxide-linux-x64-gnu@4.0.3':
855 | optional: true
856 |
857 | '@tailwindcss/oxide-linux-x64-musl@4.0.3':
858 | optional: true
859 |
860 | '@tailwindcss/oxide-win32-arm64-msvc@4.0.3':
861 | optional: true
862 |
863 | '@tailwindcss/oxide-win32-x64-msvc@4.0.3':
864 | optional: true
865 |
866 | '@tailwindcss/oxide@4.0.3':
867 | optionalDependencies:
868 | '@tailwindcss/oxide-android-arm64': 4.0.3
869 | '@tailwindcss/oxide-darwin-arm64': 4.0.3
870 | '@tailwindcss/oxide-darwin-x64': 4.0.3
871 | '@tailwindcss/oxide-freebsd-x64': 4.0.3
872 | '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.3
873 | '@tailwindcss/oxide-linux-arm64-gnu': 4.0.3
874 | '@tailwindcss/oxide-linux-arm64-musl': 4.0.3
875 | '@tailwindcss/oxide-linux-x64-gnu': 4.0.3
876 | '@tailwindcss/oxide-linux-x64-musl': 4.0.3
877 | '@tailwindcss/oxide-win32-arm64-msvc': 4.0.3
878 | '@tailwindcss/oxide-win32-x64-msvc': 4.0.3
879 |
880 | '@tailwindcss/postcss@4.0.3':
881 | dependencies:
882 | '@alloc/quick-lru': 5.2.0
883 | '@tailwindcss/node': 4.0.3
884 | '@tailwindcss/oxide': 4.0.3
885 | lightningcss: 1.29.1
886 | postcss: 8.5.1
887 | tailwindcss: 4.0.3
888 |
889 | '@tanstack/react-virtual@3.12.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
890 | dependencies:
891 | '@tanstack/virtual-core': 3.12.0
892 | react: 19.0.0
893 | react-dom: 19.0.0(react@19.0.0)
894 |
895 | '@tanstack/virtual-core@3.12.0': {}
896 |
897 | '@types/aos@3.0.7': {}
898 |
899 | '@types/node@22.13.0':
900 | dependencies:
901 | undici-types: 6.20.0
902 |
903 | '@types/react-dom@19.0.3(@types/react@19.0.8)':
904 | dependencies:
905 | '@types/react': 19.0.8
906 |
907 | '@types/react@19.0.8':
908 | dependencies:
909 | csstype: 3.1.3
910 |
911 | aos@3.0.0-beta.6:
912 | dependencies:
913 | classlist-polyfill: 1.2.0
914 | lodash.debounce: 4.0.8
915 | lodash.throttle: 4.1.1
916 |
917 | busboy@1.6.0:
918 | dependencies:
919 | streamsearch: 1.1.0
920 |
921 | caniuse-lite@1.0.30001696: {}
922 |
923 | classlist-polyfill@1.2.0: {}
924 |
925 | client-only@0.0.1: {}
926 |
927 | clsx@2.1.1: {}
928 |
929 | color-convert@2.0.1:
930 | dependencies:
931 | color-name: 1.1.4
932 | optional: true
933 |
934 | color-name@1.1.4:
935 | optional: true
936 |
937 | color-string@1.9.1:
938 | dependencies:
939 | color-name: 1.1.4
940 | simple-swizzle: 0.2.2
941 | optional: true
942 |
943 | color@4.2.3:
944 | dependencies:
945 | color-convert: 2.0.1
946 | color-string: 1.9.1
947 | optional: true
948 |
949 | csstype@3.1.3: {}
950 |
951 | detect-libc@1.0.3: {}
952 |
953 | detect-libc@2.0.3:
954 | optional: true
955 |
956 | enhanced-resolve@5.18.0:
957 | dependencies:
958 | graceful-fs: 4.2.11
959 | tapable: 2.2.1
960 |
961 | graceful-fs@4.2.11: {}
962 |
963 | is-arrayish@0.3.2:
964 | optional: true
965 |
966 | jiti@2.4.2: {}
967 |
968 | lightningcss-darwin-arm64@1.29.1:
969 | optional: true
970 |
971 | lightningcss-darwin-x64@1.29.1:
972 | optional: true
973 |
974 | lightningcss-freebsd-x64@1.29.1:
975 | optional: true
976 |
977 | lightningcss-linux-arm-gnueabihf@1.29.1:
978 | optional: true
979 |
980 | lightningcss-linux-arm64-gnu@1.29.1:
981 | optional: true
982 |
983 | lightningcss-linux-arm64-musl@1.29.1:
984 | optional: true
985 |
986 | lightningcss-linux-x64-gnu@1.29.1:
987 | optional: true
988 |
989 | lightningcss-linux-x64-musl@1.29.1:
990 | optional: true
991 |
992 | lightningcss-win32-arm64-msvc@1.29.1:
993 | optional: true
994 |
995 | lightningcss-win32-x64-msvc@1.29.1:
996 | optional: true
997 |
998 | lightningcss@1.29.1:
999 | dependencies:
1000 | detect-libc: 1.0.3
1001 | optionalDependencies:
1002 | lightningcss-darwin-arm64: 1.29.1
1003 | lightningcss-darwin-x64: 1.29.1
1004 | lightningcss-freebsd-x64: 1.29.1
1005 | lightningcss-linux-arm-gnueabihf: 1.29.1
1006 | lightningcss-linux-arm64-gnu: 1.29.1
1007 | lightningcss-linux-arm64-musl: 1.29.1
1008 | lightningcss-linux-x64-gnu: 1.29.1
1009 | lightningcss-linux-x64-musl: 1.29.1
1010 | lightningcss-win32-arm64-msvc: 1.29.1
1011 | lightningcss-win32-x64-msvc: 1.29.1
1012 |
1013 | lodash.debounce@4.0.8: {}
1014 |
1015 | lodash.throttle@4.1.1: {}
1016 |
1017 | mini-svg-data-uri@1.4.4: {}
1018 |
1019 | nanoid@3.3.8: {}
1020 |
1021 | next@15.1.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
1022 | dependencies:
1023 | '@next/env': 15.1.6
1024 | '@swc/counter': 0.1.3
1025 | '@swc/helpers': 0.5.15
1026 | busboy: 1.6.0
1027 | caniuse-lite: 1.0.30001696
1028 | postcss: 8.4.31
1029 | react: 19.0.0
1030 | react-dom: 19.0.0(react@19.0.0)
1031 | styled-jsx: 5.1.6(react@19.0.0)
1032 | optionalDependencies:
1033 | '@next/swc-darwin-arm64': 15.1.6
1034 | '@next/swc-darwin-x64': 15.1.6
1035 | '@next/swc-linux-arm64-gnu': 15.1.6
1036 | '@next/swc-linux-arm64-musl': 15.1.6
1037 | '@next/swc-linux-x64-gnu': 15.1.6
1038 | '@next/swc-linux-x64-musl': 15.1.6
1039 | '@next/swc-win32-arm64-msvc': 15.1.6
1040 | '@next/swc-win32-x64-msvc': 15.1.6
1041 | sharp: 0.33.5
1042 | transitivePeerDependencies:
1043 | - '@babel/core'
1044 | - babel-plugin-macros
1045 |
1046 | picocolors@1.1.1: {}
1047 |
1048 | postcss@8.4.31:
1049 | dependencies:
1050 | nanoid: 3.3.8
1051 | picocolors: 1.1.1
1052 | source-map-js: 1.2.1
1053 |
1054 | postcss@8.5.1:
1055 | dependencies:
1056 | nanoid: 3.3.8
1057 | picocolors: 1.1.1
1058 | source-map-js: 1.2.1
1059 |
1060 | react-dom@19.0.0(react@19.0.0):
1061 | dependencies:
1062 | react: 19.0.0
1063 | scheduler: 0.25.0
1064 |
1065 | react@19.0.0: {}
1066 |
1067 | scheduler@0.25.0: {}
1068 |
1069 | semver@7.7.1:
1070 | optional: true
1071 |
1072 | sharp@0.33.5:
1073 | dependencies:
1074 | color: 4.2.3
1075 | detect-libc: 2.0.3
1076 | semver: 7.7.1
1077 | optionalDependencies:
1078 | '@img/sharp-darwin-arm64': 0.33.5
1079 | '@img/sharp-darwin-x64': 0.33.5
1080 | '@img/sharp-libvips-darwin-arm64': 1.0.4
1081 | '@img/sharp-libvips-darwin-x64': 1.0.4
1082 | '@img/sharp-libvips-linux-arm': 1.0.5
1083 | '@img/sharp-libvips-linux-arm64': 1.0.4
1084 | '@img/sharp-libvips-linux-s390x': 1.0.4
1085 | '@img/sharp-libvips-linux-x64': 1.0.4
1086 | '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
1087 | '@img/sharp-libvips-linuxmusl-x64': 1.0.4
1088 | '@img/sharp-linux-arm': 0.33.5
1089 | '@img/sharp-linux-arm64': 0.33.5
1090 | '@img/sharp-linux-s390x': 0.33.5
1091 | '@img/sharp-linux-x64': 0.33.5
1092 | '@img/sharp-linuxmusl-arm64': 0.33.5
1093 | '@img/sharp-linuxmusl-x64': 0.33.5
1094 | '@img/sharp-wasm32': 0.33.5
1095 | '@img/sharp-win32-ia32': 0.33.5
1096 | '@img/sharp-win32-x64': 0.33.5
1097 | optional: true
1098 |
1099 | simple-swizzle@0.2.2:
1100 | dependencies:
1101 | is-arrayish: 0.3.2
1102 | optional: true
1103 |
1104 | source-map-js@1.2.1: {}
1105 |
1106 | streamsearch@1.1.0: {}
1107 |
1108 | styled-jsx@5.1.6(react@19.0.0):
1109 | dependencies:
1110 | client-only: 0.0.1
1111 | react: 19.0.0
1112 |
1113 | tabbable@6.2.0: {}
1114 |
1115 | tailwindcss@4.0.3: {}
1116 |
1117 | tapable@2.2.1: {}
1118 |
1119 | tslib@2.8.1: {}
1120 |
1121 | typescript@5.7.3: {}
1122 |
1123 | undici-types@6.20.0: {}
1124 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | '@tailwindcss/postcss': {},
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/favicon.ico
--------------------------------------------------------------------------------
/public/fonts/nacelle-italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/fonts/nacelle-italic.woff2
--------------------------------------------------------------------------------
/public/fonts/nacelle-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/fonts/nacelle-regular.woff2
--------------------------------------------------------------------------------
/public/fonts/nacelle-semibold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/fonts/nacelle-semibold.woff2
--------------------------------------------------------------------------------
/public/fonts/nacelle-semibolditalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/fonts/nacelle-semibolditalic.woff2
--------------------------------------------------------------------------------
/public/images/blurred-shape-gray.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/blurred-shape.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-01.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-02.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-03.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-04.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-05.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-06.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-07.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-08.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/client-logo-09.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/features.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/features.png
--------------------------------------------------------------------------------
/public/images/footer-illustration.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/hero-image-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/hero-image-01.jpg
--------------------------------------------------------------------------------
/public/images/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/page-illustration.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/secondary-illustration.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/testimonial-01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-01.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-02.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-03.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-04.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-05.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-05.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-06.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-06.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-07.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-07.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-08.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-08.jpg
--------------------------------------------------------------------------------
/public/images/testimonial-09.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/testimonial-09.jpg
--------------------------------------------------------------------------------
/public/images/workflow-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/workflow-01.png
--------------------------------------------------------------------------------
/public/images/workflow-02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/workflow-02.png
--------------------------------------------------------------------------------
/public/images/workflow-03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/images/workflow-03.png
--------------------------------------------------------------------------------
/public/videos/video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cruip/open-react-template/03d3192febd90543c2b159594b77f5969c3762ab/public/videos/video.mp4
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "paths": {
23 | "@/*": ["./*"]
24 | }
25 | },
26 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
27 | "exclude": ["node_modules"]
28 | }
29 |
--------------------------------------------------------------------------------
/utils/useMasonry.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState, useRef } from "react";
2 |
3 | const useMasonry = () => {
4 | const masonryContainer = useRef(null);
5 | const [items, setItems] = useState([]);
6 |
7 | useEffect(() => {
8 | if (masonryContainer.current) {
9 | const masonryItem = Array.from(masonryContainer.current.children);
10 | setItems(masonryItem);
11 | }
12 | }, []);
13 |
14 | useEffect(() => {
15 | const handleMasonry = () => {
16 | if (!items || items.length < 1) return;
17 | let gapSize = 0;
18 | if (masonryContainer.current) {
19 | gapSize = parseInt(
20 | window
21 | .getComputedStyle(masonryContainer.current)
22 | .getPropertyValue("grid-row-gap"),
23 | );
24 | }
25 | items.forEach((el) => {
26 | if (!(el instanceof HTMLElement)) return;
27 | let previous = el.previousSibling;
28 | while (previous) {
29 | if (previous.nodeType === 1) {
30 | el.style.marginTop = "0";
31 | if (
32 | previous instanceof HTMLElement &&
33 | elementLeft(previous) === elementLeft(el)
34 | ) {
35 | el.style.marginTop =
36 | -(elementTop(el) - elementBottom(previous) - gapSize) + "px";
37 | break;
38 | }
39 | }
40 | previous = previous.previousSibling;
41 | }
42 | });
43 | };
44 |
45 | handleMasonry();
46 | window.addEventListener("resize", handleMasonry);
47 | return () => {
48 | window.removeEventListener("resize", handleMasonry);
49 | };
50 | }, [items]);
51 |
52 | const elementLeft = (el: HTMLElement) => {
53 | return el.getBoundingClientRect().left;
54 | };
55 |
56 | const elementTop = (el: HTMLElement) => {
57 | return el.getBoundingClientRect().top + window.scrollY;
58 | };
59 |
60 | const elementBottom = (el: HTMLElement) => {
61 | return el.getBoundingClientRect().bottom + window.scrollY;
62 | };
63 |
64 | return masonryContainer;
65 | };
66 |
67 | export default useMasonry;
68 |
--------------------------------------------------------------------------------
/utils/useMousePosition.tsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 |
3 | interface MousePosition {
4 | x: number;
5 | y: number;
6 | }
7 |
8 | export default function useMousePosition(): MousePosition {
9 | const [mousePosition, setMousePosition] = useState({
10 | x: 0,
11 | y: 0,
12 | });
13 |
14 | useEffect(() => {
15 | const handleMouseMove = (event: MouseEvent) => {
16 | setMousePosition({ x: event.clientX, y: event.clientY });
17 | };
18 |
19 | window.addEventListener("mousemove", handleMouseMove);
20 |
21 | return () => {
22 | window.removeEventListener("mousemove", handleMouseMove);
23 | };
24 | }, []);
25 |
26 | return mousePosition;
27 | }
28 |
--------------------------------------------------------------------------------