nanochat/services/frontend/app/layout.tsx
Manmohan Sharma 634be4080b
feat(frontend): Next.js 14 frontend service for samosaChaat (#2)
Build services/frontend/ replacing the legacy nanochat/ui.html single-file UI.
Landing, login, and chat pages ported with full design system: Devanagari +
Great Vibes hero, samosa/chai/toran SVG animations, gold/cream palette.

- App Router pages: / (hero + floating illustrations), /login (split-screen
  OAuth with mandala motif), /chat (260px collapsible sidebar, suggestion
  chips, markdown + code-copy, auto-expanding input, slash commands)
- SSE streaming via useSSE hook and /api/chat/stream BFF route (proxies to
  CHAT_API_URL when set, falls back to mock echo for local dev)
- NextAuth.js v5 with Google + GitHub providers; middleware gates /chat/*
- Zustand store with localStorage persistence for conversations/settings
- Tailwind theme carries all ui.html tokens + keyframes (pendulum, float,
  wobble, steamFloat, steamType); SVG assets componentized under components/svg
- Multi-stage node:20-alpine Dockerfile with Next standalone output

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 11:26:57 -07:00

55 lines
1.4 KiB
TypeScript

import type { Metadata, Viewport } from 'next';
import { Baloo_2, Great_Vibes, Caveat, Inter } from 'next/font/google';
import SessionBoundary from '@/components/SessionBoundary';
import './globals.css';
const baloo = Baloo_2({
subsets: ['latin', 'devanagari'],
weight: ['400', '600', '700', '800'],
variable: '--font-baloo',
display: 'swap',
});
const vibes = Great_Vibes({
subsets: ['latin'],
weight: ['400'],
variable: '--font-vibes',
display: 'swap',
});
const caveat = Caveat({
subsets: ['latin'],
weight: ['400', '600', '700'],
variable: '--font-caveat',
display: 'swap',
});
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
display: 'swap',
});
export const metadata: Metadata = {
title: 'समोसाचाट — samosaChaat',
description: 'Crafted with care. For India, from India. A warm, desi-flavored chat experience powered by nanochat.',
icons: { icon: '/logo.svg' },
};
export const viewport: Viewport = {
themeColor: '#fff8e7',
width: 'device-width',
initialScale: 1,
viewportFit: 'cover',
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${baloo.variable} ${vibes.variable} ${caveat.variable} ${inter.variable}`}>
<body className="min-h-dvh bg-white text-gray-900">
<SessionBoundary>{children}</SessionBoundary>
</body>
</html>
);
}