diff --git a/app/_components/BubbleDiv.tsx b/app/_components/BubbleDiv.tsx new file mode 100644 index 0000000..38f1d87 --- /dev/null +++ b/app/_components/BubbleDiv.tsx @@ -0,0 +1,16 @@ +import Image from "next/image"; +import React from "react"; + +const BubbleDiv = () => { + return ( +
+ + 현재 775명 + 참여중이에요! + + bubble +
+ ); +}; + +export default BubbleDiv; diff --git a/app/_components/LoginActionSection.tsx b/app/_components/LoginActionSection.tsx new file mode 100644 index 0000000..d18909e --- /dev/null +++ b/app/_components/LoginActionSection.tsx @@ -0,0 +1,82 @@ +"use client"; +import BubbleDiv from "@/app/_components/BubbleDiv"; +import Button from "@/components/ui/Button"; +import { KakaoLoginButton, GoogleLoginButton } from "./SocialButtonList"; +import { + Drawer, + DrawerContent, + DrawerTitle, + DrawerTrigger, +} from "@/components/ui/drawer"; + +export default function ScreenLoginActionSection() { + const handleKakaoLogin = () => { + // window.location.href = "https://backend.comatching.site/oauth2/authorization/kakao"; + alert("코매칭 서비스는 10/13일부로 종료되었습니다."); + }; + + const handleGoogleLogin = () => { + // window.location.href = "https://backend.comatching.site/oauth2/authorization/google"; + alert("코매칭 서비스는 10/13일부로 종료되었습니다."); + }; + + return ( +
+ + + 카카오로 빠르게 시작하기 + + +
+ 또는 + + + +
+ + 다른 로그인 방법 +
+ + 로그인/회원가입 + + + 로그인과 회원가입 수단은 동일합니다. +
+ 원하는 계정으로 시작하세요. +
+
+ + 카카오로 시작하기 + + + 구글로 시작하기 + +
+ 혹은 + +
+
+
+ + Developed By Team Comatching, Catholic University of Korea + +
+ ); +} diff --git a/app/_components/LoginLogoSection.tsx b/app/_components/LoginLogoSection.tsx new file mode 100644 index 0000000..4aa40eb --- /dev/null +++ b/app/_components/LoginLogoSection.tsx @@ -0,0 +1,21 @@ +import Image from "next/image"; + +export default function ScreenLoginLogoSection() { + return ( +
+ comatching-logo +
+ 반갑습니다 +
+ 코매칭이라면 당신은 +
+ 이미 커플입니다 +
+
+ ); +} diff --git a/app/_components/ScreenLoginPage.tsx b/app/_components/ScreenLoginPage.tsx new file mode 100644 index 0000000..de2f1ea --- /dev/null +++ b/app/_components/ScreenLoginPage.tsx @@ -0,0 +1,11 @@ +import ScreenLoginLogoSection from "./LoginLogoSection"; +import ScreenLoginActionSection from "./LoginActionSection"; + +export default function ScreenLoginPage() { + return ( +
+ + +
+ ); +} diff --git a/app/_components/SocialButtonList.tsx b/app/_components/SocialButtonList.tsx new file mode 100644 index 0000000..2782d74 --- /dev/null +++ b/app/_components/SocialButtonList.tsx @@ -0,0 +1,48 @@ +import Image from "next/image"; +import Button from "@/components/ui/Button"; +import { cn } from "@/lib/utils"; + +type SocialButtonProps = React.ComponentProps & { + children?: React.ReactNode; +}; + +export function KakaoLoginButton({ + children = "카카오로 시작하기", + ...props +}: SocialButtonProps) { + return ( + + ); +} + +export function GoogleLoginButton({ + children = "구글로 시작하기", + ...props +}: SocialButtonProps) { + return ( + + ); +} diff --git a/app/layout.tsx b/app/layout.tsx index 0e50b37..2290d4f 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,6 +2,9 @@ import type { Metadata } from "next"; import localFont from "next/font/local"; import "./globals.css"; import Blur from "@/components/common/Blur"; +import { QueryProvider } from "@/providers/query-provider"; +import { ServiceStatusProvider } from "@/providers/service-status-provider"; +import { getInitialMaintenanceStatus } from "@/lib/status"; const pretendard = localFont({ src: "./fonts/PretendardVariable.woff2", @@ -31,20 +34,28 @@ export const metadata: Metadata = { }, }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + const initialMaintenanceMode = await getInitialMaintenanceStatus(); + return ( -
+ {/* */} + {/* */} +
{children}
+ {/*
*/} + {/*
*/} ); diff --git a/app/page.tsx b/app/page.tsx index 19f56fb..b467acc 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,10 +1,5 @@ -import Blur from "@/components/common/Blur"; -import Button from "@/components/ui/Button"; +import ScreenLoginPage from "@/app/_components/ScreenLoginPage"; export default function Home() { - return ( -
- -
- ); + return ; } diff --git a/app/tokens.css b/app/tokens.css index 753c63a..fa402ed 100644 --- a/app/tokens.css +++ b/app/tokens.css @@ -1,6 +1,6 @@ /* Auto-generated from token.json */ /* Run: pnpm run token to regenerate */ -/* Total unique tokens: 126 */ +/* Total unique tokens: 144 */ @layer base { :root { @@ -20,6 +20,13 @@ --border-width-thin: 0.8; --borderradius: var(--lg); --borderwidth: var(--sm); + --bottomsheet-background-main: var(--color-background-white); + --bottomsheet-text-caption: var(--color-text-caption2); + --bottomsheet-text-title: var(--color-text-black); + --bottomsheet-toggle-close: var(--color-toggle-default); + --bubble-background-white: var(--color-text-white); + --bubble-text-highight: var(--color-text-highlight); + --bubble-text-main: var(--color-text-black); --button-background-bold: var(--color-brand-black); --button-background-disabled: var(--color-background-disabled); --button-background-gradient-1-end: var(--color-brand-primary-orange); @@ -32,6 +39,7 @@ --button-primary-text-disabled: var(--color-text-disabled); --button-slate-default: var(--color-gray-0-a30); --color-background-disabled: var(--color-gray-300-a40); + --color-background-white: var(--color-gray-0); --color-border-light: var(--color-gray-0-a30); --color-brand-black: var(--color-gray-900); --color-brand-primary-flame: var(--color-flame-700); @@ -71,8 +79,14 @@ --color-pink-700: #f57db2; --color-pink-900: #e3468b; --color-surface-base: var(--color-gray-64); + --color-text-black: var(--color-gray-900); + --color-text-caption1: var(--color-gray-600); + --color-text-caption2: var(--color-gray-500); + --color-text-caption3: var(--color-gray-400); --color-text-disabled: var(--color-gray-300); + --color-text-highlight: var(--color-flame-700); --color-text-white: var(--color-gray-0); + --color-toggle-default: var(--color-gray-400); --decreased: -5%; --default: 0; --flame100: #ffc4cd; @@ -88,6 +102,7 @@ --font-size-18: 18; --font-size-20: 20; --font-size-24: 24; + --footo-text-main: var(--color-text-caption1); --h1: 32; --h2: 26; --h6: var(--body); @@ -97,6 +112,9 @@ --high: 90%; --increased: 150%; --lg: var(--lg); + --logo-text-black: var(--color-brand-black); + --logo-text-pink: var(--color-brand-primary-flame); + --logo-text-white: var(--color-text-white); --low: 10%; --md: var(--md); --multi-value: var(--xl); @@ -135,6 +153,78 @@ @layer utilities { /* Font utilities */ + .typo-10-400 { + font-size: 10px; + font-weight: 400; + line-height: 1.5; + } + + .typo-10-500 { + font-size: 10px; + font-weight: 500; + line-height: 1.5; + } + + .typo-10-600 { + font-size: 10px; + font-weight: 600; + line-height: 1.5; + } + + .typo-10-700 { + font-size: 10px; + font-weight: 700; + line-height: 1.5; + } + + .typo-12-400 { + font-size: 12px; + font-weight: 400; + line-height: 1.5; + } + + .typo-12-500 { + font-size: 12px; + font-weight: 500; + line-height: 1.5; + } + + .typo-12-600 { + font-size: 12px; + font-weight: 600; + line-height: 1.5; + } + + .typo-12-700 { + font-size: 12px; + font-weight: 700; + line-height: 1.5; + } + + .typo-14-400 { + font-size: 14px; + font-weight: 400; + line-height: 1.5; + } + + .typo-14-500 { + font-size: 14px; + font-weight: 500; + line-height: 1.5; + } + + .typo-14-600 { + font-size: 14px; + font-weight: 600; + line-height: 1.5; + } + + .typo-14-700 { + font-size: 14px; + font-weight: 700; + line-height: 1.5; + } + .typo-16-400 { font-size: 16px; font-weight: 400; @@ -159,6 +249,30 @@ line-height: 1.5; } + .typo-18-400 { + font-size: 18px; + font-weight: 400; + line-height: 1.5; + } + + .typo-18-500 { + font-size: 18px; + font-weight: 500; + line-height: 1.5; + } + + .typo-18-600 { + font-size: 18px; + font-weight: 600; + line-height: 1.5; + } + + .typo-18-700 { + font-size: 18px; + font-weight: 700; + line-height: 1.5; + } + .typo-20-400 { font-size: 20px; font-weight: 400; @@ -183,122 +297,122 @@ line-height: 1.5; } - .typo-24-400 { - font-size: 24px; + .typo-22-400 { + font-size: 22px; font-weight: 400; line-height: 1.5; } - .typo-24-500 { - font-size: 24px; + .typo-22-500 { + font-size: 22px; font-weight: 500; line-height: 1.5; } - .typo-24-600 { - font-size: 24px; + .typo-22-600 { + font-size: 22px; font-weight: 600; line-height: 1.5; } - .typo-24-700 { - font-size: 24px; + .typo-22-700 { + font-size: 22px; font-weight: 700; line-height: 1.5; } - .typo-12-400 { - font-size: 12px; + .typo-24-400 { + font-size: 24px; font-weight: 400; line-height: 1.5; } - .typo-12-500 { - font-size: 12px; + .typo-24-500 { + font-size: 24px; font-weight: 500; line-height: 1.5; } - .typo-12-600 { - font-size: 12px; + .typo-24-600 { + font-size: 24px; font-weight: 600; line-height: 1.5; } - .typo-12-700 { - font-size: 12px; + .typo-24-700 { + font-size: 24px; font-weight: 700; line-height: 1.5; } - .typo-14-400 { - font-size: 14px; + .typo-26-400 { + font-size: 26px; font-weight: 400; line-height: 1.5; } - .typo-14-500 { - font-size: 14px; + .typo-26-500 { + font-size: 26px; font-weight: 500; line-height: 1.5; } - .typo-14-600 { - font-size: 14px; + .typo-26-600 { + font-size: 26px; font-weight: 600; line-height: 1.5; } - .typo-14-700 { - font-size: 14px; + .typo-26-700 { + font-size: 26px; font-weight: 700; line-height: 1.5; } - .typo-10-400 { - font-size: 10px; + .typo-28-400 { + font-size: 28px; font-weight: 400; line-height: 1.5; } - .typo-10-500 { - font-size: 10px; + .typo-28-500 { + font-size: 28px; font-weight: 500; line-height: 1.5; } - .typo-10-600 { - font-size: 10px; + .typo-28-600 { + font-size: 28px; font-weight: 600; line-height: 1.5; } - .typo-10-700 { - font-size: 10px; + .typo-28-700 { + font-size: 28px; font-weight: 700; line-height: 1.5; } - .typo-18-400 { - font-size: 18px; + .typo-30-400 { + font-size: 30px; font-weight: 400; line-height: 1.5; } - .typo-18-500 { - font-size: 18px; + .typo-30-500 { + font-size: 30px; font-weight: 500; line-height: 1.5; } - .typo-18-600 { - font-size: 18px; + .typo-30-600 { + font-size: 30px; font-weight: 600; line-height: 1.5; } - .typo-18-700 { - font-size: 18px; + .typo-30-700 { + font-size: 30px; font-weight: 700; line-height: 1.5; } @@ -307,11 +421,14 @@ .bg-background-app-base { background-color: var(--background-app-base); } .bg-background-app-blur-bottom-left { background-color: var(--background-app-blur-bottom-left); } .bg-background-app-blur-bottom-right { background-color: var(--background-app-blur-bottom-right); } + .bg-bottomsheet-background-main { background-color: var(--bottomsheet-background-main); } + .bg-bubble-background-white { background-color: var(--bubble-background-white); } .bg-button-background-bold { background-color: var(--button-background-bold); } .bg-button-background-disabled { background-color: var(--button-background-disabled); } .bg-button-background-gradient-1-end { background-color: var(--button-background-gradient-1-end); } .bg-button-background-gradient-1-start { background-color: var(--button-background-gradient-1-start); } .bg-color-background-disabled { background-color: var(--color-background-disabled); } + .bg-color-background-white { background-color: var(--color-background-white); } .bg-color-border-light { background-color: var(--color-border-light); } .bg-color-brand-black { background-color: var(--color-brand-black); } .bg-color-brand-primary-flame { background-color: var(--color-brand-primary-flame); } @@ -351,13 +468,24 @@ .bg-color-pink-700 { background-color: var(--color-pink-700); } .bg-color-pink-900 { background-color: var(--color-pink-900); } .bg-color-surface-base { background-color: var(--color-surface-base); } + .bg-color-text-black { background-color: var(--color-text-black); } + .bg-color-text-caption1 { background-color: var(--color-text-caption1); } + .bg-color-text-caption2 { background-color: var(--color-text-caption2); } + .bg-color-text-caption3 { background-color: var(--color-text-caption3); } .bg-color-text-disabled { background-color: var(--color-text-disabled); } + .bg-color-text-highlight { background-color: var(--color-text-highlight); } .bg-color-text-white { background-color: var(--color-text-white); } + .bg-color-toggle-default { background-color: var(--color-toggle-default); } /* Text color utilities */ + .text-bottomsheet-text-caption { color: var(--bottomsheet-text-caption); } + .text-bottomsheet-text-title { color: var(--bottomsheet-text-title); } + .text-bubble-text-highight { color: var(--bubble-text-highight); } + .text-bubble-text-main { color: var(--bubble-text-main); } .text-button-primary-text-default { color: var(--button-primary-text-default); } .text-button-primary-text-disabled { color: var(--button-primary-text-disabled); } .text-color-background-disabled { color: var(--color-background-disabled); } + .text-color-background-white { color: var(--color-background-white); } .text-color-border-light { color: var(--color-border-light); } .text-color-brand-black { color: var(--color-brand-black); } .text-color-brand-primary-flame { color: var(--color-brand-primary-flame); } @@ -397,8 +525,18 @@ .text-color-pink-700 { color: var(--color-pink-700); } .text-color-pink-900 { color: var(--color-pink-900); } .text-color-surface-base { color: var(--color-surface-base); } + .text-color-text-black { color: var(--color-text-black); } + .text-color-text-caption1 { color: var(--color-text-caption1); } + .text-color-text-caption2 { color: var(--color-text-caption2); } + .text-color-text-caption3 { color: var(--color-text-caption3); } .text-color-text-disabled { color: var(--color-text-disabled); } + .text-color-text-highlight { color: var(--color-text-highlight); } .text-color-text-white { color: var(--color-text-white); } + .text-color-toggle-default { color: var(--color-toggle-default); } + .text-footo-text-main { color: var(--footo-text-main); } + .text-logo-text-black { color: var(--logo-text-black); } + .text-logo-text-pink { color: var(--logo-text-pink); } + .text-logo-text-white { color: var(--logo-text-white); } /* Border utilities */ .border-button-border-color { border-color: var(--button-border-color); } diff --git a/components/ui/Button.tsx b/components/ui/Button.tsx index d3740d1..a0f4dda 100644 --- a/components/ui/Button.tsx +++ b/components/ui/Button.tsx @@ -3,47 +3,32 @@ import { cn } from "@/lib/utils"; interface ButtonProps extends React.ButtonHTMLAttributes { children: React.ReactNode; - backgroundColor?: string; - width?: string; - height?: string; fixed?: boolean; bottom?: number; // 하단 여백 (px) sideGap?: number; // 좌우 여백 (px) - maxWidth?: number; // fixed일 때 최대 너비 (px) - textColor?: string; - fontSize?: string; safeArea?: boolean; // safe-area-inset-bottom 적용 여부 + shadow?: boolean; // 그림자 적용 여부 (기본값: false, bg-button-primary일 때 자동 적용) ref?: React.Ref; } export default function Button({ children, - backgroundColor = "bg-button-primary", - width = "w-full", - height = "h-12", fixed = false, bottom = 0, sideGap = 16, - maxWidth = 430, - textColor = "text-button-primary-text-default", - fontSize = "typo-20-600", safeArea = true, disabled = false, + shadow, className, ref, type = "button", ...props }: ButtonProps) { - // disabled 상태에 따른 배경색/텍스트색 결정 - const finalBackgroundColor = disabled - ? "bg-button-background-disabled" - : backgroundColor; - const finalTextColor = disabled - ? "text-button-primary-text-disabled" - : textColor; + // className에서 bg-button-primary 사용 여부 확인 + const isPrimaryButton = className?.includes("bg-button-primary"); - // bg-button-primary일 때 border와 shadow 추가 - const isPrimaryButton = finalBackgroundColor === "bg-button-primary"; + // 그림자 적용 여부 결정 (prop이 있으면 우선, 없으면 primary일 때 적용) + const hasShadow = shadow ?? isPrimaryButton; // fixed일 때 bottom 계산 (safeArea 적용) const getBottomValue = () => { @@ -62,34 +47,33 @@ export default function Button({ type={type} disabled={disabled} className={cn( - // 기본 스타일 - "flex items-center justify-center rounded-[12px] transition-colors duration-100", - finalBackgroundColor, - height, - finalTextColor, - fontSize, - // fixed 속성에 따른 분기 - fixed ? "fixed z-50 mx-auto" : width, - // disabled 상태에 따른 커서 + // 기본 스타일 (기본 높이 h-12, 너비 w-full, 폰트 등 복구) + "typo-20-600 text-button-primary-text-default flex h-12 w-full items-center justify-center rounded-[12px] transition-colors duration-100", + fixed && "fixed z-50 mx-auto", disabled ? "cursor-not-allowed" : "cursor-pointer", + // 1. 사용자 className 먼저 적용 (여기서 h-10 등을 넣으면 위 h-12가 덮어씌워짐) className, + // 2. disabled 스타일이 덮어쓰도록(맨 뒤에 배치) + disabled && + "bg-button-background-disabled text-button-primary-text-disabled", )} style={{ - ...(fixed - ? { - bottom: getBottomValue(), - left: `${sideGap}px`, - right: `${sideGap}px`, - maxWidth: `${maxWidth}px`, - } - : undefined), - ...(isPrimaryButton - ? { - border: "0.8px solid rgba(255, 255, 255, 0.3)", - boxShadow: - "0px 4px 8px rgba(0, 0, 0, 0.08), 0px 0px 16px rgba(0, 0, 0, 0.16)", - } - : undefined), + ...(fixed && { + bottom: getBottomValue(), + left: `${sideGap}px`, + right: `${sideGap}px`, + }), + // bg-button-primary일 때 border 자동 추가 + ...(isPrimaryButton && + !disabled && { + border: "0.8px solid rgba(255, 255, 255, 0.3)", + }), + // shadow가 true이거나 primary일 때 그림자 추가 (disabled 제외) + ...(hasShadow && + !disabled && { + boxShadow: + "0px 4px 8px rgba(0, 0, 0, 0.08), 0px 0px 16px rgba(0, 0, 0, 0.16)", + }), }} {...props} > diff --git a/components/ui/drawer.tsx b/components/ui/drawer.tsx new file mode 100644 index 0000000..4e5e34e --- /dev/null +++ b/components/ui/drawer.tsx @@ -0,0 +1,144 @@ +"use client"; + +import * as React from "react"; +import { Drawer as DrawerPrimitive } from "vaul"; + +import { cn } from "@/lib/utils"; + +function Drawer({ + ...props +}: React.ComponentProps) { + return ; +} + +function DrawerTrigger({ + ...props +}: React.ComponentProps) { + return ; +} + +function DrawerPortal({ + ...props +}: React.ComponentProps) { + return ; +} + +function DrawerClose({ + ...props +}: React.ComponentProps) { + return ; +} + +function DrawerOverlay({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +type DrawerContentProps = React.ComponentProps< + typeof DrawerPrimitive.Content +> & { + showHandle?: boolean; +}; + +function DrawerContent({ + className, + children, + showHandle = true, + ...props +}: DrawerContentProps) { + return ( + + + + {showHandle && ( +
+ )} + {children} + + + ); +} + +function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function DrawerTitle({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function DrawerDescription({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +}; diff --git a/lib/status.ts b/lib/status.ts new file mode 100644 index 0000000..66b120c --- /dev/null +++ b/lib/status.ts @@ -0,0 +1,21 @@ +export async function getInitialMaintenanceStatus() { + try { + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/status`, { + cache: "no-store", + }); + if (!res.ok) return false; + + // Check if response is JSON before parsing + const contentType = res.headers.get("content-type"); + if (!contentType || !contentType.includes("application/json")) { + console.warn("Status endpoint returned non-JSON response"); + return false; + } + + const data = await res.json(); + return data.maintenance ?? false; + } catch (error) { + console.error("Failed to fetch maintenance status:", error); + return false; + } +} diff --git a/package.json b/package.json index b770268..e0f24ec 100644 --- a/package.json +++ b/package.json @@ -13,32 +13,34 @@ "token": "node scripts/generate-tokens.js" }, "dependencies": { + "@radix-ui/react-dialog": "^1.1.15", "@tanstack/react-query": "^5.90.20", "@tanstack/react-query-devtools": "^5.91.2", - "axios": "^1.13.3", + "axios": "^1.13.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.562.0", "next": "16.1.3", "react": "19.2.3", "react-dom": "19.2.3", - "tailwind-merge": "^3.4.0" + "tailwind-merge": "^3.4.0", + "vaul": "^1.1.2" }, "devDependencies": { - "@tailwindcss/postcss": "^4", - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", + "@tailwindcss/postcss": "^4.1.18", + "@types/node": "^20.19.30", + "@types/react": "^19.2.10", + "@types/react-dom": "^19.2.3", "babel-plugin-react-compiler": "1.0.0", - "eslint": "^9", + "eslint": "^9.39.2", "eslint-config-next": "16.1.3", "husky": "^9.1.7", "lint-staged": "^16.2.7", - "prettier": "^3.8.0", + "prettier": "^3.8.1", "prettier-plugin-tailwindcss": "^0.7.2", - "tailwindcss": "^4", + "tailwindcss": "^4.1.18", "tw-animate-css": "^1.4.0", - "typescript": "^5" + "typescript": "^5.9.3" }, "lint-staged": { "*.{js,jsx,ts,tsx}": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42c8a3d..f788a65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@radix-ui/react-dialog': + specifier: ^1.1.15 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) '@tanstack/react-query': specifier: ^5.90.20 version: 5.90.20(react@19.2.3) @@ -15,8 +18,8 @@ importers: specifier: ^5.91.2 version: 5.91.2(@tanstack/react-query@5.90.20(react@19.2.3))(react@19.2.3) axios: - specifier: ^1.13.3 - version: 1.13.3 + specifier: ^1.13.4 + version: 1.13.4 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -38,28 +41,31 @@ importers: tailwind-merge: specifier: ^3.4.0 version: 3.4.0 + vaul: + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) devDependencies: '@tailwindcss/postcss': - specifier: ^4 + specifier: ^4.1.18 version: 4.1.18 '@types/node': - specifier: ^20 + specifier: ^20.19.30 version: 20.19.30 '@types/react': - specifier: ^19 - version: 19.2.8 + specifier: ^19.2.10 + version: 19.2.10 '@types/react-dom': - specifier: ^19 - version: 19.2.3(@types/react@19.2.8) + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.10) babel-plugin-react-compiler: specifier: 1.0.0 version: 1.0.0 eslint: - specifier: ^9 + specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) eslint-config-next: specifier: 16.1.3 - version: 16.1.3(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + version: 16.1.3(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) husky: specifier: ^9.1.7 version: 9.1.7 @@ -67,19 +73,19 @@ importers: specifier: ^16.2.7 version: 16.2.7 prettier: - specifier: ^3.8.0 - version: 3.8.0 + specifier: ^3.8.1 + version: 3.8.1 prettier-plugin-tailwindcss: specifier: ^0.7.2 - version: 0.7.2(prettier@3.8.0) + version: 0.7.2(prettier@3.8.1) tailwindcss: - specifier: ^4 + specifier: ^4.1.18 version: 4.1.18 tw-animate-css: specifier: ^1.4.0 version: 1.4.0 typescript: - specifier: ^5 + specifier: ^5.9.3 version: 5.9.3 packages: @@ -444,6 +450,177 @@ packages: resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} engines: {node: '>=12.4.0'} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -575,66 +752,66 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.8': - resolution: {integrity: sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg==} + '@types/react@19.2.10': + resolution: {integrity: sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==} - '@typescript-eslint/eslint-plugin@8.53.0': - resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} + '@typescript-eslint/eslint-plugin@8.54.0': + resolution: {integrity: sha512-hAAP5io/7csFStuOmR782YmTthKBJ9ND3WVL60hcOjvtGFb+HJxH4O5huAcmcZ9v9G8P+JETiZ/G1B8MALnWZQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.53.0 + '@typescript-eslint/parser': ^8.54.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.53.0': - resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} + '@typescript-eslint/parser@8.54.0': + resolution: {integrity: sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.53.0': - resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==} + '@typescript-eslint/project-service@8.54.0': + resolution: {integrity: sha512-YPf+rvJ1s7MyiWM4uTRhE4DvBXrEV+d8oC3P9Y2eT7S+HBS0clybdMIPnhiATi9vZOYDc7OQ1L/i6ga6NFYK/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.53.0': - resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} + '@typescript-eslint/scope-manager@8.54.0': + resolution: {integrity: sha512-27rYVQku26j/PbHYcVfRPonmOlVI6gihHtXFbTdB5sb6qA0wdAQAbyXFVarQ5t4HRojIz64IV90YtsjQSSGlQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.53.0': - resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} + '@typescript-eslint/tsconfig-utils@8.54.0': + resolution: {integrity: sha512-dRgOyT2hPk/JwxNMZDsIXDgyl9axdJI3ogZ2XWhBPsnZUv+hPesa5iuhdYt2gzwA9t8RE5ytOJ6xB0moV0Ujvw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.53.0': - resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} + '@typescript-eslint/type-utils@8.54.0': + resolution: {integrity: sha512-hiLguxJWHjjwL6xMBwD903ciAwd7DmK30Y9Axs/etOkftC3ZNN9K44IuRD/EB08amu+Zw6W37x9RecLkOo3pMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.53.0': - resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} + '@typescript-eslint/types@8.54.0': + resolution: {integrity: sha512-PDUI9R1BVjqu7AUDsRBbKMtwmjWcn4J3le+5LpcFgWULN3LvHC5rkc9gCVxbrsrGmO1jfPybN5s6h4Jy+OnkAA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.53.0': - resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} + '@typescript-eslint/typescript-estree@8.54.0': + resolution: {integrity: sha512-BUwcskRaPvTk6fzVWgDPdUndLjB87KYDrN5EYGetnktoeAvPtO4ONHlAZDnj5VFnUANg0Sjm7j4usBlnoVMHwA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.53.0': - resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} + '@typescript-eslint/utils@8.54.0': + resolution: {integrity: sha512-9Cnda8GS57AQakvRyG0PTejJNlA2xhvyNtEVIMlDWOOeEyBkYWhGPnfrIAnqxLMTSTo6q8g12XVjjev5l1NvMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.53.0': - resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} + '@typescript-eslint/visitor-keys@8.54.0': + resolution: {integrity: sha512-VFlhGSl4opC0bprJiItPQ1RfUhGDIBokcPwaFH4yiBCaNPeld/9VeXbiPO1cLyorQi1G1vL+ecBk1x8o1axORA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -764,6 +941,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} @@ -818,8 +999,8 @@ packages: resolution: {integrity: sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==} engines: {node: '>=4'} - axios@1.13.3: - resolution: {integrity: sha512-ERT8kdX7DZjtUm7IitEyV7InTHAF42iJuMArIiDIV5YtPanJkgw4hw5Dyg9fh0mihdWNn1GKaeIWErfe56UQ1g==} + axios@1.13.4: + resolution: {integrity: sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} @@ -831,8 +1012,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.9.15: - resolution: {integrity: sha512-kX8h7K2srmDyYnXRIppo4AH/wYgzWVCs+eKr3RusRSQ5PvRYoEFmR/I0PbdTjKFAoKqp5+kbxnNTFO9jOfSVJg==} + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} hasBin: true brace-expansion@1.1.12: @@ -866,8 +1047,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001765: - resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} + caniuse-lite@1.0.30001766: + resolution: {integrity: sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} @@ -973,6 +1154,9 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -981,8 +1165,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - electron-to-chromium@1.5.267: - resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + electron-to-chromium@1.5.282: + resolution: {integrity: sha512-FCPkJtpst28UmFzd903iU7PdeVTfY0KAeJy+Lk0GLZRwgwYHn/irRcaCbQQOmr5Vytc/7rcavsYLvTM8RiHYhQ==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1244,6 +1428,10 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} @@ -1846,8 +2034,8 @@ packages: prettier-plugin-svelte: optional: true - prettier@3.8.0: - resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true @@ -1872,6 +2060,36 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + react@19.2.3: resolution: {integrity: sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==} engines: {node: '>=0.10.0'} @@ -2005,8 +2223,8 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} - string-width@8.1.0: - resolution: {integrity: sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==} + string-width@8.1.1: + resolution: {integrity: sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==} engines: {node: '>=20'} string.prototype.includes@2.0.1: @@ -2118,8 +2336,8 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} - typescript-eslint@8.53.0: - resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==} + typescript-eslint@8.54.0: + resolution: {integrity: sha512-CKsJ+g53QpsNPqbzUsfKVgd3Lny4yKZ1pP4qN3jdMOg/sisIDLGyDMezycquXLE5JsEU0wp3dGNdzig0/fmSVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2149,6 +2367,32 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + vaul@1.1.2: + resolution: {integrity: sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==} + peerDependencies: + react: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc + which-boxed-primitive@1.1.1: resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} @@ -2196,8 +2440,8 @@ packages: peerDependencies: zod: ^3.25.0 || ^4.0.0 - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} snapshots: @@ -2543,6 +2787,149 @@ snapshots: '@nolyfill/is-core-module@1.0.39': {} + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.10)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-context@1.1.2(@types/react@19.2.10)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.10)(react@19.2.3) + aria-hidden: 1.2.6 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + react-remove-scroll: 2.7.2(@types/react@19.2.10)(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.10)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-id@1.1.1(@types/react@19.2.10)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + '@types/react-dom': 19.2.3(@types/react@19.2.10) + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.10)(react@19.2.3)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.10)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.10)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.10)(react@19.2.3) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.10)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.10)(react@19.2.3)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.10)(react@19.2.3) + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.10)(react@19.2.3)': + dependencies: + react: 19.2.3 + optionalDependencies: + '@types/react': 19.2.10 + '@rtsao/scc@1.1.0': {} '@swc/helpers@0.5.15': @@ -2648,22 +3035,22 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/react-dom@19.2.3(@types/react@19.2.8)': + '@types/react-dom@19.2.3(@types/react@19.2.10)': dependencies: - '@types/react': 19.2.8 + '@types/react': 19.2.10 - '@types/react@19.2.8': + '@types/react@19.2.10': dependencies: csstype: 3.2.3 - '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/type-utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -2672,41 +3059,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.53.0': + '@typescript-eslint/scope-manager@8.54.0': dependencies: - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 - '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.54.0(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) ts-api-utils: 2.4.0(typescript@5.9.3) @@ -2714,14 +3101,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.53.0': {} + '@typescript-eslint/types@8.54.0': {} - '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.54.0(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/visitor-keys': 8.53.0 + '@typescript-eslint/project-service': 8.54.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.54.0(typescript@5.9.3) + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/visitor-keys': 8.54.0 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 @@ -2731,20 +3118,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.53.0 - '@typescript-eslint/types': 8.53.0 - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.54.0 + '@typescript-eslint/types': 8.54.0 + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.53.0': + '@typescript-eslint/visitor-keys@8.54.0': dependencies: - '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/types': 8.54.0 eslint-visitor-keys: 4.2.1 '@unrs/resolver-binding-android-arm-eabi@1.11.1': @@ -2833,6 +3220,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.2: {} array-buffer-byte-length@1.0.2: @@ -2914,7 +3305,7 @@ snapshots: axe-core@4.11.1: {} - axios@1.13.3: + axios@1.13.4: dependencies: follow-redirects: 1.15.11 form-data: 4.0.5 @@ -2930,7 +3321,7 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.9.15: {} + baseline-browser-mapping@2.9.19: {} brace-expansion@1.1.12: dependencies: @@ -2947,9 +3338,9 @@ snapshots: browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.9.15 - caniuse-lite: 1.0.30001765 - electron-to-chromium: 1.5.267 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 + electron-to-chromium: 1.5.282 node-releases: 2.0.27 update-browserslist-db: 1.2.3(browserslist@4.28.1) @@ -2972,7 +3363,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001765: {} + caniuse-lite@1.0.30001766: {} chalk@4.1.2: dependencies: @@ -2990,7 +3381,7 @@ snapshots: cli-truncate@5.1.1: dependencies: slice-ansi: 7.1.2 - string-width: 8.1.0 + string-width: 8.1.1 client-only@0.0.1: {} @@ -3068,6 +3459,8 @@ snapshots: detect-libc@2.1.2: {} + detect-node-es@1.1.0: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -3078,7 +3471,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - electron-to-chromium@1.5.267: {} + electron-to-chromium@1.5.282: {} emoji-regex@10.6.0: {} @@ -3196,18 +3589,18 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-next@16.1.3(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + eslint-config-next@16.1.3(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: '@next/eslint-plugin-next': 16.1.3 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.39.2(jiti@2.6.1)) globals: 16.4.0 - typescript-eslint: 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + typescript-eslint: 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -3235,22 +3628,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.2(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -3261,7 +3654,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.39.2(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.2(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -3273,7 +3666,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -3304,8 +3697,8 @@ snapshots: '@babel/parser': 7.28.6 eslint: 9.39.2(jiti@2.6.1) hermes-parser: 0.25.1 - zod: 4.3.5 - zod-validation-error: 4.0.2(zod@4.3.5) + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) transitivePeerDependencies: - supports-color @@ -3489,6 +3882,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 @@ -3884,8 +4279,8 @@ snapshots: dependencies: '@next/env': 16.1.3 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.9.15 - caniuse-lite: 1.0.30001765 + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001766 postcss: 8.4.31 react: 19.2.3 react-dom: 19.2.3(react@19.2.3) @@ -4010,11 +4405,11 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-tailwindcss@0.7.2(prettier@3.8.0): + prettier-plugin-tailwindcss@0.7.2(prettier@3.8.1): dependencies: - prettier: 3.8.0 + prettier: 3.8.1 - prettier@3.8.0: {} + prettier@3.8.1: {} prop-types@15.8.1: dependencies: @@ -4035,6 +4430,33 @@ snapshots: react-is@16.13.1: {} + react-remove-scroll-bar@2.3.8(@types/react@19.2.10)(react@19.2.3): + dependencies: + react: 19.2.3 + react-style-singleton: 2.2.3(@types/react@19.2.10)(react@19.2.3) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.10 + + react-remove-scroll@2.7.2(@types/react@19.2.10)(react@19.2.3): + dependencies: + react: 19.2.3 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.10)(react@19.2.3) + react-style-singleton: 2.2.3(@types/react@19.2.10)(react@19.2.3) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.2.10)(react@19.2.3) + use-sidecar: 1.1.3(@types/react@19.2.10)(react@19.2.3) + optionalDependencies: + '@types/react': 19.2.10 + + react-style-singleton@2.2.3(@types/react@19.2.10)(react@19.2.3): + dependencies: + get-nonce: 1.0.1 + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.10 + react@19.2.3: {} reflect.getprototypeof@1.0.10: @@ -4223,7 +4645,7 @@ snapshots: get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 - string-width@8.1.0: + string-width@8.1.1: dependencies: get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 @@ -4366,12 +4788,12 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 - typescript-eslint@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): + typescript-eslint@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/parser': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.53.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.54.0(@typescript-eslint/parser@8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.54.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.54.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: @@ -4422,6 +4844,30 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.3(@types/react@19.2.10)(react@19.2.3): + dependencies: + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.10 + + use-sidecar@1.1.3(@types/react@19.2.10)(react@19.2.3): + dependencies: + detect-node-es: 1.1.0 + react: 19.2.3 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.2.10 + + vaul@1.1.2(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3): + dependencies: + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.10))(@types/react@19.2.10)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 @@ -4481,8 +4927,8 @@ snapshots: yocto-queue@0.1.0: {} - zod-validation-error@4.0.2(zod@4.3.5): + zod-validation-error@4.0.2(zod@4.3.6): dependencies: - zod: 4.3.5 + zod: 4.3.6 - zod@4.3.5: {} + zod@4.3.6: {} diff --git a/providers/query-provider.tsx b/providers/query-provider.tsx new file mode 100644 index 0000000..26a9aa5 --- /dev/null +++ b/providers/query-provider.tsx @@ -0,0 +1,27 @@ +"use client"; + +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; +import { useState } from "react"; + +export function QueryProvider({ children }: { children: React.ReactNode }) { + const [queryClient] = useState( + () => + new QueryClient({ + defaultOptions: { + queries: { + staleTime: 0, + refetchOnWindowFocus: false, + retry: 1, + }, + }, + }), + ); + + return ( + + {children} + + + ); +} diff --git a/providers/service-status-provider.tsx b/providers/service-status-provider.tsx new file mode 100644 index 0000000..9f5314f --- /dev/null +++ b/providers/service-status-provider.tsx @@ -0,0 +1,45 @@ +"use client"; + +import React, { createContext, useContext } from "react"; +import { useQuery } from "@tanstack/react-query"; + +const ServiceStatusContext = createContext(undefined); + +export function ServiceStatusProvider({ + children, + initialMaintenanceMode, +}: { + children: React.ReactNode; + initialMaintenanceMode: boolean; +}) { + const { data: isMaintenance } = useQuery({ + queryKey: ["maintenance-status"], + queryFn: async () => { + const res = await fetch("https://api.your-backend.com/status", { + cache: "no-store", + }); + const data = await res.json(); + return data.maintenance; + }, + initialData: initialMaintenanceMode, + refetchInterval: 30 * 1000, + refetchOnWindowFocus: true, + staleTime: 1000 * 20, + }); + + return ( + + {children} + + ); +} + +export function useServiceStatus() { + const context = useContext(ServiceStatusContext); + if (context === undefined) { + throw new Error( + "useServiceStatus must be used within ServiceStatusProvider", + ); + } + return context; +} diff --git a/public/bubble/bubble.svg b/public/bubble/bubble.svg new file mode 100644 index 0000000..65e7263 --- /dev/null +++ b/public/bubble/bubble.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/logo/comatching-logo.svg b/public/logo/comatching-logo.svg new file mode 100644 index 0000000..5eb8f00 --- /dev/null +++ b/public/logo/comatching-logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/public/sns/google.svg b/public/sns/google.svg new file mode 100644 index 0000000..0b1628c --- /dev/null +++ b/public/sns/google.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/sns/kakao.svg b/public/sns/kakao.svg new file mode 100644 index 0000000..dfd0baf --- /dev/null +++ b/public/sns/kakao.svg @@ -0,0 +1,3 @@ + + + diff --git a/scripts/generate-tokens.js b/scripts/generate-tokens.js index 3e34833..f512f45 100644 --- a/scripts/generate-tokens.js +++ b/scripts/generate-tokens.js @@ -179,6 +179,8 @@ const textColorUtilities = Array.from(textColorUtilitiesSet).sort().join("\n"); // 폰트 사이즈 유틸리티 (typo-{size}-{weight}) const weights = ["400", "500", "600", "700"]; const fontUtilitiesSet = new Set(); + +// token.json에서 가져온 폰트 사이즈 fontTokens.forEach((t) => { const size = t.value; if (typeof size === "number") { @@ -191,7 +193,25 @@ fontTokens.forEach((t) => { }); } }); -const fontUtilities = Array.from(fontUtilitiesSet); + +// 추가 폰트 사이즈 (10~30까지 2 간격) +const additionalSizes = [10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; +additionalSizes.forEach((size) => { + weights.forEach((weight) => { + fontUtilitiesSet.add(` .typo-${size}-${weight} { + font-size: ${size}px; + font-weight: ${weight}; + line-height: 1.5; + }`); + }); +}); + +const fontUtilities = Array.from(fontUtilitiesSet).sort((a, b) => { + const sizeA = parseInt(a.match(/typo-(\d+)-/)?.[1] || 0); + const sizeB = parseInt(b.match(/typo-(\d+)-/)?.[1] || 0); + if (sizeA !== sizeB) return sizeA - sizeB; + return a.localeCompare(b); +}); // Border 유틸리티 (중복 제거) const borderUtilitiesSet = new Set();