--- app/layout.tsx
+++ app/layout.tsx
... | ... | @@ -2,27 +2,7 @@ |
| 2 | 2 |
import { Geist_Mono } from "next/font/google";
|
| 3 | 3 |
import { FeedbackHost } from "@/app/_components/feedback-host";
|
| 4 | 4 |
import { FeedbackProvider } from "@/app/_components/feedback-provider";
|
| 5 |
-import {
|
|
| 6 |
- THEME_ATTRIBUTE_NAME, |
|
| 7 |
- THEME_STORAGE_KEY, |
|
| 8 |
-} from "@/lib/constants/theme"; |
|
| 9 | 5 |
import "./globals.scss"; |
| 10 |
- |
|
| 11 |
-// 첫 페인트 전 테마 적용 — <head>는 <body>보다 먼저 파싱되므로 <html>만 조작 가능하다 |
|
| 12 |
-// (preventing-flash-before-hydration.md의 Themes 패턴). localStorage에 명시 선택("light"
|
|
| 13 |
-// /"dark")이 저장돼 있으면 첫 페인트 전에 <html data-theme>을 부여해 FOUC를 막는다. 저장값이 |
|
| 14 |
-// 없거나("system") 손상된 값이면 속성을 부여하지 않는다 — globals.css의
|
|
| 15 |
-// `prefers-color-scheme` 미디어 쿼리가 그대로 OS 설정을 따르는 fail-safe 경로다. |
|
| 16 |
-// |
|
| 17 |
-// THEME_STORAGE_KEY/THEME_ATTRIBUTE_NAME은 반드시 'use client' 파일이 아닌 |
|
| 18 |
-// lib/constants/theme에서 import한다 — 'use client' 모듈의 일반 값(문자열) export를 |
|
| 19 |
-// Server Component가 직접 import하면 클라이언트 레퍼런스 프록시 특성상 undefined로 평가된다 |
|
| 20 |
-// (컴포넌트 export만 정상적으로 프록시된다). |
|
| 21 |
-const THEME_BOOTSTRAP_SCRIPT = `(function(){try{var t=localStorage.getItem(${JSON.stringify(
|
|
| 22 |
- THEME_STORAGE_KEY |
|
| 23 |
-)});if(t==="light"||t==="dark")document.documentElement.setAttribute(${JSON.stringify(
|
|
| 24 |
- THEME_ATTRIBUTE_NAME |
|
| 25 |
-)},t)}catch(e){}})()`;
|
|
| 26 | 6 |
|
| 27 | 7 |
// 앱 기본 서체는 여기서 선언하지 않는다 — @fox 토큰이 패밀리명을 리터럴 `Pretendard`로 못 |
| 28 | 8 |
// 박고 있어 `next/font`(패밀리명을 해시로 바꾼다)를 쓸 수 없고, globals.scss의 `@font-face`가 |
... | ... | @@ -63,11 +43,15 @@ |
| 63 | 43 |
return ( |
| 64 | 44 |
<html |
| 65 | 45 |
lang="ko" |
| 46 |
+ // 테마를 바꾸는 기획이 아직 없어 라이트로 못박는다. @fox 토큰은 `color-scheme`으로 |
|
| 47 |
+ // 갈리므로(`@fox/styles/_root.scss`) 이 속성 하나가 OS 다크 설정까지 덮는다. |
|
| 48 |
+ // 전환이 기획되면 이 값을 저장된 선택으로 되돌리고 `_hooks/use-theme-preference`와 |
|
| 49 |
+ // `_components/theme-toggle-button`을 헤더에 다시 붙이면 된다(둘 다 그대로 남아 있다). |
|
| 50 |
+ data-theme="light" |
|
| 66 | 51 |
suppressHydrationWarning |
| 67 | 52 |
className={geistMono.variable}
|
| 68 | 53 |
> |
| 69 | 54 |
<head> |
| 70 |
- <script dangerouslySetInnerHTML={{ __html: THEME_BOOTSTRAP_SCRIPT }} />
|
|
| 71 | 55 |
{/* @font-face는 CSS를 다 읽은 뒤에야 발견돼 본문이 한 번 폴백 서체로 그려진다.
|
| 72 | 56 |
거의 모든 화면이 쓰는 regular만 미리 받아 그 깜빡임을 없앤다 — 나머지 굵기는 |
| 73 | 57 |
빈도가 낮아 선점 비용이 이득보다 크다. */} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?