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

> 이 파일은 **ChatGPT·Claude·Gemini 같은 채팅 AI**에게 통째로 주면, 이 디자인(`cobalt-grid`)으로 수업 슬라이드를 만들어 주도록 쓴 지시서입니다.
> 파일을 읽고 쓸 수 있는 에이전트 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`)에서 불러오는데, 일부 서비스의 미리보기 창은 바깥 파일을 막기 때문입니다. **내려받아 브라우저(크롬·엣지 등)로 열면 정상**으로 보입니다.

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

## 라이선스

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

- Kim jung chul Myungjo Regular: Kim jung chul Myungjo — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright © 2022 Junglim Architecture co.,ltd. All right reserved.
  파일: KimjungchulMyungjo-Regular.ttf
- Paperlogy 4Regular: Paperlogy — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright © 2024 PT&
  파일: Paperlogy-4Regular.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/cobalt-grid.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/cobalt-grid.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 Kim jung chul Myungjo Regular(400) · 본문 Paperlogy 4Regular(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. 디자인 규칙 (`cobalt-grid` design.md)

````markdown
---
version: alpha
name: Cobalt Grid
description: "A Japanese-magazine trend-report system built on warm cream paper, electric cobalt ink, and a graph-paper grid that lives permanently behind every slide. Newsreader serif headlines tower at 18vh while DM Mono carries chrome and ticker text. The signature decoration is a pixel-glitch column — vertical scanlines stair-stepped down the right edge of declarative slides — paired with QR-style 8×8 grid patches. The cultural reference is WIRED Japan, Shift magazine, and architectural trend reports printed in two-color risograph: cream + one cobalt."

colors:
  paper: "#F0EBDE"
  paper-2: "#E6E0CE"
  ink: "#1F2BE0"
  ink-soft: "#5560E5"
  grid: "rgba(31, 43, 224, 0.10)"
  ink-faint: "rgba(31, 43, 224, 0.18)"

color-aliases:
  rule: ink
  bg: paper

typography:
  display-hero:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(100px, min(11vw, 18vh), 200px)"
    fontWeight: 400
    lineHeight: 0.92
    letterSpacing: -0.008em
  display-closing:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(72px, min(8.4vw, 14vh), 180px)"
    fontWeight: 400
    lineHeight: 0.96
    letterSpacing: -0.005em
  display-chapter:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(56px, min(6vw, 10vh), 130px)"
    fontWeight: 400
    lineHeight: 1
    letterSpacing: -0.005em
  display-quote:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(50px, min(5.6vw, 9vh), 110px)"
    fontWeight: 400
    lineHeight: 1.05
    letterSpacing: -0.005em
  display-manifesto:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(56px, min(6.4vw, 11vh), 120px)"
    fontWeight: 400
    lineHeight: 1.05
    letterSpacing: -0.005em
  headline:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(46px, min(4.8vw, 8.2vh), 92px)"
    fontWeight: 400
    lineHeight: 0.95
  headline-index:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(48px, min(5vw, 8.5vh), 100px)"
    fontWeight: 400
    lineHeight: 0.95
  vbig-numeral:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(110px, min(11vw, 18vh), 240px)"
    fontWeight: 400
    lineHeight: 0.92
    letterSpacing: -0.015em
  ed-callout:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(28px, min(2.8vw, 4.6vh), 50px)"
    fontWeight: 400
    lineHeight: 1.1
  row-headline:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(26px, 2vw, 40px)"
    fontWeight: 400
    lineHeight: 1.05
  table-name:
    fontFamily: "Newsreader, Georgia, serif"
    fontSize: "clamp(20px, 1.6vw, 28px)"
    fontWeight: 400
    lineHeight: 1.15
  micro:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(12px, 0.9vw, 14px)"
    fontWeight: 600
    lineHeight: 1
    letterSpacing: 0.16em
    textTransform: uppercase
  micro-strong:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(13px, 1vw, 16px)"
    fontWeight: 600
    lineHeight: 1
    letterSpacing: 0.18em
    textTransform: uppercase
  micro-sm:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(11px, 0.75vw, 12px)"
    fontWeight: 600
    lineHeight: 1
    letterSpacing: 0.18em
    textTransform: uppercase
  body:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(14px, 0.95vw, 15px)"
    fontWeight: 400
    lineHeight: 1.5
  body-lede:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(15px, 1vw, 18px)"
    fontWeight: 400
    lineHeight: 1.5
  body-stat:
    fontFamily: "Hanken Grotesk, sans-serif"
    fontSize: "clamp(15px, 1vw, 17px)"
    fontWeight: 400
    lineHeight: 1.5
  mono-tag:
    fontFamily: "DM Mono, ui-monospace, monospace"
    fontSize: "clamp(13px, 0.9vw, 15px)"
    fontWeight: 400
    lineHeight: 1
    letterSpacing: 0.04em
  mono-chrome:
    fontFamily: "DM Mono, ui-monospace, monospace"
    fontSize: "clamp(11px, 0.82vw, 13px)"
    fontWeight: 400
    lineHeight: 1
    letterSpacing: 0.06em
  mono-tick:
    fontFamily: "DM Mono, ui-monospace, monospace"
    fontSize: "clamp(12px, 0.85vw, 14px)"
    fontWeight: 400
    lineHeight: 1
    letterSpacing: 0.04em

spacing:
  edge: "clamp(36px, 3.6vw, 80px)"
  edge-inner: "clamp(60px, 8vw, 160px)"
  pad-top: "clamp(76px, 8vh, 130px)"
  pad-bottom: "clamp(100px, 10vh, 150px)"
  gap-lg: "clamp(28px, 3vw, 56px)"
  gap-md: "clamp(20px, 2.2vh, 36px)"
  gap-sm: "clamp(14px, 1.6vh, 24px)"
  gap-xs: "clamp(10px, 1.2vh, 18px)"

canvas:
  width: 100vw
  height: 100vh

components:
  graph-paper-grid:
    backgroundImage: "linear-gradient(to right, {colors.grid} 1px, transparent 1px), linear-gradient(to bottom, {colors.grid} 1px, transparent 1px)"
    backgroundSize: "clamp(28px, 2.2vw, 44px) clamp(28px, 2.2vw, 44px)"
    description: "Permanent ::before pseudo on every stage. 28–44px squared graph paper grid in 10%-opacity cobalt that sits behind every slide at z-index 1. Cannot be turned off — it is the canvas tone."
  hairlines:
    height: "1.5px"
    background: "{colors.ink}"
    description: "Two persistent slim cobalt rules — one at the top of every slide (≈2.6vh from top) and one near the bottom (≈2vh from bottom) — both inset from edges by {spacing.edge}. They frame the slide composition."
  pagenum:
    position: absolute
    right: "{spacing.edge}"
    bottom: "clamp(48px, 4.8vh, 76px)"
    fontFamily: "DM Mono, ui-monospace, monospace"
    fontSize: "clamp(11px, 0.82vw, 13px)"
    color: "{colors.ink}"
    letterSpacing: 0.06em
    description: "Mono cobalt page number anchored bottom-right above the bottom hairline. One per slide."
  nav-hint:
    position: fixed
    left: "{spacing.edge}"
    bottom: "clamp(48px, 4.8vh, 76px)"
    fontFamily: "DM Mono, ui-monospace, monospace"
    fontSize: "clamp(10px, 0.75vw, 12px)"
    color: "{colors.ink}"
    letterSpacing: 0.08em
    opacity: 0.4
    description: "Mono cobalt navigation hint anchored bottom-left, mirrors pagenum."
  pixel-glitch:
    description: "Stair-stepped column of vertical scanlines, rendered as inline SVG. Each stepped rectangle contains evenly-spaced cobalt vertical lines on cream. Sits absolutely positioned (typically right edge) at z-index 3, decorative only. Size ranges from 16vw × full-height (compact decoration) to 32vw × full-height (signature cover decoration)."
  qr-block:
    display: grid
    gridTemplateColumns: "repeat(8, 1fr)"
    gridTemplateRows: "repeat(8, 1fr)"
    gap: 1.5px
    background: "{colors.paper}"
    padding: 4px
    boxShadow: "0 0 0 1.5px {colors.paper}"
    description: "8×8 QR-style mosaic of cobalt cells on cream background. Paper-fill ensures it reads as a discrete patch when overlapping the pixel-glitch column. Typical size 58–100px square."
  topbar-rule:
    borderBottom: "1.5px solid {colors.ink}"
    paddingBottom: "clamp(12px, 1.4vh, 22px)"
    description: "1.5px cobalt rule under the topbar of an index, data, or table layout. Below the rule sits a Newsreader headline (left) and a mono lab-tag (right)."
  row-divider:
    borderBottom: "1px solid {colors.ink-faint}"
    description: "Faint 18%-opacity cobalt rule between rows of an index list, table, or ledger."
  attribution-rule:
    borderTop: "1px solid {colors.ink}"
    paddingTop: "clamp(10px, 1.2vh, 18px)"
    description: "Solid cobalt rule above a quote attribution or manifesto byline."
  pixel-stack-bars:
    description: "Vertical bar chart rendered as a column of stacked 'cells' — flex column-reverse with 3px gaps, each cell a small horizontal block. Cells default to 10%-opacity cobalt (the grid color); .on cells fill solid cobalt to represent the value. Reads as a pixelated bar made of grid units."
  ledger-row:
    display: grid
    gridTemplateColumns: "76px 0.6fr 1.4fr 0.7fr 0.5fr"
    gap: "clamp(14px, 1.4vw, 28px)"
    borderBottom: "1px solid {colors.ink-faint}"
    description: "Dense table row carrying a num-tag, name (Newsreader), description (Hanken Grotesk), mood-tag, and delta-tag (mono with up/down arrow prefix). Header row uses 1.5px solid cobalt bottom border."
  vstack-label:
    fontFamily: "DM Mono, ui-monospace, monospace"
    writingMode: "vertical-rl"
    textOrientation: "mixed"
    letterSpacing: 0.04em
    description: "Vertical-orientation mono label column anchored to the right edge of a slide. Replaces the Korean vertical column of the reference with mono catalogue text rotated 90°."
  delta-up:
    content: "↑ "
    description: "Up arrow prefix via ::before on a mono delta tag in the ledger table."
  delta-down:
    content: "↓ "
    opacity: 0.6
    description: "Down arrow prefix via ::before, dimmed 40% to read as decline."
  delta-flat:
    content: "— "
    opacity: 0.6
    description: "Em-dash prefix via ::before, dimmed 40% to read as neutral."
---

## 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

Cobalt Grid is a **two-color trend-report editorial system** built on three immovable foundations: a warm cream paper canvas (`{colors.paper}`), an electric cobalt ink (`{colors.ink}`), and a **permanent graph-paper grid** that sits behind every slide. The grid is not optional decoration — it is rendered via a `::before` pseudo on every `.stage` and cannot be turned off. The aesthetic is "two-color risograph monograph": cream + cobalt only, with the grid lending the entire deck the feel of architectural tracing paper or a Japanese trend report.

The typeface stack is a deliberate three-face conversation. **Newsreader** — a contemporary literary serif with low-modulation roman letterforms — carries every display moment, every section headline, every stat numeral. Newsreader is used at weight 400 only; the type relies on size to assert hierarchy, not weight. **Hanken Grotesk** — a humanist sans — carries every body paragraph, every uppercase label, every micro-text. Hanken runs at 400 for body and 600 for labels. **DM Mono** — a monospace — carries every chrome element: page numbers, mono tags, axis ticks, vertical-stack labels, delta arrows in tables. The three-face system creates the system's identity: serif statements + sans bodies + mono chrome.

The palette is **strictly two-color**: cream and cobalt, with a softer cobalt `{colors.ink-soft}` and two opacity tones (`{colors.grid}` at 10%, `{colors.ink-faint}` at 18%) for atmospheric and structural use. There are no accent colors. Cobalt is the *only* ink color — for headlines, body, borders, page numbers, the graph paper, the pixel-glitch decoration, and the QR patches. The cream paper is the *only* surface. Even the pixel-stack bar chart uses cobalt at two opacities (10% off, 100% on) to render data.

Depth is **flat with structural rules**. There are no drop shadows, no elevated cards, no rounded surfaces. Hierarchy comes from:
- The 1.5px cobalt **hairline frame** (top and bottom of every slide).
- 1.5px cobalt **topbar rule** under section headers.
- 1px faint-cobalt **row dividers** between table or index entries.
- The 10%-opacity **graph paper grid** behind everything.
- The pixel-glitch and QR-block **decorative SVG patches** as compositional accents.

**Density philosophy: medium to dense, structured by the grid.** Cobalt Grid is built for editorial density — magazine spreads, trend indices, data ledgers. A correctly composed slide pairs one large Newsreader headline with multiple structured information rows (an index of six trends, a ledger of eight entries, a chart with eight pixel-stack bars). The graph paper underneath actively wants to be filled; sparse slides leave too much grid showing and read as wireframe. The exception is the manifesto, quote, and colophon layouts, which deliberately leave space open and let the graph paper breathe. Choose density by slide type: chapter / manifesto / quote / colophon are sparse; index / data / table are dense.

**Key Characteristics:**
- Cream paper canvas `{colors.paper}` with electric cobalt `{colors.ink}` as the only ink — strictly two-color.
- Permanent 28–44px graph-paper grid in 10%-opacity cobalt behind every slide.
- Top and bottom 1.5px cobalt hairlines frame every slide with `{spacing.edge}` insets.
- Newsreader serif at weight 400 for every display/headline; Hanken Grotesk sans for body/labels; DM Mono for all chrome.
- Pixel-glitch vertical scanline columns and QR-style 8×8 mosaics as the system's signature decorative patches.
- Display type can be enormous — `{typography.display-hero}` up to 18vh (≈194px on a 1080-tall display) and `{typography.vbig-numeral}` to 240px.
- Hanken labels are uppercase at 0.16–0.18em letter-spacing; mono tags carry 0.04–0.06em tracking.
- Pixel-stack bar charts render data as stacks of grid-unit cells (cobalt on / cobalt-10% off).
- Page number bottom-right, mono navigation hint bottom-left, both anchored above the bottom hairline.

## Colors

### Two-Color System
- **Paper** (`{colors.paper}` — #F0EBDE): The canvas. Warm cream off-white with a clear yellow-warm bias — closer to "newsprint paper" than "blank white." Used as the universal slide background and as the fill behind QR-blocks so they read as discrete patches against the pixel-glitch column.
- **Paper-2** (`{colors.paper-2}` — #E6E0CE): A slightly deeper cream. Defined in the palette but used sparingly — available for subtle region differentiation when needed.
- **Ink** (`{colors.ink}` — #1F2BE0): Electric cobalt / royal blue. The *only* ink color in the system. Used for all headlines, all body text, all borders, all chrome, the graph paper grid, the pixel-glitch decoration, and the QR patches. The high saturation is intentional — at full strength it reads as risograph-printed cobalt, not navy blue.
- **Ink Soft** (`{colors.ink-soft}` — #5560E5): A lighter cobalt for secondary marks. Defined in the palette but used sparingly — most softened cobalt in the system comes from opacity-on-ink rather than this dedicated tone.
- **Grid** (`{colors.grid}` — rgba(31, 43, 224, 0.10)): 10%-opacity cobalt. Used exclusively for the permanent graph-paper grid behind every slide, and for the "off" cells in pixel-stack bar charts.
- **Ink Faint** (`{colors.ink-faint}` — rgba(31, 43, 224, 0.18)): 18%-opacity cobalt. Used exclusively for the faint row dividers in index lists, tables, and ledgers — between rows that share the same dense information layer.

### Defaults
- **Default slide surface**: `{colors.paper}`.
- **Default headline color**: `{colors.ink}` — every Newsreader serif headline is cobalt. There is no other headline color.
- **Default body text color**: `{colors.ink}` — body is also cobalt, just smaller. Cobalt-on-cream is the system's only text relationship.
- **Default label / mono / micro color**: `{colors.ink}`.
- **Default border color (structural rules)**: `{colors.ink}` at 1.5px solid.
- **Default border color (row dividers within dense lists)**: `{colors.ink-faint}` at 1px solid.
- **Default grid color**: `{colors.grid}` — never visible at full strength; never disabled.
- **Default chart data color (on)**: `{colors.ink}`.
- **Default chart data color (off)**: `{colors.grid}`.

The system has **no accent color** in the populist sense. A second color does not exist — adding a red callout, a green stat, or a yellow highlight breaks the risograph two-color identity. When emphasis is needed, increase type size, switch from Hanken to Newsreader, add a mono delta arrow, or use opacity to dim rather than coloring to highlight.

## Typography

### Font Family
The system runs on a **three-face conversation**: `Newsreader` (serif, weight 400 / 500 italic) carries every display and headline; `Hanken Grotesk` (sans, weights 400–700) carries every body, label, and micro-text; `DM Mono` (monospace, 400–500) carries every chrome element. There is no fourth face.

Newsreader's roman letterforms run at weight 400 almost exclusively — the type relies on size to assert hierarchy, not weight. Italic Newsreader is loaded (300/400/500 italic axis) and is used inside the manifesto's `.roman` modifier (which is *non-italic* — the modifier flips the italic body back to roman for an inline pull moment) and is available for inline `<em>` emphasis. Hanken Grotesk carries body at 400 and labels at 600. DM Mono provides chrome at 400.

The serif/grotesk/mono three-way pairing is the system's primary typographic rhythm. Each face has a strict role: serif = statement, grotesk = supporting copy, mono = catalogue chrome.

### Type Scale

| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.vbig-numeral}` | clamp(110px, min(11vw, 18vh), 240px) | Newsreader | 400 | Largest numerical display — hero stat figure |
| `{typography.display-hero}` | clamp(100px, min(11vw, 18vh), 200px) | Newsreader | 400 | Largest title — cover or hero display |
| `{typography.display-closing}` | clamp(72px, min(8.4vw, 14vh), 180px) | Newsreader | 400 | Conclusive headline on a colophon/closing layout |
| `{typography.display-chapter}` | clamp(56px, min(6vw, 10vh), 130px) | Newsreader | 400 | Section-opening or chapter title |
| `{typography.display-manifesto}` | clamp(56px, min(6.4vw, 11vh), 120px) | Newsreader | 400 | Manifesto statement display |
| `{typography.display-quote}` | clamp(50px, min(5.6vw, 9vh), 110px) | Newsreader | 400 | Pull-quote body |
| `{typography.headline-index}` | clamp(48px, min(5vw, 8.5vh), 100px) | Newsreader | 400 | Index or trend-list section header |
| `{typography.headline}` | clamp(46px, min(4.8vw, 8.2vh), 92px) | Newsreader | 400 | Data, table, or chart section header |
| `{typography.ed-callout}` | clamp(28px, min(2.8vw, 4.6vh), 50px) | Newsreader | 400 | Editorial subtitle below a hero title |
| `{typography.row-headline}` | clamp(26px, 2vw, 40px) | Newsreader | 400 | Per-row headline inside an index list |
| `{typography.table-name}` | clamp(20px, 1.6vw, 28px) | Newsreader | 400 | Per-row name cell inside a ledger table |
| `{typography.body-lede}` | clamp(15px, 1vw, 18px) | Hanken Grotesk | 400 | Lead paragraph below a chapter title |
| `{typography.body-stat}` | clamp(15px, 1vw, 17px) | Hanken Grotesk | 400 | Descriptive paragraph next to a stat figure |
| `{typography.body}` | clamp(14px, 0.95vw, 15px) | Hanken Grotesk | 400 | Standard paragraph body |
| `{typography.micro-strong}` | clamp(13px, 1vw, 16px) | Hanken Grotesk | 600 | Largest uppercase label / kicker |
| `{typography.micro}` | clamp(12px, 0.9vw, 14px) | Hanken Grotesk | 600 | Standard uppercase label / lab-tag |
| `{typography.micro-sm}` | clamp(11px, 0.75vw, 12px) | Hanken Grotesk | 600 | Smallest uppercase label / table header |
| `{typography.mono-tag}` | clamp(13px, 0.9vw, 15px) | DM Mono | 400 | Mono catalogue tag, num-tag in an index row |
| `{typography.mono-tick}` | clamp(12px, 0.85vw, 14px) | DM Mono | 400 | Mono chart tick label, vertical-stack-label entry |
| `{typography.mono-chrome}` | clamp(11px, 0.82vw, 13px) | DM Mono | 400 | Mono page number, navigation hint, secondary meta |

