/** * @file app/layout.tsx * @description 애플리케이션의 최상위 루트 레이아웃 (RootLayout) * @remarks * - [레이어] Infrastructure/Layout * - [역할] 전역 스타일(Font/CSS), 테마(Provider), 세션 관리(Manager) 초기화 * - [데이터 흐름] Providers -> Children * - [연관 파일] globals.css, theme-provider.tsx */ import type { Metadata } from "next"; import { Geist, Geist_Mono, Outfit } from "next/font/google"; import { QueryProvider } from "@/providers/query-provider"; import { ThemeProvider } from "@/components/theme-provider"; import { SessionManager } from "@/features/auth/components/session-manager"; import { Toaster } from "sonner"; import "./globals.css"; const geistSans = Geist({ variable: "--font-geist-sans", subsets: ["latin"], }); const geistMono = Geist_Mono({ variable: "--font-geist-mono", subsets: ["latin"], }); const outfit = Outfit({ variable: "--font-heading", subsets: ["latin"], display: "swap", }); export const metadata: Metadata = { title: "JOORIN-E (주린이) - 감이 아닌 전략으로 시작하는 자동매매", description: "주린이를 위한 자동매매 파트너 JOORIN-E. 손실 방어 규칙, 데이터 신호 분석, 실시간 자동 실행으로 초보의 첫 수익 루틴을 만듭니다.", }; /** * RootLayout 컴포넌트 * @param children 렌더링할 자식 컴포넌트 * @returns HTML 구조 및 전역 Provider 래퍼 * @see theme-provider.tsx - 다크모드 지원 * @see session-manager.tsx - 세션 타임아웃 감지 */ export default function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { return (