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

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

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

## 라이선스

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

- SLEI Gothic TTF: SLEI Gothic TTF — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: © Copyright Seoul Lifelong Education Institute. All rights reserved. Font designed by Leedotype.
  파일: SLEIGothicTTF.ttf
- Hakgyoansim Wooju: Hakgyoansim Wooju — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright © KERIS. All rights reserved.
  파일: HakgyoansimWoojuR.ttf
- 야근하는 김주임: 야근하는 김주임 — 야근하는 김주임 (Overtime Kim Joo-im) — 네이버 / 눈누: https://noonnu.cc/font_page/561
  파일: Kimjuim.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/retro-zine.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/retro-zine.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 SLEI Gothic TTF(400) · 본문 Hakgyoansim Wooju(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. 디자인 규칙 (`retro-zine` design.md)

````markdown
---
version: alpha
name: Retro Zine
description: "A risograph-zine editorial system on warm khaki paper with a deep forest-green accent and ink-black structure. Display type runs in Bebas Neue (condensed industrial sans, uppercase, generously tracked); body type runs in Space Grotesk at weight 300–500; handwritten emphasis runs in Caveat. A subtle SVG grain overlay sits over every slide, reinforcing the printed-paper feel. The aesthetic borrows from independent press, mid-century activist posters, and DIY zine culture: slightly rotated stamp marks, masking-tape pieces in collage layouts, drop caps, and offset paper-on-paper shadows. The effect is hand-printed editorial — warm but disciplined, confident but tactile."

colors:
  bg: "#C8B99A"
  bg-dark: "#B8A98A"
  green: "#008F4D"
  green-light: "#00A85D"
  black: "#1A1A1A"
  white: "#F4EFE6"

color-aliases:
  line: black

typography:
  display-hero:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(56px, 10vw, 160px)"
    fontWeight: 400
    lineHeight: 0.85
    letterSpacing: 0.04em
    textTransform: uppercase
  display-cover:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(48px, 10vw, 140px)"
    fontWeight: 400
    lineHeight: 0.88
    letterSpacing: 0.04em
    textTransform: uppercase
  display:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(48px, 8vw, 120px)"
    fontWeight: 400
    lineHeight: 0.9
    letterSpacing: 0.04em
    textTransform: uppercase
  headline:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(42px, 6vw, 90px)"
    fontWeight: 400
    lineHeight: 0.95
    letterSpacing: 0.03em
    textTransform: uppercase
  headline-md:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(36px, 5vw, 72px)"
    fontWeight: 400
    lineHeight: 0.95
    letterSpacing: 0.03em
    textTransform: uppercase
  statement:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(36px, 6vw, 90px)"
    fontWeight: 400
    lineHeight: 1.1
    letterSpacing: 0.02em
    textTransform: uppercase
  title:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(24px, 3vw, 42px)"
    fontWeight: 400
    lineHeight: 1.1
    letterSpacing: 0.04em
    textTransform: uppercase
  number-hero:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(80px, 12vw, 160px)"
    fontWeight: 400
    lineHeight: 1.0
    letterSpacing: 0.02em
  number-md:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(44px, 6vw, 80px)"
    fontWeight: 400
    lineHeight: 1.0
    letterSpacing: 0.02em
  drop-cap:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "clamp(48px, 6vw, 80px)"
    fontWeight: 400
    lineHeight: 0.8
    letterSpacing: 0.02em
  body:
    fontFamily: "'Space Grotesk', sans-serif"
    fontSize: "clamp(13px, 1.2vw, 16px)"
    fontWeight: 400
    lineHeight: 1.7
  body-md:
    fontFamily: "'Space Grotesk', sans-serif"
    fontSize: "clamp(14px, 1.3vw, 18px)"
    fontWeight: 400
    lineHeight: 1.6
  label-eyebrow:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "14–18px"
    fontWeight: 400
    lineHeight: 1.2
    letterSpacing: 0.2em
    textTransform: uppercase
  label-spaced:
    fontFamily: "'Space Grotesk', sans-serif"
    fontSize: "12–14px"
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: 0.25em
    textTransform: uppercase
  caption-feature:
    fontFamily: "'Bebas Neue', sans-serif"
    fontSize: "13–15px"
    fontWeight: 400
    lineHeight: 1.2
    letterSpacing: 0.2em
    textTransform: uppercase
  hand-script:
    fontFamily: "'Caveat', cursive"
    fontSize: "clamp(22px, 3vw, 36px)"
    fontWeight: 600
    lineHeight: 1.3
  hand-script-sm:
    fontFamily: "'Caveat', cursive"
    fontSize: "clamp(16px, 2vw, 22px)"
    fontWeight: 400
    lineHeight: 1.3
  hand-script-lg:
    fontFamily: "'Caveat', cursive"
    fontSize: "clamp(24px, 3vw, 36px)"
    fontWeight: 600
    lineHeight: 1.3

spacing:
  slide-pad: 60px
  slide-pad-wide: "60px 80px"
  card-pad-lg: 48px
  card-pad-md: 32px
  card-pad-sm: 24px
  gap-lg: 60px
  gap-md: 40px
  gap-sm: 24px

canvas:
  width: 100vw
  height: 100vh

components:
  grain-overlay:
    backgroundImage: "SVG fractal-noise filter, base 200×200 tile"
    opacity: 0.07
    zIndex: 9999
    description: "Fixed, full-viewport SVG grain overlay sitting above all content. Imitates the print-grain texture of a risograph or letterpress page. Pointer-events disabled. Required on every slide."
  line-box:
    border: "3px solid {colors.black}"
    description: "Generic outlined card with 3px solid black border on khaki background. The system's default content container."
  line-divider:
    border: "3px solid {colors.black}"
    description: "Strict 3px black rule used as a region divider. May be top, bottom, left, or right of a region; meets adjacent borders without gap."
  line-thin:
    border: "2px solid {colors.black}"
    description: "2px black rule used inside a section for sub-region division (editorial column rule, ed-header bottom rule)."
  line-fine:
    border: "1.5px solid {colors.black}"
    description: "1.5px black rule used inside grid containers for cell separation (sub-cells inside a 3px-bordered grid)."
  stamp:
    transform: "rotate(-8deg) or rotate(6deg)"
    display: inline-block
    description: "Any element may be rotated -8deg (stamp) or 6deg (stamp-alt) to read as a hand-pressed ink stamp or applied label. Reserve for badges, callouts, and decorative overlays."
  stamp-mark:
    background: "{colors.black}"
    color: "{colors.green}"
    fontFamily: "'Bebas Neue', sans-serif"
    padding: "10px 24px"
    border: "2px solid {colors.green}"
    transform: "rotate(-8deg)"
    fontSize: 18px
    letterSpacing: 0.1em
    description: "Approval / status stamp — black background, green text, green 2px border, rotated -8deg. Used as a 'stamp of authenticity' callout."
  ribbon-bar:
    background: "{colors.green}"
    color: "{colors.white}"
    padding: "4–8px 12–20px"
    description: "Solid green color-block that contains light cream text — used as section labels, accent strips, and inline highlight bars."
  inline-highlight:
    background: "{colors.black}"
    color: "{colors.bg}"
    padding: "2px 8px"
    fontWeight: 600
    description: "Black-on-khaki marker highlight applied inline inside body paragraphs to lift a phrase. The print equivalent of a marker pen swipe."
  drop-cap:
    float: left
    fontSize: "clamp(48px, 6vw, 80px)"
    fontFamily: "'Bebas Neue', sans-serif"
    color: "{colors.green}"
    lineHeight: 0.8
    marginRight: 12px
    description: "Oversized green initial cap at the start of an editorial paragraph. Bebas Neue, line-height 0.8, floated left so body text wraps around."
  card-offset:
    background: "{colors.white}"
    border: "3px solid {colors.black}"
    positionBefore:
      offset: "12px down, 12px right"
      background: "{colors.green}"
      zIndex: -1
    description: "Card with a paper-on-paper offset effect — a solid green slab sits 12px behind the card, offset down-and-right. Reads as a colored shadow without using box-shadow."
  collage-piece:
    border: "3px solid {colors.black}"
    padding: 24px
    position: absolute
    transform: "rotate(-5deg to 5deg)"
    description: "Free-positioned collage panel with a 3px black border and small rotation. Backgrounds vary across pieces — white, khaki-dark, green, or black-with-inversion. Used in scatter-on-page compositions."
  tape:
    width: 80px
    height: 24px
    background: "rgba(255,255,255,0.4)"
    border: "1px solid rgba(0,0,0,0.1)"
    transform: "rotate(-40deg to 35deg)"
    description: "Translucent masking-tape rectangle layered at random angles over a collage to suggest physically taped-down pieces. Positioned absolutely; 1px hairline border. Always semi-transparent white."
  divider-stub:
    width: 60–80px
    height: 4px
    background: "{colors.white} or {colors.green}"
    description: "Short solid horizontal rule used as a centered visual breath above/below a statement or closing title. 4px tall."
  rsvp-field:
    borderBottom: "2px solid {colors.black}"
    paddingBottom: 8px
    description: "Form-field row pattern: small Bebas Neue green label, hand-script value drawn over a 2px black underline. Mimics a written form."
  ledger-row:
    borderBottom: "1.5px solid {colors.black} (header) or 1px solid rgba(black, 0.22) (body)"
    padding: "10–18px 0"
    description: "Horizontal data row pattern: date | title | edition | track | nr. Header row has stronger bottom border; body rows have hairline dividers."
  chip:
    padding: "4px 10px"
    fontFamily: "'JetBrains Mono', ui-monospace, monospace"
    fontSize: "11–12px"
    color: "{colors.white}"
    textTransform: uppercase
    letterSpacing: 0.06em
    description: "Mono-font color chip used inline in tabular ledger rows to tag a row's category. Fill pulls from green / red-stamp / orange / pink / blue as a categorical palette extension."
---

## 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

Retro Zine is a **risograph-zine editorial system** on a warm khaki canvas (`{colors.bg}` — #C8B99A) with deep forest-green (`{colors.green}` — #008F4D) as the meaningful accent and ink-black (`{colors.black}` — #1A1A1A) as the structural color. The aesthetic borrows from independent press culture, mid-century activist posters, and DIY zine layouts: condensed industrial display type, hand-script emphasis, slightly rotated stamps, masking-tape collage marks, drop caps, and a print-grain overlay that ties every surface to a printed-paper register.

The typeface stack pairs three faces with distinct emotional roles. **Bebas Neue** is the display voice — a condensed, all-caps industrial sans with generous tracking (0.02–0.04em) used for every headline, statement, statistic, numeral, and label. Its compressed verticality is the system's visual identity; substituting any other display sans loses the zine voice. **Space Grotesk** is the body voice — a clean humanist geometric sans at weight 300–500 for paragraphs, used at small sizes (13–18px) which preserves the magazine column-text density. **Caveat** is the hand-script voice — a casual ballpoint cursive used for author attributions, side notes, captions on display elements, and the form-field "writing" in RSVP-style layouts. The three faces together read as "an editorial spread typeset by a small press."

The color philosophy is **earth + forest**: a warm khaki paper canvas, a deeper khaki tonal sibling for layered surfaces, deep forest-green for accents and accent surfaces, ink-black for structure and body, and an off-white cream (`{colors.white}` — #F4EFE6) for cards and inverted text fills. The white is deliberately not pure — it's a soft cream that sits as paper inside paper rather than as a hard rectangle. Green carries the system's emotional voice: it is what activates a section, what stamps approval, what marks the brand. The same hex (#008F4D) appears as drop caps, ribbon bars, inline labels, statement backgrounds, and the progress bar.

Depth comes from **paper-on-paper offset blocks** and **slight rotations**, not blurred shadows. The signature treatment: a `{components.card-offset}` carries a solid green slab sitting 12px down-and-right behind it via an absolutely-positioned `::before` pseudo-element. The visual effect is a layered paper or letterpress underprint rather than a soft drop shadow. Rotations on stamps (`-8deg` or `6deg`) and on collage pieces (`-5deg` to `5deg`) add the hand-placed feeling.

**Density philosophy: medium-high.** The zine register depends on visual richness — collage compositions, multi-column editorial layouts, drop caps inside body text, tabular ledgers with chip categories, ribbon-bar headers stamped at angles. A slide that holds only one centered headline reads as underdesigned; the zine voice expects a layout to be packed with editorial moves. The correct density is one dominant text moment supported by multiple subordinate components (decorative stamps, eyebrow labels, divider stubs, hand-script attributions, drop caps). Reserve true sparseness for the manifesto / statement moment where a single large quote dominates a solid green field.

**Key Characteristics:**
- Warm khaki paper canvas (`{colors.bg}`) + deep forest-green accent (`{colors.green}`) + ink-black structure (`{colors.black}`).
- An SVG grain overlay (`{components.grain-overlay}`) sits over every slide at 0.07 opacity, reinforcing the printed-paper register.
- Bebas Neue uppercase + tracked for every display moment; Space Grotesk at small sizes for body; Caveat for hand-script emphasis.
- 3px solid black structural borders divide regions; 2px and 1.5px borders subdivide.
- Paper-on-paper offset cards: green slab sits 12px behind a white card via `::before`.
- Stamps and collage pieces carry small rotations (-8°, +6°, -5° to +5°).
- Translucent masking-tape pieces (`{components.tape}`) layered over collage compositions.
- Green drop caps, green ribbon bars, and green inline highlights mark editorial emphasis.

## Colors

### Palette
- **Background** (`{colors.bg}` — #C8B99A): The warm khaki paper canvas. The default surface for every slide. Saturated enough to read as paper-with-history rather than as a neutral; warm enough to harmonize with the forest-green accent.
- **Background Dark** (`{colors.bg-dark}` — #B8A98A): A slightly darker tonal sibling of the canvas. Used for layered surface regions when one half of a split-screen needs to sit visually behind the other, and for collage pieces that want to read as "paper on khaki paper."
- **Green** (`{colors.green}` — #008F4D): Deep forest green. The system's accent color — hero numerals, drop caps, ribbon bars, statement-slide backgrounds, progress bar, inline highlights, RSVP labels, the offset slab behind cards, divider stubs on the closing slide. The single most distinctive non-canvas color.
- **Green Light** (`{colors.green-light}` — #00A85D): A slightly brighter sibling of green. Available as a hover-state or secondary green where the deep green needs a step-up; rarely used in baseline static slides.
- **Black** (`{colors.black}` — #1A1A1A): Ink-black. The structural color — all borders, all body text, all dividers, all closing-slide backgrounds, all label fills (when inverted). Slightly softer than pure black (#000000) so it sits as warm ink on warm paper.
- **White / Cream** (`{colors.white}` — #F4EFE6): Soft cream. Used as card fills (paper-on-paper), as text inside black surfaces, and as the divider-stub color on statement slides. Critically, this is not pure white — it's a paper-cream that maintains the warm-paper register even when used as a "white" surface.

### Defaults
- **Default surface background**: `{colors.bg}` — every slide opens on warm khaki paper.
- **Default headline color**: `{colors.green}` for primary section headlines and hero titles; `{colors.black}` for body-paired headlines in two-column or split layouts. When in doubt, reach for `{colors.green}` — a green headline is the system's loudest editorial signal.
- **Default body text color**: `{colors.black}`.
- **Default border color**: `{colors.black}` — every structural border is black, no exceptions.
- **Default accent surface for emphasis (statement, hero callout)**: `{colors.green}` with `{colors.white}` text.
- **Default text color on a `{colors.green}` surface**: `{colors.white}` (cream).
- **Default text color on a `{colors.black}` surface**: `{colors.bg}` (the khaki canvas), so type still reads as "ink on paper" even in inversion. Green accents on a black surface (closing slide eyebrow + hand-script) lift the inversion.
- **Default eyebrow / label color**: `{colors.green}` for Bebas Neue labels; `{colors.black}` for letter-spaced Space Grotesk labels.
- **Default drop-cap color**: `{colors.green}`. Drop caps are the editorial fingerprint and they are always green.
- **Default hand-script color**: `{colors.black}` on khaki/cream surfaces; `{colors.green}` on black surfaces (closing).
- **Default inline highlight**: black-on-khaki (`{components.inline-highlight}`) — used to lift phrases inside body paragraphs as if marked with a pen.

The green and black accents are not interchangeable: **green = emphasis** (this is what we want you to notice), **black = structure** (this is what holds the page together). Reversing them — using black for emphasis and green for structure — flips the system's voice.

## Typography

### Font Family
The system pairs three Google Fonts:

- **Bebas Neue** (display): A condensed all-caps industrial sans-serif. Single weight (400) but reads bold by virtue of its dense vertical strokes. Used uppercase with 0.02–0.04em letter-spacing for every display moment — headlines, statements, statistics, ordinals, eyebrow labels. The narrow tracked Bebas voice is what makes the system unmistakably "zine."
- **Space Grotesk** (body): A clean humanist geometric sans-serif with subtle quirky proportions. Used at weights 300–500 for body paragraphs at small sizes (13–18px), and at weight 600 for letter-spaced Space Grotesk caps labels. Provides the readable counterpoint to Bebas's expressive density.
- **Caveat** (hand-script): A casual handwritten cursive. Used at weights 400–700 for author attributions ("— Our founding principle since day one"), side notes, decorative captions on display elements, value-fills in RSVP-style form layouts. Provides warmth and a human-hand voice against the otherwise typeset system.

There is no fourth face. Italic does not exist (Caveat is a script face, not an italic). Underline does not exist. Emphasis is achieved by switching face (Space Grotesk body → Caveat hand-script for a personal note, Bebas Neue display for a callout) or by color (`{colors.black}` → `{colors.green}`).

### Type Scale

| Token | Size (clamp) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display-hero}` | 56–160px | Bebas Neue | 400 | Closing or oversized cover headline |
| `{typography.display-cover}` | 48–140px | Bebas Neue | 400 | Cover / opening display headline |
| `{typography.display}` | 48–120px | Bebas Neue | 400 | Major declarative or callout display |
| `{typography.headline}` | 42–90px | Bebas Neue | 400 | Primary section headline |
| `{typography.statement}` | 36–90px | Bebas Neue | 400 | Long-form quoted statement |
| `{typography.headline-md}` | 36–72px | Bebas Neue | 400 | Editorial section header |
| `{typography.title}` | 24–42px | Bebas Neue | 400 | Region or collage-piece title |
| `{typography.number-hero}` | 80–160px | Bebas Neue | 400 | Hero statistic numeral |
| `{typography.number-md}` | 44–80px | Bebas Neue | 400 | Tile or sub-stat numeral |
| `{typography.drop-cap}` | 48–80px | Bebas Neue | 400 | Initial cap leading an editorial paragraph |
| `{typography.body-md}` | 14–18px | Space Grotesk | 400 | Lead paragraph or emphasized body |
| `{typography.body}` | 13–16px | Space Grotesk | 400 | Standard paragraph body |
| `{typography.label-eyebrow}` | 14–18px | Bebas Neue | 400 | Eyebrow label above a headline, tracked 0.2em |
| `{typography.label-spaced}` | 12–14px | Space Grotesk | 600 | Tracked all-caps small label |
| `{typography.caption-feature}` | 13–15px | Bebas Neue | 400 | Tracked all-caps caption or feature-callout label |
| `{typography.hand-script}` | 22–36px | Caveat | 600 | Author attribution, decorative note, statement byline |
| `{typography.hand-script-sm}` | 16–22px | Caveat | 400 | Small handwritten label or descriptor |
| `{typography.hand-script-lg}` | 24–36px | Caveat | 600 | Larger handwritten subtitle |

### Defaults
- **Default size for a primary section headline**: `{typography.headline}` (42–90px clamp) in `{colors.green}`.
- **Default size for a cover or oversized opening headline**: `{typography.display-cover}` (48–140px clamp) in `{colors.green}`.
- **Default size for paragraph body**: `{typography.body}` (13–16px clamp) — the zine register expects small body type, not modern 18px+ paragraphs.
- **Default size for a lead paragraph or emphasized body**: `{typography.body-md}` (14–18px).
- **Default size for an eyebrow label above a headline**: `{typography.label-eyebrow}` (14–18px) in `{colors.green}`, tracked 0.2em uppercase.
- **Default size for a hero numerical figure**: `{typography.number-hero}` (80–160px clamp) in `{colors.green}`.
- **Default size for any hand-script attribution / side note**: `{typography.hand-script}` (22–36px clamp).
- **Default weight for any Bebas display element**: 400 (Bebas Neue ships at 400; weight changes are not part of the system).
- **Default weight for body**: 400; for tracked-caps small labels: 600.

When unsure between `{typography.headline}` and `{typography.title}` for the dominant text moment on a slide, reach for `{typography.headline}` — `{typography.title}` is for collage-piece or region-level subtitling within a slide.

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every Bebas Neue element is uppercase.** The font has lowercase glyphs but they are not used in this system. Sentence-case Bebas is not part of the vocabulary.
- **Every Bebas Neue element carries positive letter-spacing of at least 0.02em.** Default tracking on Bebas reads as cramped; the 0.02–0.04em opens it up. Labels and eyebrows track even more (0.2–0.25em).
- **Every primary section headline is set in `{colors.green}`.** Black headlines exist (for body-paired columns) but the system's loudest editorial voice is green-on-khaki.
- **Every editorial paragraph that opens a column may carry a drop cap.** The drop cap is always `{components.drop-cap}` — green, Bebas Neue, line-height 0.8, floated left. Use it as the opening flourish for a feature-length body column.
- **Every hand-script element uses Caveat.** Substituting another script face loses the personal-note voice.
- **Hand-script attributions follow display headlines on quote / statement layouts.** A statement without a hand-script byline reads as incomplete; the byline grounds the quote as a human voice.
- **Inline highlights inside body use the black-on-khaki pattern** (`{components.inline-highlight}`), not green-on-khaki. Green inline reads as a typo; black inline reads as a marker stripe.

### Typography Principles
The system's typographic rhythm comes from **three-face contrast**: condensed industrial Bebas display (loud, tracked, uppercase) → clean Space Grotesk body (quiet, small, sentence case) → expressive Caveat hand-script (personal, looser, signature-style). Slides that use only one face read as monotonous; slides that mix all three within a single composition read as zine-correct.

Line-height: tight on display (0.85–1.1), generous on body (1.6–1.7), loose on hand-script (1.3). Never invert these — tight body and loose display both break the rhythm.

## Layout

### Canvas System
The system targets `100vw × 100vh` — full viewport. Each `.slide` is absolutely positioned to fill the viewport; only the `.active` slide is visible (opacity 1, others at opacity 0). Slide transitions use a 0.6s opacity + translateY(20px) ease for a soft paper-shuffle feel. Navigation is JS-driven via arrow keys, space, click, and touch swipe. A 4px tall `{colors.green}` progress bar runs flush along the bottom edge.

### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 60px | Standard slide outer padding |
| `{spacing.slide-pad-wide}` | 60px 80px | Editorial column-spread outer padding |
| `{spacing.card-pad-lg}` | 48px | Inside hero cards (RSVP, large callout) |
| `{spacing.card-pad-md}` | 32px | Inside grid-box cells |
| `{spacing.card-pad-sm}` | 24px | Inside collage pieces, smaller card cells |
| `{spacing.gap-lg}` | 60px | Editorial column gap |
| `{spacing.gap-md}` | 40px | Standard region gap |
| `{spacing.gap-sm}` | 24px | Tight inline gap |

### Persistent Chrome
Three persistent elements live outside the slide composition:
- **Progress bar** flush along the bottom-left, 4px tall, fill in `{colors.green}`. Grows as the deck advances.
- **Slide counter** at bottom-right — Bebas Neue 14px in a 2px-bordered cream chip with khaki ink.
- **Nav hint** at bottom-center — a black-fill pill with cream text, fading in only on `body:hover` (0.4s opacity transition).

### Region Borders vs Internal Padding
The system follows a **border-as-divider** principle for grid containers — a parent container has a 3px solid black outer border, and each child cell has a 1.5px solid black border that creates a hairline cell-to-cell divider. Where regions abut at a slide-edge (split-screen layouts), the dividing line is 3px solid black with the two regions meeting it directly — no gap.

For free compositions (collage, hero, manifesto), regions are positioned absolutely with rotation and overlap; borders sit on individual pieces, not on the slide grid.

## Depth and Elevation

### Paper-on-Paper Offset Block (Primary Technique)
The signature depth treatment is the **offset color block**: a card carries a `::before` pseudo-element absolutely positioned, offset 12px down-and-right, filled in `{colors.green}` (or another accent), and z-indexed behind the card. The visual effect is a layered paper underprint — the card looks like it sits on top of a slightly-larger green sheet of paper, with the green showing through at the bottom-right edges. Used on hero RSVP cards and primary callout containers.

### Rotation (Secondary Technique)
Small rotations (`-8deg` stamp, `+6deg` stamp-alt, `-5deg` to `+5deg` collage) on stamp marks, RSVP labels, visual overlay callouts, and collage pieces give the system its hand-placed energy. Rotations are intentional — never accidental tilt — and reserved for elements meant to read as physical artifacts (stamps, taped pieces, applied labels).

### Grain Overlay (Atmospheric Texture)
A subtle SVG fractal-noise overlay sits over every slide at 0.07 opacity, tinting all surfaces with print grain. This is not depth in the strict sense — it's surface texture that grounds every flat color block in the printed-paper register. Removing the grain breaks the zine voice immediately.

### No Web Shadows
The system uses **no blurred `box-shadow`, no `drop-shadow`, no rgba shadow tints** for depth. The offset color block, the rotations, and the grain overlay are the entire depth grammar. A modern soft shadow on any element breaks the print aesthetic.

### Color-Block Contrast
Beyond shadows and rotations, **green-on-khaki and black-on-khaki contrast** provides regional depth. A green ribbon bar inside a khaki region visually projects forward; a black region behind a white card visually recedes. The palette's high contrast is the secondary depth signal.

## Shapes and Treatment

### Border Radius
The system has **no rounded corners**. Every shape — cards, ribbon bars, stamps, RSVP cards, table cells, drop caps, chips, divider stubs — is a strict rectangle or square. Border-radius is `0` system-wide.

### Border Weights
- **3px solid `{colors.black}`** — the universal structural border on cards, region dividers, grid container outer borders, collage pieces, RSVP cards, hero callouts.
- **2px solid `{colors.black}`** — used for editorial column rules, RSVP-field underlines, ed-header bottoms, and the stamp-mark green border.
- **1.5px solid `{colors.black}`** — used for grid cell sub-borders inside a 3px outer-bordered container, and for ledger header underlines.
- **1px solid rgba(black, 0.22)** — used for ledger row dividers and hairline tabular separations.

Borders are always black. Colored borders do not exist except the green border on the `{components.stamp-mark}` approval stamp.

### Decorative Element Types

**Line box** (`{components.line-box}`) — Generic 3px-bordered card on khaki background. The system's default content container. Padding from the `{spacing.card-pad-*}` scale.

**Card with offset** (`{components.card-offset}`) — White cream card with a 3px black border and a 12px-offset green slab sitting behind via `::before`. The signature paper-on-paper card.

**Stamp** (`{components.stamp}` / `{components.stamp-mark}`) — Any element may be rotated -8° (stamp) or +6° (stamp-alt) to read as a hand-pressed mark. The `stamp-mark` variant is a black rectangle with green text and green border. Used as approval seals, "CONTACT US" badges, and editorial stamps.

**Collage piece** (`{components.collage-piece}`) — Free-positioned panel with 3px black border and small rotation. Backgrounds rotate across pieces: green, white-cream, khaki-dark, black-inverted. Used in collage compositions where multiple pieces scatter across the slide with overlap.

**Tape** (`{components.tape}`) — Translucent white rectangle layered at random angle over collage pieces to suggest physical taped-down paper. Always semi-transparent, always at a sharp angle (-40° to +35°).

**Ribbon bar** (`{components.ribbon-bar}`) — Solid green color block with cream text — used as eyebrow strips, accent bars, and inline section labels. Read as a printed ribbon glued onto the page.

**Drop cap** (`{components.drop-cap}`) — Oversized green Bebas Neue initial that opens an editorial paragraph. Floated left, line-height 0.8, body text wraps around.

**Inline highlight** (`{components.inline-highlight}`) — Black-on-khaki marker swipe applied inline inside body paragraphs to lift a phrase. The print equivalent of a marker pen.

**RSVP field** (`{components.rsvp-field}`) — Form-field row pattern with a Bebas Neue green label paired with hand-script Caveat "writing" over a 2px black underline. The system's "filled-by-hand" form pattern.

**Ledger row** (`{components.ledger-row}`) — Horizontal data row pattern with date | title | edition | track | nr columns. Header row has 1.5px black underline; body rows have 1px hairline dividers. Each row may contain a color-coded chip (`{components.chip}`) tagging its category.

**Chip** (`{components.chip}`) — Mono-font color block (JetBrains Mono if used, else default mono) tagging a row category. Fill colors: green, plus the categorical-palette extension on slides that pull from the broader stamp palette.

**Divider stub** (`{components.divider-stub}`) — A short 4px solid horizontal rule (60–80px wide), centered, used as visual breath above/below a hero title or statement. White on green surfaces, green on black surfaces.

**Hand-script element** — Any text in Caveat. The system signal for "human voice" — attributions, side notes, captions, RSVP-field fills, closing-slide sign-offs.

## Do's and Don'ts

### Do
- Keep the SVG grain overlay (`{components.grain-overlay}`) on every slide at 0.07 opacity. It is the texture that anchors the entire deck to the printed-paper register.
- Use Bebas Neue uppercase with 0.02–0.04em tracking for every display, headline, statement, statistic, numeral, and eyebrow label.
- Reach for `{colors.green}` as the default headline color for primary section headlines. Green-on-khaki is the system's loudest editorial signal.
- Use the paper-on-paper offset pattern (`{components.card-offset}`) on hero callouts and RSVP-style cards — a green slab behind a white card via `::before`.
- Apply small rotations (-8° stamps, -5° to +5° collage pieces) to elements meant to read as physical artifacts. Rotation should always feel intentional.
- Use drop caps (`{components.drop-cap}`) to open editorial body columns. They are the system's editorial fingerprint.
- Mix the three faces — Bebas Neue display + Space Grotesk body + Caveat hand-script — within a single composition. Three-face contrast is the typographic rhythm.
- Set inline highlights inside body paragraphs in black-on-khaki (`{components.inline-highlight}`), mimicking a marker swipe.
- Pair every quote / statement with a Caveat hand-script byline below. The script attribution grounds the quote as a human voice.
- Layer translucent tape pieces (`{components.tape}`) at sharp angles over collage compositions to suggest physical taped-down paper.

### Don't
- Don't round any corner. Border-radius is 0 system-wide on every element.
- Don't use blurred `box-shadow`. All depth comes from the offset color block, rotation, and the grain overlay.
- Don't substitute another display face for Bebas Neue. The condensed industrial tracked-uppercase voice is the entire system identity.
- Don't use Bebas Neue in sentence case. Bebas always renders uppercase in this system; lowercase Bebas reads as wrong.
- Don't substitute another script face for Caveat. The casual ballpoint voice is part of the system; Lobster, Pacifico, etc. land elsewhere.
- Don't introduce a third brand color. Khaki + green + black + cream is the system. Adding blue or red breaks the earth-and-forest palette. The chip palette extension (orange / pink / blue / red) is reserved for categorical chip tags inside tabular ledgers — not for general accents.
- Don't use green-on-khaki for inline highlights. Inline marker swipes are black-on-khaki; green inline reads as a typo.
- Don't tilt elements more than ±8°. Beyond that, hand-placed becomes broken.
- Don't put body text larger than 18px. The zine column-density register depends on small body type (13–16px). Modern 20px+ body reads as overscaled.
- Don't use pure white (#FFFFFF) for cards. The cream (`{colors.white}` #F4EFE6) maintains the paper-on-paper register; pure white reads as digital.

## Responsive Behavior

The system targets `100vw × 100vh` and uses `clamp()` throughout for fluid scaling. A single media query at `max-width: 768px` reflows multi-column layouts to single-column, removes inter-column border rules and replaces them with bottom-borders, and reduces slide padding to 32px.

### Scaling Behavior
- Display headlines scale from 48px at minimum to 140–160px at maximum.
- Body text scales from 13px to 16–18px.
- Padding scales from 32px (mobile) to 60–80px (desktop).
- Borders, tape sizes, and stamp rotations are fixed — they do not scale with viewport.

### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, `Space`, `Enter`, `PageDown`, or a click on the right half of the viewport.
- Slides reverse via `ArrowLeft`, `ArrowUp`, `PageUp`, or a click on the left half.
- The active slide carries the `.active` class; inactive slides are at opacity 0 with `translateY(20px)`.
- Touch swipe horizontal advances/reverses on mobile.
- The nav hint at bottom-center fades in on `body:hover` (0.4s opacity).

### Print Behavior
No `@media print` rule is defined. The deck is web/viewport-first.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Statement / Title / Number / Drop-cap / Label-eyebrow | Bebas Neue (400) | **思源宋体 Noto Serif SC** | 900 |
| Body / Body-md / Label-spaced | Space Grotesk (400 / 600) | **思源宋体 Noto Serif SC** | 400 (body), 600 (label) |
| Hand-script (Caveat) — Latin only | Caveat (400 / 600) | *(no CJK substitute)* | n/a |

### Mixed-Content Strategy

**Strategy A — single CJK family (思源宋体 Noto Serif SC) carries every typeset role.** Bebas Neue's condensed-industrial-uppercase voice has no Chinese sans equivalent that preserves the heavy poster weight without reading as a clichéd kanji-style display. Noto Serif SC at weight 900, however, carries genuine print-press weight that maps to the zine register: the deep serif strokes echo letterpress and woodblock printing, which is *closer* to the system's mid-century-activist-poster aesthetic than any Chinese sans would be. Pairing Latin Bebas + Chinese Noto Serif SC reads as "translated edition of the same zine," not as two competing systems. For body, the same family at weight 400 sits comfortably at small sizes (13–16px) and preserves the magazine column density.

### 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=Noto+Serif+SC:wght@400;600;700;900&display=swap" rel="stylesheet">
```

Then append `'Noto Serif SC'` to the appropriate font stacks:
```css
/* Display roles */
font-family: 'Bebas Neue', 'Noto Serif SC', sans-serif;
/* Body roles */
font-family: 'Space Grotesk', 'Noto Serif SC', sans-serif;
```

### Universal CJK Adjustments

- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence

### Aesthetic Notes for This System

- **The 0.02–0.04em positive tracking that defines Bebas display must drop to 0** on CJK. Tracked Chinese characters look broken — the spacing visually divides each character into a separate word. The compression-and-tracking signature of Bebas does not transfer; lean on weight 900 alone to carry the display voice.
- **Display line-height must open from 0.85–0.95 to 1.15–1.25.** Bebas's tight line-height is a Latin-display convention; CJK characters fully occupy their em-box and need vertical breathing room.
- **Drop caps need re-thinking.** A Bebas drop cap floats left of body text; a Noto Serif SC drop cap at the same size (`clamp(48px, 6vw, 80px)`) in `{colors.green}` works visually but lacks the editorial-tradition resonance — Chinese typography has historically not used drop caps. Either retain the treatment as a Western-editorial nod, or replace with a green vertical sidebar (3px wide, green fill) running alongside the opening paragraph.
- **Inline highlights, ribbon bars, and stamp marks all translate cleanly** — they are color-block treatments, not glyph-dependent.
- **Hand-script Caveat is the system's "human voice" — and has no Chinese equivalent that preserves the ballpoint-cursive personality.** Treat Caveat moments as Latin-only: attributions in Latin, side notes in Latin even on otherwise-Chinese slides, RSVP form fills in Latin. The contrast between Chinese typeset body and Latin handwritten margin notes can actually deepen the zine voice (it reads as "translator's annotation," which fits the small-press register).
- **Editorial body sizes (13–16px) still apply** — Noto Serif SC at this size reads as dense magazine column text, which is correct for the zine register.

### Known CJK Gap

The system's three-face contrast (Bebas display + Space Grotesk body + Caveat hand-script) is a Latin-typographic argument; collapsing it to a single CJK serif loses one rhythm and gains another. The decision to use a serif (Noto Serif SC) rather than a sans (Noto Sans SC) is deliberate — the zine's mid-century printed-press lineage maps better to Chinese serif tradition than to Chinese geometric sans. A deck that mixes Chinese and English will need to accept that the English Bebas voice and the Chinese Serif voice are different registers; this is unavoidable in any heavy-poster CJK adaptation.

## Iteration Guide

1. Every new slide carries the SVG grain overlay at 0.07 opacity. Removing the grain breaks the zine voice immediately.
2. Any new headline uses Bebas Neue uppercase, weight 400, tracking 0.02–0.04em. For the primary slide moment reach for `{typography.headline}` in `{colors.green}`; for splits or columns where the headline pairs with body, use `{colors.black}`.
3. Any new body uses Space Grotesk at 13–16px (or 14–18px for lead body). Line-height 1.6–1.7. Don't enlarge body beyond 18px.
4. Any new eyebrow label uses `{typography.label-eyebrow}` (Bebas Neue, 14–18px, 0.2em tracking) in `{colors.green}` for the most-emphasized eyebrow; switch to `{typography.label-spaced}` (Space Grotesk weight 600, 0.25em tracking) for secondary labels.
5. Any new card uses a 3px solid black border on white-cream or khaki background. For hero callouts, add the 12px-offset green slab via `::before` (`{components.card-offset}`).
6. Any new editorial column may carry a drop cap — green Bebas Neue, floated left, line-height 0.8. Drop caps are the editorial fingerprint.
7. Any new statement / quote slide pairs a Bebas Neue uppercase quote with a Caveat hand-script byline. The byline is not optional.
8. Any collage composition uses 3px-bordered collage pieces at small rotations (-5° to +5°), with translucent tape pieces at sharp angles overlapping the joints. Cycle backgrounds: green, white-cream, khaki-dark, black-inverted.
9. Any tabular ledger uses the `{components.ledger-row}` pattern with header underline at 1.5px and body row dividers at 1px hairline. Categorical tags use mono-font `{components.chip}` in green or the categorical chip palette.
10. Status / approval stamps use `{components.stamp-mark}` — black background, green text, green 2px border, rotated -8°. Reserve for moments that earn a stamp; overuse degrades the signal.

## Known Gaps

- The system loads three Google Fonts (Bebas Neue, Caveat, Space Grotesk) from a CDN. Bebas Neue is single-weight (400 only); attempting to use a heavier weight will fall back. Self-hosting is recommended for production.
- The grain overlay is an inline SVG data URI with `feTurbulence` — rendering will vary slightly across browsers, especially older Safari and Firefox versions.
- The paper-on-paper offset block depends on a `::before` pseudo-element with `z-index: -1`. Cards must have `position: relative` and the parent must not clip overflow, or the offset slab will be cut off.
- The chip color extension on ledger rows uses red / pink / orange / blue / green — pulled in only for categorical tagging inside tables. These colors are not part of the general system palette and should not appear elsewhere in a slide composition.
- The Caveat hand-script face has a strong cultural register (casual American handwriting). It does not pair well with non-Latin scripts; a CJK or Cyrillic deck would need a different hand-script substitution.
- The `body:hover` fade-in on the nav hint does not trigger on touch devices, which means mobile users may never see the nav hint. Treat the hint as desktop-only chrome.
- The closing slide uses a `{colors.black}` background with `{colors.bg}` (khaki) text. The grain overlay still applies but is much less visible at 0.07 opacity over black — the print register is weaker on the closing slide than on khaki-background slides.
- The form-field RSVP card uses hand-drawn underscores (`_________`) as the "blank line" — these are character-based, not rendered as actual `<input>` underlines, and will not align perfectly across system fonts.
````

---

## 2. 글씨체

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

---

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

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

**1장(표지)에서 처음 나오는 부품**
- `.by` — 1장 — 예: `<p class="hand by">`
- `.c1` — 1장 — 예: `<div class="col c1">`
- `.c2` — 1장 — 예: `<div class="col c2 green">`
- `.col` — 1·4·6장 — 예: `<div class="col c1">`
- `.e1` — 1장 — 예: `<p class="eye e1">`
- `.eye` — 1·2·3·4·5·6장 — 예: `<p class="eye e1">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.gl` — 1장 — 예: `<span class="ribbon gl">`
- `.grain` — 1·2·3·4·5·6장 — 예: `<section class="slide grain">`
- `.green` — 1·6장 — 예: `<div class="col c2 green">`
- `.hand` — 1·2·3·4·5·6장 — 예: `<p class="hand by">`
- `.num` — 1장 — 예: `<b class="num">`
- `.ribbon` — 1·2·4·5·6장 — 예: `<span class="ribbon gl">`
- `.s1` — 1장 — 예: `<span class="stamp s1">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide grain">`
- `.stamp` — 1·5·6장 — 예: `<span class="stamp s1">`
- `.stub` — 1장 — 예: `<i class="stub">`
- `.t` — 1장 — 예: `<p class="t">`
- `.t1` — 1장 — 예: `<h1 class="t1">`
- `.t1a` — 1장 — 예: `<i class="tape t1a">`
- `.t1b` — 1장 — 예: `<i class="tape t1b">`
- `.tape` — 1·4·6장 — 예: `<i class="tape t1a">`
- `.unit` — 1장 — 예: `<p class="unit">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.bt` — 2·5·6장 — 예: `<button class="bt go" data-act="step">`
- `.btns` — 2장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<span class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&…`
- `.capw` — 2장 — 예: `<p class="capw">`
- `.cf` — 2장 — 예: `<span class="eye cf">`
- `.chip` — 2·5장 — 예: `<span class="chip">`
- `.dc` — 2·4·6장 — 예: `<span class="dc">`
- `.edp` — 2·4장 — 예: `<p class="edp">`
- `.fig` — 2장 — 예: `<div class="offc fig">`
- `.go` — 2장 — 예: `<button class="bt go" data-act="step">`
- `.hd` — 2·3·4·5·6장 — 예: `<h2 class="hd">`
- `.lg2` — 2장 — 예: `<div class="ledger lg2">`
- `.lh` — 2·3·4장 — 예: `<div class="lh">`
- `.lr` — 2·3·4·6장 — 예: `<div class="lr" data-s="1">`
- `.lt` — 2·4장 — 예: `<b class="lt">`
- `.nr` — 2·3장 — 예: `<p class="nr hand">`
- `.nr2` — 2·3장 — 예: `<span class="nr2">`
- `.offc` — 2·6장 — 예: `<div class="offc fig">`
- `.rbh` — 2·4·6장 — 예: `<span class="ribbon rbh">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.cell` — 3장 — 예: `<div class="cell">`
- `.e2` — 3·5장 — 예: `<p class="eye e2">`
- `.ed` — 3장 — 예: `<div class="ed">`
- `.lg3` — 3장 — 예: `<div class="ledger lg3">`
- `.mx` — 3장 — 예: `<i class="rb mx" style="width:95%">`
- `.nm` — 3장 — 예: `<b class="nm">`
- `.note3` — 3장 — 예: `<p class="hand note3">`
- `.rb` — 3장 — 예: `<i class="rb" style="width:63%">`
- `.sp` — 3장 — 예: `<span class="sp">`
- `.trk` — 3장 — 예: `<span class="trk">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cp` — 4장 — 예: `<div class="col cp cpa">`
- `.cpa` — 4장 — 예: `<div class="col cp cpa">`
- `.cpb` — 4장 — 예: `<div class="col cp dark cpb">`
- `.dark` — 4장 — 예: `<div class="col cp dark cpb">`
- `.e4` — 4장 — 예: `<p class="edp e4">`
- `.lg4` — 4장 — 예: `<div class="ledger lg4">`
- `.sq` — 4장 — 예: `<p class="sq">`
- `.stmt` — 4장 — 예: `<div class="stmt">`
- `.t4a` — 4장 — 예: `<i class="tape t4a">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bf` — 5장 — 예: `<div class="bf">`
- `.blank` — 5장 — 예: `<button class="blank" data-blank aria-pressed="false">`
- `.blk` — 5장 — 예: `<div class="blk">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.field` — 5장 — 예: `<button class="field" data-opt="0">`
- `.fl` — 5장 — 예: `<span class="fl">`
- `.fv` — 5장 — 예: `<span class="hand fv">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.rb5` — 5장 — 예: `<span class="ribbon rb5">`
- `.rsvp` — 5장 — 예: `<div class="rsvp" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해…`
- `.rty` — 5장 — 예: `<button class="bt rty" data-act="retry">`
- `.s5` — 5장 — 예: `<span class="stamp s5">`
- `.wl` — 5장 — 예: `<p class="eye wl">`
- `.words` — 5장 — 예: `<div class="words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.a` — 6장 — 예: `<div class="col d6 a">`
- `.ab6` — 6장 — 예: `<p class="ab6">`
- `.b` — 6장 — 예: `<div class="col d6 b">`
- `.by6` — 6장 — 예: `<p class="hand by6">`
- `.c` — 6장 — 예: `<div class="col d6 c">`
- `.cl6` — 6장 — 예: `<div class="cl6" id="rz-col">`
- `.d6` — 6장 — 예: `<div class="col d6 a">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.g6` — 6장 — 예: `<div class="offc g6">`
- `.of6` — 6장 — 예: `<div class="of6" id="rz-off">`
- `.r6` — 6장 — 예: `<div class="lr r6">`
- `.sl6` — 6장 — 예: `<span class="eye sl6">`
- `.sm` — 6장 — 예: `<button class="bt sm" data-demo="#rz-off" data-mode="toggle" aria-pressed="false">`
- `.st6` — 6장 — 예: `<div class="st6" id="rz-st">`
- `.sw6` — 6장 — 예: `<span class="sw6">`

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

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="retro-zine">
<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=Bebas+Neue&family=Space+Grotesk:wght@400;500;600&family=Caveat:wght@400;600&family=JetBrains+Mono:wght@500&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/retro-zine.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide grain">
  <p class="eye e1">초등 과학 · 6학년 2학기 · 1단원 · 3~4차시</p>
  <p class="unit">계절의 변화<span>Sun, Shadow & Temperature</span></p>
  <span class="ribbon gl">학습 목표</span>
  <h1 class="t1">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1>
  <i class="stub"></i>
  <p class="hand by">— 오늘의 탐구 노트, 2026</p>
  <div class="col c1"><span class="eye">LESSON</span><b class="num">No.03</b></div>
  <div class="col c2 green"><p class="t">00초등학교</p></div>
  <i class="tape t1a"></i><i class="tape t1b"></i>
  <span class="stamp s1">SCIENCE ✓ APPROVED</span>
</section>
<section class="slide grain" data-steps="4">
  <span class="ribbon rbh">측정 준비</span><h2 class="hd">태양 고도 <em>측정기</em> 만들기</h2>
  <div class="offc fig"><span class="eye cf">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="edp"><span class="dc">태</span>양 고도 — 태양이 지표면과 이루는 각. <mark>막대기의 그림자와 실이 이루는 각 = 태양 고도</mark></p>
  <div class="ledger lg2"><div class="lh"><span>NR.</span><span>STEP</span><span>STATUS</span></div><div class="lr" data-s="1"><span class="nr2">01</span><div><b class="lt">자 붙이기</b><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div><span class="chip"></span></div><div class="lr" data-s="2"><span class="nr2">02</span><div><b class="lt">수수깡 꽂기</b><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div><span class="chip"></span></div><div class="lr" data-s="3"><span class="nr2">03</span><div><b class="lt">실 묶기</b><p>수수깡 끝에 실을 묶어요</p></div><span class="chip"></span></div><div class="lr" data-s="4"><span class="nr2">04</span><div><b class="lt">각도기 끼우기</b><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div><span class="chip"></span></div></div>
  <div class="btns"><button class="bt go" data-act="step">다음 단계 →</button><button class="bt" data-act="reset">처음부터</button></div>
  <p class="capw"><span class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quot;03 — 실 묶기&quot;,&quot;04 — 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</span></p>
  <p class="nr hand">버튼 규칙 없음 → 콜라주 조각으로 표현</p>
</section>
<section class="slide grain">
  <p class="eye e2">측정 결과</p><h2 class="hd">하루 동안 무엇이 <em>어떻게</em> 변할까요?</h2>
  <div class="ed"><div class="cell"><b class="nm">12:30</b><span class="sp">남중 시각</span><p>태양 고도가 가장 높아요</p></div><div class="cell"><b class="nm">정남</b><span class="sp">남중 방향</span><p>남중할 때 태양의 위치</p></div><div class="cell"><b class="nm">14:30</b><span class="sp">최고 기온</span><p>기온이 가장 높아요</p></div><div class="cell"><b class="nm">9:30</b><span class="sp">가장 긴 그림자</span><p>그림자가 가장 길어요</p></div></div>
  <div class="ledger lg3"><div class="lh"><span>시각</span><span>태양 고도(°)</span><span>그림자 길이(cm)</span><span>기온(℃)</span></div><div class="lr"><span class="nr2">9:30</span><span class="trk"><i class="rb" style="width:63%">38°</i></span><span>12.9</span><span>22</span></div><div class="lr"><span class="nr2">10:30</span><span class="trk"><i class="rb" style="width:80%">48°</i></span><span>9.1</span><span>23.8</span></div><div class="lr"><span class="nr2">11:30</span><span class="trk"><i class="rb" style="width:92%">55°</i></span><span>7</span><span>25.2</span></div><div class="lr"><span class="nr2">12:30</span><span class="trk"><i class="rb mx" style="width:95%">57°</i></span><span>6.4</span><span>26.3</span></div><div class="lr"><span class="nr2">13:30</span><span class="trk"><i class="rb" style="width:90%">54°</i></span><span>7.2</span><span>27</span></div><div class="lr"><span class="nr2">14:30</span><span class="trk"><i class="rb" style="width:78%">47°</i></span><span>9.4</span><span>27.4</span></div><div class="lr"><span class="nr2">15:30</span><span class="trk"><i class="rb" style="width:62%">37°</i></span><span>13.4</span><span>26.9</span></div></div>
  <p class="hand note3">예시 값! 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</p>
  <p class="nr hand">그래프 규칙 없음 → 원장 행 + 초록 리본 막대으로 표현</p>
</section>
<section class="slide grain">
  <span class="ribbon rbh">관계 정리</span><h2 class="hd">태양 고도가 바뀌면 무엇이 <em>달라질까요</em>?</h2>
  <div class="col cp cpa"><span class="eye">HIGH</span><h3>태양 고도가 높을 때</h3><p>— 그림자 길이는 짧아져요</p><p>— 기온은 높아져요</p></div><div class="col cp dark cpb"><span class="eye">LOW</span><h3>태양 고도가 낮을 때</h3><p>— 그림자 길이는 길어져요</p><p>— 기온은 낮아져요</p></div>
  <i class="tape t4a"></i>
  <div class="ledger lg4"><div class="lh"><span>시각</span><span>태양 고도</span><span>그림자 길이</span><span>기온</span></div><div class="lr"><span class="lt">오전 9:30</span><span>낮아요</span><span>길어요</span><span>낮아요</span></div><div class="lr"><span class="lt">낮 12:30</span><span>가장 높아요</span><span>가장 짧아요</span><span>높아지는 중</span></div><div class="lr"><span class="lt">오후 14:30</span><span>낮아지는 중</span><span>길어지는 중</span><span>가장 높아요</span></div></div>
  <div class="stmt"><p class="sq">태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><p class="hand">— 오늘의 정리</p></div>
  <p class="edp e4"><span class="dc">남</span>중 — 태양이 정남쪽에 있을 때 '<mark>남중했다</mark>'고 해요 이때의 태양 고도를 남중 고도라고 해요</p>
</section>
<section class="slide grain">
  <p class="eye e2">확인하기</p><h2 class="hd">배운 내용을 <em>확인해</em> 볼까요?</h2>
  <div class="rsvp" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
    <span class="eye">QUIZ · 답을 골라 적어 보세요</span>
    <h3 class="q">하루 중 그림자 길이가 가장 짧을 때는?</h3>
    <button class="field" data-opt="0"><span class="fl">A</span><span class="hand fv">오전 9시 30분</span></button><button class="field" data-opt="1"><span class="fl">B</span><span class="hand fv">낮 12시 30분 무렵</span></button><button class="field" data-opt="2"><span class="fl">C</span><span class="hand fv">오후 3시 30분</span></button>
    <p class="fb" data-fb></p>
    <button class="bt rty" data-act="retry">다시 풀기 ↺</button>
    <span class="stamp s5">정답 ✓ CHECKED</span>
  </div>
  <div class="blk">
    <span class="ribbon rb5">빈칸을 눌러 확인해요</span>
    <div class="bf"><span class="fl">01</span><button class="blank" data-blank aria-pressed="false"><span class="hand">태양 고도</span></button><span class="rest">는 점점 높아졌다가 다시 낮아진다</span></div><div class="bf"><span class="fl">02</span><button class="blank" data-blank aria-pressed="false"><span class="hand">그림자 길이</span></button><span class="rest">는 점점 짧아졌다가 다시 길어진다</span></div><div class="bf"><span class="fl">03</span><button class="blank" data-blank aria-pressed="false"><span class="hand">기온</span></button><span class="rest">은 점점 높아졌다가 다시 낮아진다</span></div>
    <p class="eye wl">오늘의 낱말</p>
    <div class="words"><span class="chip on">태양 고도</span><span class="chip on">남중 고도</span><span class="chip on">그림자 길이</span><span class="chip on">기온</span></div>
  </div>
</section>
<section class="slide grain">
  <span class="ribbon rbh">디자인 안내</span><h2 class="hd">이 디자인 사용 <em>설명서</em></h2>
  <div class="offc g6">
    <p class="ab6"><b class="dc">리</b>소그래프로 찍은 동아리 소식지(진). <mark>카키 종이 + 숲 초록 + 잉크 검정</mark> — 초록은 강조, 검정은 구조, 카드는 크림(순백 금지).</p>
    <div class="lr r6"><span class="eye">색</span><p><span class="sw6"><span><i style="background:#C8B99A"></i>카키 종이</span><span><i style="background:#008F4D"></i>숲 초록</span><span><i style="background:#1A1A1A"></i>잉크</span><span><i style="background:#F4EFE6"></i>크림</span></span></p></div><div class="lr r6"><span class="eye">글꼴</span><p>제목·숫자 Bebas Neue → SLEI Gothic TTF<br>본문 Space Grotesk → Hakgyoansim Wooju · 손글씨 Caveat → 야근하는 김주임</p></div><div class="lr r6"><span class="eye">이렇게 쓰면 좋아요</span><p>모둠 신문·탐구 기록장처럼 오려 붙인 느낌의 수업. 손글씨는 서명·메모에만.</p></div>
  </div>
  <p class="hand by6">— 한눈에: 종이를 겹쳐 붙인 잡지처럼!</p>
  <span class="eye sl6">대표 장치 — 눌러 보세요</span>
  <div class="col d6 a"><div class="dh"><h3>종이 위 종이</h3><button class="bt sm" data-demo="#rz-off" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>크림 카드 뒤로 12px 어긋난 초록 판을 한 장 더.</p><div class="of6" id="rz-off">계절의 변화</div></div>
  <div class="col d6 b"><div class="dh"><h3>승인 도장</h3><button class="bt sm" data-demo="#rz-st" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>검정 바탕 · 초록 글자 · 2px 초록 테두리, -8°.</p><div class="st6" id="rz-st"><span class="stamp">SCIENCE ✓ APPROVED</span></div></div>
  <div class="col d6 c"><div class="dh"><h3>콜라주 + 테이프</h3><button class="bt sm" data-demo="#rz-col" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>3px 테두리 조각을 -5~+5° 기울이고 반투명 테이프로 붙여요.</p><div class="cl6" id="rz-col"><span>관찰</span><span class="green">기록</span><i class="tape"></i></div></div>
</section>
<nav class="dk-nav"><span class="hintp">← → 넘기기</span><span class="ctr"><button class="dk-prev" aria-label="이전">‹</button><span class="dk-count" data-pad></span><button class="dk-next" aria-label="다음">›</button></span></nav><i class="prog"></i>
  </main>
</div>

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

---

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

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

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

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


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

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

/* --- 카키 · 초록 · 검정 · 크림 --- */
:root{--bg:#C8B99A;--bgd:#B8A98A;--green:#008F4D;--k:#1A1A1A;--cream:#F4EFE6;--bd:3px solid #1A1A1A;--hair:1px solid rgba(26,26,26,.22)}
.slide{background:var(--bg);color:var(--k);font-family:'Space Grotesk',var(--kb),sans-serif;font-weight:var(--wb)}
.grain::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:50;opacity:.07;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")}
.slide>*{position:absolute}
.slide em{font-style:normal;color:var(--green)}
.eye{font:400 28px/1.2 'Bebas Neue',var(--kb),sans-serif;letter-spacing:.2em;color:var(--green)}
.hand{font-family:'Caveat',var(--ka),cursive;font-weight:600}
h1,h2,h3,.unit,.lt,.sq,.q,.c2 .t{font-family:'Bebas Neue',var(--kt),sans-serif;font-weight:var(--wt);letter-spacing:.02em}
.green{background:var(--green);color:var(--cream)}.dark{background:var(--bgd)}
.ribbon{background:var(--green);color:var(--cream);padding:6px 18px;font:400 28px/1.1 'Bebas Neue',var(--kb),sans-serif;letter-spacing:.2em}
.stamp{background:var(--k);color:var(--green);border:2px solid var(--green);padding:12px 26px;font:400 32px/1 'Bebas Neue',var(--kb),sans-serif;letter-spacing:.1em;transform:rotate(-8deg)}
.tape{width:120px;height:34px;background:rgba(255,255,255,.4);border:1px solid rgba(0,0,0,.1);z-index:5}
.col{border:var(--bd);padding:26px}
mark,.cap{background:var(--k);color:var(--bg);padding:2px 8px;font-weight:600;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.dc{float:left;font:400 84px/.8 'Bebas Neue',var(--kt),sans-serif;color:var(--green);margin:6px 12px 0 0}
.nr{left:80px;bottom:22px;font-size:28px;opacity:.85}
.bt{position:relative;background:var(--cream);border:var(--bd);padding:12px 28px;font:400 34px/1 'Bebas Neue',var(--kb),sans-serif;letter-spacing:.04em;color:var(--k)}
.bt.go{background:var(--green);color:var(--cream)}
.bt:disabled{opacity:.4}
/* 종이 위 종이: 회전 카드에서도 카드 뒤에만 보이도록 '흐림 없는 어긋난 판'(초록 + 3px 잉크 테두리)으로 그림 */
.offc,.c1,.rsvp{background:var(--cream);border:var(--bd);box-shadow:12px 12px 0 -3px var(--green),12px 12px 0 0 var(--k)}
.e2{left:80px;top:72px}
.rbh{left:80px;top:70px}
.hd{left:80px;right:80px;top:116px;font-size:84px;line-height:1.08;color:var(--k);white-space:nowrap}
.hd em{color:var(--green)}

/* --- 원장 행(머리 1.5px · 몸 1px 22%) + 모노 칩 --- */
.lh{display:grid;padding:0 0 10px;border-bottom:1.5px solid var(--k);font:400 26px/1 'Bebas Neue',var(--kb),sans-serif;letter-spacing:.2em}
.lr{display:grid;align-items:center;padding:12px 0;border-bottom:var(--hair)}
.nr2{font:400 44px/1 'Bebas Neue',sans-serif;color:var(--green);letter-spacing:.02em}
.chip{justify-self:start;font:500 22px/1 'JetBrains Mono',var(--kb),ui-monospace,monospace;letter-spacing:.06em;text-transform:uppercase;padding:8px 12px;color:var(--cream);background:rgba(26,26,26,.3)}

/* --- 1. 표지: 단원 → 리본 '학습 목표' → 학습 목표(가장 큰 Bebas, 검정 + 핵심 낱말 초록) → 토막 + 손글씨 | 콜라주(종이 위 종이 · 초록 조각 · 테이프) + 승인 도장 --- */
.e1{left:80px;top:110px}
.unit{left:80px;top:160px;display:flex;align-items:baseline;gap:28px;font-size:84px;line-height:1.05;white-space:nowrap}
.unit span{font:400 60px/1 'Bebas Neue',sans-serif;letter-spacing:.04em;color:var(--green)}
.gl{left:80px;top:300px}
.t1{left:76px;top:370px;font-size:124px;line-height:1.15;white-space:nowrap}
.t1 .gk{font-style:normal;color:var(--green)}
.stub{left:80px;top:690px;width:80px;height:4px;background:var(--green)}
.by{left:80px;top:716px;font-size:50px}
.c1{left:1260px;top:660px;width:440px;height:300px;transform:rotate(-3deg);display:flex;flex-direction:column}
.num{margin-top:auto;font:400 170px/.9 'Bebas Neue',sans-serif;letter-spacing:.02em;color:var(--green)}
.c2{left:1000px;top:790px;width:300px;transform:rotate(4deg);z-index:2}
.c2 .t{font-size:46px}
.t1a{left:1420px;top:640px;transform:rotate(-30deg)}.t1b{left:990px;top:770px;transform:rotate(-40deg)}
.s1{left:120px;top:860px}

/* --- 2. 만들기: 종이 위 종이 카드 속 측정기 그림 + 드롭캡 문단(형광펜) | 원장 행 4개(칩 WAIT → DONE → NOW) + 콜라주 버튼 + 형광펜 설명 --- */
.fig{left:80px;top:256px;width:860px;padding:14px 30px 10px;
  --g-ink:var(--k);--g-acc:var(--green);--g-stick:var(--green);--g-board:var(--bgd);--g-ruler:var(--cream);--g-prot:rgba(0,143,77,.08);--g-shadow:rgba(26,26,26,.4);--g-font:'Space Grotesk',var(--kb),sans-serif;--g-sw:2.5}
.cf{display:block;font-size:24px}
.fig .gauge{width:760px;display:block;margin:0 auto}
.edp{left:80px;width:880px;top:880px;font-size:26px;line-height:1.6}
.lg2{left:1030px;right:92px;top:262px}
.lg2 .lh,.lg2 .lr{grid-template-columns:90px 1fr 140px}
.lg2 .lr{transition:opacity .3s}
.lg2 .lt{font-size:40px;line-height:1.1}
.lg2 p{margin-top:4px;font-size:23px;line-height:1.45}
.lg2 .chip::after{content:'WAIT'}
.slide[data-step]:not([data-step="0"]) .lr:not(.on){opacity:.4}
.lg2 .lr.on .chip{background:var(--green)}.lg2 .lr.on .chip::after{content:'DONE'}
.lg2 .lr.now .chip{background:var(--k)}.lg2 .lr.now .chip::after{content:'NOW ▶'}
.btns{left:1030px;top:842px;display:flex;gap:24px}
.capw{left:1030px;right:92px;top:930px;font-size:26px;line-height:1.6}

/* --- 3. 숫자와 그래프: 편집 격자(3px 바깥 · 1.5px 칸, 초록 숫자) + 원장 행(초록 리본 막대, 가장 높은 값 = 검정) + 손글씨 메모 --- */
.ed{left:80px;right:92px;top:240px;display:grid;grid-template-columns:repeat(4,1fr);border:var(--bd)}
.cell{padding:20px 26px;border-right:1.5px solid var(--k);display:flex;flex-direction:column;gap:6px}
.cell:last-child{border-right:0}
.nm{font:400 80px/1 'Bebas Neue',var(--kt),sans-serif;letter-spacing:.02em;color:var(--green)}
.sp{font:600 20px/1.2 'Space Grotesk',var(--kb),sans-serif;letter-spacing:.25em}
.cell p{font-size:24px;line-height:1.4}
.lg3{left:80px;right:92px;top:480px}
.lg3 .lh,.lg3 .lr{grid-template-columns:150px 1fr 220px 180px;gap:24px}
.lg3 .lr{padding:7px 0;font-size:28px}
.trk{display:block}
.rb{display:block;background:var(--green);color:var(--cream);padding:4px 12px;font:400 26px/1.1 'Bebas Neue',sans-serif;letter-spacing:.06em;font-style:normal}
.rb.mx{background:var(--k);color:var(--green)}
.note3{right:92px;top:930px;font-size:30px;text-align:right;width:1100px}

/* --- 4. 비교와 표: 콜라주 조각 둘(크림 / 카키 진하게, 반대 기울기 + 테이프) + 원장 표 | 초록 문장 판(손글씨 서명) + 드롭캡 문단 --- */
.cp{top:270px;width:470px;display:flex;flex-direction:column;gap:6px}
.cpa{left:90px;background:var(--cream);transform:rotate(-2deg)}
.cpb{left:620px;transform:rotate(2deg)}
.cp h3{font-size:44px;line-height:1.1}
.cp p{font-size:26px;line-height:1.5}
.t4a{left:520px;top:254px;transform:rotate(20deg)}
.lg4{left:80px;width:1020px;top:600px}
.lg4 .lh,.lg4 .lr{grid-template-columns:1.2fr 1fr 1fr 1fr;gap:16px}
.lg4 .lr{padding:16px 0;font-size:28px}
.lg4 .lt{font-size:36px}
.stmt{left:1180px;right:92px;top:270px;background:var(--green);color:var(--cream);padding:36px 40px}
.sq{font-size:52px;line-height:1.15}
.stmt .hand{margin-top:16px;font-size:40px;transform:rotate(-3deg);display:inline-block}
.e4{left:1180px;width:640px;top:680px}

/* --- 5. 확인하기: RSVP 카드 퀴즈(종이 위 종이, 손글씨 값, 정답 = 형광펜 + 도장) | RSVP 칸 빈칸(초록 라벨 + 손글씨 값 + 2px 밑줄) + 칩 낱말 --- */
.rsvp{left:80px;width:940px;top:240px;bottom:110px;padding:30px 40px;display:flex;flex-direction:column;gap:4px}
.q{margin:8px 0 12px;font-size:54px;line-height:1.15}
.field{display:flex;align-items:baseline;gap:24px;text-align:left;padding:8px 0 6px;border-bottom:2px solid var(--k)}
.fl{font:400 38px/1 'Bebas Neue',sans-serif;color:var(--green);letter-spacing:.1em;flex:none}
.fv{font-size:46px;line-height:1.1}
.field.right .fv{background:var(--k);color:var(--bg);padding:0 10px}
.field.wrong .fv{text-decoration:line-through;text-decoration-thickness:3px}
.field:disabled:not(.right){opacity:.45}
.fb{margin-top:14px;font-size:26px;line-height:1.5}
.rty{align-self:flex-start;margin-top:auto;font-size:30px}
.s5{position:absolute;right:30px;bottom:40px;visibility:hidden}
.rsvp.solved .s5{visibility:visible}
.blk{left:1110px;right:92px;top:250px;bottom:110px;display:flex;flex-direction:column;gap:26px}
.rb5{position:static;align-self:flex-start}
.bf{display:grid;grid-template-columns:60px auto 1fr;align-items:end;gap:14px;padding-bottom:8px;border-bottom:2px solid var(--k);font-size:28px;line-height:1.4}
.blank{position:relative;min-width:150px;padding:0 6px;text-align:center}
.blank .hand{font-size:44px;line-height:1;color:var(--green);visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0;bottom:2px;font:400 40px/1 'Bebas Neue',sans-serif;color:var(--green)}
.blank.open .hand{visibility:visible}
.blank.open::after{content:none}
.wl{margin-top:auto}
.words{display:flex;flex-wrap:wrap;gap:10px}
.words .chip{background:var(--green);font-size:24px;text-transform:none}

/* --- 크롬: 4px 초록 진행 막대 · 크림 칩 번호 · 검정 알약 안내(마우스를 올리면) --- */
.dk-nav{position:absolute;inset:0;pointer-events:none;z-index:60}
.hintp{position:absolute;left:50%;bottom:22px;transform:translateX(-50%);background:var(--k);color:var(--cream);padding:8px 20px;font:500 22px/1 var(--kb),sans-serif;opacity:0;transition:opacity .4s}
.dk-nav:hover .hintp,body:hover .hintp{opacity:.85}
.ctr{position:absolute;right:30px;bottom:20px;display:flex;align-items:center;gap:6px;pointer-events:auto}
.ctr button{width:44px;height:44px;border:2px solid var(--k);background:var(--cream);font:400 34px/1 'Bebas Neue',sans-serif;color:var(--k)}
.ctr button:disabled{opacity:.35}
.dk-count{background:var(--cream);border:2px solid var(--k);padding:8px 14px;font:400 28px/1 'Bebas Neue',sans-serif;letter-spacing:.1em;color:#8a7a5a}
.prog{position:absolute;left:0;bottom:0;height:6px;background:var(--green);width:16.7%;transition:width .6s ease;z-index:60}
[data-slide="2"] .prog{width:33.3%}[data-slide="3"] .prog{width:50%}[data-slide="4"] .prog{width:66.7%}[data-slide="5"] .prog{width:83.3%}
/* --- 6. 디자인 안내: 종이 위 종이 카드(드롭캡 + 원장 행) | 3px 테두리 칸 시연 3개 --- */
.g6{left:80px;width:900px;top:290px;padding:28px 36px}
.ab6{font-size:31px;line-height:1.6;margin-bottom:10px}
.ab6 .dc{font-size:96px;margin-top:4px}
.r6{grid-template-columns:200px 1fr;gap:16px;align-items:start;padding:18px 0}
.r6:last-child{border-bottom:0}
.r6 .eye{font-size:30px}
.r6 p{font-size:28px;line-height:1.5}
.sw6{display:flex;flex-wrap:wrap;gap:6px 22px}
.sw6 i{display:inline-block;width:24px;height:24px;margin-right:8px;vertical-align:-5px;border:2px solid var(--k)}
.by6{left:90px;top:920px;font-size:40px;color:var(--green);transform:rotate(-2deg)}
.sl6{left:1060px;top:250px;font-size:26px}
.d6{left:1060px;right:80px;height:200px;padding:14px 24px;background:var(--cream)}
.d6.a{top:292px}.d6.b{top:516px}.d6.c{top:740px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:16px}
.d6 h3{font-size:44px;line-height:1}
.d6 p{margin-top:4px;font-size:21px;line-height:1.4}
.bt.sm{font-size:22px;padding:8px 14px}
.bt.sm[aria-pressed="true"]{background:var(--green);color:var(--cream)}
.of6{margin-top:12px;display:inline-block;padding:10px 26px;border:var(--bd);background:var(--cream);font:400 34px/1.1 'Bebas Neue',var(--kt),sans-serif}
.of6.play{box-shadow:12px 12px 0 -3px var(--green),12px 12px 0 0 var(--k)}
.st6{margin-top:14px;height:60px;padding-left:20px}
.st6 .stamp{display:inline-block;font-size:28px;padding:10px 22px;visibility:hidden}
.st6.play .stamp{visibility:visible}
.cl6{position:relative;margin-top:10px;display:flex;gap:22px;padding:12px 16px;background:var(--bg)}
.cl6 span{padding:8px 22px;border:var(--bd);background:var(--cream);font:400 30px/1.1 'Bebas Neue',var(--kt),sans-serif}
.cl6 .green{background:var(--green)}
.cl6 .tape{position:absolute;left:40px;top:2px;width:90px;height:26px;visibility:hidden}
.cl6.play span:first-child{transform:rotate(-4deg)}.cl6.play span:nth-child(2){transform:rotate(3deg)}
.cl6.play .tape{visibility:visible;transform:rotate(-6deg)}
[data-slide="6"] .prog{width:100%}

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