### Defaults
- **Default size for the primary section headline (index, data, table)**: `{typography.headline}` (clamp 46–92px) or `{typography.headline-index}` for index layouts.
- **Default size for a cover or hero display**: `{typography.display-hero}` (clamp 100–200px).
- **Default size for a chapter or section-opener title**: `{typography.display-chapter}` (clamp 56–130px).
- **Default size for paragraph body**: `{typography.body}` (clamp 14–15px).
- **Default size for any inline uppercase label**: `{typography.micro}` (clamp 12–14px) at weight 600 with 0.16em tracking.
- **Default size for any mono chrome (page number, tag, tick)**: `{typography.mono-tag}` (clamp 13–15px).
- **Default weight for Newsreader**: 400. Newsreader bold is not used.
- **Default weight for Hanken body**: 400.
- **Default weight for Hanken label**: 600.

When unsure, reach for `{typography.headline}` (clamp 46–92px) for the slide's primary section header, not `{typography.display-chapter}` (which is for chapter-opening moments only).

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every Newsreader element is set at weight 400.** Newsreader at 600/700 is not used in this system. The literary-serif aesthetic depends on the open roman letterforms at modest weight.
- **Every Newsreader element is rendered in `{colors.ink}` (cobalt).** A cream serif headline does not exist.
- **Every Hanken label, kicker, lab-tag, and micro-text is uppercase with at least 0.16em letter-spacing** at weight 600. Hanken caps without tracking read as untreated.
- **Every DM Mono element is rendered in `{colors.ink}` with 0.04–0.08em letter-spacing.** Mono with tighter tracking reads as code, not editorial.
- **Every display element carries negative letter-spacing.** Display-hero at -0.008em, vbig-numeral at -0.015em, chapter / closing / manifesto / quote at -0.005em.
- **The graph-paper grid is permanent on every slide.** The `.stage::before` rule is not overridable per-slide — every composition sits on top of it.
- **The top and bottom hairlines frame every slide.** The `.hairlines::before` and `.hairlines::after` rules apply by default; they should not be suppressed.
- **Page number sits above the bottom hairline with clear vertical space.** The bottom hairline anchors at `bottom: clamp(20px, 2vh, 32px)`; the page number anchors at `bottom: clamp(48px, 4.8vh, 76px)` — they must not collide.

