# editorial-forest — 슬라이드 만들기 지시서 (채팅 AI용)

> 이 파일은 **ChatGPT·Claude·Gemini 같은 채팅 AI**에게 통째로 주면, 이 디자인(`editorial-forest`)으로 수업 슬라이드를 만들어 주도록 쓴 지시서입니다.
> 파일을 읽고 쓸 수 있는 에이전트 AI(Claude Code 등)를 쓴다면 갤러리의 **받기 .zip**을 쓰세요.

## 사용법 (사람이 읽는 안내)

1. 채팅 AI 대화창에 **이 파일을 첨부**합니다. 첨부가 안 되면 파일 내용을 **전부 복사해 붙여 넣습니다**(끝까지 빠짐없이).
2. 이어서 만들고 싶은 수업을 말합니다(**"결과는 .html 파일로 만들어 줘"**도 같이 말하면 좋습니다). 예) "6학년 2학기 과학 1단원 3~4차시, 학습 목표는 ○○○, 00초등학교, 슬라이드로 만들어 줘(장 수와 구성은 내용에 맞게 정해 줘)."
3. AI가 먼저 **장별 구성안**(장마다 제목·내용·쓸 부품)을 보여 줍니다. 마음에 들면 "좋아, 만들어 줘", 고칠 곳이 있으면 "3장은 빼고 퀴즈를 하나 더 넣어 줘"처럼 말합니다. 구성 확인 없이 바로 받고 싶으면 2번에서 "구성 확인 없이 바로 만들어 줘"라고 하세요.
4. AI가 **슬라이드.html 파일**을 만들어 줍니다. 내려받아 더블클릭하면 브라우저에서 열립니다. 방향키(→ ←)와 스페이스로 넘깁니다. 만약 파일 대신 **코드만 글로 보여 주면** "코드 말고 .html 파일로 만들어서 내려받게 해 줘"라고 다시 요청하세요. 그래도 안 되면 코드를 모두 복사해 메모장에 붙여 넣고 `슬라이드.html`로 저장합니다(파일 형식은 '모든 파일', 인코딩은 UTF-8).
5. 고치고 싶으면 AI에게 "2장 제목을 ○○로 바꿔 줘"처럼 말하면 됩니다. 중간에 코드가 끊기면 "끊긴 곳부터 이어서 출력해 줘"라고 하세요.

서비스별 팁 (메뉴 이름은 서비스마다 바뀔 수 있습니다)
- 공통: 고를 수 있다면 **생각하는(추론) 모드**나 상위 모델을 쓰세요. 긴 코드를 끝까지 정확하게 쓰는 데 차이가 큽니다.
- ChatGPT: "캔버스로 만들어 줘" 또는 "다운로드할 수 있는 .html 파일로 만들어 줘"라고 요청합니다.
- Gemini: 입력창의 **Canvas**를 켜고 요청하면 화면에서 바로 보고 내려받을 수 있습니다.
- Claude: 결과가 **아티팩트**(오른쪽 창)로 열리면 거기서 내려받습니다.
- AI가 그림 파일(이미지)을 따로 만들어 주더라도 슬라이드에는 들어가지 않습니다. 슬라이드는 .html 파일입니다.
- **AI 화면 안의 미리보기에서는 색·모양·버튼이 안 나올 수 있습니다.** 이 디자인의 공통 모양과 동작은 슬라이드를 열 때 인터넷(`https://k-slide.web.app`)에서 불러오는데, 일부 서비스의 미리보기 창은 바깥 파일을 막기 때문입니다. **내려받아 브라우저(크롬·엣지 등)로 열면 정상**으로 보입니다.

알아 둘 점
- 이 디자인의 한글 글씨체는 제목 HS활공명조(400) · 본문 Cafe24 Oneprettynight(400)입니다. 글씨체와 공통 모양·동작은 **인터넷에서 불러오므로 슬라이드를 열 때 인터넷이 필요**합니다(영문 글꼴도 마찬가지). 인터넷 없이 발표하려면 갤러리의 **받기 .zip**(모든 것이 파일 안에 들어 있음)을 쓰세요.
- AI가 긴 코드를 일부 생략하거나 어긋나게 쓸 수 있습니다. 열어서 한 번 확인하세요. 안 열리거나 깨지면 "코드가 생략되었어. 완성된 HTML 하나로 처음부터 끝까지 다시 출력해 줘"라고 요청합니다.
- 사진·학생 이름 같은 개인정보는 AI에게 넣지 마세요.

## 라이선스

폰트 라이선스 안내
==================

- HS활공명조: HS활공명조 — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: 2025 Ⓒ RTF Type Study Dept. All Rights Reserved.
  파일: HSHwalkongSerif-Regular.ttf
- Cafe24 Oneprettynight: Cafe24 Oneprettynight — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright (c) 2020 by Cafe24. All rights reserved.
  파일: Cafe24Oneprettynight-v2.0.ttf

SIL Open Font License 1.1 요약
- 폰트를 자유롭게 사용·복제·수정·재배포할 수 있습니다(폰트 파일 단독 판매는 불가).
- 수정본(글자를 줄인 서브셋 포함)은 원래 폰트의 '예약 이름'을 쓰지 못할 수 있습니다.
- 재배포할 때는 저작권 표시와 라이선스 문구를 함께 넣어야 합니다.
- 전문: https://openfontlicense.org

학교안심 글꼴과 easy3D 폴더의 글꼴은 사용자가 OFL로 확인한 내용을 따랐습니다. 배포 전에 각 배포처에서 최신 라이선스를 다시 확인하세요.

design.md 라이선스 (MIT)
=======================
design.md는 frontend-slides(https://github.com/zarazhangrui/frontend-slides)의 템플릿을 바탕으로 한 것이며, 아래 MIT 라이선스를 따릅니다.

MIT License

Copyright (c) 2025 Zara Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

---

# ▼▼▼ 여기부터 AI에게 주는 지시서 ▼▼▼

(이 줄 위의 '사용법'과 '라이선스'는 사람을 위한 안내입니다. AI는 아래 지시서를 따르세요.)

## 0. 당신(AI)의 일

당신은 슬라이드 제작 도우미입니다. 사용자가 알려 주는 수업 내용으로, 아래 **디자인 규칙(1)**, **부품 사전(3)**, **HTML 뼈대(4)**를 지켜 **브라우저에서 바로 열리는 슬라이드 HTML 파일 하나**를 만듭니다.
이 디자인의 공통 CSS(글씨체·색·부품 모양)와 동작 엔진은 사이트에 올려 둔 파일이라, 뼈대의 `<link>`·`<script src>` 두 줄이 불러옵니다. **당신이 쓰는 것은 슬라이드 HTML(`<section class="slide">`들과 내비)과, 꼭 필요할 때만 '추가 부품' CSS뿐입니다.** 공통 CSS의 내용은 참고용으로 5에 있습니다.

### 진행 순서
1. 사용자가 아직 수업 내용을 말하지 않았다면, 먼저 아래를 짧게 물어보세요: 학교급·학년·과목, 단원과 차시, 학습 목표, 학교 이름(선택), 원하는 장 수(말하지 않으면 내용 분량에 맞게 정함).
2. **장별 구성안을 먼저 보여 주고 확인을 받습니다**(아래 '구성은 내용이 정합니다'). 이때는 코드를 쓰지 마세요.
3. 확인을 받으면 HTML을 만들고, 내보내기 전에 아래 '내보내기 전 점검'을 하나씩 확인합니다.
- 내용은 사용자가 준 것만 쓰고, **숫자·사실·출처를 지어내지 마세요.** 모르면 묻거나 "(예시)"라고 표시하세요.
- **사용자가 주지 않은 사실(연도·기록·수치·등재·'세계 최고'·'가장 ○○하다' 같은 말)을 덧붙이고 싶으면, 구성안에 '추가 사실'로 따로 적어 확인을 받으세요.** 확인받지 않은 사실은 슬라이드에 넣지 않습니다. 널리 알려진 이야기라도 정확한 대상을 쓰세요(예: 유네스코 세계기록유산에 오른 것은 '한글'이 아니라 《훈민정음》 해례본이라는 책).

### 반드시 지킬 것
1. **디자인 규칙(1)을 어기지 마세요.** 색·글꼴·배치·장식·움직임 규칙과 '하지 말 것'을 그대로 따릅니다. 규칙에 없는 효과(임의의 애니메이션, 새 색, 새 장식)를 더하지 마세요.
2. **뼈대(4)의 공통 파일 두 줄을 그대로 두세요.** `<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/editorial-forest.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/editorial-forest.js"></script>`(body 맨 끝)는 주소 한 글자도 바꾸거나 지우지 마세요. **공통 CSS(5)나 엔진을 HTML 안에 옮겨 쓰거나, 줄이거나, 비슷하게 새로 짜지 마세요**(이미 불러오므로 같은 규칙을 또 쓰면 서로 부딪혀 깨집니다). `<style>`에는 '추가 부품' 줄과 그 아래에 직접 정의한 클래스만 둡니다. 엔진이 쓰는 속성 이름(`data-steps`, `data-s`, `data-quiz`, `data-opt`, `data-act`, `data-blank` 등)은 5의 엔진 사용법대로 씁니다.
3. **클래스는 부품 사전(3)과 공통 CSS(5)에 있는 것만 쓰세요.** 없는 클래스 이름을 지어 쓰면 아무 모양도 적용되지 않아 배치가 무너집니다(창이 좁아지고 빈 공간이 생김). 새 부품이 꼭 필요하면 `<style>`의 '추가 부품' 주석 줄 **아래에** 그 클래스를 직접 정의하세요(디자인 규칙의 색·선·글꼴만 사용). 모양을 `style="…"`로 하나하나 지정하는 것보다 부품 클래스를 쓰는 쪽이 낫습니다.
   - **새 배치를 만들기 전에, 예시 장의 배치 클래스로 할 수 있는지 먼저 보세요.** 직접 만든 배치는 화면을 볼 수 없는 상태에서 쓰기 때문에 깨질 위험이 큽니다. 예시 배치로 안 될 때만 새로 정의합니다.
4. **슬라이드의 장 수·순서·내용은 사용자 수업에 맞게 새로 구성하세요.** 뼈대의 슬라이드는 '계절의 변화' 예시이므로 그 문구는 하나도 남기지 마세요. 장을 늘리거나 줄이거나 순서를 바꾸면 **내비 점 개수와 쪽 표시(예: 01 / 06)를 실제 장 수에 맞추세요.** 뼈대의 6번째 장은 이 디자인의 대표 장치를 눌러 보여 주는 안내 장이므로, 그 부품·움직임(예: data-demo 시연 버튼과 .play 상태)만 참고하고 디자인 안내 문구는 남기지 마세요. 아래 '구성은 내용이 정합니다'를 따르세요.
5. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 HS활공명조(400) · 본문 Cafe24 Oneprettynight(400))는 공통 CSS가 불러옵니다. `@font-face`를 새로 쓰지 말고, 글꼴은 `var(--kt)`(제목)·`var(--kb)`(본문)·`var(--ka)`(포인트) 변수로만 지정하세요.
6. **글자 크기와 화면 채우기** (슬라이드는 1920×1080 기준으로 그려져 화면 크기에 맞게 통째로 줄어듭니다)
   - 읽어야 하는 글(본문·설명·표 내용·보기)은 **28px 이상**, 보조 글(캡션·주석)은 **22px 이상**으로 씁니다. 창 제목줄·쪽 번호·작은 라벨 같은 장식 글자는 디자인 규칙의 크기를 따릅니다.
   - 창·판·카드가 **화면의 대부분을 채우게** 하세요. 한쪽에 작게 몰리거나 큰 빈 공간이 남으면 안 됩니다. 내용이 적은 장은 글자와 그림을 키우거나 다른 장과 합칩니다.
   - **높이 예산**: 장 제목과 아래 내비를 빼면 본문에 쓸 수 있는 높이는 대략 **650~750px**입니다. 모든 내용이 1920×1080 안에 들어가야 하고, 넘친 부분은 잘려서 보이지 않습니다. 쓰기 전에 줄 수 × 줄 높이(글자 크기의 약 1.5배)로 높이를 어림해 보세요.
   - **카드 규칙**: 한 장에 카드(칸)를 4개 이상 놓으면 카드마다 글은 **3줄 이하**로 줄입니다. 글이 들어가는 칸은 **너비 400px 이상**으로 두고(그림+글을 나란히 놓을 때는 글 칸 기준), 한 줄에 몇 글자밖에 안 들어가게 좁히지 마세요. 카드를 두 줄로 쌓아야 하면 그 줄들의 높이 합이 높이 예산 안에 드는지 확인합니다.
   - 제목은 **두 줄 이내**로 씁니다. 표지 제목은 한 줄에 15자 안팎으로 끊어 줄을 바꾸세요. 글이 창 밖으로 넘치거나 잘리면 글자를 줄이지 말고 문장을 짧게 고칩니다.
   - 한글은 단어 중간에서 줄이 바뀌지 않게(`word-break:keep-all`) 합니다(공통 CSS에 이미 들어 있음).
