diff --git a/apps/web/app/.gitignore b/apps/web/app/.gitignore
index 4e4766d..5dccd89 100644
--- a/apps/web/app/.gitignore
+++ b/apps/web/app/.gitignore
@@ -1,3 +1,4 @@
# clerk configuration (can include secrets)
/.clerk/
+.vercel
diff --git a/apps/web/app/app/(auth)/sign-in/[[...sign-in]]/page.tsx b/apps/web/app/app/(auth)/sign-in/[[...sign-in]]/page.tsx
index 9009fb5..b56e4e7 100644
--- a/apps/web/app/app/(auth)/sign-in/[[...sign-in]]/page.tsx
+++ b/apps/web/app/app/(auth)/sign-in/[[...sign-in]]/page.tsx
@@ -1,8 +1,10 @@
import { SignIn } from "@clerk/nextjs";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Sign In | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Sign In",
+ description: "Sign in to your Qurious account",
+});
export default function SignInPage() {
return ;
diff --git a/apps/web/app/app/(auth)/sign-up/[[...sign-up]]/page.tsx b/apps/web/app/app/(auth)/sign-up/[[...sign-up]]/page.tsx
index f807462..25bdb1e 100644
--- a/apps/web/app/app/(auth)/sign-up/[[...sign-up]]/page.tsx
+++ b/apps/web/app/app/(auth)/sign-up/[[...sign-up]]/page.tsx
@@ -1,8 +1,10 @@
import { SignUp } from "@clerk/nextjs";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Sign Up | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Sign Up",
+ description: "Create a new Qurious account",
+});
export default function SignUpPage() {
return ;
diff --git a/apps/web/app/app/(user)/folders/[id]/layout.tsx b/apps/web/app/app/(user)/folders/[id]/layout.tsx
index 829fa02..72659df 100644
--- a/apps/web/app/app/(user)/folders/[id]/layout.tsx
+++ b/apps/web/app/app/(user)/folders/[id]/layout.tsx
@@ -1,6 +1,7 @@
import { fetchQuery } from "convex/nextjs";
import { api } from "@workspace/backend/_generated/api";
import { Id } from "@workspace/backend/_generated/dataModel";
+import { createMetadata } from "@workspace/seo/metadata";
import { FolderLayoutClient } from "./client";
type Props = {
@@ -19,11 +20,15 @@ export async function generateMetadata({
folderId: id as Id<"folders">,
});
- return {
- title: `${folder.name} | Folder | Qurious`,
- };
+ return createMetadata({
+ title: `${folder.name} | Folder`,
+ description: `View and manage papers and searches in the ${folder.name} folder`,
+ });
} catch {
- return { title: "Folder | Qurious" };
+ return createMetadata({
+ title: "Folder",
+ description: "View and manage papers and searches in this folder",
+ });
}
}
diff --git a/apps/web/app/app/(user)/folders/page.tsx b/apps/web/app/app/(user)/folders/page.tsx
index ca8a4e4..fb6d68d 100644
--- a/apps/web/app/app/(user)/folders/page.tsx
+++ b/apps/web/app/app/(user)/folders/page.tsx
@@ -1,9 +1,10 @@
import { FolderClient } from "./client";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Folders | Qurious",
+export const metadata = createMetadata({
+ title: "Folders",
description: "Manage your folders and organize your papers",
-};
+});
export default function FoldersPage() {
return ;
diff --git a/apps/web/app/app/(user)/papers/[id]/layout.tsx b/apps/web/app/app/(user)/papers/[id]/layout.tsx
index 2b5fcfb..5585fde 100644
--- a/apps/web/app/app/(user)/papers/[id]/layout.tsx
+++ b/apps/web/app/app/(user)/papers/[id]/layout.tsx
@@ -1,5 +1,6 @@
import { api } from "@workspace/backend/_generated/api";
import { fetchAction } from "convex/nextjs";
+import { createMetadata } from "@workspace/seo/metadata";
import { PaperLayoutClient } from "./client";
type Props = {
@@ -36,11 +37,16 @@ export async function generateMetadata({
},
);
- return {
- title: `${paper.title} | Paper | Qurious`,
- };
+ return createMetadata({
+ title: `${paper.title} | Paper`,
+ description:
+ paper.tldr?.text || paper.abstract || "View paper details on Qurious",
+ });
} catch {
- return { title: "Paper | Qurious" };
+ return createMetadata({
+ title: "Paper",
+ description: "View paper details on Qurious",
+ });
}
}
diff --git a/apps/web/app/app/(user)/search/page.tsx b/apps/web/app/app/(user)/search/page.tsx
index ebb6baa..9af07e4 100644
--- a/apps/web/app/app/(user)/search/page.tsx
+++ b/apps/web/app/app/(user)/search/page.tsx
@@ -5,6 +5,7 @@ import {
fieldsOfStudy,
publicationTypes,
} from "@workspace/semantic-scholar/src/index";
+import { createMetadata } from "@workspace/seo/metadata";
import { SearchResults } from "./client";
@@ -33,9 +34,12 @@ export async function generateMetadata(props: Props) {
const searchParams = await props.searchParams;
const { q } = searchParamsSchema.parse(searchParams);
- return {
- title: q ? `${q} | Search | Qurious` : "Search | Qurious",
- };
+ return createMetadata({
+ title: q ? `${q} | Search` : "Search",
+ description: q
+ ? `Search results for "${q}" on Qurious`
+ : "Search for research papers and academic content",
+ });
}
export default async function SearchPage(props: Props) {
diff --git a/apps/web/app/app/(user)/settings/account/[[...account]]/page.tsx b/apps/web/app/app/(user)/settings/account/[[...account]]/page.tsx
index 72b58f9..90674fe 100644
--- a/apps/web/app/app/(user)/settings/account/[[...account]]/page.tsx
+++ b/apps/web/app/app/(user)/settings/account/[[...account]]/page.tsx
@@ -9,10 +9,12 @@ import {
CardHeader,
CardTitle,
} from "@workspace/design-system/components/card";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Account Settings | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Account Settings",
+ description: "Manage your account profile and authentication settings",
+});
export default function AccountSettingsPage() {
return (
diff --git a/apps/web/app/app/(user)/settings/credits/page.tsx b/apps/web/app/app/(user)/settings/credits/page.tsx
index 2a88a88..18c230f 100644
--- a/apps/web/app/app/(user)/settings/credits/page.tsx
+++ b/apps/web/app/app/(user)/settings/credits/page.tsx
@@ -1,10 +1,12 @@
import { Heading } from "@/components/global-heading";
import { CreditsClient } from "./client";
import { CreditCard } from "@workspace/design-system/icons";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Credits | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Credits",
+ description: "Manage your credits and billing preferences",
+});
export default function CreditsSettingsPage() {
return (
diff --git a/apps/web/app/app/(user)/settings/customization/page.tsx b/apps/web/app/app/(user)/settings/customization/page.tsx
index 6b0ddd2..e725787 100644
--- a/apps/web/app/app/(user)/settings/customization/page.tsx
+++ b/apps/web/app/app/(user)/settings/customization/page.tsx
@@ -1,10 +1,12 @@
import { Heading } from "@/components/global-heading";
import { ContentSettingsBox } from "./client";
import { Palette } from "@workspace/design-system/icons";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Customization Settings | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Customization Settings",
+ description: "Customize your AI preferences and appearance",
+});
export default function CustomizationSettingsPage() {
return (
diff --git a/apps/web/app/app/(user)/settings/keys/page.tsx b/apps/web/app/app/(user)/settings/keys/page.tsx
index b0620b0..15cf67b 100644
--- a/apps/web/app/app/(user)/settings/keys/page.tsx
+++ b/apps/web/app/app/(user)/settings/keys/page.tsx
@@ -7,10 +7,12 @@ import {
CardHeader,
CardTitle,
} from "@workspace/design-system/components/card";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "API Keys | Qurious",
-};
+export const metadata = createMetadata({
+ title: "API Keys",
+ description: "Manage your API keys for external integrations",
+});
export default function KeysSettingsPage() {
return (
diff --git a/apps/web/app/app/(user)/settings/webhooks/page.tsx b/apps/web/app/app/(user)/settings/webhooks/page.tsx
index bed1bc7..54fd406 100644
--- a/apps/web/app/app/(user)/settings/webhooks/page.tsx
+++ b/apps/web/app/app/(user)/settings/webhooks/page.tsx
@@ -7,10 +7,12 @@ import {
CardHeader,
CardTitle,
} from "@workspace/design-system/components/card";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata = {
- title: "Webhooks | Qurious",
-};
+export const metadata = createMetadata({
+ title: "Webhooks",
+ description: "Configure webhooks for real-time notifications",
+});
export default function WebhooksSettingsPage() {
return (
diff --git a/apps/web/app/app/icon.svg b/apps/web/app/app/icon.svg
deleted file mode 100644
index 3f2531a..0000000
--- a/apps/web/app/app/icon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/apps/web/app/app/layout.tsx b/apps/web/app/app/layout.tsx
index 6efbc9d..dd61b2e 100644
--- a/apps/web/app/app/layout.tsx
+++ b/apps/web/app/app/layout.tsx
@@ -1,5 +1,4 @@
import "@workspace/design-system/styles/globals.css";
-import type { Metadata } from "next";
import { GeistSans, GeistMono } from "@workspace/design-system/font";
// Providers
@@ -10,13 +9,14 @@ import { FontProvider } from "@workspace/design-system/providers/font-provider";
import { PostHogProvider } from "@/providers/posthog-provider";
import { APP_DESCRIPTION, APP_NAME } from "@workspace/design-system/content";
+import { createMetadata } from "@workspace/seo/metadata";
import { Analytics } from "@vercel/analytics/next";
-export const metadata: Metadata = {
- title: APP_NAME,
+export const metadata = createMetadata({
+ title: "Home",
description: APP_DESCRIPTION,
-};
+});
export default function RootLayout({
children,
diff --git a/apps/web/app/package.json b/apps/web/app/package.json
index 8e1e084..da1c0a4 100644
--- a/apps/web/app/package.json
+++ b/apps/web/app/package.json
@@ -28,6 +28,7 @@
"@workspace/backend": "workspace:*",
"@workspace/design-system": "workspace:*",
"@workspace/semantic-scholar": "workspace:*",
+ "@workspace/seo": "workspace:*",
"ai": "^6.0.68",
"convex": "^1.31.7",
"d3": "^7.9.0",
diff --git a/apps/web/blog/app/(home)/blog/[slug]/page.tsx b/apps/web/blog/app/(home)/blog/[slug]/page.tsx
index 85a9871..8450d2c 100644
--- a/apps/web/blog/app/(home)/blog/[slug]/page.tsx
+++ b/apps/web/blog/app/(home)/blog/[slug]/page.tsx
@@ -1,20 +1,21 @@
-import { notFound } from 'next/navigation';
-import Link from 'next/link';
-import { InlineTOC } from 'fumadocs-ui/components/inline-toc';
-import defaultMdxComponents from 'fumadocs-ui/mdx';
-import { blog } from '@/lib/source';
+import { notFound } from "next/navigation";
+import Link from "next/link";
+import { InlineTOC } from "fumadocs-ui/components/inline-toc";
+import defaultMdxComponents from "fumadocs-ui/mdx";
+import { blog } from "@/lib/source";
+import { createMetadata } from "@workspace/seo/metadata";
export async function generateMetadata(props: {
- params: Promise<{ slug: string }>;
- }) {
- const params = await props.params;
- const page = blog.getPage([params.slug]);
- if (!page) notFound();
- return {
- title: page.data.title,
- description: page.data.description,
- };
- }
+ params: Promise<{ slug: string }>;
+}) {
+ const params = await props.params;
+ const page = blog.getPage([params.slug]);
+ if (!page) notFound();
+ return createMetadata({
+ title: page.data.title,
+ description: page.data.description || "Blog post",
+ });
+}
export default async function Page(props: {
params: Promise<{ slug: string }>;
@@ -58,4 +59,4 @@ export function generateStaticParams(): { slug: string }[] {
return blog.getPages().map((page) => ({
slug: page.slugs[0],
}));
-}
\ No newline at end of file
+}
diff --git a/apps/web/help/app/(docs)/[[...slug]]/page.tsx b/apps/web/help/app/(docs)/[[...slug]]/page.tsx
index 3cb6d70..64b508d 100644
--- a/apps/web/help/app/(docs)/[[...slug]]/page.tsx
+++ b/apps/web/help/app/(docs)/[[...slug]]/page.tsx
@@ -1,13 +1,14 @@
-import { source } from '@/lib/source';
+import { source } from "@/lib/source";
import {
DocsPage,
DocsBody,
DocsDescription,
DocsTitle,
-} from 'fumadocs-ui/page';
-import { notFound } from 'next/navigation';
-import { createRelativeLink } from 'fumadocs-ui/mdx';
-import { getMDXComponents } from '@/mdx-components';
+} from "fumadocs-ui/page";
+import { notFound } from "next/navigation";
+import { createRelativeLink } from "fumadocs-ui/mdx";
+import { getMDXComponents } from "@/mdx-components";
+import { createMetadata } from "@workspace/seo/metadata";
export default async function Page(props: {
params: Promise<{ slug?: string[] }>;
@@ -45,8 +46,8 @@ export async function generateMetadata(props: {
const page = source.getPage(params.slug);
if (!page) notFound();
- return {
+ return createMetadata({
title: page.data.title,
- description: page.data.description,
- };
+ description: page.data.description || "Documentation",
+ });
}
diff --git a/apps/web/www/app/(legal)/privacy/page.tsx b/apps/web/www/app/(legal)/privacy/page.tsx
index 9e11851..cd74118 100644
--- a/apps/web/www/app/(legal)/privacy/page.tsx
+++ b/apps/web/www/app/(legal)/privacy/page.tsx
@@ -1,11 +1,11 @@
-import type { Metadata } from "next";
import Link from "next/link";
import { APP_NAME, LEGAL_CONFIG } from "@workspace/design-system/content";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata: Metadata = {
- title: `Privacy Policy | ${APP_NAME}`,
+export const metadata = createMetadata({
+ title: "Privacy Policy",
description: `Privacy Policy for ${APP_NAME} - Learn how we collect, use, and protect your data.`,
-};
+});
export default function PrivacyPage() {
return (
diff --git a/apps/web/www/app/(legal)/terms/page.tsx b/apps/web/www/app/(legal)/terms/page.tsx
index c5e671a..c3822c1 100644
--- a/apps/web/www/app/(legal)/terms/page.tsx
+++ b/apps/web/www/app/(legal)/terms/page.tsx
@@ -1,11 +1,11 @@
-import type { Metadata } from "next";
import Link from "next/link";
import { APP_NAME, LEGAL_CONFIG } from "@workspace/design-system/content";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata: Metadata = {
- title: `Terms of Service | ${APP_NAME}`,
+export const metadata = createMetadata({
+ title: "Terms of Service",
description: `Terms of Service for ${APP_NAME} - A research tool for the AI age.`,
-};
+});
export default function TermsPage() {
return (
diff --git a/apps/web/www/app/layout.tsx b/apps/web/www/app/layout.tsx
index 233999c..f1fe4b5 100644
--- a/apps/web/www/app/layout.tsx
+++ b/apps/web/www/app/layout.tsx
@@ -1,4 +1,3 @@
-import type { Metadata } from "next";
import type { ReactNode } from "react";
import "@workspace/design-system/styles/globals.css";
@@ -10,11 +9,12 @@ import { ThemeProvider } from "@workspace/design-system/providers/theme-provider
import { APP_DESCRIPTION, APP_NAME } from "@workspace/design-system/content";
import { Separator } from "@workspace/design-system/components/separator";
import { Footer } from "@/components/footer";
+import { createMetadata } from "@workspace/seo/metadata";
-export const metadata: Metadata = {
+export const metadata = createMetadata({
title: APP_NAME,
description: APP_DESCRIPTION,
-};
+});
const BackgroundGridsAndBlob = () => {
return (
diff --git a/apps/web/www/package.json b/apps/web/www/package.json
index 7981af4..d720a22 100644
--- a/apps/web/www/package.json
+++ b/apps/web/www/package.json
@@ -11,6 +11,8 @@
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"@workspace/design-system": "workspace:*",
+ "@workspace/seo": "workspace:*",
+ "motion": "^12.34.0",
"next": "15.5.4",
"next-themes": "^0.4.6",
"react": "^19.0.0",
diff --git a/apps/web/www/public/image.png b/apps/web/www/public/image.png
new file mode 100644
index 0000000..286ec83
Binary files /dev/null and b/apps/web/www/public/image.png differ
diff --git a/apps/web/www/public/logo.svg b/apps/web/www/public/logo.svg
new file mode 100644
index 0000000..5344d01
--- /dev/null
+++ b/apps/web/www/public/logo.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/cspell.json b/cspell.json
index 11bc46a..807736e 100644
--- a/cspell.json
+++ b/cspell.json
@@ -82,7 +82,9 @@
"worklets",
"zod",
"zotero",
- "samhoque"
+ "samhoque",
+ "Sahil",
+ "sahillll"
],
"ignorePaths": [
"**/*.map",
diff --git a/packages/seo/metadata.ts b/packages/seo/metadata.ts
new file mode 100644
index 0000000..4d13d94
--- /dev/null
+++ b/packages/seo/metadata.ts
@@ -0,0 +1,91 @@
+import type { Metadata } from "next";
+
+type MetadataGenerator = Omit & {
+ title: string;
+ description: string;
+ image?: string;
+};
+
+const applicationName = "Qurious";
+const author: Metadata["authors"] = {
+ name: "Sahil Khan",
+ url: "https://sahilll.dev/",
+};
+const publisher = "Sahil Khan";
+const twitterHandle = "@sahillll_khan";
+
+const metadataBase = new URL(`https://quriousai.xyz`);
+
+export const createMetadata = ({
+ title,
+ description,
+ image = "https://quriousai.xyz/image.png",
+ ...properties
+}: MetadataGenerator): Metadata => {
+ const parsedTitle = `${title} | ${applicationName}`;
+ const defaultMetadata: Metadata = {
+ title: parsedTitle,
+ description,
+ applicationName,
+ icons: "https://quriousai.xyz/logo.svg",
+ metadataBase,
+ authors: [author],
+ creator: author.name,
+ keywords: [
+ "Qurious",
+ "AI research tool",
+ "AI research assistant",
+ "research paper search engine",
+ "scientific paper search",
+ "academic research platform",
+ "AI literature review tool",
+ "Semantic Scholar alternative",
+ "Google Scholar alternative",
+ "Consensus alternative",
+ "chat with research papers",
+ "AI paper analysis",
+ "summarize scientific papers",
+ "research workflow tool",
+ "organize research papers",
+ "AI academic assistant",
+ ],
+ formatDetection: {
+ telephone: false,
+ },
+ appleWebApp: {
+ capable: true,
+ statusBarStyle: "default",
+ title: parsedTitle,
+ },
+ openGraph: {
+ title: parsedTitle,
+ description,
+ type: "website",
+ siteName: applicationName,
+ locale: "en_US",
+ },
+ publisher,
+ twitter: {
+ card: "summary_large_image",
+ creator: twitterHandle,
+ },
+ };
+
+ const metadata: Metadata = { ...defaultMetadata, ...properties };
+
+ if (image && metadata.openGraph) {
+ metadata.openGraph.images = [
+ {
+ url: image,
+ width: 1200,
+ height: 630,
+ alt: title,
+ },
+ ];
+ if (metadata.twitter) {
+ metadata.twitter.images = [image];
+ }
+ }
+
+ return metadata;
+};
diff --git a/packages/seo/package.json b/packages/seo/package.json
new file mode 100644
index 0000000..58a2256
--- /dev/null
+++ b/packages/seo/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "@workspace/seo",
+ "packageManager": "pnpm@10.18.2",
+ "dependencies": {
+ "next": "^16.1.6"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 440db6e..a36ace8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -246,6 +246,9 @@ importers:
'@workspace/semantic-scholar':
specifier: workspace:*
version: link:../../../packages/semantic-scholar
+ '@workspace/seo':
+ specifier: workspace:*
+ version: link:../../../packages/seo
ai:
specifier: ^6.0.68
version: 6.0.68(zod@3.25.76)
@@ -532,6 +535,12 @@ importers:
'@workspace/design-system':
specifier: workspace:*
version: link:../../../packages/design-system
+ '@workspace/seo':
+ specifier: workspace:*
+ version: link:../../../packages/seo
+ motion:
+ specifier: ^12.34.0
+ version: 12.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
next:
specifier: 15.5.4
version: 15.5.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -653,7 +662,7 @@ importers:
version: 13.8.0(react@19.2.3)
'@next/font':
specifier: ^14.2.15
- version: 14.2.15(next@15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
+ version: 14.2.15(next@16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
'@radix-ui/react-avatar':
specifier: ^1.1.10
version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -707,7 +716,7 @@ importers:
version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.9))(@types/react@19.2.9)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
geist:
specifier: ^1.4.2
- version: 1.5.1(next@15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
+ version: 1.5.1(next@16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))
lucide-react:
specifier: ^0.511.0
version: 0.511.0(react@19.2.3)
@@ -806,6 +815,12 @@ importers:
specifier: ^8.2.0
version: 8.2.0
+ packages/seo:
+ dependencies:
+ next:
+ specifier: ^16.1.6
+ version: 16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+
tools/eslint:
devDependencies:
'@eslint/js':
@@ -2984,6 +2999,9 @@ packages:
'@next/env@15.5.9':
resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==}
+ '@next/env@16.1.6':
+ resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
+
'@next/eslint-plugin-next@15.3.3':
resolution: {integrity: sha512-VKZJEiEdpKkfBmcokGjHu0vGDG+8CehGs90tBEy/IDoDDKGngeyIStt2MmE5FYNyU9BhgR7tybNWTAJY/30u+Q==}
@@ -3007,6 +3025,12 @@ packages:
cpu: [arm64]
os: [darwin]
+ '@next/swc-darwin-arm64@16.1.6':
+ resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
'@next/swc-darwin-x64@15.5.4':
resolution: {integrity: sha512-QOTCFq8b09ghfjRJKfb68kU9k2K+2wsC4A67psOiMn849K9ZXgCSRQr0oVHfmKnoqCbEmQWG1f2h1T2vtJJ9mA==}
engines: {node: '>= 10'}
@@ -3019,6 +3043,12 @@ packages:
cpu: [x64]
os: [darwin]
+ '@next/swc-darwin-x64@16.1.6':
+ resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
'@next/swc-linux-arm64-gnu@15.5.4':
resolution: {integrity: sha512-eRD5zkts6jS3VfE/J0Kt1VxdFqTnMc3QgO5lFE5GKN3KDI/uUpSyK3CjQHmfEkYR4wCOl0R0XrsjpxfWEA++XA==}
engines: {node: '>= 10'}
@@ -3031,6 +3061,12 @@ packages:
cpu: [arm64]
os: [linux]
+ '@next/swc-linux-arm64-gnu@16.1.6':
+ resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
'@next/swc-linux-arm64-musl@15.5.4':
resolution: {integrity: sha512-TOK7iTxmXFc45UrtKqWdZ1shfxuL4tnVAOuuJK4S88rX3oyVV4ZkLjtMT85wQkfBrOOvU55aLty+MV8xmcJR8A==}
engines: {node: '>= 10'}
@@ -3043,6 +3079,12 @@ packages:
cpu: [arm64]
os: [linux]
+ '@next/swc-linux-arm64-musl@16.1.6':
+ resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
'@next/swc-linux-x64-gnu@15.5.4':
resolution: {integrity: sha512-7HKolaj+481FSW/5lL0BcTkA4Ueam9SPYWyN/ib/WGAFZf0DGAN8frNpNZYFHtM4ZstrHZS3LY3vrwlIQfsiMA==}
engines: {node: '>= 10'}
@@ -3055,6 +3097,12 @@ packages:
cpu: [x64]
os: [linux]
+ '@next/swc-linux-x64-gnu@16.1.6':
+ resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
'@next/swc-linux-x64-musl@15.5.4':
resolution: {integrity: sha512-nlQQ6nfgN0nCO/KuyEUwwOdwQIGjOs4WNMjEUtpIQJPR2NUfmGpW2wkJln1d4nJ7oUzd1g4GivH5GoEPBgfsdw==}
engines: {node: '>= 10'}
@@ -3067,6 +3115,12 @@ packages:
cpu: [x64]
os: [linux]
+ '@next/swc-linux-x64-musl@16.1.6':
+ resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
'@next/swc-win32-arm64-msvc@15.5.4':
resolution: {integrity: sha512-PcR2bN7FlM32XM6eumklmyWLLbu2vs+D7nJX8OAIoWy69Kef8mfiN4e8TUv2KohprwifdpFKPzIP1njuCjD0YA==}
engines: {node: '>= 10'}
@@ -3079,6 +3133,12 @@ packages:
cpu: [arm64]
os: [win32]
+ '@next/swc-win32-arm64-msvc@16.1.6':
+ resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
'@next/swc-win32-x64-msvc@15.5.4':
resolution: {integrity: sha512-1ur2tSHZj8Px/KMAthmuI9FMp/YFusMMGoRNJaRZMOlSkgvLjzosSdQI0cJAKogdHl3qXUQKL9MGaYvKwA7DXg==}
engines: {node: '>= 10'}
@@ -3091,6 +3151,12 @@ packages:
cpu: [x64]
os: [win32]
+ '@next/swc-win32-x64-msvc@16.1.6':
+ resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
'@noble/ciphers@1.3.0':
resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==}
engines: {node: ^14.21.3 || >=16}
@@ -7581,6 +7647,20 @@ packages:
react-dom:
optional: true
+ framer-motion@12.34.0:
+ resolution: {integrity: sha512-+/H49owhzkzQyxtn7nZeF4kdH++I2FWrESQ184Zbcw5cEqNHYkE5yxWxcTLSj5lNx3NWdbIRy5FHqUvetD8FWg==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
freeport-async@2.0.0:
resolution: {integrity: sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==}
engines: {node: '>=8'}
@@ -9413,6 +9493,9 @@ packages:
motion-dom@12.30.0:
resolution: {integrity: sha512-p6Mp+lxm+mK4O86YVyL6KAlFDVCIqpmcBt+uMVapMBqltPXpwZ5Wj2crnN2VE7lwsas0ONCPIW9YVpMigu4F5g==}
+ motion-dom@12.34.0:
+ resolution: {integrity: sha512-Lql3NuEcScRDxTAO6GgUsRHBZOWI/3fnMlkMcH5NftzcN37zJta+bpbMAV9px4Nj057TuvRooMK7QrzMCgtz6Q==}
+
motion-utils@12.27.2:
resolution: {integrity: sha512-B55gcoL85Mcdt2IEStY5EEAsrMSVE2sI14xQ/uAdPL+mfQxhKKFaEag9JmfxedJOR4vZpBGoPeC/Gm13I/4g5Q==}
@@ -9447,6 +9530,20 @@ packages:
react-dom:
optional: true
+ motion@12.34.0:
+ resolution: {integrity: sha512-01Sfa/zgsD/di8zA/uFW5Eb7/SPXoGyUfy+uMRMW5Spa8j0z/UbfQewAYvPMYFCXRlyD6e5aLHh76TxeeJD+RA==}
+ peerDependencies:
+ '@emotion/is-prop-valid': '*'
+ react: ^18.0.0 || ^19.0.0
+ react-dom: ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/is-prop-valid':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
mri@1.2.0:
resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
engines: {node: '>=4'}
@@ -9578,6 +9675,27 @@ packages:
sass:
optional: true
+ next@16.1.6:
+ resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==}
+ engines: {node: '>=20.9.0'}
+ hasBin: true
+ peerDependencies:
+ '@opentelemetry/api': ^1.1.0
+ '@playwright/test': ^1.51.1
+ babel-plugin-react-compiler: '*'
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+ '@playwright/test':
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+
nextstepjs@2.2.0:
resolution: {integrity: sha512-VpUvKpIMbxBaLAMM3O8mc5Tavao4UBpKZ0+KyUGXxZhqdJt2ejS2l7pXLtlq2r62NG3EV0yv1wit5mgte7c3Vw==}
peerDependencies:
@@ -14842,6 +14960,8 @@ snapshots:
'@next/env@15.5.9': {}
+ '@next/env@16.1.6': {}
+
'@next/eslint-plugin-next@15.3.3':
dependencies:
fast-glob: 3.3.1
@@ -14850,9 +14970,9 @@ snapshots:
dependencies:
fast-glob: 3.3.1
- '@next/font@14.2.15(next@15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))':
+ '@next/font@14.2.15(next@16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))':
dependencies:
- next: 15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ next: 16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@next/swc-darwin-arm64@15.5.4':
optional: true
@@ -14860,48 +14980,72 @@ snapshots:
'@next/swc-darwin-arm64@15.5.7':
optional: true
+ '@next/swc-darwin-arm64@16.1.6':
+ optional: true
+
'@next/swc-darwin-x64@15.5.4':
optional: true
'@next/swc-darwin-x64@15.5.7':
optional: true
+ '@next/swc-darwin-x64@16.1.6':
+ optional: true
+
'@next/swc-linux-arm64-gnu@15.5.4':
optional: true
'@next/swc-linux-arm64-gnu@15.5.7':
optional: true
+ '@next/swc-linux-arm64-gnu@16.1.6':
+ optional: true
+
'@next/swc-linux-arm64-musl@15.5.4':
optional: true
'@next/swc-linux-arm64-musl@15.5.7':
optional: true
+ '@next/swc-linux-arm64-musl@16.1.6':
+ optional: true
+
'@next/swc-linux-x64-gnu@15.5.4':
optional: true
'@next/swc-linux-x64-gnu@15.5.7':
optional: true
+ '@next/swc-linux-x64-gnu@16.1.6':
+ optional: true
+
'@next/swc-linux-x64-musl@15.5.4':
optional: true
'@next/swc-linux-x64-musl@15.5.7':
optional: true
+ '@next/swc-linux-x64-musl@16.1.6':
+ optional: true
+
'@next/swc-win32-arm64-msvc@15.5.4':
optional: true
'@next/swc-win32-arm64-msvc@15.5.7':
optional: true
+ '@next/swc-win32-arm64-msvc@16.1.6':
+ optional: true
+
'@next/swc-win32-x64-msvc@15.5.4':
optional: true
'@next/swc-win32-x64-msvc@15.5.7':
optional: true
+ '@next/swc-win32-x64-msvc@16.1.6':
+ optional: true
+
'@noble/ciphers@1.3.0': {}
'@noble/curves@1.9.1':
@@ -17831,7 +17975,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.15
tinyrainbow: 2.0.0
- vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@20.19.31)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@1.8.0)(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
+ vitest: 3.2.4(@edge-runtime/vm@3.2.0)(@types/debug@4.1.12)(@types/node@20.19.30)(@vitest/ui@3.2.4)(jiti@2.6.1)(jsdom@27.4.0(@noble/hashes@1.8.0)(bufferutil@4.1.0)(utf-8-validate@5.0.10))(lightningcss@1.31.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
'@vitest/utils@3.2.4':
dependencies:
@@ -20532,6 +20676,15 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
+ framer-motion@12.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ motion-dom: 12.34.0
+ motion-utils: 12.29.2
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+
freeport-async@2.0.0: {}
fresh@0.5.2: {}
@@ -20876,9 +21029,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
- geist@1.5.1(next@15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)):
+ geist@1.5.1(next@16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)):
dependencies:
- next: 15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ next: 16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
generator-function@2.0.1: {}
@@ -22850,6 +23003,10 @@ snapshots:
dependencies:
motion-utils: 12.29.2
+ motion-dom@12.34.0:
+ dependencies:
+ motion-utils: 12.29.2
+
motion-utils@12.27.2: {}
motion-utils@12.29.2: {}
@@ -22870,6 +23027,14 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
+ motion@12.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ framer-motion: 12.34.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ tslib: 2.8.1
+ optionalDependencies:
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+
mri@1.2.0: {}
mrmime@2.0.1: {}
@@ -22969,15 +23134,15 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
- next@15.5.9(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ next@15.5.9(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
'@next/env': 15.5.9
'@swc/helpers': 0.5.15
caniuse-lite: 1.0.30001767
postcss: 8.4.31
- react: 19.2.3
- react-dom: 19.2.3(react@19.2.3)
- styled-jsx: 5.1.6(@babel/core@7.28.6)(react@19.2.3)
+ react: 19.2.4
+ react-dom: 19.2.4(react@19.2.4)
+ styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4)
optionalDependencies:
'@next/swc-darwin-arm64': 15.5.7
'@next/swc-darwin-x64': 15.5.7
@@ -22994,24 +23159,51 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
- next@15.5.9(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ next@16.1.6(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies:
- '@next/env': 15.5.9
+ '@next/env': 16.1.6
'@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.9.16
+ caniuse-lite: 1.0.30001767
+ postcss: 8.4.31
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ styled-jsx: 5.1.6(@babel/core@7.28.6)(react@19.2.3)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 16.1.6
+ '@next/swc-darwin-x64': 16.1.6
+ '@next/swc-linux-arm64-gnu': 16.1.6
+ '@next/swc-linux-arm64-musl': 16.1.6
+ '@next/swc-linux-x64-gnu': 16.1.6
+ '@next/swc-linux-x64-musl': 16.1.6
+ '@next/swc-win32-arm64-msvc': 16.1.6
+ '@next/swc-win32-x64-msvc': 16.1.6
+ '@opentelemetry/api': 1.9.0
+ babel-plugin-react-compiler: 1.0.0
+ sharp: 0.34.5
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
+ next@16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+ dependencies:
+ '@next/env': 16.1.6
+ '@swc/helpers': 0.5.15
+ baseline-browser-mapping: 2.9.16
caniuse-lite: 1.0.30001767
postcss: 8.4.31
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4)
optionalDependencies:
- '@next/swc-darwin-arm64': 15.5.7
- '@next/swc-darwin-x64': 15.5.7
- '@next/swc-linux-arm64-gnu': 15.5.7
- '@next/swc-linux-arm64-musl': 15.5.7
- '@next/swc-linux-x64-gnu': 15.5.7
- '@next/swc-linux-x64-musl': 15.5.7
- '@next/swc-win32-arm64-msvc': 15.5.7
- '@next/swc-win32-x64-msvc': 15.5.7
+ '@next/swc-darwin-arm64': 16.1.6
+ '@next/swc-darwin-x64': 16.1.6
+ '@next/swc-linux-arm64-gnu': 16.1.6
+ '@next/swc-linux-arm64-musl': 16.1.6
+ '@next/swc-linux-x64-gnu': 16.1.6
+ '@next/swc-linux-x64-musl': 16.1.6
+ '@next/swc-win32-arm64-msvc': 16.1.6
+ '@next/swc-win32-x64-msvc': 16.1.6
'@opentelemetry/api': 1.9.0
babel-plugin-react-compiler: 1.0.0
sharp: 0.34.5