### Typography Principles
The Newsreader-400 + Hanken-600-uppercase-tracked + DM-Mono-tracked combination is the system's voice. Switching any of those three face/weight/case rules reads as a different design system. Italic is permitted via Newsreader italic (loaded) for inline `<em>` and for the manifesto's editorial italic-with-`.roman`-flip treatment. Underline is not used.

Line-height collapses at the top: display-hero / vbig-numeral at 0.92, display-chapter at 1.0, body at 1.5. The tight display + open body contrast is what gives the system its trend-report rhythm.

## Layout

### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport; one slide carries `.active` (opacity 1, pointer-events auto) at a time. Transitions are 280ms opacity fades.

A `.stage` wrapper sits inside `.deck` (`position: fixed; inset: 0`) and provides the cream background plus the permanent `::before` graph-paper grid.

### Edge and Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.edge}` | clamp(36px, 3.6vw, 80px) | Standard slide edge inset for content, page number, hairlines |
| `{spacing.edge-inner}` | clamp(60px, 8vw, 160px) | Tighter inset used for manifesto-style centered statements |
| `{spacing.pad-top}` | clamp(76px, 8vh, 130px) | Top padding inside index/data/table frame, below the top hairline |
| `{spacing.pad-bottom}` | clamp(100px, 10vh, 150px) | Bottom padding inside index/data/table frame, above the bottom hairline |
| `{spacing.gap-lg}` | clamp(28px, 3vw, 56px) | Large gap between major regions inside a slide |
| `{spacing.gap-md}` | clamp(20px, 2.2vh, 36px) | Standard inter-element spacing |
| `{spacing.gap-sm}` | clamp(14px, 1.6vh, 24px) | Tight spacing — chrome bar inner gap, attribution-to-quote gap |
| `{spacing.gap-xs}` | clamp(10px, 1.2vh, 18px) | Vertical-stack row gap, smallest inter-element gap |

### Universal Chrome Frame
Every slide carries a four-piece chrome frame:
1. **Top hairline** — 1.5px solid cobalt at ≈2.6vh from top, inset by `{spacing.edge}` left/right.
2. **Bottom hairline** — 1.5px solid cobalt at ≈2vh from bottom, inset by `{spacing.edge}` left/right.
3. **Page number** — DM Mono cobalt anchored bottom-right, ≈4.8vh from bottom (above the bottom hairline).
4. **Nav hint** — DM Mono cobalt at 40% opacity anchored bottom-left, same vertical level as page number.

This frame is rendered automatically by the `.hairlines` and `.pagenum` / `.nav-hint` rules — every new slide inherits it.

A nested **`.frame` content rectangle** sits inside the chrome on index, data, table, and chapter layouts. It is absolutely positioned with `inset: {spacing.pad-top} {spacing.edge} {spacing.pad-bottom}` and serves as the actual content container.

### Composition Patterns
Within the chrome frame, content typically follows one of these compositional moves (not enumerated as available layouts — these are descriptive, not prescriptive):
- A `topbar` block (Newsreader headline left, mono lab-tag right, 1.5px cobalt rule beneath) above a main content region.
- A pixel-glitch column anchored to the right edge of the content region (or occasionally the left, as on the colophon).
- A QR-block patch as a small punctuation mark (typically top-right corner).
- A vertical-stack mono label column anchored to one edge.
- A dense ledger or index of equal-flex rows separated by faint cobalt dividers.

## Depth and Elevation

### Flat With Structural Rules
Cobalt Grid has no drop shadows, no elevated cards, no rounded surfaces, no gradients. Every element sits on a single plane.

Depth signals are entirely structural:
- **1.5px cobalt rules** — top/bottom slide hairlines, topbar rule, attribution rule.
- **1px faint cobalt dividers** — row separators inside index lists, tables, and ledgers.
- **Graph-paper grid** — the 10%-opacity cobalt background creates a sense of measured plane.
- **Pixel-glitch decoration** — vertical scanline columns add visual texture without z-axis elevation.
- **QR-block patches** — read as discrete graphic objects against the grid+glitch background due to their paper-fill and 1.5px paper-color outset shadow (which is functionally an "anti-shadow" — it pushes the grid away so the QR mosaic stays readable).

The QR-block's 1.5px paper-color outset is the *only* shadow-like effect in the system, and it exists to preserve readability against the pixel-glitch column, not to create elevation. There is no z-axis depth.

## Shapes and Treatment

### Border Radius
| Value | Use |
|---|---|
| 0 | Every structural element — frames, cards, ledger rows, QR cells, pixel-glitch rectangles, charts, tables |
| 50% (circle) | None — Cobalt Grid has no circular elements |

The system uses **zero rounded corners**. Every shape is a strict rectangle. This is unusual for editorial systems and is part of the trend-report identity.

### Border Weights
- **1.5px solid `{colors.ink}`** — primary structural rules: top/bottom slide hairlines, topbar bottom rule, table head row bottom border, chart baseline rule.
- **1px solid `{colors.ink}`** — attribution rules above quote bylines, manifesto attribution top border.
- **1px solid `{colors.ink-faint}`** (18% opacity) — faint row dividers between dense list / table / ledger entries.
- **1px solid `{colors.grid}`** (10% opacity) — the permanent graph-paper grid behind every slide.
- **1.5px box-shadow in `{colors.paper}`** — QR-block readability outset (functional, not decorative).

