diff --git a/public/fonts/Merriweather-Black.woff2 b/public/fonts/Merriweather-Black.woff2 index 27efff6..b3fdf21 100644 Binary files a/public/fonts/Merriweather-Black.woff2 and b/public/fonts/Merriweather-Black.woff2 differ diff --git a/public/fonts/Merriweather-Bold.woff2 b/public/fonts/Merriweather-Bold.woff2 index 4391699..1c1896b 100644 Binary files a/public/fonts/Merriweather-Bold.woff2 and b/public/fonts/Merriweather-Bold.woff2 differ diff --git a/public/fonts/Merriweather-Light.woff2 b/public/fonts/Merriweather-Light.woff2 index a6919a9..cafa2fd 100644 Binary files a/public/fonts/Merriweather-Light.woff2 and b/public/fonts/Merriweather-Light.woff2 differ diff --git a/public/fonts/Merriweather-Regular.woff2 b/public/fonts/Merriweather-Regular.woff2 index 6515c26..824753f 100644 Binary files a/public/fonts/Merriweather-Regular.woff2 and b/public/fonts/Merriweather-Regular.woff2 differ diff --git a/src/app/fonts.css b/src/app/fonts.css new file mode 100644 index 0000000..5c89f57 --- /dev/null +++ b/src/app/fonts.css @@ -0,0 +1,36 @@ +/* Merriweather Font Faces */ +@font-face { + font-family: 'Merriweather'; + src: url('/fonts/Merriweather-Light.woff2') format('woff2'); + font-weight: 300; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Merriweather'; + src: url('/fonts/Merriweather-Regular.woff2') format('woff2'); + font-weight: 400; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Merriweather'; + src: url('/fonts/Merriweather-Bold.woff2') format('woff2'); + font-weight: 700; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Merriweather'; + src: url('/fonts/Merriweather-Black.woff2') format('woff2'); + font-weight: 900; + font-style: normal; + font-display: swap; +} + +:root { + --font-merriweather: 'Merriweather', serif; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index fb73365..6cbfde3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next"; import localFont from "next/font/local"; import "./globals.css"; +import "./fonts.css"; import { OfflineIndicator } from "../components/features/common"; import { InstallPrompt } from "../components/features/pwa/install-prompt"; import { ThemeProvider } from "@/components/theme-provider"; @@ -11,20 +12,9 @@ const inter = localFont({ display: "swap", }); -const merriweather = localFont({ - src: [ - { path: "../../public/fonts/Merriweather-Light.woff2", weight: "300", style: "normal" }, - { path: "../../public/fonts/Merriweather-Regular.woff2", weight: "400", style: "normal" }, - { path: "../../public/fonts/Merriweather-Bold.woff2", weight: "700", style: "normal" }, - { path: "../../public/fonts/Merriweather-Black.woff2", weight: "900", style: "normal" }, - ], - variable: "--font-merriweather", - display: "swap", -}); - export const metadata: Metadata = { - title: "Test01 - Local-First Venting", - description: "Transform your struggles into personal branding content with AI-powered journaling", + title: "Brachnha Insight", + description: "Transform what in your mind into a powerful notes", // Story 3.4: PWA metadata manifest: "/manifest.webmanifest", // Next.js 14+ convention themeColor: "#64748B", @@ -52,7 +42,7 @@ export default function RootLayout({ return ( (null); + const containerRef = useRef(null); + const [isUserScrolling, setIsUserScrolling] = useState(false); - // Auto-scroll to bottom + // Auto-scroll to bottom only when new messages arrive useEffect(() => { - bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); - }, [messages, isTyping]); + if (!isUserScrolling) { + bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages.length, isUserScrolling]); + + // Detect when user is manually scrolling + useEffect(() => { + const container = containerRef.current; + if (!container) return; + + const handleScroll = () => { + const { scrollTop, scrollHeight, clientHeight } = container; + const isAtBottom = scrollHeight - scrollTop - clientHeight < 100; + + // If user scrolls up from bottom, disable auto-scroll + if (!isAtBottom && !isUserScrolling) { + setIsUserScrolling(true); + } + + // If user scrolls back near bottom, re-enable auto-scroll + if (isAtBottom && isUserScrolling) { + setIsUserScrolling(false); + } + }; + + container.addEventListener('scroll', handleScroll); + return () => container.removeEventListener('scroll', handleScroll); + }, [isUserScrolling]); if (!messages || messages.length === 0) { return ( @@ -38,7 +66,7 @@ export function ChatWindow() { } return ( -
+
{messages.map((msg) => (