7. 저작권이 있는 글·그림·사진을 가져오지 마세요. **사용자가 요청하지 않으면 그림 파일(이미지 생성)을 따로 만들지 마세요. 슬라이드에 필요한 그림은 HTML 안에서 SVG·CSS로 그립니다.**

### 구성은 내용이 정합니다
- 예시 덱(deck.html)은 이 디자인의 **부품 견본**입니다. 따라야 할 장 구성이 아닙니다. 예시의 장 순서·장 수·제목 짜임·문장 구조를 그대로 따라 하지 마세요.
- 사용자가 준 내용을 먼저 살펴 **필요한 장 수와 장별 역할을 직접 정하세요.** 내용이 적으면 3~4장, 많으면 8장 이상도 괜찮습니다.
- **코드를 쓰기 전에 장별 구성안(장마다 제목 · 전할 내용 한 줄 · 쓸 부품)을 먼저 보여 주고 확인을 받으세요.** 사용자가 고치라고 하면 고친 구성안을 다시 보여 주고, "좋아", "만들어 줘"라고 하면 그때 만듭니다. 사용자가 처음부터 "구성 확인 없이 바로 만들어 줘"라고 했으면 이 단계는 건너뜁니다.
- 아래 부품 중 **필요한 것만 골라 쓰세요.** 안 쓰는 부품이 있어도 되고(예: 퀴즈 없는 덱), 같은 부품을 여러 장에 쓰거나 한 장에 섞어 써도 됩니다.
  · 표지 · 단계 버튼이 있는 흐름(data-steps) · 큰 숫자와 통계 · 그래프 · 비교와 표 · 목록과 인용 · 퀴즈와 다시 풀기 · 빈칸 채우기 · 시연 버튼(data-demo)
- 장마다 전하는 메시지는 하나로 하고, 같은 모양의 장이 연달아 나오지 않게 하세요.
- 지켜야 하는 것은 디자인 규칙(design.md)과 동작 엔진입니다. 자유로운 것은 장의 수·순서·구성입니다.