All structural borders are cobalt. Colored borders do not exist (there is no "colored" — only cobalt at different opacities).

### Decorative Element Types

**Pixel-glitch column** — A stair-stepped vertical column rendered as inline SVG. Each step is a rectangle filled with evenly-spaced cobalt vertical scanlines on cream. Steps decrease in width as the column descends (or vice versa), creating a "glitch" pixelation effect. Anchored to one edge of a slide (typically right), absolutely positioned, z-index 3, pointer-events disabled. Decorative only — sizes range from compact 16vw × full-height secondary use to 32vw × full-height signature cover decoration. Opacity 0.6–1.0 depending on context (lower opacity when used as background, full opacity when used as primary decoration).

**QR-block patch** — An 8×8 grid of cells (some `.on` = solid cobalt, some default = paper) forming a QR-code-like mosaic. Sits over a paper-fill background with 4px internal padding and 1.5px paper-color outset (which preserves readability when overlapping the pixel-glitch column). Typical size 58–100px square. Used as compositional punctuation — typically top-right corner.

**Vertical-stack label column** — A column of DM Mono labels written with `writing-mode: vertical-rl` and `text-orientation: mixed`, rotating Latin text 90° clockwise. Anchored to right edge, vertically centered, evenly spaced. Reads as catalogue-style metadata stacked along the slide edge.

**Topbar (with rule)** — A flex row containing a Newsreader headline left and a small mono lab-tag right, separated from the content below by a 1.5px solid cobalt bottom border. The universal section-header pattern.

**Frame** — An absolutely-positioned content container with `inset: {spacing.pad-top} {spacing.edge} {spacing.pad-bottom}`. Holds the slide's actual content while keeping it clear of the hairline frame, page number, and nav hint.

**Index list** — A 2×3 grid of equal-flex rows, each row a 56px num-tag column + a content column with a Newsreader row-headline and a Hanken body paragraph, separated by 1px faint-cobalt bottom borders.

**Pixel-stack bar chart** — A row of 8 vertical "stacks," each a flex column-reverse of small horizontal cells (default 10%-cobalt off, .on solid cobalt). Cell counts represent values. A 1.5px cobalt top border with mono tick labels sits beneath the bars as the axis. Renders data as pixelated bars made of grid units — directly echoes the pixel-glitch decoration.

**Ledger table** — A flex column of dense rows, each row a 5-column grid (76px num-tag / 0.6fr name / 1.4fr description / 0.7fr mood-tag / 0.5fr delta-tag), separated by 1px faint-cobalt bottom borders. Header row uses 1.5px solid cobalt. Delta tags use `↑` / `↓` / `—` prefixes via `::before`.

**Manifesto** — A centered statement in `{typography.display-manifesto}` Newsreader with an italic `<em>` body containing inline `.roman` (non-italic) emphasis moments. Below: a 1px cobalt top border with a Hanken who-tag and a mono meta-tag side-by-side.

**Quote** — A Hanken kicker above a `{typography.display-quote}` Newsreader pull, with a 1px cobalt top-border attribution row beneath. Paired with a compact pixel-glitch column at the right edge.

**Colophon** — Right-aligned closing layout. A large `{typography.display-closing}` Newsreader title aligned right with a kicker above. Pixel-glitch column anchored to left edge (mirroring the cover). Page footer with 3–4 column grid of paragraph credits.

## Do's and Don'ts

### Do
- Set every Newsreader element at weight 400 in `{colors.ink}`. The thin roman serif at modest weight is the literary register's identity.
- Render every label, kicker, and micro-text in Hanken Grotesk weight 600 uppercase with 0.16em+ letter-spacing in `{colors.ink}`.
- Render every chrome element (page number, mono tag, tick label, vertical-stack) in DM Mono with 0.04–0.08em tracking in `{colors.ink}`.
- Keep the permanent graph-paper grid behind every slide. The grid is the system — disabling it breaks the identity.
- Maintain the top and bottom 1.5px cobalt hairlines on every slide, with the page number and nav hint sitting above the bottom hairline.
- Use the pixel-glitch column as the system's primary decorative move on declarative slides (cover, chapter, quote, colophon).
- Pair pixel-glitch with a QR-block patch when the composition needs a discrete graphic anchor — the QR's paper-fill keeps it readable against the glitch lines.
- Use the `topbar + 1.5px cobalt rule` pattern as the standard section-header treatment on index, data, and table layouts.
- Use 1px faint-cobalt dividers between rows of dense lists, tables, and ledgers.
- Render charts as pixel-stack columns of grid cells (cobalt on / cobalt-10% off). The pixel-stack bar treatment echoes the decorative glitch and unifies the visual language.

### Don't
- Don't introduce a second ink color. The system is strictly two-color: cream paper + cobalt ink. A second hue breaks the risograph identity.
- Don't render a Newsreader headline at weight 600 or 700. The 400-only rule is a signature.
- Don't disable or hide the graph-paper grid. It is the canvas tone, not optional decoration.
- Don't suppress the top/bottom hairlines on a slide. They are the frame — every slide carries them.
- Don't round any corner. Every shape is a strict rectangle; the system has zero circular elements.
- Don't add drop shadows, elevated cards, or gradient fills. Depth is structural (rules + grid + glitch), not z-axis.
- Don't use Hanken caps without 0.16em+ tracking. Untracked Hanken caps read as untreated.
- Don't put the page number directly on the bottom hairline. It sits at `bottom: clamp(48px, 4.8vh, 76px)` with clear space above the hairline.
- Don't render the QR-block without its paper-fill and 1.5px paper outset. The fill is what preserves QR readability against the pixel-glitch column.
- Don't crowd the manifesto, quote, or colophon layouts. Those layouts deliberately leave grid showing — over-stuffing them breaks the contemplative register.

## Responsive Behavior

Cobalt Grid is a viewport-fluid 1920×1080 presentation system using `clamp()` and viewport-relative units throughout. There are no explicit responsive breakpoints in the source — every dimension scales between a min and max.

### Scaling Behavior
- Display-hero scales from ~100px at minimum viewport to ~200px at maximum.
- Body text scales from 14px to 15px (deliberately narrow range — body stays compact).
- Graph-paper grid scales from 28px cells (smaller viewports) to 44px cells (larger viewports), maintaining roughly 50–80 cells across the slide width.
- Edge insets scale from 36px to 80px.
- The 1.5px hairlines and 1px row dividers are fixed and do not scale.

### Presenter Behavior
- Slides cross-fade via 280ms opacity transitions.
- Navigation is JS-driven (the source includes a `.deck` / `.slide.active` pattern); typical keyboard arrow / spacebar conventions apply.
- The nav hint at bottom-left displays interaction guidance in mono cobalt at 40% opacity.

### Print / Export
Not explicitly handled. Each slide is a 100vw × 100vh block; export workflows should snapshot each slide at 1920×1080. The grid and hairline overlays should render correctly in PDF capture (no blend modes or filters).

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Newsreader 400) | Newsreader | 思源宋体 Noto Serif SC 700 | Google Fonts |
| Body / Label (Hanken Grotesk 400–600) | Hanken Grotesk | 思源宋体 Noto Serif SC 400 | Google Fonts |
| Chrome / Mono (DM Mono) | DM Mono | DM Mono (Latin/digit only — keep mono chrome in Latin) | Google Fonts |

### Mixed-Content Strategy

Use **Strategy A — single-font-stack with fallback**: declare Noto Serif SC *after* the Latin font in the same `font-family` stack so Latin glyphs render in Newsreader / Hanken Grotesk and CJK glyphs fall through to NSC automatically. Mono chrome stays Latin/digit-only — page numbers, ticks, and vertical-stack tags do not need a CJK fallback (and DM Mono has no CJK glyphs by design).

### Loading

```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=Newsreader:ital,opsz,wght@0,6..72,400..500;1,6..72,400..500&family=Hanken+Grotesk:wght@400..700&family=DM+Mono:wght@400..500&family=Noto+Serif+SC:wght@400;700&display=swap" rel="stylesheet">
```

```css
:root {
  --font-display: "Newsreader", "Noto Serif SC", Georgia, serif;
  --font-body: "Hanken Grotesk", "Noto Serif SC", sans-serif;
  --font-mono: "DM Mono", ui-monospace, monospace;
}
/* Headlines use Noto Serif SC 700; body uses Noto Serif SC 400. */
```

### Universal CJK Adjustments

