feat: complete ANL lab homepage with light/dark theme, responsive layout, and 100% SSG E2E test suite
This commit is contained in:
@@ -1,37 +1,8 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Fraunces, Noto_Serif_KR, Inter } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import Header from "@/components/Header";
|
||||
import Footer from "@/components/Footer";
|
||||
|
||||
/**
|
||||
* CUSTOMIZATION HOOK — FONTS
|
||||
* The editorial system pairs an English display serif (Fraunces) and a
|
||||
* Korean serif (Noto Serif KR) for headlines, with a clean sans for body.
|
||||
* Pretendard is preferred for body but is not served by Google Fonts, so
|
||||
* Inter is loaded as the web fallback (see tailwind.config.ts sans stack).
|
||||
*/
|
||||
const fraunces = Fraunces({
|
||||
subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600"],
|
||||
style: ["normal", "italic"],
|
||||
variable: "--font-display",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
const notoSerifKr = Noto_Serif_KR({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "600", "700"],
|
||||
variable: "--font-serif-ko",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
display: "swap",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: "ANL · AI 에이전트 네트워크 연구실",
|
||||
@@ -41,17 +12,31 @@ export const metadata: Metadata = {
|
||||
"경북대학교 컴퓨터학부 AI 에이전트 네트워크 연구실 (ANL). QUIC, gRPC, A2A 기반 에이전트 통신 및 멀티에이전트 오케스트레이션 연구.",
|
||||
};
|
||||
|
||||
const themeScript = `
|
||||
(function() {
|
||||
try {
|
||||
var storedTheme = localStorage.getItem('theme');
|
||||
var supportDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if (storedTheme === 'dark' || (!storedTheme && supportDarkMode)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
document.documentElement.setAttribute('data-theme', 'dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
document.documentElement.setAttribute('data-theme', 'light');
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
`;
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html
|
||||
lang="ko"
|
||||
className={`${fraunces.variable} ${notoSerifKr.variable} ${inter.variable}`}
|
||||
>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
|
||||
{/* No-JS fallback for the .reveal scroll-reveal: without this, every
|
||||
page is blank if hydration fails (e.g. Google Fonts request blocked). */}
|
||||
<noscript>
|
||||
|
||||
Reference in New Issue
Block a user