### 출력 방식
- **결과물은 '.html 파일'로 주세요.** 파일 이름은 슬라이드.html, 형식은 UTF-8 HTML 문서 하나입니다. 파일을 만들거나 내려받게 해 주는 기능(아티팩트·캔버스·코드 실행 환경·파일 첨부 등)이 있으면 **반드시 그 기능으로 .html 파일을 만들어 내려받거나 열 수 있게** 하세요. 코드만 글로 보여 주고 끝내지 마세요.
- 파일을 만들 수 있는 기능이 **전혀 없을 때만**, 설명은 한두 줄로 줄이고 **완성된 HTML 전체를 ```html 코드 블록 하나**로 출력하세요(이때 사용자가 직접 .html로 저장합니다).
- **`...`, "(이하 동일)", "(생략)" 같은 생략 표시를 쓰지 마세요.** `<!DOCTYPE html>`부터 `</html>`까지 전부 씁니다.
- 너무 길어 끊길 것 같으면 먼저 쓰지 말고, 사용자에게 "장 수를 줄일까요?"라고 묻거나, 끊기면 사용자가 "이어서"라고 할 때 **끊긴 글자 바로 다음부터** 이어 쓰세요.
- **미리보기 창에서 색·모양·버튼이 안 보여도 고치지 마세요.** 공통 CSS·엔진은 인터넷 주소(`https://k-slide.web.app`)에서 불러오는데, 일부 미리보기 창은 바깥 파일을 막습니다. 내려받아 브라우저로 열면 정상입니다. 이때 공통 CSS나 엔진을 HTML 안에 직접 써 넣으면 안 됩니다. 사용자에게 "내려받아 브라우저로 열어 보세요"라고 안내하세요.
- 파일을 코드(파이썬 등)로 써서 만든다면, HTML 전체를 **원문 그대로의 문자열**로 쓰세요(예: 파이썬은 따옴표 세 개짜리 raw 문자열). 백슬래시(`\`)가 다른 문자로 바뀌어 깨지는 일을 막기 위해서입니다. 새로 쓰는 CSS·JS에서도 `\00a0` 같은 이스케이프 대신 실제 문자를 쓰세요.
- 파일로 줬다면 "슬라이드.html을 내려받아 더블클릭하세요(열 때 인터넷 필요)"라고, 코드 블록으로 줬다면 "코드를 모두 복사해 메모장에 붙여 넣고 슬라이드.html로 저장한 뒤 더블클릭하세요(열 때 인터넷 필요)"라고 한 줄로 안내하세요.

### 내보내기 전 점검 (하나라도 아니면 고친 뒤 내보내기)
1. HTML에 쓴 클래스가 모두 부품 사전(3)·공통 CSS(5)·'추가 부품' 칸에 정의되어 있는가?
2. 공통 파일 두 줄(`<link>`·`<script src>`)이 주소 그대로 있고, 공통 CSS·엔진을 HTML 안에 옮겨 쓰지 않았는가? `@font-face`를 새로 쓰지 않았는가?
3. 장 수 = 내비 점 개수 = 쪽 표시 숫자인가?
4. 모든 장의 내용이 1920×1080 안에 들어가는가(높이 예산, 카드 규칙)? 제목·글이 창 밖으로 넘치거나 잘리지 않는가(특히 표지 제목과 마지막 장)? 읽는 글이 28px 이상이고, 화면에 큰 빈 공간이 없는가?
5. '계절의 변화' 예시 문구나 디자인 안내 문구가 남아 있지 않은가?
6. 사용자가 주지 않았고 확인도 받지 않은 사실을 넣지 않았는가?
7. `...`·"(생략)" 같은 생략이 없고, `<!DOCTYPE html>`부터 `</html>`까지 다 있는가?
8. 사용자가 요청하지 않은 그림 파일을 따로 만들지 않았는가?

---

## 1. 디자인 규칙 (`editorial-forest` design.md)

````markdown
---
version: alpha
name: Editorial Forest
description: A serif-led editorial presentation system in the register of a literary quarterly or art-book monograph. Display type runs in Source Serif 4 at weight 500 with optical-size axis engaged, scaling up to 220px for cover and stat moments. The palette pairs a deep forest green (#2e4a2a) with a dusty rose pink (#e89cb1) over an oat-cream paper ground (#efe7d4), with JetBrains Mono as the editorial chrome (labels, captions, axis ticks). The aesthetic is closer to a Penguin classic, Apartamento spread, or quiet annual report than a tech keynote — confident, paper-feeling, and committed to a small color vocabulary.

colors:
  green: "#2e4a2a"
  green-deep: "#243a21"
  green-lite: "#3a5a36"
  pink: "#e89cb1"
  pink-deep: "#d27e96"
  cream: "#efe7d4"
  cream-2: "#e6dcc4"
  ink: "#1a1a17"

typography:
  display-hero:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 220
    fontWeight: 500
    lineHeight: 0.92
    letterSpacing: -0.02em
  display:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 140
    fontWeight: 500
    lineHeight: 1.02
    letterSpacing: -0.02em
  headline-xl:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 96
    fontWeight: 500
    lineHeight: 0.96
    letterSpacing: -0.02em
  headline:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 84
    fontWeight: 500
    lineHeight: 1.0
    letterSpacing: -0.02em
  headline-sm:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 80
    fontWeight: 500
    lineHeight: 0.98
    letterSpacing: -0.02em
  title-card-lg:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 84
    fontWeight: 500
    lineHeight: 0.98
    letterSpacing: -0.01em
  title-card:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 68
    fontWeight: 500
    lineHeight: 0.96
    letterSpacing: -0.01em
  title-card-sm:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 56
    fontWeight: 500
    lineHeight: 0.98
    letterSpacing: -0.01em
  figure-caption-serif:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 56
    fontWeight: 500
    lineHeight: 1.05
  name:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 44
    fontWeight: 600
    lineHeight: 1.0
  meta-value:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 32
    fontWeight: 500
  body-lg:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 32
    fontWeight: 400
    lineHeight: 1.32
  body:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 30
    fontWeight: 400
    lineHeight: 1.38
  body-card:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 26
    fontWeight: 400
    lineHeight: 1.34
  label:
    fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
    fontSize: 26
    fontWeight: 500
    letterSpacing: 0.18em
    textTransform: uppercase
  label-tight:
    fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
    fontSize: 26
    fontWeight: 500
    letterSpacing: 0.14em
    textTransform: uppercase
  caption-mono:
    fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
    fontSize: 24
    fontWeight: 500
    letterSpacing: 0.14em
    textTransform: uppercase
  axis-mono:
    fontFamily: "'JetBrains Mono', ui-monospace, Menlo, monospace"
    fontSize: 26
    fontWeight: 500
    letterSpacing: 0.08em
  stat-figure:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 220
    fontWeight: 500
    lineHeight: 0.92
    letterSpacing: -0.03em
  stat-figure-unit:
    fontFamily: "'Source Serif 4', 'Source Serif Pro', Georgia, serif"
    fontSize: 110
    fontWeight: 500
    lineHeight: 0.92

spacing:
  slide-pad-default: "96px 120px"
  slide-pad-narrow: "100px 120px"
  slide-pad-wide: "100px 140px"
  slide-pad-statement: "130px 160px"
  grid-gap-cards: 28
  grid-gap-topics: 24
  grid-gap-kpi: 60
  rule-weight: "2px"
  rule-weight-card: "2.5px"
  radius-card: "6px"
  radius-card-step: "8px"
  radius-bar-top: "3px 3px 0 0"
  radius-mark-circle: "50%"

canvas:
  width: 1920px
  height: 1080px

components:
  topic-tile:
    description: "Bordered or filled rectangular region holding a mono ordinal, a serif title, optional body, and a mono foot. Background may be green / green-lite / pink / cream-2-with-green-border. Corner radius 6px."
    borderRadius: "{spacing.radius-card}"
    padding: "40px 40px 36px"
  step-tile:
    description: "Vertical card carrying a mono ordinal, a serif title, body paragraph, and a mono marker row separated by a top rule. Background fills: cream-with-green-border, solid green, or solid pink."
    borderRadius: "{spacing.radius-card-step}"
    padding: "40px 32px 32px"
    minHeight: "470px"
    border: "2.5px solid currentColor-region"
  monogram-circle:
    width: "130px"
    height: "130px"
    borderRadius: "{spacing.radius-mark-circle}"
    border: "2px solid {colors.pink}"
    fontFamily: "JetBrains Mono"
    fontSize: 28
    letterSpacing: 0.1em
    fontWeight: 500
    description: "Outlined round mark holding a short mono monogram. The system's signature identity stamp."
  topbar:
    placement: "top edge of slide"
    layout: "flex space-between, baseline-aligned"
    content: "{components.label} on the left, monogram-circle or counter on the right"
  footline:
    position: "absolute"
    placement: "bottom edge of slide, full-width between slide padding"
    layout: "flex space-between"
    typography: "{typography.caption-mono}"
  meta-dl:
    description: "Three-column definition list separated by a top rule (2px {colors.green}). Each entry has a mono dt label and a serif dd value."
    columns: 3
    gap: "36px"
    topBorder: "2px solid {colors.green}"
  bar:
    width: "56px"
    borderRadius: "{spacing.radius-bar-top}"
    description: "Vertical chart bar in pink, cream, or green. Value label printed above bar in mono."
  chart-axis:
    border: "2px solid currentColor"
    description: "Y-axis and x-axis use a single 2px rule on the inner edges of the plot region; no full axis box."
  rule-thin:
    description: "Hairline 2px rule, used as section separator above kpi rows, summary grids, meta dls. Color follows region (green on cream, pink on green)."
  legend-swatch:
    display: "inline-block"
    width: "26px"
    height: "26px"
    borderRadius: "2px"
    description: "Small filled square preceding a mono legend label. 2px corner radius is the smallest radius in the system."
---

## Frontend Slides Fixed-Stage Policy

When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.

This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.

This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.

Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.


## Overview

Editorial Forest is a **serif-led editorial presentation system** in the tonal register of a Penguin classic, a quiet annual report, or an art-book spread. The system's foundational premise is a single, confident typographic voice — Source Serif 4 — used at extreme scale (up to 220px) for headlines and stat figures, with JetBrains Mono playing the supporting role of editorial chrome (labels, captions, axis ticks, page footlines).

The serif is run at **weight 500** for nearly every display moment — never the more familiar 400 or 700. The 500 weight is the system's most distinctive typographic choice: heavy enough to feel authored, light enough to keep the page calm. Optical-size axis is engaged (`opsz` 8..60), which means the same Source Serif 4 face renders with subtly different letterforms at 26px caption sizes versus 220px display sizes — the small sizes pick up extra contrast and finer details automatically. JetBrains Mono runs at 500 in uppercase with 0.14em–0.18em letter-spacing, used for every label, tag, caption, axis tick, and footer line. The system never mixes a third typeface.

The palette is a tight five-color editorial set built around three primary surfaces: a **deep forest green** (`{colors.green}` — #2e4a2a), a **dusty rose pink** (`{colors.pink}` — #e89cb1), and an **oat cream paper** (`{colors.cream}` — #efe7d4). Two near-duplicates round out the set: `{colors.green-deep}` for green-on-pink text contrast, `{colors.green-lite}` for tile fills that need a second green shade, `{colors.pink-deep}` for pink-on-pink borders, and `{colors.cream-2}` for tiles that sit on the main cream surface. Body text everywhere is `{colors.ink}` (#1a1a17) — a warm near-black — except when sat on a green or pink surface, where it switches to the surface's complementary color (cream or pink on green; green-deep or cream on pink).

Depth is **flat and paper-based**. There are no drop shadows, no glows, no gradients, no overlays. Elevation is communicated entirely through color-block contrast, 2px hairline rules, and the difference between a filled region and a bordered region. The 6px and 8px card radii are the only roundness in the system besides the monogram circle. The page feels printed, not glassy.

**Density philosophy: spacious and committed.** Each slide carries one strong subject — a headline, a quote, a chart, a stat row, a card grid — surrounded by deep negative space. The slide padding of 96–140px is generous; the top of the slide carries a mono topbar (label + monogram or counter), the bottom carries a mono footline, and the middle holds the main subject at scale. A slide that crams two competing content blocks reads as broken; a slide with one display headline + supporting cards + breathing room reads as authoritative. Reach for fewer elements at larger sizes rather than more elements at smaller sizes.

**Key Characteristics:**
- Three-color editorial palette: deep forest green, dusty rose pink, oat cream paper. Two surface tones per slide is typical; three is loud.
- Source Serif 4 at weight 500 for every headline, body, and display moment. Optical-size axis engaged for size-aware letterforms.
- JetBrains Mono at weight 500 uppercase with wide tracking (0.14em–0.18em) for every label, caption, axis tick, and footline.
- Display type scales to 220px for cover and stat-figure moments; 96px for primary headlines; 56–84px for card titles.
- 2px hairline rules separate stacked sections — never thicker, never colored beyond region context.
- Card radius is 6px for topic tiles and 8px for step tiles. The monogram circle is the only fully round shape.
- Every slide carries a topbar (label + monogram or counter) and most carry a footline (mono caption row). The chrome anchors the editorial feel.
- No shadows, no gradients, no glows. Elevation is color-block + rule.

## Colors

### Palette
- **Green** (`{colors.green}` — #2e4a2a): The deep forest primary. Used as a slide surface, a tile fill, a card border, a meta-dl rule color, and a primary text color on cream surfaces. The most distinctive surface in the system.
- **Green Deep** (`{colors.green-deep}` — #243a21): A darker green used almost exclusively as text color on pink surfaces, where pure green would lack contrast. Also used as text color on pink tiles.
- **Green Lite** (`{colors.green-lite}` — #3a5a36): A lighter green used as a tile fill when two greens need to sit beside each other (e.g., a primary green tile next to a secondary green-lite tile in the same grid). Carries pink text.
- **Pink** (`{colors.pink}` — #e89cb1): A dusty rose. Used as a slide surface, a tile fill, the on-green text color, a bar-chart series color, and the monogram circle border color. The system's primary accent.
- **Pink Deep** (`{colors.pink-deep}` — #d27e96): A slightly darker rose used only as a border color on pink-filled tiles where the same-color border needs to differentiate from the fill.
- **Cream** (`{colors.cream}` — #efe7d4): The oat paper surface. The default slide background on non-cover slides, the on-green body text color, and the cream bar-chart series color.
- **Cream 2** (`{colors.cream-2}` — #e6dcc4): A subtly darker cream used as a tile fill on the cream slide surface. Pairs with a 2px green border so the tile reads as distinct from the slide ground.
- **Ink** (`{colors.ink}` — #1a1a17): The body text color on cream surfaces. A warm near-black; never pure #000.

### Defaults
- **Default slide background**: `{colors.cream}` for content-heavy slides; `{colors.green}` for cover, statement-data, summary, and any moment that needs gravity.
- **Default headline color on `{colors.cream}` surface**: `{colors.green}`.
- **Default headline color on `{colors.green}` surface**: `{colors.cream}` for primary headlines, `{colors.pink}` for hero / cover-scale headlines.
- **Default headline color on `{colors.pink}` surface**: `{colors.green-deep}`.
- **Default body color on `{colors.cream}` surface**: `{colors.ink}`.
- **Default body color on `{colors.green}` surface**: `{colors.cream}`.
- **Default body color on `{colors.pink}` surface**: `{colors.green-deep}`.
- **Default label / caption color**: matches the region's accent (label is pink on green, green on cream, green-deep on pink).
- **Default tile fill on a cream slide**: choose from the rotation — solid green (with pink text), solid pink (with green-deep text), green-lite (with pink text), or cream-2 with a 2px green border (with green text). A single grid typically mixes 3 of these 4.
- **Default rule color**: green on cream, pink on green, green-deep on pink. The 2px hairline always picks up the region's accent.

The palette is intentionally tight. Introducing a fourth chromatic family (a yellow, a blue, an additional rose) breaks the editorial discipline. Stick to the green / pink / cream triad and let the contrast between filled and bordered tiles do the variation work.

## Typography

### Font Family
The system loads exactly two web fonts: **Source Serif 4** (with the full optical-size axis 8..60 and weights 300–800) and **JetBrains Mono** (weights 400, 500, 700). Source Serif 4 carries every editorial moment — headlines, body, captions in serif, names, figures. JetBrains Mono carries every piece of chrome — labels, taglines, axis ticks, footlines, ordinals on tiles.

The mono / serif pairing is the system's typographic identity. Mono never tries to be the headline; serif never tries to be the caption. The roles are inverted from a typical "sans for chrome, serif for body" stack — here it's "mono for chrome, serif for body and display."

Source Serif 4 is run at **weight 500** for nearly every moment. Weight 400 appears only for body paragraphs (where the lighter weight reads better at small scale). Weight 600 appears once, for the attribution name on the statement slide — its slightly heavier set distinguishes a proper name from surrounding mono labels. Weight 700 is not used.

### Display, Body, and Chrome Scale

| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 220px | Source Serif 4 | 500 | Cover-scale or closing-scale headline |
| `{typography.display}` | 140px | Source Serif 4 | 500 | Pull-quote / big-idea statement |
| `{typography.headline-xl}` | 96px | Source Serif 4 | 500 | Primary section headline on cream |
| `{typography.headline}` | 84px | Source Serif 4 | 500 | Primary section headline on green |
| `{typography.headline-sm}` | 80px | Source Serif 4 | 500 | Stat-row introductory headline |
| `{typography.title-card-lg}` | 84px | Source Serif 4 | 500 | Title inside a hero topic tile (largest tile in a grid) |
| `{typography.title-card}` | 68px | Source Serif 4 | 500 | Title inside a step tile |
| `{typography.title-card-sm}` | 56px | Source Serif 4 | 500 | Title inside a standard topic tile |
| `{typography.figure-caption-serif}` | 56px | Source Serif 4 | 500 | Centered figure / image-placeholder caption |
| `{typography.stat-figure}` | 220px | Source Serif 4 | 500 | KPI numeral |
| `{typography.stat-figure-unit}` | 110px | Source Serif 4 | 500 | Unit suffix on a KPI numeral (e.g. "%") |
| `{typography.name}` | 44px | Source Serif 4 | 600 | Personal name in an attribution row |
| `{typography.meta-value}` | 32px | Source Serif 4 | 500 | Definition-list value in a meta row |
| `{typography.body-lg}` | 32px | Source Serif 4 | 400 | Primary body paragraph in a summary or stat description |
| `{typography.body}` | 30px | Source Serif 4 | 400 | Standard body paragraph |
| `{typography.body-card}` | 26px | Source Serif 4 | 400 | Body inside a card or tile |
| `{typography.label}` | 26px | JetBrains Mono | 500 / 0.18em | Eyebrow or section label in topbar |
| `{typography.label-tight}` | 26px | JetBrains Mono | 500 / 0.14em | Caption row, foot line, attribution row, tile ordinal |
| `{typography.caption-mono}` | 24px | JetBrains Mono | 500 / 0.12–0.16em | Tile foot, tile marker, kpi tag, meta-dl term |
| `{typography.axis-mono}` | 26px | JetBrains Mono | 500 / 0.08em | Chart axis ticks and labels |

### Defaults
- **Default size for a primary section headline**: `{typography.headline-xl}` (96px) on cream surfaces, `{typography.headline}` (84px) on green surfaces.
- **Default size for a cover-scale or closing-scale moment**: `{typography.display-hero}` (220px).
- **Default size for a quote / big-idea statement**: `{typography.display}` (140px).
- **Default size for a body paragraph**: `{typography.body}` (30px) in serif weight 400.
- **Default size for a body paragraph inside a card / tile**: `{typography.body-card}` (26px).
- **Default size for a meta dt label or tile ordinal**: `{typography.caption-mono}` (24px) in JetBrains Mono uppercase.
- **Default size for a topbar label / eyebrow**: `{typography.label}` (26px) in JetBrains Mono uppercase with 0.18em tracking.
- **Default weight for any serif moment**: 500. (400 is reserved for body paragraphs; 600 only for a proper name in attribution.)
- **Default weight for any mono moment**: 500.

When unsure, reach for `{typography.headline-xl}` (96px) for the slide's primary headline on cream, not the larger display sizes. The 140–220px tier is reserved for statement, stat-figure, and hero/closing moments — using it for routine headlines flattens the system's hierarchy.

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every JetBrains Mono element is UPPERCASE with letter-spacing of at least 0.08em.** Mono in sentence case or without tracking reads as code, not editorial chrome. The wide tracking is what makes mono feel like a caption row in a magazine, not a terminal.
- **Every Source Serif 4 display element uses negative letter-spacing (-0.01em to -0.03em).** Tighter tracking pulls the large serif glyphs into a single mass and is essential for the 96–220px sizes. Display serif at default tracking reads loose and untreated.
- **Display headlines use line-height between 0.92 and 1.02.** Tight line-height is part of the system's display voice. Larger headlines run tighter (0.92 at 220px); smaller headlines (84–96px) run at 0.96–1.0.
- **Body paragraphs use serif weight 400, not 500.** The weight drop from headline to body is the system's reading rhythm. Body at 500 reads heavy.
- **Every slide carries a topbar (mono label + monogram or counter on the opposite edge).** The topbar is the system's universal chrome anchor.
- **Hairline rules between sections are always 2px solid.** Never 1px (reads as web app), never 3px+ (reads as poster).

### Typography Principles
The weight 500 + optical-size + tight tracking combination is the system's display voice — switching any of those three properties (e.g., serif weight 700, or default tracking, or no opsz) reads as a different design system. The serif/mono role split is strict: mono never appears at headline scale, serif never appears at axis-tick scale.

Italics are not used anywhere in the system. Underline is not used. Emphasis is communicated through size and color contrast, not type variants.

## Layout

### Canvas System
The system targets a fixed **1920×1080** canvas. Slides are `<section>` elements at exact width/height; rendering relies on `deck-stage.js` to scale the canvas to fit the viewport. The canvas is paper, not a viewport — designed for projector, printer, or PDF export.

### Slide Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad-default}` | 96px 120px | Standard slide padding |
| `{spacing.slide-pad-narrow}` | 100px 120px | Data, framework, stats slides — slightly taller top padding |
| `{spacing.slide-pad-wide}` | 100px 140px | Cover, summary slides — extra side padding for hero headlines |
| `{spacing.slide-pad-statement}` | 130px 160px | Statement slide — most generous padding for the display-quote moment |

Pick the padding that matches the content gravity. Statement-class moments get the widest padding; everyday content slides use the default 96×120.

### Chrome Anatomy
Every slide carries (at minimum) a **topbar** at the top edge — a flex-row with a JetBrains Mono `{typography.label}` on one side and either a `{components.monogram-circle}` or a mono counter / location string on the other. Heavier slides (cover, data, summary) also carry a **footline** absolutely positioned at `bottom: 60–80px` with a mono caption row spanning the slide width between the padding.

The topbar is the system's spine. Without it, a slide reads as untreated.

### Card Radii
| Value | Use |
|---|---|
| 2px | Legend swatch only (smallest radius in the system) |
| 3px 3px 0 0 | Top corners of bar-chart bars |
| 6px | Topic tile (agenda-style grid) |
| 8px | Step tile (framework-style grid) |
| 50% | Monogram circle |

Cards are subtly rounded — never sharp-cornered, never heavily-rounded. The 6–8px radius gives the system its paper-not-plastic feel.

## Depth and Elevation

### Flat, No Shadows
There are **no shadows in this system**. Not on cards, not on tiles, not on text, not on the monogram circle. Elevation is communicated entirely through:

1. **Color-block contrast** — a green tile on a cream slide reads as elevated because the dark green block separates from the paper ground.
2. **2px hairline rules** — section separators (above kpi rows, summary grids, meta dls) sit on a 2px line in the region's accent color.
3. **Border vs fill** — a cream-2 tile with a 2px green border reads as a different elevation than a solid-fill tile beside it.

The absence of shadow is itself the elevation language. Adding `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` would shatter the editorial feel.

### Paper-Surface Rule
Every surface in the system reads as paper, not as a digital pane. The cream tones (`{colors.cream}`, `{colors.cream-2}`) carry that quality literally. The green and pink surfaces inherit it by association — used at full saturation, surrounded by cream chrome, never with shadow or glow, they read as printed ink on stock.

## Shapes and Treatment

### Border Weight and Style
- **2px solid** — the universal hairline. Section separator rules above kpi rows / summary grids / meta dls / chart axes; the border on cream-2 tiles; the border on the monogram circle.
- **2.5px solid** — step-tile borders. Slightly heavier so the tile reads as a separate object from a hairline rule.

Borders take the region's accent color (`{colors.green}` on cream, `{colors.pink}` on green, `{colors.green-deep}` or `{colors.pink-deep}` on pink).

### Decorative Element Types

**Monogram Circle** (`{components.monogram-circle}`) — A 130px outlined circle with a 2px pink border, holding a 2–3-character JetBrains Mono monogram at 28px. Lives in the top-right of cover and summary slides. The system's identity stamp.

**Topbar** (`{components.topbar}`) — A flex row spanning the top of every slide. A JetBrains Mono label on one side, a monogram or counter or location string on the other. The topbar establishes which surface family the slide belongs to (label color tells you).

**Footline** (`{components.footline}`) — An absolutely positioned flex row at `bottom: 60–80px` spanning the slide between padding. Two mono caption strings (e.g., a section name on the left, a page number on the right). Used on cover, data, summary, and any slide that wants to feel like a printed page.

**Topic Tile** (`{components.topic-tile}`) — A 6px-radius rectangular region holding a mono ordinal, a serif title, optional body, and a mono foot string. Background fills rotate through green, green-lite, pink, or cream-2-with-green-border. A grid of these tiles is the agenda / table-of-contents pattern.

**Step Tile** (`{components.step-tile}`) — An 8px-radius vertical card with 2.5px border, holding a mono ordinal, a serif title (68px), a body paragraph, and a mono marker row separated by a top rule. Background fills: cream-with-green-border, solid green, or solid pink. A row of 3–4 step tiles is the framework / process pattern.

**KPI Block** — A vertical stack: mono tag (24px) on top, oversized serif figure (220px) with optional 110px unit, then a serif description paragraph (30px). Sits inside a row separated above by a 2px pink rule on green surfaces.

**Bar (chart)** — A 56px-wide rectangle with top corners rounded at 3px, filled in pink, cream, or green. The value label is mono 24px, absolutely positioned 38px above the bar.

**Meta Definition List** (`{components.meta-dl}`) — A three-column dt/dd grid with a 2px top border. The dt is mono 24px uppercase tracked, the dd is serif 32px weight 500. Used as a credits / specs / details row at the bottom of a two-column slide.

**Legend Row** — A horizontal flex of mono uppercase items, each preceded by a 26×26px filled swatch with 2px corner radius. Used in chart and data contexts.

## Do's and Don'ts

### Do
- Run every display headline in Source Serif 4 at weight 500 with negative letter-spacing (-0.01em to -0.03em) and tight line-height (0.92–1.0). The combination is the system's voice.
- Run every label, caption, tag, axis tick, and footline in JetBrains Mono at weight 500 uppercase with 0.08em–0.18em letter-spacing.
- Place a topbar (mono label + monogram or counter) on every slide. The topbar is the system's spine.
- Pick a single dominant surface per slide (green, pink, or cream) and let it carry the whole canvas. Two surface colors per slide is the maximum.
- Pair tile fills in a grid: rotate through green + pink + green-lite + cream-2-with-green-border rather than reusing one fill across all tiles.
- Use 2px solid hairline rules to separate stacked sections (kpi rows, summary grids, meta dls). The hairline is the system's separator language.
- Scale display type aggressively when content allows — 140–220px for statement, hero, and closing moments. The system rewards bigness when there's room.
- Use generous slide padding (96–160px). Negative space is part of the editorial register; cramped padding reads as broken.
- Reserve the monogram circle for cover and summary moments. Using it on every slide dilutes its function as an identity stamp.

### Don't
- Don't add box-shadow to any element. The system is shadow-free; adding shadow shatters the paper feel.
- Don't introduce a third typeface. Only Source Serif 4 and JetBrains Mono. No Inter, no system stack.
- Don't run serif text in italic or underline. Emphasis is size and color, not type variant.
- Don't render JetBrains Mono in sentence case or without letter-spacing. Mono without uppercase + tracking reads as code, not chrome.
- Don't introduce a fourth chromatic family (yellow, blue, lavender). The green / pink / cream triad is the entire palette.
- Don't use heavy borders (4px+) or thin hairlines (1px). The system has 2px and 2.5px — pick one.
- Don't pile two competing content blocks on one slide. One subject per slide; expand or split.
- Don't use rgba transparency for surface colors. Each surface is solid ink-on-paper.
- Don't run serif body text at weight 500 — it reads heavy. Body is weight 400; display is weight 500.
- Don't omit the topbar. A slide without the mono label at the top loses its editorial spine.

## Responsive Behavior

This is a **fixed 1920×1080 presentation system** rendered through `deck-stage.js`. The canvas is not responsive in the web sense — there are no media queries, no breakpoints, no fluid sizing. Every measurement is in fixed pixels at 1920×1080.

### Scaling Behavior
The `deck-stage.js` script wraps each `<section>` and scales the 1920×1080 canvas uniformly to fit the browser viewport, letterboxing as needed. Type, padding, gaps, and rule weights are all in pixels and scale proportionally with the canvas. Borders that read as 2px at 1920px will read as 1px at 960px viewport width — this is acceptable inside the system's tolerance.

### Presenter Behavior
Navigation is delegated to whatever wrapper `deck-stage.js` provides — there is no inline keyboard handler. Treat each `<section>` as a slide; the runtime handles transitions.

### Print / Export
Because every measurement is fixed-pixel inside a 1920×1080 canvas, the system exports cleanly to PDF at the same aspect ratio (16:9). Source Serif 4 with the optical-size axis renders well at print resolution because the small-sized variants pick up the print-appropriate letterform detail automatically.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Chinese Face | Weight | Why |
|---|---|---|---|
| Display headline (220 / 140 / 96 / 84px) | 霞鹜文楷 LXGW WenKai (Noto Serif SC fallback) | 400 | Literary, handwritten-ish brushwork; matches the Penguin-classic register of Source Serif 4 |
| Body paragraph (26 / 30 / 32px) | 思源宋体 Noto Serif SC | 400 | Reads as the printed body voice of a literary quarterly |
| Stat figure (220px) | 思源宋体 Noto Serif SC | 700 | Mincho weight 700 gives the numeric mass that Source Serif 4 weight 500 provides in Latin |
| Mono label / caption / footline (24–26px) | 思源等宽 Noto Sans Mono CJK SC | 500 | JetBrains Mono has no CJK glyphs; Noto Sans Mono CJK SC preserves the typewriter-chrome quality |

### Mixed-Content Strategy

Use **Strategy C** — keep Source Serif 4 as the Latin face and fall back to LXGW WenKai (for headlines / display) or Noto Serif SC (for body / stats) for CJK glyphs. This is the right call for Editorial Forest because the Source Serif 4 optical-size axis is a signature of the system; replacing it wholesale with a Mincho would flatten the Penguin-classic register that defines the deck. The font-family stack puts the Latin face first, then the CJK fallback, then the generic serif:

```css
font-family: 'Source Serif 4', 'Source Serif Pro', 'LXGW WenKai TC', 'Noto Serif SC', Georgia, serif;
```

Browsers per-glyph fall back: Latin characters render in Source Serif 4 at weight 500 with opsz engaged, Chinese characters render in LXGW WenKai (display) or Noto Serif SC (body). The baseline mismatch at display sizes (96–220px) is the main thing to watch — LXGW WenKai sits slightly higher than Source Serif 4 in optical baseline, so a mixed-script line like "Designed in 北京" may show a 1–2px vertical wobble. Acceptable for slide content; for printed export, prefer all-CJK or all-Latin lines.

### Loading

Add to the existing Google Fonts `<link>` (or as a second link tag):

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=LXGW+WenKai+TC&family=Noto+Serif+SC:wght@400;500;700&display=swap" rel="stylesheet">
```

LXGW WenKai TC is the version served on Google Fonts (the Simplified-Chinese build `LXGW+WenKai+SC` is not yet on the Google CDN — TC ships both traditional and simplified glyphs and works for both).

### Universal CJK Adjustments

These adjustments apply to **every CJK block** in this system, regardless of size or role:

- **Loosen line-height by 0.05–0.08.** CJK glyphs are full-width squares with more visual weight than Latin letterforms; line-heights tuned for Latin (0.92–1.0 on display, 1.32–1.38 on body) read as cramped in Chinese. Bump display to 1.0–1.1 and body to 1.5–1.6.
- **Remove negative letter-spacing on CJK headlines.** Source Serif 4 display uses -0.01em to -0.03em tracking, which collides Chinese glyphs into each other. For CJK runs, set `letter-spacing: 0` — or a tiny positive `0.02em` if the headline feels visually packed.
- **Never `text-transform: uppercase` on CJK text.** Chinese has no case; the CSS property does nothing on Han glyphs but will silently break any mixed-script line where the Latin portion was meant to be capitalized.
- **Use Chinese full-width punctuation** (`，。：；！？「」『』（）`) inside Chinese sentences, not the Latin equivalents (`,.:;!?""''()`). Mixing punctuation systems within one sentence reads as a typesetting error.
- **No period (。) at the end of CJK headlines.** Chinese headlines follow the same rule as Latin — title-style lines drop terminal punctuation. Body paragraphs keep their 。
- **Apply Pangu spacing (盘古之白) at the boundary between CJK and Latin runs.** A space (or 0.25em margin) belongs between a Chinese character and an adjacent Latin word or digit, e.g. `2026 年 5 月` not `2026年5月`. Either type the spaces manually or use a `pangu.js`-style auto-spacer.
- **One font per sentence.** Don't switch between LXGW WenKai and Noto Serif SC inside the same sentence — pick the face that matches the size tier (display = LXGW WenKai, body = Noto Serif SC) and commit to it for the whole run.

### Aesthetic Notes for This System

Editorial Forest's whole voice is "Penguin classic / quiet annual report" — a serif at weight 500 with the optical-size axis doing the size-aware letterform work. The Chinese equivalent of that register is **LXGW WenKai for display moments** (it has the same hand-set, slightly informal warmth as Source Serif 4 at 500) and **Noto Serif SC at 400 for body** (the calm Mincho voice that reads like a literary journal). Avoid Noto Sans SC for body — the sans face flips the system into "tech report" rather than "monograph spread."

The system's mono / serif role split (JetBrains Mono for chrome, Source Serif 4 for everything else) maps cleanly onto Chinese. Use Noto Sans Mono CJK SC for the topbar label, footline strings, tile ordinals, and axis ticks — keep them uppercase-equivalent (i.e., 0.14em–0.18em letter-spacing on Latin labels, and for Chinese, the Mono CJK face at 500 weight provides the same chrome quality). Do not run Chinese labels in LXGW WenKai or Noto Serif SC; the editorial chrome would lose its typewriter feel.

### Known CJK Gap

LXGW WenKai's brushwork warmth is its strength at large display sizes, but at body scale (26–32px) the same brushwork reads slightly noisy. The system bumps body to Noto Serif SC (a cleaner Mincho) to avoid this, but the visual handoff between a 96px LXGW WenKai headline and a 30px Noto Serif SC paragraph below it is the system's biggest CJK seam — the two faces have different stroke contrast profiles. If the seam reads loud, use Noto Serif SC for both display and body (sacrifices warmth for consistency), or use LXGW WenKai for both (sacrifices body legibility for consistency). The default split is the right trade-off for most decks, but worth a manual check on cover and statement slides.

## Iteration Guide

1. Any new headline is Source Serif 4 weight 500 with negative letter-spacing. Pick the size from the display ladder (220 / 140 / 96 / 84 / 80 / 68 / 56) — do not invent a new size.
2. Any new label, caption, or tag is JetBrains Mono weight 500 uppercase with 0.08em–0.18em letter-spacing. Pick the size from the mono ladder (26 / 24).
3. Any new slide carries a topbar at the top. The mono label color follows the surface (pink-on-green, green-on-cream, green-deep-on-pink).
4. Any new card uses 6px (topic tile) or 8px (step tile) radius. The monogram circle is the only fully round shape; do not introduce a fourth radius.
5. Any new section separator is a 2px hairline rule in the region's accent color. No 1px rules, no 3px rules.
6. Any new fill color must come from the existing palette (`{colors.green}`, `{colors.green-lite}`, `{colors.pink}`, `{colors.cream}`, `{colors.cream-2}`). Do not introduce a yellow, blue, or third pink.
7. Any new body paragraph is serif weight 400 at 26–32px. Do not run body at weight 500.
8. Any new KPI figure is `{typography.stat-figure}` (220px). Smaller KPI sizes are not in the system — if the layout can't accommodate 220px, restructure the slide.
9. Any new chart uses the bar treatment (pink / cream / green fills, mono axes, 2px axis rules) on a green surface. The data composition is part of the system identity.
10. When in doubt, reach for fewer elements at larger sizes. The system's editorial register collapses when crowded.

## Known Gaps

- The system depends on `deck-stage.js` for canvas scaling and slide navigation. The script is not described in this design.md — treat it as a runtime dependency.
- Source Serif 4 and JetBrains Mono are loaded from Google Fonts via `<link>`. Offline rendering will fall back to Georgia serif and Menlo mono respectively, which will preserve the rough character but lose the optical-size axis and the JetBrains Mono identity. Self-hosting recommended for offline / print reliability.
- The Source Serif 4 optical-size axis (`opsz` 8..60) is critical to the system's quality — using a non-opsz fallback face flattens the size-aware letterform contrast.
- The bar chart uses hand-set bar heights (`%` of a fixed 520px plot region). There is no data-binding — extending the chart requires manually computing heights.
- The monogram circle, footline strings, and tile counters carry hardcoded text in the source. Replacing them with a deck's actual identity is required per-deck.
- The system has no `@media print` rule and no responsive breakpoints — it is fixed 1920×1080 and relies on `deck-stage.js` for any viewport adaptation.
- The green-on-pink and pink-on-green text contrast ratios are sufficient at the display sizes used (84px+) but would fail WCAG AA at body-text sizes. Do not put 26px body text in pink-on-green or green-on-pink — keep small text in cream-on-green or ink-on-cream.
````

---

## 2. 글씨체

- 이 디자인의 한글 글씨체: 제목 HS활공명조(400) · 본문 Cafe24 Oneprettynight(400). (쓰는 폰트: HS활공명조, Cafe24 Oneprettynight)
- 글씨체 파일은 공통 CSS(5)의 `@font-face`가 인터넷의 폰트 창고(`https://maker-ssam.github.io/korean-ofl-fonts/…`)에서 불러옵니다. 설치하지 않아도 되지만 열 때 인터넷이 필요합니다.
- 글씨체 규칙(굵기·크기·자간)은 1의 디자인 규칙을 따르고, 한글 폰트는 변수(`--kt` 제목, `--kb` 본문, `--ka` 포인트)로만 지정하세요.

---

## 3. 부품 사전 (이 디자인의 CSS에 정의된 클래스)

이 목록과 공통 CSS(5)에 있는 클래스만 쓰세요. '○장'은 아래 뼈대에서 그 클래스를 쓴 예시 장이고, '예'는 그 장의 실제 태그입니다. 장 구성은 따라 하지 말고, 필요한 부품을 골라 어느 장에서든 쓰면 됩니다. 클래스를 조합하는 방법(어떤 부품 안에 어떤 부품이 들어가는지)은 뼈대의 예시 장을 보고 따르세요.
- 여러 장에서 쓰인 클래스는 이 디자인의 공통 부품입니다(창·제목줄·버튼·표 등).
- 한 장에서만 쓰인 클래스 중 크기·위치를 정하는 것(이름에 번호가 붙은 창·격자 등)은 **그 예시 장 전용 배치**입니다. 같은 배치를 다시 쓸 때만 쓰고, 새 배치가 필요하면 비슷한 이름을 지어 쓰지 말고 '추가 부품' 칸에 직접 정의하세요.
- 예시 장의 측정기 그림(`g-…` 클래스)은 예시 주제 전용이라 이 목록에 없습니다. 새 주제의 그림은 SVG로 새로 그리세요.

**1장(표지)에서 처음 나오는 부품**
- `.foot` — 1·2·3·4·5·6장 — 예: `<div class="foot">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.gl` — 1장 — 예: `<span class="lab gl">`
- `.green` — 1·2·3·4·5·6장 — 예: `<section class="slide green">`
- `.lab` — 1·6장 — 예: `<span class="lab gl">`
- `.mdl` — 1·3장 — 예: `<dl class="mdl">`
- `.mono-c` — 1·6장 — 예: `<div class="mono-c">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide green">`
- `.t1` — 1장 — 예: `<h1 class="t1">`
- `.topbar` — 1·2·3·4·5·6장 — 예: `<div class="topbar">`
- `.unit` — 1장 — 예: `<p class="unit">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.bt` — 2·5·6장 — 예: `<button class="bt go" data-act="step">`
- `.btns` — 2장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quo…`
- `.cream` — 2·4·6장 — 예: `<section class="slide cream" data-steps="4">`
- `.cream2` — 2·4·5·6장 — 예: `<div class="tile st cream2" data-s="1">`
- `.fig` — 2장 — 예: `<div class="tile fig">`
- `.go` — 2장 — 예: `<button class="bt go" data-act="step">`
- `.hd` — 2·3·4·5·6장 — 예: `<h2 class="hd">`
- `.lite` — 2·4·6장 — 예: `<div class="tile st lite" data-s="4">`
- `.note` — 2장 — 예: `<p class="note">`
- `.ord` — 2·3·4·5·6장 — 예: `<span class="ord">`
- `.pink` — 2·4·6장 — 예: `<div class="tile st pink" data-s="3">`
- `.st` — 2장 — 예: `<div class="tile st cream2" data-s="1">`
- `.steps` — 2장 — 예: `<div class="steps">`
- `.tile` — 2·4·5·6장 — 예: `<div class="tile fig">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.a` — 3·6장 — 예: `<i class="bar a" style="height:139px">`
- `.bar` — 3장 — 예: `<i class="bar a" style="height:139px">`
- `.chart` — 3장 — 예: `<div class="chart">`
- `.cr` — 3장 — 예: `<i class="sw cr">`
- `.grp` — 3장 — 예: `<div class="grp">`
- `.kpi` — 3장 — 예: `<div class="kpi">`
- `.legend` — 3장 — 예: `<div class="legend">`
- `.m3` — 3장 — 예: `<dl class="mdl m3">`
- `.pk` — 3장 — 예: `<i class="sw pk">`
- `.plot` — 3장 — 예: `<div class="plot">`
- `.s` — 3장 — 예: `<i class="bar s" style="height:189px">`
- `.sf` — 3장 — 예: `<b class="sf">`
- `.src` — 3장 — 예: `<p class="src">`
- `.sw` — 3장 — 예: `<i class="sw cr">`
- `.trow` — 3장 — 예: `<div class="trow">`
- `.v2` — 3장 — 예: `<span class="val v2">`
- `.val` — 3장 — 예: `<span class="val">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cmp` — 4장 — 예: `<div class="cmp">`
- `.lst` — 4장 — 예: `<div class="tile tt lite lst">`
- `.qt` — 4장 — 예: `<blockquote class="qt">`
- `.tbl` — 4장 — 예: `<div class="tile tt cream2 tbl">`
- `.th` — 4장 — 예: `<div class="tr th">`
- `.tr` — 4장 — 예: `<div class="tr th">`
- `.tt` — 4·5장 — 예: `<div class="tile tt green">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bl` — 5장 — 예: `<p class="bl">`
- `.blank` — 5장 — 예: `<button class="blank" data-blank aria-pressed="false">`
- `.blk` — 5장 — 예: `<div class="tile tt green blk">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.opt` — 5장 — 예: `<button class="opt" data-opt="0">`
- `.opts` — 5장 — 예: `<div class="opts">`
- `.ot` — 5장 — 예: `<span class="ot">`
- `.pinkbg` — 5장 — 예: `<section class="slide pinkbg">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.quiz` — 5장 — 예: `<div class="tile tt cream2 quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" dat…`
- `.rt` — 5장 — 예: `<button class="bt rt" data-act="retry">`
- `.wl` — 5장 — 예: `<span class="ord wl">`
- `.words` — 5장 — 예: `<p class="words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.ab6` — 6장 — 예: `<p class="ab6">`
- `.b` — 6장 — 예: `<div class="tile cream2 d6 b">`
- `.br6` — 6장 — 예: `<div class="br6" id="ef-bar">`
- `.c` — 6장 — 예: `<div class="tile cream2 d6 c">`
- `.d6` — 6장 — 예: `<div class="tile cream2 d6 a">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.dl6` — 6장 — 예: `<dl class="dl6">`
- `.g6` — 6장 — 예: `<div class="g6">`
- `.lab6` — 6장 — 예: `<span class="lab6">`
- `.m6` — 6장 — 예: `<span class="mono-c m6" id="ef-mono">`
- `.mc6` — 6장 — 예: `<div class="mc6">`
- `.sl6` — 6장 — 예: `<span class="lab sl6">`
- `.sm` — 6장 — 예: `<button class="bt sm" data-demo="#ef-tile" data-mode="toggle" aria-pressed="false">`
- `.sw6` — 6장 — 예: `<dd class="sw6">`
- `.tl6` — 6장 — 예: `<div class="tl6" id="ef-tile">`
- `.v6` — 6장 — 예: `<em class="v6">`

**예시 장에는 없지만 CSS에 정의된 클래스**(디자인 규칙에 맞으면 써도 됨): `.lt` `.mx`

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.on` `.now` `.open` `.right` `.wrong` `.play` `.solved` `.tried` `.active` `.visible` `.flash` `.in-frame`)와 내비 클래스(`.dk-…`)는 배치용으로 쓰지 마세요(뼈대의 내비 부분은 그대로 둡니다).

---

## 4. HTML 뼈대 (예시 덱 6장 — 부품 견본입니다. 장 구성은 따라 하지 말고, 공통 파일 두 줄은 그대로 두며, 장은 내용에 맞게 새로 구성)

```html
<!DOCTYPE html>
<html lang="ko" data-template="editorial-forest">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>계절의 변화</title>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Source+Serif+4:opsz,wght@8..60,400;8..60,500&family=JetBrains+Mono:wght@500&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/editorial-forest.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide green">
  <div class="topbar"><span>초등 과학 · 6학년 2학기</span></div>
  <div class="mono-c">SCI</div>
  <p class="unit">계절의 변화<span>Sun, Shadow & Temperature</span></p>
  <span class="lab gl">학습 목표</span>
  <h1 class="t1">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1>
  <dl class="mdl"><div><dt>SCHOOL</dt><dd>00초등학교</dd></div><div><dt>UNIT</dt><dd>1단원 · 3~4차시</dd></div><div><dt>YEAR</dt><dd>2026</dd></div></dl>
  <div class="foot"><span>Sun, Shadow & Temperature</span><span>01 / 06</span></div>
</section>
<section class="slide cream" data-steps="4">
  <div class="topbar"><span>측정 준비</span><span>02 / 06</span></div>
  <h2 class="hd">태양 고도 측정기 만들기</h2>
  <div class="tile fig"><span class="ord">FIG. 01 — 태양 고도 측정기</span><svg class="gauge" viewBox="0 0 1000 660" role="img" aria-label="태양 고도 측정기: 태양 빛, 수수깡, 실, 태양 고도, 그림자 길이, 자, 각도기">
  <line class="g-ground" x1="20" x2="980" y1="580" y2="580"/>
  <rect class="g-board" x="80" y="540" width="860" height="40"/>
  <g class="g-part" data-s="1"><rect class="g-ruler" x="110" y="524" width="800" height="16"/><line class="g-tick" x1="120" x2="120" y1="524" y2="536"/><line class="g-tick" x1="140" x2="140" y1="524" y2="530"/><line class="g-tick" x1="160" x2="160" y1="524" y2="530"/><line class="g-tick" x1="180" x2="180" y1="524" y2="530"/><line class="g-tick" x1="200" x2="200" y1="524" y2="530"/><line class="g-tick" x1="220" x2="220" y1="524" y2="536"/><line class="g-tick" x1="240" x2="240" y1="524" y2="530"/><line class="g-tick" x1="260" x2="260" y1="524" y2="530"/><line class="g-tick" x1="280" x2="280" y1="524" y2="530"/><line class="g-tick" x1="300" x2="300" y1="524" y2="530"/><line class="g-tick" x1="320" x2="320" y1="524" y2="536"/><line class="g-tick" x1="340" x2="340" y1="524" y2="530"/><line class="g-tick" x1="360" x2="360" y1="524" y2="530"/><line class="g-tick" x1="380" x2="380" y1="524" y2="530"/><line class="g-tick" x1="400" x2="400" y1="524" y2="530"/><line class="g-tick" x1="420" x2="420" y1="524" y2="536"/><line class="g-tick" x1="440" x2="440" y1="524" y2="530"/><line class="g-tick" x1="460" x2="460" y1="524" y2="530"/><line class="g-tick" x1="480" x2="480" y1="524" y2="530"/><line class="g-tick" x1="500" x2="500" y1="524" y2="530"/><line class="g-tick" x1="520" x2="520" y1="524" y2="536"/><line class="g-tick" x1="540" x2="540" y1="524" y2="530"/><line class="g-tick" x1="560" x2="560" y1="524" y2="530"/><line class="g-tick" x1="580" x2="580" y1="524" y2="530"/><line class="g-tick" x1="600" x2="600" y1="524" y2="530"/><line class="g-tick" x1="620" x2="620" y1="524" y2="536"/><line class="g-tick" x1="640" x2="640" y1="524" y2="530"/><line class="g-tick" x1="660" x2="660" y1="524" y2="530"/><line class="g-tick" x1="680" x2="680" y1="524" y2="530"/><line class="g-tick" x1="700" x2="700" y1="524" y2="530"/><line class="g-tick" x1="720" x2="720" y1="524" y2="536"/><line class="g-tick" x1="740" x2="740" y1="524" y2="530"/><line class="g-tick" x1="760" x2="760" y1="524" y2="530"/><line class="g-tick" x1="780" x2="780" y1="524" y2="530"/><line class="g-tick" x1="800" x2="800" y1="524" y2="530"/><line class="g-tick" x1="820" x2="820" y1="524" y2="536"/><line class="g-tick" x1="840" x2="840" y1="524" y2="530"/><line class="g-tick" x1="860" x2="860" y1="524" y2="530"/><line class="g-tick" x1="880" x2="880" y1="524" y2="530"/><line class="g-tick" x1="900" x2="900" y1="524" y2="530"/><text class="g-lb" x="922" y="516" text-anchor="start">자</text></g>
  <g class="g-meas"><rect class="g-shadow" x="220" y="524" width="446" height="16"/>
    <path class="g-dim" d="M220 600v24M666 600v24M220 612H666"/><text class="g-lb" x="443" y="652" text-anchor="middle">그림자 길이</text></g>
  <g class="g-part" data-s="2"><rect class="g-stick" x="196" y="150" width="24" height="374"/><path class="g-mark" d="M220 504h20v20"/>
    <path class="g-lead" d="M182 330H196"/><text class="g-lb" x="174" y="342" text-anchor="end">수수깡</text></g>
  <g class="g-part" data-s="4"><path class="g-prot" d="M546 524A120 120 0 0 1 786 524Z"/><path class="g-prot2" d="M588 524A78 78 0 0 1 744 524"/><line class="g-tick" x1="570" y1="524" x2="546" y2="524"/><line class="g-tick" x1="561.6" y1="505.6" x2="547.8" y2="503.2"/><line class="g-tick" x1="566.4" y1="487.7" x2="553.2" y2="483"/><line class="g-tick" x1="582.9" y1="476" x2="562.1" y2="464"/><line class="g-tick" x1="584.8" y1="455.9" x2="574.1" y2="446.9"/><line class="g-tick" x1="597.9" y1="442.8" x2="588.9" y2="432.1"/><line class="g-tick" x1="618" y1="440.9" x2="606" y2="420.1"/><line class="g-tick" x1="629.7" y1="424.4" x2="625" y2="411.2"/><line class="g-tick" x1="647.6" y1="419.6" x2="645.2" y2="405.8"/><line class="g-tick" x1="666" y1="428" x2="666" y2="404"/><line class="g-tick" x1="684.4" y1="419.6" x2="686.8" y2="405.8"/><line class="g-tick" x1="702.3" y1="424.4" x2="707" y2="411.2"/><line class="g-tick" x1="714" y1="440.9" x2="726" y2="420.1"/><line class="g-tick" x1="734.1" y1="442.8" x2="743.1" y2="432.1"/><line class="g-tick" x1="747.2" y1="455.9" x2="757.9" y2="446.9"/><line class="g-tick" x1="749.1" y1="476" x2="769.9" y2="464"/><line class="g-tick" x1="765.6" y1="487.7" x2="778.8" y2="483"/><line class="g-tick" x1="770.4" y1="505.6" x2="784.2" y2="503.2"/><line class="g-tick" x1="762" y1="524" x2="786" y2="524"/><circle class="g-hole" cx="666" cy="524" r="5"/><text class="g-lb" x="800" y="456" text-anchor="start">각도기</text></g>
  <g class="g-part" data-s="3"><line class="g-string" x1="220" y1="150" x2="666" y2="524"/><text class="g-lb" x="478" y="344" text-anchor="start">실</text></g>
  <g class="g-meas"><path class="g-angle" d="M616 524A50 50 0 0 1 627.7 491.9"/><path class="g-lead" d="M542 498L615 506.9"/><text class="g-lb" x="536" y="508" text-anchor="end">태양 고도</text>
    <line class="g-ray" x1="74.5" y1="27.9" x2="187.8" y2="123"/><polygon class="g-rayh" points="209.3,141 179.5,133 196.2,113"/><text class="g-lb" x="150" y="60" text-anchor="start">태양 빛</text></g>
</svg></div>
  <p class="note">막대기의 그림자와 실이 이루는 각 = 태양 고도</p>
  <div class="steps"><div class="tile st cream2" data-s="1"><span class="ord">STEP 01</span><div><h3>자 붙이기</h3><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div></div><div class="tile st green" data-s="2"><span class="ord">STEP 02</span><div><h3>수수깡 꽂기</h3><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div></div><div class="tile st pink" data-s="3"><span class="ord">STEP 03</span><div><h3>실 묶기</h3><p>수수깡 끝에 실을 묶어요</p></div></div><div class="tile st lite" data-s="4"><span class="ord">STEP 04</span><div><h3>각도기 끼우기</h3><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
  <div class="btns"><button class="bt go" data-act="step">다음 단계 →</button><button class="bt" data-act="reset">처음부터</button><p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quot;03 — 실 묶기&quot;,&quot;04 — 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</p></div>
  <div class="foot"><span>버튼 규칙 없음 → 2.5px 테두리 칸으로 표현</span><span>계절의 변화</span></div>
</section>
<section class="slide green">
  <div class="topbar"><span>측정 결과</span><span>예시 값 · 03 / 06</span></div>
  <h2 class="hd">하루 동안 무엇이 어떻게 변할까요?</h2>
  <div class="kpi"><span class="ord">남중 시각</span><b class="sf">12:30</b><p>태양 고도가 가장 높아요</p></div>
  <div class="chart">
    <div class="legend"><span><i class="sw cr"></i>태양 고도(°)</span><span><i class="sw pk"></i>그림자 길이(cm)</span><span>아래 숫자 = 기온(℃)</span></div>
    <div class="plot"><div class="grp"><i class="bar a" style="height:139px"><span class="val">38°</span></i><i class="bar s" style="height:189px"><span class="val v2">12.9</span></i><b>9:30</b></div><div class="grp"><i class="bar a" style="height:176px"><span class="val">48°</span></i><i class="bar s" style="height:133px"><span class="val v2">9.1</span></i><b>10:30</b></div><div class="grp"><i class="bar a" style="height:202px"><span class="val">55°</span></i><i class="bar s" style="height:103px"><span class="val v2">7</span></i><b>11:30</b></div><div class="grp"><i class="bar a" style="height:209px"><span class="val">57°</span></i><i class="bar s" style="height:94px"><span class="val v2">6.4</span></i><b>12:30</b></div><div class="grp"><i class="bar a" style="height:198px"><span class="val">54°</span></i><i class="bar s" style="height:106px"><span class="val v2">7.2</span></i><b>13:30</b></div><div class="grp"><i class="bar a" style="height:172px"><span class="val">47°</span></i><i class="bar s" style="height:138px"><span class="val v2">9.4</span></i><b>14:30</b></div><div class="grp"><i class="bar a" style="height:136px"><span class="val">37°</span></i><i class="bar s" style="height:197px"><span class="val v2">13.4</span></i><b>15:30</b></div></div>
    <div class="trow"><span>22</span><span>23.8</span><span>25.2</span><span>26.3</span><span>27</span><span>27.4</span><span>26.9</span></div>
  </div>
  <dl class="mdl m3"><div><dt>남중 방향</dt><dd>정남 <small>남중할 때 태양의 위치</small></dd></div><div><dt>최고 기온</dt><dd>14:30 <small>기온이 가장 높아요</small></dd></div><div><dt>가장 긴 그림자</dt><dd>9:30 <small>그림자가 가장 길어요</small></dd></div></dl>
  <p class="src">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</p>
  <div class="foot"><span>00초등학교</span><span>1단원 · 3~4차시</span></div>
</section>
<section class="slide cream">
  <div class="topbar"><span>관계 정리</span><span>04 / 06</span></div>
  <h2 class="hd">태양 고도가 바뀌면 무엇이 달라질까요?</h2>
  <div class="cmp"><div class="tile tt green"><span class="ord">HIGH</span><h3>태양 고도가 높을 때</h3><p>그림자 길이는 짧아져요</p><p>기온은 높아져요</p></div><div class="tile tt pink"><span class="ord">LOW</span><h3>태양 고도가 낮을 때</h3><p>그림자 길이는 길어져요</p><p>기온은 낮아져요</p></div></div>
  <div class="tile tt lite lst"><span class="ord">남중</span><p>태양이 정남쪽에 있을 때 '남중했다'고 해요</p><p>이때의 태양 고도를 남중 고도라고 해요</p></div>
  <div class="tile tt cream2 tbl"><span class="ord">시각별 변화</span><div class="tr th"><span>시각</span><span>태양 고도</span><span>그림자 길이</span><span>기온</span></div><div class="tr"><span>오전 9:30</span><span>낮아요</span><span>길어요</span><span>낮아요</span></div><div class="tr"><span>낮 12:30</span><span>가장 높아요</span><span>가장 짧아요</span><span>높아지는 중</span></div><div class="tr"><span>오후 14:30</span><span>낮아지는 중</span><span>길어지는 중</span><span>가장 높아요</span></div></div>
  <blockquote class="qt"><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span class="ord">— 오늘의 정리</span></blockquote>
  <div class="foot"><span>표 규칙 없음 → 토픽 타일 + 2px 줄으로 표현</span><span>계절의 변화</span></div>
</section>
<section class="slide pinkbg">
  <div class="topbar"><span>확인하기</span><span>05 / 06</span></div>
  <h2 class="hd">배운 내용을 확인해 볼까요?</h2>
  <div class="tile tt cream2 quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
    <span class="ord">QUESTION</span>
    <h3 class="q">하루 중 그림자 길이가 가장 짧을 때는?</h3>
    <div class="opts"><button class="opt" data-opt="0"><span class="ord">01</span><span class="ot">오전 9시 30분</span></button><button class="opt" data-opt="1"><span class="ord">02</span><span class="ot">낮 12시 30분 무렵</span></button><button class="opt" data-opt="2"><span class="ord">03</span><span class="ot">오후 3시 30분</span></button></div>
    <p class="fb" data-fb></p>
    <button class="bt rt" data-act="retry">다시 풀기 ↺</button>
  </div>
  <div class="tile tt green blk">
    <span class="ord">빈칸을 눌러 확인해요</span>
    <p class="bl"><button class="blank" data-blank aria-pressed="false"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</p><p class="bl"><button class="blank" data-blank aria-pressed="false"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</p><p class="bl"><button class="blank" data-blank aria-pressed="false"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</p>
    <span class="ord wl">오늘의 낱말</span>
    <p class="words">태양 고도 · 남중 고도 · 그림자 길이 · 기온</p>
  </div>
  <div class="foot"><span>빈칸 규칙 없음 → 2px 테두리 칸으로 표현</span><span>00초등학교</span></div>
</section>
<section class="slide cream">
  <div class="topbar"><span>디자인 안내</span><span>06 / 06</span></div>
  <h2 class="hd">이 디자인 사용 설명서</h2>
  <div class="g6">
    <span class="lab6">한눈에</span>
    <p class="ab6">문학 계간지·아트북처럼 <b>숲 초록 · 먼지 장미 · 귀리 크림</b> 세 색으로만 씁니다. 장마다 바탕 하나 — 표지·데이터는 초록, 내용은 크림, 마무리는 장미.</p>
    <dl class="dl6">
      <div><dt>색</dt><dd class="sw6"><span><i style="background:#2e4a2a"></i>숲 초록</span><span><i style="background:#e89cb1"></i>먼지 장미</span><span><i style="background:#efe7d4"></i>귀리 크림</span><span><i style="background:#3a5a36"></i>연초록</span></dd></div>
      <div><dt>글꼴</dt><dd>제목 Source Serif 4 500 → HS활공명조<br>본문 → Cafe24 Oneprettynight<br>라벨 JetBrains Mono</dd></div>
      <div><dt>이렇게 쓰면 좋아요</dt><dd>읽기 자료·작품 감상처럼 차분한 수업. 작은 글자는 분홍·초록 대비 위에 두지 말고 크림 위에.</dd></div>
    </dl>
  </div>
  <span class="lab sl6">대표 장치 — 눌러 보세요</span>
  <div class="tile cream2 d6 a"><div class="dh"><h3>스텝 타일 순환</h3><button class="bt sm" data-demo="#ef-tile" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>단계 타일 채움은 크림2 → 초록 → 장미 → 연초록 차례로.</p><div class="tl6" id="ef-tile"><span class="tile cream2"><b class="ord">01</b></span><span class="tile green"><b class="ord">02</b></span><span class="tile pink"><b class="ord">03</b></span><span class="tile lite"><b class="ord">04</b></span></div></div>
  <div class="tile cream2 d6 b"><div class="dh"><h3>막대 위 모노 값</h3><button class="bt sm" data-demo="#ef-bar" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>막대는 위 모서리만 3px 둥글게, 값은 막대 위에 모노 글자로.</p><div class="br6" id="ef-bar"><span><em class="v6">38°</em><i class="pink" style="height:27px"></i></span><span><em class="v6">57°</em><i class="green" style="height:40px"></i></span><span><em class="v6">47°</em><i class="cream" style="height:33px"></i></span></div></div>
  <div class="tile cream2 d6 c"><div class="dh"><h3>모노그램 원</h3><button class="bt sm" data-demo="#ef-mono" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>표지 오른쪽 위 130px 원 — 분홍 2px 선 안에 모노 글자 세 개.</p><div class="mc6"><span class="mono-c m6" id="ef-mono">SCI</span></div></div>
  <div class="foot"><span>Sun, Shadow & Temperature</span><span>계절의 변화</span></div>
</section>
<nav class="dk-nav"><button class="dk-prev" aria-label="이전">←</button><span class="dk-dots"><button class="dk-dot" aria-label="1장"></button><button class="dk-dot" aria-label="2장"></button><button class="dk-dot" aria-label="3장"></button><button class="dk-dot" aria-label="4장"></button><button class="dk-dot" aria-label="5장"></button><button class="dk-dot" aria-label="6장"></button></span><button class="dk-next" aria-label="다음">→</button></nav>
  </main>
</div>

<!-- 슬라이드 넘김·단계 버튼·퀴즈 엔진. 이 줄은 지우거나 바꾸지 마세요 -->
<script src="https://k-slide.web.app/kit/v1/editorial-forest.js"></script>
</body>
</html>
```

---

## 5. 참고: 공통 CSS와 엔진 사용법 (뼈대가 이미 불러옴 — HTML에 옮겨 쓰지 마세요)

아래는 `https://k-slide.web.app/kit/v1/editorial-forest.css`의 내용과 엔진(`https://k-slide.web.app/kit/v1/editorial-forest.js`)의 사용법 주석입니다. 클래스의 모양·크기·배치를 이해하는 데에만 쓰세요. 이 내용을 `<style>`이나 `<script>`에 넣으면 안 됩니다.

```css
/* editorial-forest — k-slide 공통 CSS v1 (채팅 AI용 받기 .md가 불러옴, 고치지 말 것) */
/* === KOREAN FONTS === */
@font-face{font-family:'kp-21';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/hshwalkongserif-regular/HSHwalkongSerif-Regular.woff2") format("woff2");font-weight:400}
@font-face{font-family:'kp-9';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/cafe24-oneprettynight/Cafe24Oneprettynight-v2.0.woff2") format("woff2");font-weight:400}
/* === THEME === */
:root{--stage-bg:#2e4a2a;--slide-bg:#2e4a2a;
  --kt:'kp-21';--kb:'kp-9';--ka:'kp-9';
  --wt:400;--wb:400}
*{margin:0;padding:0;box-sizing:border-box}
body{font-synthesis:none;word-break:keep-all;letter-spacing:0}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
button:disabled{cursor:default}
/* === VIEWPORT BASE (frontend-slides, mandatory) === */
/* ===========================================
   FIXED 16:9 STAGE: MANDATORY BASE STYLES
   Include this ENTIRE file in every presentation.
   Slides are authored at 1920×1080 and scaled as a whole.
   =========================================== */

/* 1. Lock the browser viewport */
html,
body {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
    background: var(--stage-bg, #000);
}

/* 2. Full-window deck viewport */
.deck-viewport {
    position: fixed;
    inset: 0;
    overflow: hidden;
    background: var(--stage-bg, #000);
}

/* 3. Fixed 16:9 design canvas.
   JavaScript sets transform: translate(...) scale(...). */
.deck-stage {
    position: absolute;
    left: 0;
    top: 0;
    width: 1920px;
    height: 1080px;
    overflow: hidden;
    transform-origin: 0 0;
    background: var(--slide-bg, #fff);
}

/* 4. Slides stack inside the fixed stage.
   Content must be laid out at 1920×1080, not reflowed per device. */
.slide {
    position: absolute;
    inset: 0;
    width: 1920px;
    height: 1080px;
    overflow: hidden;
    display: block;
    visibility: hidden;
    opacity: 0;
    pointer-events: none;
    background: var(--slide-bg, #fff);
}

.slide.active,
.slide.visible {
    visibility: visible;
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
}

/* 5. Keep media inside authored slide bounds */
img,
video,
canvas,
svg {
    max-width: 100%;
    max-height: 100%;
}

/* 6. Presentation chrome stays outside the slide design system */
.deck-controls {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    z-index: 1000;
}

/* 7. Print one fixed-size slide per page */
@media print {
    html,
    body {
        width: 1920px;
        height: auto;
        overflow: visible;
        background: #fff;
    }

    .deck-viewport {
        position: static;
        overflow: visible;
        background: #fff;
    }

    .deck-stage {
        position: static;
        width: auto;
        height: auto;
        transform: none !important;
        background: none;
    }

    .slide {
        position: relative;
        display: block !important;
        visibility: visible !important;
        opacity: 1 !important;
        pointer-events: auto !important;
        width: 1920px;
        height: 1080px;
        break-after: page;
        page-break-after: always;
    }

    .slide:last-child {
        break-after: auto;
        page-break-after: auto;
    }

    .deck-controls {
        display: none !important;
    }
}

/* 8. Reduced motion */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.2s !important;
    }
}

/* 동작 줄이기(Windows '애니메이션 효과' 끔 등): 위 규칙이 길이를 0.01ms로 줄이면 반복 애니메이션이 깜빡이듯 빨라짐 → 반복은 한 번만 */
@media (prefers-reduced-motion: reduce){*,*::before,*::after{animation-iteration-count:1 !important}}
.dk-nav{position:absolute;z-index:50}


/* === 측정기 그림(figure-gauge.js) 기본 === */
.gauge{display:block;width:100%;height:auto;overflow:visible;--g-sw:2.5}
.gauge .g-lb{font-family:var(--g-font,var(--kb));font-size:40px;font-weight:700;fill:var(--g-ink,currentColor)}
.gauge .g-ground{stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw);opacity:.35}
.gauge .g-board{fill:var(--g-board,none);stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw)}
.gauge .g-ruler{fill:var(--g-ruler,none);stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw)}
.gauge .g-tick{stroke:var(--g-ink,currentColor);stroke-width:1.5}
.gauge .g-stick{fill:var(--g-stick,var(--g-ink,currentColor));stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw)}
.gauge .g-mark,.gauge .g-lead,.gauge .g-dim,.gauge .g-angle{fill:none;stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw)}
.gauge .g-angle{stroke-width:4}
.gauge .g-shadow{fill:var(--g-shadow,var(--g-ink,currentColor));opacity:.6}
.gauge .g-string{stroke:var(--g-acc,var(--g-ink,currentColor));stroke-width:4}
.gauge .g-prot{fill:var(--g-prot,none);stroke:var(--g-ink,currentColor);stroke-width:var(--g-sw)}
.gauge .g-prot2{fill:none;stroke:var(--g-ink,currentColor);stroke-width:1.5}
.gauge .g-hole{fill:var(--g-ink,currentColor)}
.gauge .g-ray{stroke:var(--g-acc,var(--g-ink,currentColor));stroke-width:7}
.gauge .g-rayh{fill:var(--g-acc,var(--g-ink,currentColor))}
/* 만드는 중(1~3단계): 아직 안 만든 부품과 측정 표시는 흐리게 / 0·4단계는 모두 또렷 */
.slide[data-step="1"] .gauge .g-part:not(.on),.slide[data-step="2"] .gauge .g-part:not(.on),.slide[data-step="3"] .gauge .g-part:not(.on),
.slide[data-step="1"] .gauge .g-meas,.slide[data-step="2"] .gauge .g-meas,.slide[data-step="3"] .gauge .g-meas{opacity:var(--g-dim,.2)}

/* === TEMPLATE STYLES === */

/* --- 토큰 --- */
:root{--green:#2e4a2a;--gdeep:#243a21;--lite:#3a5a36;--pink:#e89cb1;--pdeep:#d27e96;--cream:#efe7d4;--cream2:#e6dcc4;--ink:#1a1a17}
.slide{font-family:'Source Serif 4',var(--kb),Georgia,serif;font-weight:var(--wb);font-optical-sizing:auto}
.slide>*{position:absolute}
.green{background:var(--green);color:var(--cream);--acc:var(--pink)}
.cream{background:var(--cream);color:var(--ink);--acc:var(--green)}
.pinkbg{background:var(--pink);color:var(--gdeep);--acc:var(--gdeep)}
.topbar,.foot,.ord,dt,.legend,.val,.mono-c,.lab{font-family:'JetBrains Mono',var(--kb),monospace;font-weight:500;text-transform:uppercase}
h3,.hd,.t1,.unit,.sf,.q,.qt p,dd{font-family:'Source Serif 4',var(--kt),serif;font-weight:var(--wt);letter-spacing:0}

/* --- 크롬: 상단줄 · 꼬리줄 · 모노그램 원 --- */
.topbar{left:120px;right:120px;top:84px;display:flex;justify-content:space-between;align-items:baseline;font-size:26px;letter-spacing:.18em;color:var(--acc)}
.foot{left:120px;right:120px;bottom:60px;display:flex;justify-content:space-between;gap:40px;font-size:22px;letter-spacing:.1em;color:var(--acc)}
.foot span{max-width:640px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mono-c{right:140px;top:56px;width:130px;height:130px;border:2px solid var(--pink);border-radius:50%;display:grid;place-items:center;font-size:28px;letter-spacing:.1em;color:var(--pink)}
.ord{font-size:24px;letter-spacing:.14em}
.hd{left:120px;right:120px;top:150px;font-size:84px;line-height:1.1;color:var(--acc)}
.green .hd{color:var(--cream)}
.tile{border-radius:6px;border:2.5px solid var(--green)}
.tile.cream2{background:var(--cream2);color:var(--green)}
.tile.green{background:var(--green);color:var(--pink);border-color:var(--green)}
.tile.pink{background:var(--pink);border-color:var(--pdeep);color:var(--gdeep)}
.tile.lite{background:var(--lite);border-color:var(--lite);color:var(--pink)}
.tile p{color:var(--ink)}
.tile.green p,.tile.lite p{color:var(--cream)}
.tile.pink p{color:var(--gdeep)}
.bt{border:2.5px solid var(--green);border-radius:6px;padding:14px 28px;font:500 30px/1 var(--kb);color:var(--green);background:transparent}
.bt.go{background:var(--green);color:var(--cream)}
.bt:disabled{opacity:.3}

/* --- 1. 표지(초록): 모노그램 원 + 단원(크림) + '학습 목표' + 학습 목표(분홍 display) + 3열 정의 목록 + 꼬리줄 --- */
.unit{left:136px;top:210px;display:flex;align-items:baseline;gap:30px;font-size:80px;line-height:1.1;white-space:nowrap}
.unit span{font:500 48px/1 'Source Serif 4',serif;letter-spacing:-.02em;color:rgba(239,231,212,.8)}
.lab{left:140px;font-size:26px;letter-spacing:.18em;color:var(--pink)}
.lab.gl{top:380px}
.t1{left:132px;top:430px;font-size:124px;line-height:1.16;color:var(--pink);white-space:nowrap}
.t1 .gk{font-style:normal}
.mdl{left:140px;right:140px;top:790px;display:grid;grid-template-columns:repeat(3,1fr);gap:36px;border-top:2px solid var(--pink);padding-top:22px}
dt{font-size:24px;letter-spacing:.14em;color:var(--pink)}
dd{margin-top:10px;font-size:34px}
dd small{display:block;margin-top:6px;font-family:'Source Serif 4',var(--kb),serif;font-weight:var(--wb);font-size:26px;line-height:1.4}

/* --- 2. 흐름(크림): 크림2 토픽 타일 속 측정기 그림 + 2px 초록 헤어라인 메모 | 스텝 타일 4장(순환 채움, 켜지면 또렷) + 버튼 --- */
.fig{left:120px;top:280px;width:860px;padding:20px 32px 10px;background:var(--cream2);
  --g-ink:var(--green);--g-acc:var(--pdeep);--g-stick:var(--green);--g-board:var(--pink);--g-ruler:var(--cream);--g-prot:rgba(239,231,212,.8);--g-shadow:var(--green);--g-font:'Source Serif 4',var(--kb),serif;--g-sw:2}
.note{left:120px;width:860px;top:880px;border-top:2px solid var(--green);padding-top:16px;font-family:'Source Serif 4',var(--kt),serif;font-weight:var(--wt);font-size:32px;line-height:1.35;color:var(--green)}
.steps{left:1030px;right:120px;top:280px;display:flex;flex-direction:column;gap:16px}
.st{border-radius:8px;padding:16px 26px;display:grid;grid-template-columns:150px 1fr;gap:14px;align-items:baseline}
.slide[data-step]:not([data-step="0"]) .st:not(.on){opacity:.35}
.st h3{font-size:40px;line-height:1.1}
.st p{margin-top:4px;font-size:26px;line-height:1.45}
.btns{left:1030px;right:120px;top:850px;display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center}
.cap{width:100%;font-size:26px;color:var(--green)}

/* --- 3. 데이터(초록): KPI(220px 세리프 숫자) | 막대(크림 = 태양 고도 · 가장 높은 막대 = 연초록 + 분홍 테두리, 분홍 = 그림자 길이) + 범례 + 기온 숫자 줄 / 3열 정의 목록 --- */
.kpi{left:120px;top:300px;width:620px;display:flex;flex-direction:column;gap:6px;border-top:2px solid var(--pink);padding-top:16px}
.kpi .ord{color:var(--pink)}
.sf{font-size:200px;line-height:.98;letter-spacing:-.03em;color:var(--pink)}
.kpi p{font-size:30px;line-height:1.38}
.chart{left:800px;right:120px;top:290px;display:flex;flex-direction:column;gap:10px}
.legend{display:flex;gap:30px;font-size:22px;letter-spacing:.08em;color:var(--pink)}
.legend span{display:flex;align-items:center;gap:10px}
.sw{display:inline-block;width:26px;height:26px;border-radius:2px}
.sw.pk{background:var(--pink)}.sw.cr{background:var(--cream)}.sw.lt{background:var(--lite);outline:2px solid var(--pink);outline-offset:-2px}
.plot{height:290px;display:grid;grid-template-columns:repeat(7,1fr);border-left:2px solid var(--pink);border-bottom:2px solid var(--pink);padding:0 10px}
.grp{position:relative;display:flex;align-items:flex-end;justify-content:center;gap:6px}
.bar{position:relative;display:block;width:40px;border-radius:3px 3px 0 0}
.bar.a{background:var(--cream)}.bar.a.mx{background:var(--lite);outline:2px solid var(--pink);outline-offset:-2px}
.bar.s{background:var(--pink)}
.val{position:absolute;bottom:calc(100% + 6px);font-size:22px;letter-spacing:.04em;color:var(--cream);white-space:nowrap}
.val{left:50%;transform:translateX(-50%)}
.v2{color:var(--pink)}
.grp b{position:absolute;left:0;right:0;bottom:-38px;text-align:center;font:500 22px 'JetBrains Mono',monospace;letter-spacing:.06em;color:var(--pink)}
.trow{margin-top:50px;display:grid;grid-template-columns:repeat(7,1fr);padding-left:12px;border-top:2px solid var(--pink);padding-top:10px;font-size:28px;text-align:center;position:relative}
.m3{left:120px;right:120px;top:770px}
.src{left:120px;right:120px;top:930px;font-size:20px;color:rgba(239,231,212,.75)}

/* --- 4. 비교와 표(크림): 토픽 타일(초록 · 분홍 · 연초록 · 크림2 + 초록선) + 인용 --- */
.tt{padding:22px 28px;display:flex;flex-direction:column;gap:6px}
.tt h3{margin:6px 0 4px;font-size:44px;line-height:1.1}
.tt p{font-size:28px;line-height:1.45}
.cmp{left:120px;width:1060px;top:270px;display:grid;grid-template-columns:1fr 1fr;gap:28px}
.lst{left:1220px;right:120px;top:270px}
.tbl{left:120px;width:1060px;top:560px}
.tr{display:grid;grid-template-columns:1.2fr 1fr 1fr 1fr;gap:12px;padding:10px 0;border-bottom:2px solid var(--green);font-size:28px;line-height:1.35;color:var(--ink)}
.tr:last-child{border-bottom:0}
.tr.th{font:500 22px 'JetBrains Mono',var(--kb),monospace;letter-spacing:.1em;color:var(--green);padding-top:12px}
.tr span:first-child{font-family:'Source Serif 4',var(--kt),serif;font-weight:var(--wt);color:var(--green)}
.tr.th span:first-child{font-family:'JetBrains Mono',var(--kb),monospace}
.qt{left:1220px;right:120px;top:590px;border-top:2px solid var(--green);padding-top:22px}
.qt p{font-size:46px;line-height:1.25;color:var(--green)}
.qt .ord{display:block;margin-top:16px;color:var(--green)}

/* --- 5. 확인하기(장미 바탕, 짙은 초록 글자): 크림2 퀴즈 타일(2px 줄 보기, 정답 = 초록 반전) | 초록 타일 빈칸(크림 글자) + 낱말 --- */
.quiz{left:120px;width:940px;top:270px;bottom:120px}
.q{margin-top:4px;font-size:48px;line-height:1.2;color:var(--green)}
.opts{margin-top:18px;border-top:2px solid var(--green)}
.opt{width:100%;display:flex;align-items:center;gap:22px;text-align:left;padding:12px 10px;border-bottom:2px solid var(--green);color:var(--ink)}
.opt .ord{color:var(--green);font-size:22px}
.opt .ot{font-size:34px}
.opt.right{background:var(--green);color:var(--cream)}
.opt.right .ord{color:var(--pink)}
.opt.wrong{color:rgba(26,26,23,.45)}
.opt:disabled:not(.right){opacity:.5}
.fb{margin-top:14px;min-height:80px;font-size:28px;line-height:1.45;color:var(--green)}
.rt{align-self:flex-start;margin-top:auto}
.blk{left:1100px;right:120px;top:270px;bottom:120px;gap:16px}
.bl{font-size:30px;line-height:1.55;color:var(--cream)}
.blank{position:relative;min-width:170px;margin-right:10px;padding:0 12px;border:2px solid var(--pink);border-radius:6px;font-family:'Source Serif 4',var(--kt),serif;font-size:30px;color:var(--pink);text-align:center}
.blank span{visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0}
.blank.open{background:var(--pink);color:var(--gdeep)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.wl{margin-top:auto}
.words{font-family:'Source Serif 4',var(--kt),serif;font-weight:var(--wt);font-size:44px;line-height:1.25;color:var(--pink)}

/* --- 내비: 가운데 아래(꼬리줄 두 글 사이) 점 + 원형 화살표 --- */
.dk-nav{position:absolute;left:50%;bottom:48px;transform:translateX(-50%);display:flex;align-items:center;gap:18px;color:var(--pink)}
[data-slide="2"] .dk-nav,[data-slide="4"] .dk-nav{color:var(--green)}
[data-slide="5"] .dk-nav{color:var(--gdeep)}
.dk-dots{display:flex;gap:14px}
.dk-dot{width:14px;height:14px;border-radius:50%;border:2px solid currentColor}
.dk-dot.on{background:currentColor}
.dk-prev,.dk-next{width:50px;height:50px;border:2px solid currentColor;border-radius:50%;font-size:22px;color:inherit}
.dk-prev:disabled,.dk-next:disabled{opacity:.25}
/* --- 6. 디자인 안내(크림): 한눈에 + 3열 정의 목록 | 토픽 타일 시연 3개 --- */
.g6{left:120px;width:900px;top:290px;display:flex;flex-direction:column;gap:14px}
.lab6{font:500 24px 'JetBrains Mono',var(--kb),monospace;letter-spacing:.18em;color:var(--green)}
.ab6{font-size:30px;line-height:1.55}
.ab6 b{font-weight:600;color:var(--green)}
.dl6{margin-top:20px;display:grid;grid-template-columns:repeat(3,1fr);gap:30px}
.dl6>div{border-top:2px solid var(--green);padding-top:14px}
.dl6 dt{font-size:22px;color:var(--green)}
.dl6 dd{margin-top:10px;font-size:23px;line-height:1.5}
.sw6{display:flex;flex-direction:column;gap:8px}
.sw6 i{display:inline-block;width:24px;height:24px;margin-right:8px;vertical-align:-5px;border-radius:2px;border:1px solid var(--green)}
.lab.sl6{left:1090px;top:290px;color:var(--green)}
.d6{left:1090px;right:120px;height:190px;padding:14px 24px}
.d6.a{top:340px}.d6.b{top:548px}.d6.c{top:756px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:16px}
.d6 h3{font-size:32px;color:var(--green)}
.d6 p{margin-top:2px;font-size:21px;line-height:1.4}
.bt.sm{font-size:20px;padding:6px 16px;border-width:2px}
.bt.sm[aria-pressed="true"]{background:var(--green);color:var(--cream)}
.tl6{margin-top:10px;display:flex;gap:12px}
.tl6 .tile{flex:1;height:56px;display:flex;align-items:center;padding:0 14px;border-width:2px}
.tl6:not(.play) .tile{background:var(--cream)!important;color:var(--green)!important;border-color:var(--green)!important}
.br6{margin-top:2px;height:84px;display:flex;align-items:flex-end;gap:26px;border-bottom:2px solid var(--green)}
.br6 span{display:flex;flex-direction:column;align-items:center;gap:4px}
.br6 i{width:56px;border-radius:3px 3px 0 0}
.br6 i.pink{background:var(--pink)}.br6 i.green{background:var(--green)}.br6 i.cream{background:var(--cream);border:2px solid var(--green);border-bottom:0}
.br6 .v6{font-style:normal;font-size:20px;line-height:1;color:var(--green);letter-spacing:.06em;visibility:hidden}
.br6.play .v6{visibility:visible}
.mc6{margin-top:6px;height:84px;display:flex;align-items:center}
.m6{position:static;width:84px;height:84px;font-size:20px;border-color:transparent;color:transparent}
.m6.play{border-color:var(--pink);color:var(--green)}

/* === DECK ENGINE (slide-refs 공용, 덱 HTML에 그대로 인라인됨) ===
   window.DECK_CFG = { type: 'x' | 'y' | 'fade' | 'shift' | 'rise', dur: ms, ease: css, dist: px, wheel: bool }
   window.DECK_FX  = { enter(slide, i), step(slide, k), answer(quiz, ok, btn) }  // 템플릿별 효과 훅(선택)
   - 넘김: → ↓ Space PageDown Enter = 다음(단계가 남았으면 단계 먼저), ← ↑ PageUp = 이전, Home/End
   - 내비: .dk-dot(점) .dk-count(번호, data-pad면 01 형식) .dk-prev .dk-next
   - 단계: <section data-steps="4"> 안의 [data-s="k"] 요소가 k단계부터 .on, 현재 단계는 .now
           [data-caps='["...",...]'] 요소의 글이 단계마다 바뀜, 버튼 [data-act="step"] [data-act="reset"]
   - 퀴즈: [data-quiz data-answer data-right data-wrong] 안의 버튼 [data-opt="i"], 결과 글 [data-fb], 다시 풀기 [data-act="retry"]
   - 빈칸: [data-blank] 를 누르면 .open (답 보이기/숨기기)
   - 시연(6장 디자인 안내): 버튼 [data-demo="선택자"] 를 누르면 같은 장 안의 그 요소에 .play
       data-mode="toggle" 이면 .play 켜기/끄기(aria-pressed), 아니면 .play를 뺐다 다시 붙여 애니메이션을 처음부터 다시 재생 */
```

(끝. 사용자의 수업 내용을 받아 위 지시대로 HTML을 만드세요.)