- **Line-height**: bump CJK body line-height to ~1.7 (from 1.5) — Hanzi need more vertical breathing than Latin lowercase.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (the 0.16em+ Hanken caps tracking shatters Hanzi cadence). Keep tight tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any micro/label/kicker when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (，。：；「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick a single weight of Noto Serif SC for a given text run, never two inside one phrase.

### Aesthetic Notes

Noto Serif SC (思源宋体) is the natural Hanzi partner for Newsreader — both are quiet literary serifs with thin-thick modulation that holds at very large display sizes (up to 18vh / 240px on the vbig-numeral). The cobalt-on-cream two-color rule absorbs Chinese without negotiation because there's only one ink color to assign. NSC 700 carries display moments where Newsreader 400 would have at 100–200px; NSC 400 carries body and labels. The DM Mono chrome layer (page numbers, vertical-stack tags, ticks) intentionally stays Latin/digit-only — `编号 001` is rendered as Latin "001" in DM Mono with the Hanzi prefix in Hanken/NSC, preserving the mono catalogue chrome's "technical spec" voice. The graph-paper grid, pixel-glitch column, and QR-block decoration are content-agnostic and read identically in any language. Vertical-stack labels written with `writing-mode: vertical-rl` work for Hanzi too — Chinese is the original vertical script — but mixing Latin and Hanzi in the same vertical run will rotate the Hanzi to upright while keeping Latin rotated 90°; isolate runs by language.

### Known CJK Gap

Noto Serif SC has no italic axis (Chinese type historically has no italic), so the manifesto layout's italic-Newsreader-with-`.roman`-flip emphasis pattern collapses when content is Hanzi. Substitute a weight contrast (NSC 700 vs NSC 400) or a faint-cobalt tone (`{colors.ink-faint}`) to recover the emphasis register. Newsreader's optical-size axis (6..72) has no NSC equivalent — the literary "this is a small caption" optical refinement is unavailable for Hanzi, but at NSC's quality this is rarely noticeable.

## Iteration Guide

1. Every new slide inherits the permanent graph-paper grid, the top and bottom 1.5px cobalt hairlines, the page number bottom-right, and the nav hint bottom-left. Don't author these per-slide — they live on `.stage` and `.hairlines`.
2. Every new headline uses Newsreader at weight 400 in `{colors.ink}`. Don't bold; don't color.
3. Every new label uses Hanken Grotesk weight 600 uppercase with 0.16em+ letter-spacing in `{colors.ink}`.
4. Every new chrome element uses DM Mono in `{colors.ink}` with 0.04–0.08em tracking.
5. New content slides on index / data / table layouts use a topbar (Newsreader headline left + Hanken lab-tag right) with a 1.5px cobalt bottom rule.
6. New chart slides use the pixel-stack treatment — cobalt on / cobalt-10% off cells in column-reverse stacks. Don't introduce filled bar charts in a single solid block.
7. New declarative slides (cover, chapter, quote, colophon) use a pixel-glitch column as the primary decoration. Pair with a QR-block when the composition needs a discrete graphic anchor.
8. New row dividers in dense lists use 1px solid `{colors.ink-faint}` (18% opacity), not full-strength cobalt. Full-strength cobalt is reserved for major structural rules.
9. New components inherit the zero-radius, no-shadow, no-gradient flatness. If a component breaks any of these, redesign it before adding.
10. The system has one ink color (`{colors.ink}`) and one surface (`{colors.paper}`). New compositions should never introduce a third color or a third surface tone (paper-2 is available but rarely needed).

## Known Gaps

- The pixel-glitch column is rendered as inline SVG hand-authored per usage; there is no generative component — adjusting the stair-step pattern requires editing the SVG markup directly.
- The QR-block 8×8 cell pattern is hand-authored per usage; each instance places `.on` cells manually. There is no QR-code generation logic.
- The pixel-stack bar chart cell counts are hardcoded in markup; there is no data-binding layer translating numeric values to cell-on counts.
- The vertical-stack label column uses `writing-mode: vertical-rl`; this works in modern browsers but rendering of mixed Latin/CJK in this orientation may vary across rendering engines.
- The manifesto layout's italic-with-`.roman`-flip pattern (italic Newsreader body containing inline non-italic `.roman` spans for emphasis) is the inverse of typical italic emphasis — the rule lives in the manifesto-specific CSS and is not generalized.
- The 1.5px paper-color outset on the QR-block is a `box-shadow` used as an anti-shadow (it extends the paper fill outward to clear the grid behind the QR cells). This is the only `box-shadow` in the system and it should not be repurposed for elevation.
- The colophon's pixel-glitch column anchors to the left edge (mirroring the cover); other slides anchor to the right edge — the directionality is per-slide and should be considered when authoring new declarative layouts.
- The graph-paper grid cell size scales between 28–44px via `clamp` — at extreme aspect ratios, the grid count across the slide width may feel uneven.
- The system loads three Google Fonts families (Newsreader, Hanken Grotesk, DM Mono) with multiple weights — initial render requires successful font load to avoid Georgia/Helvetica fallback shifting the visual rhythm.
````

---

## 2. 글씨체

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

---

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

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

**1장(표지)에서 처음 나오는 부품**
- `.b` — 1·2·3·4·5·6장 — 예: `<i class="hl b">`
- `.cv` — 1장 — 예: `<div class="cv">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.gl` — 1장 — 예: `<div class="micro gl">`
- `.glitch` — 1·6장 — 예: `<svg class="glitch" viewBox="0 0 500 1080" width="500" height="1080">`
- `.hero` — 1장 — 예: `<h1 class="kh hero">`
- `.hint` — 1·2·3·4·5·6장 — 예: `<span class="hint">`
- `.hl` — 1·2·3·4·5·6장 — 예: `<i class="hl t">`
- `.kh` — 1·2·3·4·5·6장 — 예: `<p class="unit kh">`
- `.micro` — 1·2·3·4·5·6장 — 예: `<div class="micro">`
- `.mono` — 1·2·3·4·5·6장 — 예: `<span class="pg mono">`
- `.pg` — 1·2·3·4·5·6장 — 예: `<span class="pg mono">`
- `.q1` — 1장 — 예: `<div class="qr q1">`
- `.qr` — 1·5장 — 예: `<div class="qr q1">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide cover">`
- `.t` — 1·2·3·4·5·6장 — 예: `<i class="hl t">`
- `.tags` — 1장 — 예: `<div class="tags">`
- `.unit` — 1장 — 예: `<p class="unit kh">`
- `.who` — 1장 — 예: `<span class="who">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.btn` — 2·5·6장 — 예: `<button class="btn" data-act="step">`
- `.btns` — 2·5장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03…`
- `.def` — 2장 — 예: `<p class="def">`
- `.fig` — 2장 — 예: `<div class="fig">`
- `.fnote` — 2장 — 예: `<p class="fnote">`
- `.frame` — 2·3·4·5·6장 — 예: `<div class="frame">`
- `.ft` — 2장 — 예: `<span class="mono ft">`
- `.ghost` — 2장 — 예: `<button class="btn ghost" data-act="reset">`
- `.index` — 2·6장 — 예: `<div class="index">`
- `.lab` — 2·3·4·5·6장 — 예: `<span class="lab">`
- `.lcol` — 2장 — 예: `<div class="lcol">`
- `.nr` — 2·5장 — 예: `<p class="nr">`
- `.num` — 2·4·5·6장 — 예: `<span class="mono num">`
- `.rcol` — 2장 — 예: `<div class="rcol">`
- `.row` — 2·5·6장 — 예: `<div class="row" data-s="1">`
- `.split2` — 2장 — 예: `<div class="split2">`
- `.topbar` — 2·3·4·5·6장 — 예: `<div class="topbar">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.ax` — 3장 — 예: `<span class="mono ax">`
- `.bars` — 3장 — 예: `<div class="bars">`
- `.bv` — 3장 — 예: `<span class="mono bv">`
- `.cells` — 3장 — 예: `<div class="cells">`
- `.chart` — 3장 — 예: `<div class="chart">`
- `.clab` — 3장 — 예: `<div class="clab">`
- `.col` — 3장 — 예: `<div class="col">`
- `.mx` — 3장 — 예: `<div class="col mx">`
- `.nrow` — 3장 — 예: `<div class="nrow tm">`
- `.src` — 3장 — 예: `<p class="src">`
- `.st` — 3장 — 예: `<div class="st">`
- `.stats` — 3장 — 예: `<div class="stats">`
- `.sv` — 3장 — 예: `<b class="kh sv">`
- `.tm` — 3장 — 예: `<div class="nrow tm">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.attr` — 4장 — 예: `<span class="attr">`
- `.cc` — 4장 — 예: `<div class="cc">`
- `.cmp` — 4장 — 예: `<div class="cmp">`
- `.ledger` — 4·5장 — 예: `<div class="ledger">`
- `.lh` — 4·5장 — 예: `<div class="lh">`
- `.li` — 4장 — 예: `<div class="li">`
- `.lr` — 4·5장 — 예: `<div class="lr">`
- `.nm` — 4·5장 — 예: `<span class="kh nm">`
- `.qt` — 4장 — 예: `<blockquote class="qt">`
- `.row4` — 4장 — 예: `<div class="row4">`
- `.rr` — 4장 — 예: `<div class="rr">`
- `.vstack` — 4장 — 예: `<div class="vstack">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.blank` — 5장 — 예: `<button class="blank" data-blank aria-pressed="false">`
- `.blk` — 5장 — 예: `<div class="blk">`
- `.dt` — 5장 — 예: `<span class="mono dt">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.q` — 5장 — 예: `<h3 class="kh q">`
- `.q3` — 5장 — 예: `<div class="lh q3">`
- `.q5` — 5장 — 예: `<div class="qr q5">`
- `.quiz` — 5장 — 예: `<div class="quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해…`
- `.split5` — 5장 — 예: `<div class="split5">`
- `.wl` — 5장 — 예: `<span class="micro wl">`
- `.words` — 5장 — 예: `<p class="kh words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.d6` — 6장 — 예: `<div class="d6">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.g6` — 6장 — 예: `<div class="index g6">`
- `.gl6` — 6장 — 예: `<div class="gl6" id="cg-gl">`
- `.ld6` — 6장 — 예: `<div class="ld6" id="cg-ld">`
- `.px6` — 6장 — 예: `<div class="px6" id="cg-px">`
- `.sig6` — 6장 — 예: `<div class="sig6">`
- `.sm` — 6장 — 예: `<button class="btn sm" data-demo="#cg-px" data-mode="toggle" aria-pressed="false">`
- `.split6` — 6장 — 예: `<div class="split6">`
- `.sw6` — 6장 — 예: `<span class="sw6">`

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="cobalt-grid">
<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=Newsreader:ital,opsz,wght@0,6..72,400..500;1,6..72,400..500&family=Hanken+Grotesk:wght@400..700&family=DM+Mono:wght@400;500&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/cobalt-grid.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide cover"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 01 / 06</span>
  <svg class="glitch" viewBox="0 0 500 1080" width="500" height="1080"><defs><pattern id="g1a" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="5" height="12" fill="#1F2BE0"/></pattern><pattern id="g1b" width="7" height="12" patternUnits="userSpaceOnUse"><rect width="3" height="12" fill="#1F2BE0"/></pattern></defs><rect x="0" y="0.0" width="500" height="154.8" fill="url(#g1a)"/><rect x="89" y="154.3" width="411" height="154.8" fill="url(#g1b)"/><rect x="32" y="308.6" width="468" height="154.8" fill="url(#g1a)"/><rect x="169" y="462.9" width="331" height="154.8" fill="url(#g1b)"/><rect x="97" y="617.1" width="403" height="154.8" fill="url(#g1a)"/><rect x="242" y="771.4" width="258" height="154.8" fill="url(#g1b)"/><rect x="153" y="925.7" width="347" height="154.8" fill="url(#g1a)"/></svg>
  <div class="qr q1"><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i></div>
  <div class="cv">
    <div class="micro">초등 과학 · 6학년 2학기 — 1단원 · 3~4차시</div>
    <p class="unit kh">계절의 변화<span>Sun, Shadow & Temperature</span></p>
    <div class="micro gl">학습 목표</div>
    <h1 class="kh hero">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1>
    <div class="tags"><span class="mono">VOL. 01</span><span class="mono">2026</span><span class="who">00초등학교</span></div>
  </div>
</section>
<section class="slide" data-steps="4"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 02 / 06</span>
  <div class="frame">
    <div class="topbar"><h2 class="kh">태양 고도 측정기 만들기</h2><span class="lab"><span class="micro">측정 준비</span><span class="mono">INDEX 01—04</span></span></div>
    <div class="split2">
      <div class="lcol">
        <div class="fig"><span class="mono ft">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="fnote">막대기의 그림자와 실이 이루는 각 = 태양 고도</p>
      </div>
      <div class="rcol">
        <p class="def"><b>태양 고도</b> — 태양이 지표면과 이루는 각</p>
        <div class="index"><div class="row" data-s="1"><span class="mono num">01</span><div><h3 class="kh">자 붙이기</h3><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div></div><div class="row" data-s="2"><span class="mono num">02</span><div><h3 class="kh">수수깡 꽂기</h3><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div></div><div class="row" data-s="3"><span class="mono num">03</span><div><h3 class="kh">실 묶기</h3><p>수수깡 끝에 실을 묶어요</p></div></div><div class="row" data-s="4"><span class="mono num">04</span><div><h3 class="kh">각도기 끼우기</h3><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
        <div class="btns"><button class="btn" data-act="step">다음 단계 <span class="mono">→</span></button><button class="btn ghost" data-act="reset">처음부터</button></div>
        <p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03 실 묶기&quot;,&quot;04 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</p>
      </div>
    </div>
  </div>
  <p class="nr">버튼 규칙 없음 → 1.5px 코발트 선 칸으로 표현</p>
</section>
<section class="slide"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 03 / 06</span>
  <div class="frame">
    <div class="topbar"><h2 class="kh">하루 동안 무엇이 어떻게 변할까요?</h2><span class="lab"><span class="micro">측정 결과</span><span class="mono">예시 값</span></span></div>
    <div class="stats"><div class="st"><b class="kh sv">12:30</b><span class="micro">남중 시각</span><p>태양 고도가 가장 높아요 무렵 · 남중</p></div><div class="st"><b class="kh sv">정남</b><span class="micro">남중 방향</span><p>남중할 때 태양의 위치 쪽</p></div><div class="st"><b class="kh sv">14:30</b><span class="micro">최고 기온</span><p>기온이 가장 높아요 무렵</p></div><div class="st"><b class="kh sv">9:30</b><span class="micro">가장 긴 그림자</span><p>그림자가 가장 길어요 · 15:30</p></div></div>
    <div class="chart">
      <div class="clab"><span class="micro">측정 시각별 태양 고도, 그림자 길이, 기온</span><span class="mono">1칸 = 5°</span></div>
      <div class="bars"><span class="mono ax">태양 고도<br>(°)</span><div class="col"><span class="mono bv">38°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i><i class=""></i><i class=""></i></div></div><div class="col"><span class="mono bv">48°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i></div></div><div class="col"><span class="mono bv">55°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></div></div><div class="col mx"><span class="mono bv">57°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></div></div><div class="col"><span class="mono bv">54°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></div></div><div class="col"><span class="mono bv">47°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i><i class=""></i></div></div><div class="col"><span class="mono bv">37°</span><div class="cells"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i><i class=""></i><i class=""></i><i class=""></i></div></div></div>
      <div class="nrow tm"><span class="ax">시각</span><span class="mono">9:30</span><span class="mono">10:30</span><span class="mono">11:30</span><span class="mono">12:30</span><span class="mono">13:30</span><span class="mono">14:30</span><span class="mono">15:30</span></div><div class="nrow "><span class="ax">그림자 길이 (cm)</span><span class="mono">12.9</span><span class="mono">9.1</span><span class="mono">7</span><span class="mono">6.4</span><span class="mono">7.2</span><span class="mono">9.4</span><span class="mono">13.4</span></div><div class="nrow "><span class="ax">기온 (℃)</span><span class="mono">22</span><span class="mono">23.8</span><span class="mono">25.2</span><span class="mono">26.3</span><span class="mono">27</span><span class="mono">27.4</span><span class="mono">26.9</span></div>
    </div>
    <p class="src">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값 · 꺾은선 규칙 없음 → 숫자 줄으로 표현</p>
  </div>
</section>
<section class="slide"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 04 / 06</span>
  <div class="frame">
    <div class="topbar"><h2 class="kh">태양 고도가 바뀌면 무엇이 달라질까요?</h2><span class="lab"><span class="micro">관계 정리</span><span class="mono">LEDGER</span></span></div>
    <div class="cmp"><div class="cc"><span class="mono num">↑</span><div><h3 class="kh">태양 고도가 높을 때</h3><p>그림자 길이는 짧아져요</p><p>기온은 높아져요</p></div></div><div class="cc"><span class="mono num">↓</span><div><h3 class="kh">태양 고도가 낮을 때</h3><p>그림자 길이는 길어져요</p><p>기온은 낮아져요</p></div></div></div>
    <div class="row4">
      <div class="ledger"><div class="lh"><span class="micro">NO.</span><span class="micro">시각</span><span class="micro">태양 고도</span><span class="micro">그림자 길이</span><span class="micro">기온</span></div><div class="lr"><span class="mono">01</span><span class="kh nm">오전 9:30</span><span class="">낮아요</span><span class="">길어요</span><span class="">낮아요</span></div><div class="lr"><span class="mono">02</span><span class="kh nm">낮 12:30</span><span class="">가장 높아요</span><span class="">가장 짧아요</span><span class="">높아지는 중</span></div><div class="lr"><span class="mono">03</span><span class="kh nm">오후 14:30</span><span class="">낮아지는 중</span><span class="">길어지는 중</span><span class="">가장 높아요</span></div></div>
      <div class="rr">
        <div><span class="micro">남중</span><div class="li"><span class="mono">01</span><p>태양이 정남쪽에 있을 때 '남중했다'고 해요</p></div><div class="li"><span class="mono">02</span><p>이때의 태양 고도를 남중 고도라고 해요</p></div></div>
        <blockquote class="qt"><p class="kh">태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span class="attr"><span class="micro">오늘의 정리</span><span class="mono">1단원 · 3~4차시</span></span></blockquote>
      </div>
    </div>
  </div>
  <div class="vstack"><span class="mono">TREND REPORT</span><span class="mono">2026</span></div>
</section>
<section class="slide"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 05 / 06</span>
  <div class="qr q5"><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i><i class="on"></i><i class=""></i></div>
  <div class="frame">
    <div class="topbar"><h2 class="kh">배운 내용을 확인해 볼까요?</h2><span class="lab"><span class="micro">확인하기</span><span class="mono">CHECK 01—03</span></span></div>
    <div class="split5">
      <div class="quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
        <h3 class="kh q">하루 중 그림자 길이가 가장 짧을 때는?</h3>
        <div class="ledger"><div class="lh q3"><span class="micro">NO.</span><span class="micro">ANSWER</span><span class="micro">CHECK</span></div>
          <button class="lr q3" data-opt="0"><span class="mono">A</span><span class="kh nm">오전 9시 30분</span><span class="mono dt">—</span></button><button class="lr q3" data-opt="1"><span class="mono">B</span><span class="kh nm">낮 12시 30분 무렵</span><span class="mono dt">—</span></button><button class="lr q3" data-opt="2"><span class="mono">C</span><span class="kh nm">오후 3시 30분</span><span class="mono dt">—</span></button>
        </div>
        <p class="fb" data-fb></p>
        <div class="btns"><button class="btn" data-act="retry">다시 풀기 <span class="mono">↺</span></button></div>
      </div>
      <div class="blk">
        <span class="micro">빈칸을 눌러 확인해요</span>
        <div class="row"><span class="mono num">01</span><p><button class="blank" data-blank aria-pressed="false"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</p></div><div class="row"><span class="mono num">02</span><p><button class="blank" data-blank aria-pressed="false"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</p></div><div class="row"><span class="mono num">03</span><p><button class="blank" data-blank aria-pressed="false"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</p></div>
        <span class="micro wl">오늘의 낱말</span>
        <p class="kh words">태양 고도 / 남중 고도 / 그림자 길이 / 기온</p>
      </div>
    </div>
  </div>
  <p class="nr">빈칸 규칙 없음 → 1.5px 선 칸으로 표현</p>
</section>
<section class="slide"><i class="hl t"></i><i class="hl b"></i><span class="hint">← → 키로 넘기기</span><span class="pg mono">P. 06 / 06</span>
  <div class="frame">
    <div class="topbar"><h2 class="kh">이 디자인 사용 설명서</h2><span class="lab"><span class="micro">디자인 안내</span><span class="mono">GUIDE 06</span></span></div>
    <div class="split6">
      <div class="index g6"><div class="row"><span class="mono num">01</span><div><h3 class="kh">한눈에</h3><p>방안지 위에 <b>코발트 잉크 한 색</b>으로만 그린 기술 보고서. 둘째 색·그림자·둥근 모서리가 없고, 픽셀을 쌓아 그래프와 장식을 만들어요.</p></div></div><div class="row"><span class="mono num">02</span><div><h3 class="kh">색</h3><p><span class="sw6"><span><i style="background:#F0EBDE"></i>크림 종이</span><span><i style="background:#1F2BE0"></i>코발트 잉크</span><span><i style="background:rgba(31,43,224,.18)"></i>18% 선</span><span><i style="background:rgba(31,43,224,.10)"></i>10% 격자</span></span></p></div></div><div class="row"><span class="mono num">03</span><div><h3 class="kh">글꼴</h3><p>제목·숫자 Newsreader → Kim jung chul Myungjo Regular<br>본문 Hanken Grotesk → Paperlogy 4Regular · 크롬 DM Mono</p></div></div><div class="row"><span class="mono num">04</span><div><h3 class="kh">이렇게 쓰면 좋아요</h3><p>측정 기록·데이터 표가 중심인 수업. 그래프는 칸을 쌓은 픽셀 막대로, 표에는 ↑ ↓ — 로 변화 표시.</p></div></div></div>
      <div class="sig6">
        <span class="micro">대표 장치 — 눌러 보세요</span>
        <div class="d6"><div class="dh"><h3 class="kh">픽셀 막대</h3><button class="btn sm" data-demo="#cg-px" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>막대 대신 칸을 쌓아요 — 켜진 칸 코발트, 꺼진 칸 10%.</p><div class="px6" id="cg-px"><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i></span><span><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class=""></i><i class=""></i></span></div></div>
        <div class="d6"><div class="dh"><h3 class="kh">계단식 글리치 기둥</h3><button class="btn sm" data-demo="#cg-gl" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>선언 장 한쪽을 어긋난 줄무늬 칸으로 채워 디지털 잡음처럼 보이게 해요.</p><div class="gl6" id="cg-gl"><svg class="glitch" viewBox="0 0 560 80" width="560" height="80"><defs><pattern id="g6a" width="12" height="12" patternUnits="userSpaceOnUse"><rect width="5" height="12" fill="#1F2BE0"/></pattern><pattern id="g6b" width="7" height="12" patternUnits="userSpaceOnUse"><rect width="3" height="12" fill="#1F2BE0"/></pattern></defs><rect x="0" y="0.0" width="560" height="11.9" fill="url(#g6a)"/><rect x="99" y="11.4" width="461" height="11.9" fill="url(#g6b)"/><rect x="36" y="22.9" width="524" height="11.9" fill="url(#g6a)"/><rect x="190" y="34.3" width="370" height="11.9" fill="url(#g6b)"/><rect x="108" y="45.7" width="452" height="11.9" fill="url(#g6a)"/><rect x="271" y="57.1" width="289" height="11.9" fill="url(#g6b)"/><rect x="172" y="68.6" width="388" height="11.9" fill="url(#g6a)"/></svg></div></div>
        <div class="d6"><div class="dh"><h3 class="kh">원장 표 변화 표시</h3><button class="btn sm" data-demo="#cg-ld" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>줄 사이 18% 선, 값 옆에 ↑ ↓ — 로 오르내림을 적어요.</p><div class="ld6" id="cg-ld"><span>9:30</span><b>38°<i>↑</i></b><span>12:30</span><b>57°<i>—</i></b><span>15:30</span><b>37°<i>↓</i></b></div></div>
      </div>
    </div>
  </div>
</section>
<nav class="dk-nav"></nav>
  </main>
</div>

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

---

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

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

```css
/* cobalt-grid — k-slide 공통 CSS v1 (채팅 AI용 받기 .md가 불러옴, 고치지 말 것) */
/* === KOREAN FONTS === */
@font-face{font-family:'kp-15';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/kim-jung-chul-myungjo/KimjungchulMyungjo-Regular.woff2") format("woff2");font-weight:400}
@font-face{font-family:'kp-16';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/paperlogy/Paperlogy-4Regular.woff2") format("woff2");font-weight:400}
/* === THEME === */
:root{--stage-bg:#F0EBDE;--slide-bg:#F0EBDE;
  --kt:'kp-15';--kb:'kp-16';--ka:'kp-16';
  --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 === */

/* --- 토큰(1920×1080 무대: edge 3.6vw=69px, 위 헤어라인 2.6vh=28px, 아래 2vh=22px, 쪽번호 4.8vh=52px) --- */
:root{--paper:#F0EBDE;--ink:#1F2BE0;--soft:#5560E5;--grid:rgba(31,43,224,.10);--faint:rgba(31,43,224,.18);--edge:69px}
.slide{background:var(--paper);color:var(--ink);font-family:'Hanken Grotesk',var(--kb),sans-serif}
/* 격자: 명세는 1px. 축소 화면(썸네일·작은 창)에서도 보이도록 1.5px로 둠 */
.slide::before{content:'';position:absolute;inset:0;background-image:linear-gradient(to right,var(--grid) 1.5px,transparent 1.5px),linear-gradient(to bottom,var(--grid) 1.5px,transparent 1.5px);background-size:44px 44px}
.hl{position:absolute;left:var(--edge);right:var(--edge);height:1.5px;background:var(--ink);z-index:2}
.hl.t{top:28px}.hl.b{bottom:22px}
.hint,.pg{position:absolute;bottom:52px;font:400 22px 'DM Mono',var(--kb),monospace;letter-spacing:.08em;z-index:2}
.hint{left:var(--edge);opacity:.4}.pg{right:var(--edge)}
.nr{position:absolute;left:0;right:0;bottom:52px;text-align:center;font-size:18px;opacity:.6;z-index:2}
.mono{font-family:'DM Mono',monospace;font-weight:400;letter-spacing:.06em}
.micro{font-weight:600;font-size:26px;letter-spacing:0}
.kh{font-family:'Newsreader',var(--kt),serif;font-weight:var(--wt);letter-spacing:0}
.btns{display:flex;gap:20px;flex-wrap:wrap}
.btn{border:1.5px solid var(--ink);padding:14px 32px;font-weight:600;font-size:30px;background:var(--paper)}
.btn.ghost{border-color:var(--faint)}
.btn:disabled{opacity:.3}

/* --- 1. 표지: 라벨 + 단원 + '학습 목표' + 학습 목표 display + 오른쪽 계단식 글리치 기둥 + QR 패치 --- */
.glitch{position:absolute;right:0;top:0;z-index:1}
.qr{position:absolute;z-index:3;width:150px;height:150px;display:grid;grid-template:repeat(8,1fr)/repeat(8,1fr);gap:2px;padding:6px;background:var(--paper);box-shadow:0 0 0 2px var(--paper)}
.qr i.on{background:var(--ink)}
.qr.q1{right:220px;top:110px}
.qr.q5{right:var(--edge);top:600px;width:96px;height:96px;padding:4px;gap:1.5px}
.cv{position:absolute;left:var(--edge);top:150px;width:1340px;z-index:2}
.unit{margin-top:22px;display:flex;align-items:baseline;gap:30px;font-size:72px;line-height:1.15;white-space:nowrap}
.unit span{font:italic 400 48px 'Newsreader',serif}
.gl{margin-top:70px}
.hero{margin-top:16px;font-size:112px;line-height:1.22;white-space:nowrap}
.hero .gk{font-style:normal}
.tags{margin-top:60px;display:flex;gap:30px;align-items:center;padding-top:18px;border-top:1px solid var(--ink);width:760px}
.tags .mono{font-size:26px}.who{font-weight:600;font-size:28px}

/* --- 내용 장 틀: 상단 바(제목 + 라벨) + 1.5px 규칙선 --- */
.frame{position:absolute;inset:70px var(--edge) 104px;z-index:2;display:flex;flex-direction:column}
.topbar{display:flex;justify-content:space-between;align-items:flex-end;padding-bottom:16px;border-bottom:1.5px solid var(--ink)}
.topbar h2{font-size:76px;line-height:1.15}
.topbar .lab{display:flex;flex-direction:column;align-items:flex-end;gap:8px}
.topbar .lab .mono{font-size:24px}

/* --- 2. 흐름: 종이색 그림 자리(18% 선) 속 측정기 그림 + 메모 | 정의 + 번호 목록 4단계(행 사이 18% 선, 켜지면 또렷) + 선 칸 버튼 --- */
.split2{flex:1;min-height:0;margin-top:26px;display:grid;grid-template-columns:840px 1fr;gap:56px}
.lcol{display:flex;flex-direction:column;gap:14px}
.fig{background:var(--paper);border:1px solid var(--faint);padding:14px 26px 8px;--g-ink:var(--ink);--g-acc:var(--ink);--g-stick:var(--ink);--g-board:var(--grid);--g-ruler:var(--paper);--g-prot:rgba(240,235,222,.85);--g-shadow:var(--ink);--g-font:'Hanken Grotesk',var(--kb),sans-serif;--g-sw:1.5}
.ft{font-size:20px}
.fnote{font-family:'Newsreader',var(--kt),serif;font-size:32px;line-height:1.4}
.rcol{display:flex;flex-direction:column;min-height:0}
.def{font-size:28px;line-height:1.5}
.def b{font-weight:600}
.index{margin-top:6px}
.row{display:grid;grid-template-columns:76px 1fr;align-items:baseline;padding:12px 0;border-bottom:1px solid var(--faint)}
.num{font-size:30px}
.row h3{font-size:40px;line-height:1.15}
.row p{margin-top:4px;font-size:28px;line-height:1.5}
.slide[data-step]:not([data-step="0"]) .index .row:not(.on){opacity:.35}
.rcol .btns{margin-top:auto}
.cap{margin-top:14px;font-size:28px;line-height:1.5}

/* --- 3. 숫자와 그래프: 통계 4개(Newsreader 숫자) + 픽셀 막대(1칸 = 5°, 켜짐 코발트 / 꺼짐 10%) + 숫자 줄 --- */
.stats{margin-top:22px;display:grid;grid-template-columns:repeat(4,1fr);gap:40px}
.st{display:flex;flex-direction:column;gap:6px;border-bottom:1px solid var(--faint);padding-bottom:12px}
.sv{font-size:88px;line-height:1}
.st p{font-size:28px;line-height:1.45}
.chart{margin-top:20px;display:flex;flex-direction:column;gap:4px}
.clab{display:flex;justify-content:space-between;align-items:baseline}
.clab .mono{font-size:22px}
.bars,.nrow{display:grid;grid-template-columns:230px repeat(7,1fr);gap:24px;align-items:end}
.bars{padding-bottom:6px;border-bottom:1.5px solid var(--ink)}
.ax{font-size:22px;line-height:1.3}
.col{display:flex;flex-direction:column;gap:6px}
.bv{font-size:24px}
.col.mx .bv{font-weight:500;text-decoration:underline}
.cells{display:flex;flex-direction:column-reverse;gap:3px}
.cells i{display:block;height:13px;background:var(--grid)}
.cells i.on{background:var(--ink)}
.nrow{align-items:baseline;padding:6px 0;border-bottom:1px solid var(--faint)}
.nrow .mono{font-size:28px}
.nrow.tm .mono{font-size:24px}
.src{margin-top:auto;font-size:20px;line-height:1.4}

/* --- 4. 비교와 표: 비교 두 칸(↑ / ↓) + 원장 표(머리 1.5px · 행 18% 선) / 번호 목록 + 인용(1px 윗선 출처) + 오른쪽 세로쓰기 라벨 --- */
.cmp{margin-top:20px;display:grid;grid-template-columns:1fr 1fr;gap:56px}
.cc{display:grid;grid-template-columns:76px 1fr;align-items:baseline;padding:14px 0;border-bottom:1px solid var(--faint)}
.cc .num{font-size:40px}
.cc h3{font-size:44px;line-height:1.2;margin-bottom:6px}
.cc p{font-size:28px;line-height:1.55}
.row4{flex:1;min-height:0;margin-top:26px;display:grid;grid-template-columns:1.15fr 1fr;gap:60px;margin-right:60px}
.ledger .lh,.ledger .lr{display:grid;grid-template-columns:76px 1.2fr 1fr 1fr 1fr;gap:16px;align-items:baseline}
.lh{padding-bottom:10px;border-bottom:1.5px solid var(--ink)}
.lh .micro{font-size:22px}
.lr{width:100%;text-align:left;padding:14px 0;border-bottom:1px solid var(--faint);font-size:28px;line-height:1.4}
.lr .mono{font-size:24px}
.nm{font-size:32px}
.rr{display:flex;flex-direction:column;gap:22px}
.li{display:grid;grid-template-columns:60px 1fr;align-items:baseline;padding:8px 0;border-bottom:1px solid var(--faint)}
.li .mono{font-size:24px}
.li p{font-size:28px;line-height:1.5}
.qt p{font-size:42px;line-height:1.3}
.attr{margin-top:14px;padding-top:12px;border-top:1px solid var(--ink);display:flex;justify-content:space-between}
.attr .mono{font-size:22px}
.vstack{position:absolute;right:var(--edge);top:300px;bottom:130px;width:44px;display:flex;flex-direction:column;align-items:center;justify-content:space-between;border-left:1px solid var(--faint);z-index:2}
.vstack .mono{writing-mode:vertical-rl;font-size:22px}

/* --- 5. 확인하기: 원장 퀴즈(정답 = 코발트 반전 · ↑ / 오답 = ↓) | 번호 목록 빈칸(선 칸) + 낱말 + QR 패치 --- */
.split5{flex:1;min-height:0;margin-top:26px;display:grid;grid-template-columns:1.05fr 1fr;gap:70px}
.quiz,.blk{display:flex;flex-direction:column;min-height:0}
.q{font-size:52px;line-height:1.25}
.quiz .ledger{margin-top:24px}
.ledger .q3{grid-template-columns:76px 1fr 180px}
.lr.q3{align-items:center}
.lr .dt{opacity:.6}
.lr.right{background:var(--ink);color:var(--paper)}
.lr.right .dt{opacity:1}
.lr:disabled:not(.right){opacity:.45}
.fb{margin-top:20px;min-height:90px;font-size:30px;line-height:1.5}
.quiz .btns{margin-top:auto}
.blk{gap:10px}
.blk .row{grid-template-columns:76px 1fr;align-items:baseline}
.blk .row p{font-size:30px;line-height:1.6}
.blank{position:relative;min-width:180px;margin-right:10px;padding:2px 14px;border:1.5px solid var(--ink);font-family:'Newsreader',var(--kt),serif;font-size:30px;text-align:center;background:var(--paper)}
.blank span{visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0}
.blank.open{background:var(--ink);color:var(--paper)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.wl{margin-top:auto}
.words{font-size:44px;line-height:1.3}
/* --- 6. 디자인 안내: 번호 목록 | 1.5px 선 칸 시연 3개 --- */
.split6{flex:1;min-height:0;margin-top:24px;display:grid;grid-template-columns:900px 1fr;gap:64px}
.g6{margin-top:0}
.g6 .row{padding:14px 0}
.g6 h3{font-size:36px}
.g6 p{font-size:25px;line-height:1.5}
.g6 b{font-weight:600}
.sw6{display:flex;flex-wrap:wrap;gap:6px 22px}
.sw6 i{display:inline-block;width:26px;height:26px;margin-right:8px;vertical-align:-6px;border:1.5px solid var(--ink)}
.sig6{display:flex;flex-direction:column;gap:16px}
.d6{border:1.5px solid var(--ink);background:var(--paper);padding:14px 22px 16px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:16px}
.d6 h3{font-size:34px}
.d6 p{margin-top:2px;font-size:21px;line-height:1.4}
.btn.sm{font-size:20px;padding:6px 16px}
.btn.sm[aria-pressed="true"]{background:var(--ink);color:var(--paper)}
.px6{margin-top:10px;height:80px;display:flex;gap:14px;align-items:flex-end}
.px6 span{display:flex;flex-direction:column-reverse;gap:3px;width:44px}
.px6 i{height:10px;background:var(--grid)}
.px6.play i.on{background:var(--ink)}
.gl6{margin-top:10px;height:80px;overflow:hidden;visibility:hidden}
.gl6.play{visibility:visible}
.gl6 .glitch{position:static}
.ld6{margin-top:10px;display:grid;grid-template-columns:repeat(3,auto 1fr);align-items:baseline;gap:6px 16px;border-top:1.5px solid var(--ink);padding-top:10px;font-size:24px}
.ld6 span{font-family:'DM Mono',monospace;font-size:20px}
.ld6 b{font:400 30px 'Newsreader',serif}
.ld6 i{font-style:normal;margin-left:8px;opacity:0}
.ld6.play i{opacity:1}

/* === 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을 만드세요.)
