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

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

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

## 라이선스

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

- Noto Serif KR Black: Noto Serif KR — [합침 2026-10-07] 같은 가족의 폴더를 이 폴더로 합침 / --- NotoSerifCJKKR ---
  파일: NotoSerifKR-Black.ttf
- Noto Sans KR Regular: Noto Sans KR — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: (c) 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'.
  파일: NotoSansKR-Regular.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/capsule.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/capsule.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 Noto Serif KR Black(900) · 본문 Noto Sans KR Regular(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. 디자인 규칙 (`capsule` design.md)

````markdown
---
version: alpha
name: Capsule
description: A playful editorial system built on pill-shaped containers, a sun-bleached cream canvas, and a nine-color candy palette. Bodoni Moda serif headlines pair with Space Grotesk body to suggest a literary magazine that took a holiday at a 1970s ice-cream parlor. Every container that holds text is a pill (border-radius 9999px) outlined with a 2px ink stroke, casting a soft 6–12px offset shadow. The aesthetic is "Memphis-meets-editorial" — confident typography, generous bordered shapes, and decorative floating pills as atmospheric wallpaper.

colors:
  cream: "#F5F5F0"
  ink: "#1A1A1A"
  outline: "#1E1E1E"
  white: "#FFFFFF"
  coral: "#E85D4E"
  lime: "#C4D94E"
  lavender: "#C5B5E0"
  sky: "#8BB4F7"
  violet: "#A06CE8"
  yellow: "#F2D160"
  peach: "#F5B895"
  mint: "#A8E6CF"
  shadow: "rgba(26, 26, 26, 0.08)"

color-aliases:
  bg: cream
  fg: ink
  outline: outline                  # same hue family as ink; reserved for stroke role

typography:
  display:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(3rem, 8vw, 7rem)"
    fontWeight: 800
    lineHeight: 0.9
    letterSpacing: -0.02em
  closing-display:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(2.5rem, 6vw, 5rem)"
    fontWeight: 800
    lineHeight: 0.95
    letterSpacing: -0.03em
  headline:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(2rem, 4vw, 3.5rem)"
    fontWeight: 700
    lineHeight: 1.05
    letterSpacing: -0.02em
  section-headline:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(1.8rem, 3.5vw, 3rem)"
    fontWeight: 700
    lineHeight: 1.05
    letterSpacing: -0.01em
  quote-display:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(1.6rem, 3.5vw, 3rem)"
    fontWeight: 600
    lineHeight: 1.35
    letterSpacing: -0.01em
  card-headline:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "1.5rem"
    fontWeight: 700
    lineHeight: 1.1
  stat-number:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "clamp(2rem, 3.5vw, 3rem)"
    fontWeight: 800
    lineHeight: 1
    letterSpacing: -0.03em
  orbit-numeral:
    fontFamily: "Bodoni Moda, serif"
    fontSize: "2.5rem"
    fontWeight: 700
    lineHeight: 1
  body:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "clamp(0.95rem, 1.2vw, 1.15rem)"
    fontWeight: 400
    lineHeight: 1.6
  body-sm:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "0.9rem"
    fontWeight: 400
    lineHeight: 1.55
  subtitle:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "clamp(0.8rem, 1.5vw, 1.1rem)"
    fontWeight: 400
    lineHeight: 1.4
    letterSpacing: 0.15em
    textTransform: uppercase
  pill-text-md:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "0.85rem"
    fontWeight: 600
    lineHeight: 1
    letterSpacing: 0.12em
    textTransform: uppercase
  pill-text-sm:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "0.7rem"
    fontWeight: 600
    lineHeight: 1
    letterSpacing: 0.1em
    textTransform: uppercase
  label:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "0.75rem"
    fontWeight: 500
    lineHeight: 1
    letterSpacing: 0.1em
    textTransform: uppercase
  mini-label:
    fontFamily: "Space Grotesk, sans-serif"
    fontSize: "0.65rem"
    fontWeight: 500
    lineHeight: 1
    letterSpacing: 0.08em
    textTransform: uppercase

spacing:
  pad-lg: "3rem 4rem"
  pad-md: "2rem"
  gap-xl: "4rem"
  gap-lg: "3rem"
  gap-md: "2rem"
  gap-sm: "1.5rem"
  gap-xs: "0.75rem"
  card-pad: "2.5rem 2rem"
  pill-pad-lg: "1.5rem 3.5rem"
  pill-pad-md: "1rem 2.5rem"
  pill-pad-sm: "0.4rem 1.2rem"
  pill-pad-xs: "0.35rem 1rem"

canvas:
  width: 100vw
  height: 100vh

components:
  pill:
    borderRadius: 9999px
    border: "2px solid {colors.outline}"
    fontFamily: "Space Grotesk, sans-serif"
    fontWeight: 500
    letterSpacing: 0.02em
    whiteSpace: nowrap
    description: "The universal container shape. Any text container — chip, button, label, statement-highlight, stat tile, card, bar — is a pill with 2px outline. Background can be any palette accent or white."
  pill-card:
    background: "{colors.white}"
    border: "2px solid {colors.outline}"
    borderRadius: "2rem"
    padding: "{spacing.card-pad}"
    boxShadow: "8px 8px 0 {colors.shadow}"
    description: "Larger pill-shaped card (slightly squared corners at 2rem rather than full pill) for content blocks. Always white background, always shadowed."
  stat-pill:
    background: "{colors.white}"
    border: "2px solid {colors.outline}"
    borderRadius: "2rem"
    padding: "2rem 1.5rem"
    boxShadow: "6px 6px 0 {colors.shadow}"
    description: "Stat tile — pill-shaped white card containing a colored stat number, label, and a tiny accent bar."
  bar-track:
    height: 36px
    background: "{colors.cream}"
    border: "2px solid {colors.outline}"
    borderRadius: 9999px
    overflow: hidden
    description: "Horizontal bar chart track shaped as a pill. Fills use the candy palette."
  bar-fill:
    height: "100%"
    borderRadius: 9999px
    borderRight: "2px solid {colors.outline}"
    description: "Inner bar pill with the value label printed at right edge inside the fill."
  accent-line:
    width: 60px
    height: 4px
    background: "{colors.coral}"
    borderRadius: 9999px
    description: "Pill-shaped 60×4 accent rule. Default color coral; closing-context variant uses 80×4."
  card-icon:
    width: 60px
    height: 60px
    borderRadius: "50%"
    border: "2px solid {colors.outline}"
    fontFamily: "Bodoni Moda, serif"
    fontSize: "1.5rem"
    fontWeight: 700
    description: "Circular pill icon (60px) used as a card mark. Background is an accent color; contains a 1–3 character Roman numeral or letter."
  step-node:
    width: 56px
    height: 56px
    borderRadius: "50%"
    border: "2px solid {colors.outline}"
    background: "{colors.white}"
    fontFamily: "Bodoni Moda, serif"
    fontSize: "1.3rem"
    fontWeight: 700
    boxShadow: "4px 4px 0 {colors.shadow}"
    description: "Circular pill node (56px) used as a timeline step or sequence marker. Step accent color appears as filled-pill class on the node."
  orbit-center:
    width: 160px
    height: 160px
    borderRadius: "50%"
    background: "{colors.lime}"
    border: "2px solid {colors.outline}"
    fontFamily: "Bodoni Moda, serif"
    fontSize: "2.5rem"
    fontWeight: 700
    description: "Large circular pill (160px) used as the gravitational anchor of an orbit composition. Default fill lime; small satellite pills orbit around it."
  diagram-node:
    borderRadius: 9999px
    border: "2px solid {colors.outline}"
    padding: "1rem 2rem"
    boxShadow: "6px 6px 0 {colors.shadow}"
    background: "{colors.white}"
    description: "Flow-diagram node — pill-shaped container with shadow. Connected by 50×4 ink connectors with triangular arrowheads."
  diagram-connector:
    width: 50px
    height: 4px
    background: "{colors.outline}"
    description: "Solid 50×4 ink bar with a triangular arrowhead at the right end, connecting two diagram nodes inline."
  visual-frame:
    borderRadius: "2rem"
    border: "2px solid {colors.outline}"
    boxShadow: "12px 12px 0 {colors.shadow}"
    description: "Large image/illustration frame — slightly squared pill (2rem radius) with thicker 12px offset shadow. Often filled with a tri-stop linear gradient and a dot-pattern overlay."
  grain-overlay:
    position: fixed
    inset: 0
    pointerEvents: none
    zIndex: 9999
    opacity: 0.04
    mixBlendMode: multiply
    backgroundImage: "fractalNoise SVG"
    description: "Subtle film-grain noise overlay applied to the entire viewport at 4% opacity in multiply blend mode. Always present, never absent."
  radial-glow:
    description: "Soft radial gradient wash anchored to a corner or center of a slide background. Uses one of the candy palette colors at 6–15% opacity, blended into the cream canvas. Provides atmospheric warmth without changing the surface color."
---

## 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

Capsule is a **playful editorial system** whose defining structural premise is the **pill**: every text container is a pill, every icon is a pill, every bar is a pill, every node in a diagram is a pill. The `border-radius: 9999px` rule applies to virtually all UI elements, with larger panels softening to a 2rem radius. Combined with the 2px ink outline that wraps every shape, the result is a system where containers feel inflated, friendly, and graphically distinct — a nod to Memphis design and late-70s ice-cream-parlor signage without abandoning editorial discipline.

The typeface stack is a deliberate two-face conversation. **Bodoni Moda** — a high-contrast didone serif — carries every display moment, every section headline, every stat numeral, every card title, every quote. Bodoni's tall capitals and thin-thick stroke contrast give the headlines their editorial weight and a touch of fashion-magazine glamour. **Space Grotesk** — a contemporary geometric sans — carries every body paragraph, every label, every pill text, every subtitle. The serif/grotesk pairing creates the system's primary typographic rhythm: glamorous serif statements + clean grotesk supporting structure.

The palette runs nine colors plus three neutrals. The canvas is `{colors.cream}` — a warm sun-bleached off-white that signals "magazine paper" rather than "screen white." The ink is `{colors.ink}`, used for body text, headlines, and the universal outline. The seven candy accents — `{colors.coral}`, `{colors.lime}`, `{colors.lavender}`, `{colors.sky}`, `{colors.violet}`, `{colors.yellow}`, `{colors.peach}`, plus `{colors.mint}` — are interchangeable. They fill pills, color stat numbers, fill bar charts, and float as decorative atmosphere. There is no semantic mapping: no color means "warning," none means "success." Each accent is chosen for compositional balance, not meaning.

Depth comes from **soft hard-offset shadows** at 4px, 6px, 8px, and 12px in a low-opacity ink color (`{colors.shadow}` = `rgba(26, 26, 26, 0.08)`). Unlike a true brutalist shadow, these are slightly transparent — they read as "lifted" rather than "stamped." Combined with the 2px outline, every pill feels like it's floating just above the cream canvas. There is no use of blurred drop shadows; the offset is always solid, always to the bottom-right.

**Density philosophy: medium-high atmospheric.** Capsule slides feel populated. The system is built around the idea that decorative floating pills should orbit the actual content as wallpaper — small colored pills tilted at 5–25° rotations across the slide background, each containing a single uppercase word. These atmospheric pills are non-functional; they are typographic confetti. A correctly composed slide pairs one or two substantive content blocks (a pill-card, a stat grid, a diagram) with 5–8 floating decorative pills around the edges. A slide that feels broken in Capsule is one with empty corners or unrelieved cream space — the candy palette wants to participate even where the content doesn't strictly require it.

**Key Characteristics:**
- Universal pill geometry — `border-radius: 9999px` for small containers, 2rem for larger cards/frames.
- 2px solid `{colors.outline}` stroke wraps every pill, icon, and card.
- Bodoni Moda serif for every display/headline/stat; Space Grotesk sans for every body/label/pill text.
- Sun-bleached cream canvas `{colors.cream}` with soft radial glows in candy accent colors at 6–15% opacity for background atmosphere.
- Hard-offset shadows in low-opacity ink (`{colors.shadow}`) at 4/6/8/12px offsets, always solid, always bottom-right.
- Nine-color candy accent palette used interchangeably — no semantic mapping.
- Decorative floating pills tilted at 5–25° rotations populate slide backgrounds as atmospheric wallpaper.
- A persistent fractal-noise grain overlay (4% opacity, multiply blend) sits over the entire viewport at all times.
- Full-screen vertical nav-dot column at right, mono slide counter at bottom-right.

## Colors

### Canvas & Ink
- **Cream** (`{colors.cream}` — #F5F5F0): The canvas. Warm sun-bleached off-white. Used as default slide background, default bar-track interior, and any neutral region that wants paper warmth without being pure white.
- **Ink** (`{colors.ink}` — #1A1A1A): The primary text color. Used for headlines, body, and (under the alias `outline`) the universal stroke.
- **Outline** (`{colors.outline}` — #1E1E1E): Functionally identical to ink; reserved as the stroke color on every pill, card, icon, and frame for semantic clarity.
- **White** (`{colors.white}` — #FFFFFF): True white. Used as the default fill for pill-cards, stat-pills, diagram nodes, and any pill that needs the highest contrast against the cream canvas. White pills always carry the 2px ink outline.

### Candy Accents
- **Coral** (`{colors.coral}` — #E85D4E): Warm orange-red. The most "voice-y" of the accents; used as a default accent-line color, default pill-card icon fill on the first card in a sequence, and the most frequent stat-number color.
- **Lime** (`{colors.lime}` — #C4D94E): Vivid chartreuse-green. Pairs well with coral; default fill for orbit-center anchors and frequent stat-number color.
- **Lavender** (`{colors.lavender}` — #C5B5E0): Soft lilac-purple. Used as a calming pill fill in headers and as a frequent quote-highlight color.
- **Sky** (`{colors.sky}` — #8BB4F7): Mid-saturation cornflower blue. The default "third accent" — sits comfortably next to coral and lime in a 3-card grid.
- **Violet** (`{colors.violet}` — #A06CE8): Deeper purple. Used when a slide already has lavender as one accent and needs a second purple-family pop.
- **Yellow** (`{colors.yellow}` — #F2D160): Warm marigold. The default fill for title pills, closing pills, and any pill that should read as "important / featured."
- **Peach** (`{colors.peach}` — #F5B895): Pale apricot. The softest accent; used in floating decorative pills and circular decorative spots.
- **Mint** (`{colors.mint}` — #A8E6CF): Pale aqua-green. Used most often inside the linear-gradient visual frame and in lower-emphasis decorative pills.
- **Shadow** (`{colors.shadow}` — `rgba(26, 26, 26, 0.08)`): The universal soft hard-offset shadow color. Never use a different shadow color.

### Defaults
- **Default slide surface**: `{colors.cream}`.
- **Default headline color**: `{colors.ink}` — Bodoni serif headlines are always ink, never colored. Color appears only on stat numerals and inside accent pills.
- **Default body text color**: `{colors.ink}` rendered at opacity 0.6–0.7 to soften it against the cream canvas.
- **Default outline color**: `{colors.outline}` (≈ ink) — 2px on every pill/card/icon, no exceptions.
- **Default card fill**: `{colors.white}`.
- **Default accent-line color**: `{colors.coral}`.
- **Default title-pill fill**: `{colors.yellow}`.
- **Default closing-pill fill**: `{colors.yellow}`.
- **Default orbit-center fill**: `{colors.lime}`.
- **Default first accent in a 3- or 4-accent sequence**: coral → lime → sky → violet (rotated when more colors are needed). The sequence is the system's "Roy G. Biv"; it gives the agent a deterministic order to reach for so the candy palette doesn't feel random.
- **Default decorative pill background opacity**: full saturation (no fading). The floating pills are loud on purpose.

Accent colors have no semantic role. Choose accents based on warm/cool balance and adjacency, not meaning. When three accents appear together, pair a warm (coral/yellow/peach) with a cool (sky/lavender/violet/mint) with a neutral-bright (lime). Avoid placing two same-family accents adjacent (two purples, two greens, two warms).

## Typography

### Font Family
The system runs on a **two-face conversation**: `Bodoni Moda` (serif, weights 400–900, opsz axis) carries every display and headline; `Space Grotesk` (sans, weights 300–700) carries every body, label, and pill text. There is no third face. Both families are loaded from Google Fonts at variable-axis weights.

Bodoni Moda's high contrast and didone modulation give the system its editorial-glamour register; the thin-thick stroke contrast is most pronounced at large sizes, so display weights should always be 700+ to maintain stroke presence. Space Grotesk's geometric grotesque carries clean, modern body — it never tries to compete with the Bodoni headlines.

An inline `<em>` inside a Bodoni headline keeps Bodoni and shifts to italic. A `quote-highlight` inside a Bodoni quote body switches the wrapped word to a pill (Space Grotesk uppercase pill text on a candy fill) for visual emphasis.

### Type Scale

| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.display}` | clamp(3rem, 8vw, 7rem) | Bodoni Moda | 800 | Largest cover/title display |
| `{typography.closing-display}` | clamp(2.5rem, 6vw, 5rem) | Bodoni Moda | 800 | Conclusive declarative headline |
| `{typography.headline}` | clamp(2rem, 4vw, 3.5rem) | Bodoni Moda | 700 | Primary slide headline on split or two-column layouts |
| `{typography.section-headline}` | clamp(1.8rem, 3.5vw, 3rem) | Bodoni Moda | 700 | Section-opening or centered headline above cards/charts |
| `{typography.quote-display}` | clamp(1.6rem, 3.5vw, 3rem) | Bodoni Moda | 600 | Pull-quote body |
| `{typography.card-headline}` | 1.5rem | Bodoni Moda | 700 | Card or pillar-block title |
| `{typography.stat-number}` | clamp(2rem, 3.5vw, 3rem) | Bodoni Moda | 800 | Large numerical stat figure |
| `{typography.orbit-numeral}` | 2.5rem | Bodoni Moda | 700 | Centered ordinal inside the orbit-center circle |
| `{typography.body}` | clamp(0.95rem, 1.2vw, 1.15rem) | Space Grotesk | 400 | Paragraph body |
| `{typography.body-sm}` | 0.9rem | Space Grotesk | 400 | Compact body inside a card |
| `{typography.subtitle}` | clamp(0.8rem, 1.5vw, 1.1rem) | Space Grotesk | 400 | Uppercase tracked subtitle below a display headline |
| `{typography.pill-text-md}` | 0.85rem | Space Grotesk | 600 | Text inside title/closing pills |
| `{typography.pill-text-sm}` | 0.7rem | Space Grotesk | 600 | Text inside small floating decorative pills |
| `{typography.label}` | 0.75rem | Space Grotesk | 500 | Header tag pills, attribution lines |
| `{typography.mini-label}` | 0.65rem | Space Grotesk | 500 | Mini-pill chips in a tag cluster |

### Defaults
- **Default size for the primary section headline**: `{typography.section-headline}` (clamp 1.8–3rem). For two-column or split layouts, `{typography.headline}` (clamp 2–3.5rem).
- **Default size for a cover or opening display moment**: `{typography.display}` (clamp 3–7rem).
- **Default size for paragraph body**: `{typography.body}` (clamp 0.95–1.15rem).
- **Default size for any inline label or chip**: `{typography.label}` (0.75rem).
- **Default weight for any Bodoni display element**: 700 minimum; 800 for the largest display.
- **Default weight for any Space Grotesk body element**: 400.
- **Default size for a hero stat figure**: `{typography.stat-number}` (clamp 2–3rem).

When unsure, reach for `{typography.section-headline}` for the slide's primary text moment, not `{typography.card-headline}` (which is for block-level titles within a card).

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every display, headline, stat-number, card-headline, and quote-display element is set in Bodoni Moda.** Space Grotesk does not appear in any display role.
- **Every body, subtitle, pill-text, label, and chip element is set in Space Grotesk.** Bodoni does not appear in body or chip roles.
- **Every Bodoni display element uses negative letter-spacing** (-0.01em to -0.03em). Bodoni at large sizes with default tracking reads loose.
- **Every Space Grotesk subtitle, label, pill-text, and chip element is uppercase with 0.08em+ tracking.** The uppercase + tracking is the small-text identity signal.
- **Bodoni headlines are always rendered in `{colors.ink}`, never in a candy color.** Color appears on stat numerals (e.g., `color: {colors.coral}`) but not on serif headlines. The exception is the orbit-center numeral, which sits inside a colored circular pill but the numeral itself remains ink.
- **Every pill element carries the 2px solid outline.** A pill without its 2px ink stroke breaks the system.
- **Every container with `border-radius: 9999px` or `2rem` carries either the 2px outline or sits inside an already-outlined parent.** Unoutlined rounded containers do not exist.
- **Every card or elevated pill carries a hard-offset shadow** at 4/6/8/12px in `{colors.shadow}`. Smaller pills get 4–6px; cards get 8px; visual frames get 12px.

### Typography Principles
The Bodoni-headline + Space-Grotesk-body pairing is the primary rhythm; switching either face breaks the system. Italic appears only inside pull-quote bodies via the `<em>` tag (Bodoni italic). Underline is not used. Pill-encapsulation is the system's primary emphasis mechanism: wrapping a phrase in a candy-filled pill is the equivalent of bold-italicizing it in a traditional editorial system.

Line-height tightens at scale: `{typography.display}` at 0.9, `{typography.headline}` at 1.05, body at 1.6. The tight display + open body contrast is what gives the system its editorial breathing rhythm.

## Layout

### Canvas System
The canvas is `100vw × 100vh` — full viewport with hidden overflow. Each `.slide` is absolutely positioned to fill the viewport, with one slide carrying `.active` (opacity 1) at a time. Transitions are 0.6s opacity fades via `cubic-bezier(0.4, 0, 0.2, 1)`. All sizes use rem units inside CSS `clamp()` so the layout scales fluidly.

### Padding and Gap Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.pad-lg}` | 3rem 4rem | Default slide outer padding |
| `{spacing.gap-xl}` | 4rem | Major two-column gutter |
| `{spacing.gap-lg}` | 3rem | Section-block spacing |
| `{spacing.gap-md}` | 2rem | Standard inter-element spacing |
| `{spacing.gap-sm}` | 1.5rem | Tight card-internal spacing |
| `{spacing.gap-xs}` | 0.75rem | Inline gap between mini-pills |
| `{spacing.card-pad}` | 2.5rem 2rem | Default pillar-card padding |
| `{spacing.pill-pad-lg}` | 1.5rem 3.5rem | Title-pill / closing-pill padding |
| `{spacing.pill-pad-md}` | 1rem 2.5rem | Featured pill padding |
| `{spacing.pill-pad-sm}` | 0.4rem 1.2rem | Header-tag pill padding |
| `{spacing.pill-pad-xs}` | 0.35rem 1rem | Mini-pill chip padding |

### Atmospheric Background Layer
Every slide layers two atmospheric treatments on top of the cream canvas:
1. **Radial glows** — one to three soft `radial-gradient(ellipse at X% Y%, rgba(accent, 0.06–0.15), transparent)` washes anchored to corners or center. These tint the canvas warmly without changing its surface color.
2. **Grain overlay** — a fractal-noise SVG fixed at `inset: 0`, opacity 0.04, mix-blend-mode multiply, z-index 9999. Always present, always identical, never removed.

These are not decorative options; they are baseline canvas treatments that should appear on every slide.

### Decorative Pill Wallpaper
A signature: small decorative pills (60–160px wide, 35–90px tall) tilted at -20° to +25° rotations are placed absolutely on slide backgrounds as atmospheric typographic confetti. Each contains a single uppercase Space-Grotesk word and a candy fill. Some are circular (border-radius 50%) instead of capsule-shaped. They have no informational role — they are visual atmosphere. Typical count: 5–8 per slide on cover/closing/quote layouts; 0 on dense data layouts.

## Depth and Elevation

### Soft Hard-Offset Shadow
The system's only depth technique is a **solid hard-offset shadow** in low-opacity ink:
- **4px 4px 0** — small elevated nodes (step nodes, small pills).
- **6px 6px 0** — orbit pills, stat-pills, diagram nodes.
- **8px 8px 0** — pillar-cards, chart container.
- **12px 12px 0** — large visual frame (the most lifted element in the system).

All shadows use `{colors.shadow}` (`rgba(26, 26, 26, 0.08)`). The opacity is the key distinction from a brutalist hard shadow: at 8% the shadow reads as a soft lift rather than a stamped offset. The offset direction is always bottom-right.

### Outline-Based Depth
Most apparent depth comes from the 2px ink outline that wraps every pill against the cream canvas. The outline does much of the elevation work; the shadow adds the lift on cards and elevated pills.

### Flat Decorative Layer
Decorative floating pills and radial glows are flat — they cast no shadow. The shadow is reserved for content-bearing containers (cards, stat tiles, diagram nodes, visual frames). This visual rule separates "content" from "atmosphere" at a glance.

## Shapes and Treatment

### Border Radius
| Value | Use |
|---|---|
| 9999px (full pill) | All small pills: title pill, closing pill, decorative pills, header tags, mini chips, bar tracks, bar fills, accent lines, orbit pills, floating pills, quote highlights, diagram nodes |
| 2rem (32px) | Larger cards: pillar-cards, stat-pills, chart container, visual frame |
| 1.5rem (24px) | Inner dashed frame inside the visual frame |
| 50% (circle) | Circular pills: card-icon (60px), step-node (56px), orbit-center (160px), nav dots (10px) |
| 0 | The grain overlay; the slide itself; the candy-color gradient regions inside a visual frame |

The system has **no sharp-cornered text containers**. Every container that holds text or icon content is rounded.

### Border Weights
- **2px solid `{colors.outline}`** — the universal stroke. Used on every pill, card, icon, frame, bar track, nav dot.
- **2px dashed `{colors.outline}`** — used only on the inner frame inside the visual-frame component (a decorative interior border indicating "image placeholder").
- **4px solid ink** — used only on the timeline-line that connects sequential step nodes horizontally.

All borders are `{colors.outline}`. Colored borders do not exist in the system.

### Decorative Element Types

**Decorative floating pill** — A small (60–160px wide × 35–90px tall) pill or circle in a candy fill, tilted at -20° to +25° rotation, positioned absolutely on the slide background. Contains a single uppercase Space-Grotesk word at 0.55–0.85rem. Functions as typographic confetti / atmospheric wallpaper. Five to eight per declarative slide.

**Header tag pill** — A small (≈0.7rem text) pill in a candy fill (typically lavender) with `pill-pad-sm` padding, centered above a section headline. The system's section-tag chip.

**Title pill / closing pill** — A medium pill (`pill-pad-lg`) in `{colors.yellow}` carrying uppercase Space-Grotesk text. Placed above the largest display headline on cover and closing slides.

**Pillar-card** — A 2rem-radius white card with 2px outline and 8px offset shadow, containing a circular `card-icon` at the top, a Bodoni `card-headline`, and a Space-Grotesk body paragraph. Used in 3-card and 4-card grids.

**Stat-pill** — A 2rem-radius white card containing a colored Bodoni stat number, a small uppercase label, and a tiny 40×4 accent bar at the bottom. Sits in 3- or 4-column stat grids.

**Bar-track** — A 36px-tall horizontal pill (9999px radius) with 2px outline and cream interior. The fill is a child pill in a candy color with the value label printed at the right edge inside the fill.

**Orbit composition** — A central 160px circular pill in `{colors.lime}` carrying a Bodoni ordinal, surrounded by 4–6 small `orbit-pill` satellites in candy fills, each tilted, positioned at 8–45% / 8–45% offsets, with 6px shadows.

**Diagram-node + connector** — Pill-shaped flow node (`diagram-node`) with 6px shadow, connected to the next node by a 50×4 ink bar with a triangular arrowhead. Nodes may carry candy fills; arrows are always ink.

**Visual-frame** — A 2rem-radius large frame with 12px offset shadow, filled with a tri-stop linear gradient (typically lavender → sky → mint), overlaid with a dot-grid pattern at 0.15 opacity, with an inner dashed border indicating "image placeholder." Used for hero visual moments.

**Quote-highlight** — An inline pill in lime or sky with 2px outline, wrapped around a single phrase inside a Bodoni quote body. The system's primary inline emphasis mechanism.

**Accent line** — A 60×4 (or 80×4 on closing slides) horizontal pill in `{colors.coral}` used as a sub-headline accent rule.

## Do's and Don'ts

### Do
- Make every text container a pill — 9999px radius for small pills, 2rem radius for larger cards. The pill geometry is the system's most distinctive single trait.
- Apply the 2px `{colors.outline}` stroke to every pill, card, icon, and frame. The outline is what makes the candy palette read as graphic rather than candy.
- Set every Bodoni display element in `{colors.ink}`, never in a candy color. Color belongs on stat numerals and pill fills, not on serif headlines.
- Use Bodoni Moda for every headline/stat/card title; use Space Grotesk for every body/label/pill. The two-face split is non-negotiable.
- Render shadows as solid hard offsets at 4/6/8/12px in `{colors.shadow}` (`rgba(26,26,26,0.08)`). Never blur; never re-color.
- Populate slide backgrounds with 5–8 floating decorative pills tilted at -20° to +25° rotations on cover, closing, quote, and other declarative layouts. The wallpaper-pill treatment is a system signature.
- Layer radial-gradient accent glows (6–15% opacity) into the cream canvas on every slide for atmospheric warmth.
- Keep the grain overlay (4% opacity, multiply blend) active on every slide — it is a baseline layer, not optional decoration.
- Wrap inline emphasis phrases in `quote-highlight` pills (lime, sky, or another candy) inside Bodoni quote bodies, rather than bolding or italicizing.
- Pair warm + cool accents adjacently: coral with sky, yellow with lavender, peach with mint. Avoid two same-family accents next to each other.

### Don't
- Don't render any text container with sharp corners. Square text containers do not exist in Capsule.
- Don't render a pill, card, or icon without the 2px ink outline. The stroke is the system's identity.
- Don't render Bodoni headlines in a candy color. Headlines are always `{colors.ink}`; color lives on stat numerals and pill fills.
- Don't use blurred drop shadows. The shadow is always solid offset at 4/6/8/12px in `{colors.shadow}`.
- Don't pair Bodoni with a different sans companion. The Bodoni Moda + Space Grotesk pairing is fixed.
- Don't use uppercase on Bodoni headlines. Bodoni in this system is sentence case (or true title case for proper nouns).
- Don't use sentence case on Space Grotesk subtitles, labels, or pill text. Small Space Grotesk text is always uppercase + 0.08em tracking.
- Don't introduce a tenth accent color. The nine candy accents are the closed palette.
- Don't apply shadows to decorative floating pills. Shadows are reserved for content-bearing containers.
- Don't leave a slide's corners empty on declarative layouts. The cream canvas wants atmospheric pills or radial glows; bare corners read as broken.

## Responsive Behavior

Capsule is a viewport-fluid 1920×1080 presentation system using `clamp()` and viewport-relative units throughout. There is a single `@media (max-width: 900px)` breakpoint that collapses grid columns to single-column stacks and hides the nav-dot column; below 600px the stats grid further collapses from 2-col to 1-col. The system is otherwise responsive without breakpoints.

### Scaling Behavior
- Display headline scales from 3rem at minimum viewport to 7rem at maximum.
- Body text scales from 0.95rem to 1.15rem.
- Padding scales via `clamp` inside individual layout selectors.
- Borders, pill outlines, shadow offsets, and grain overlay are fixed and do not scale.

### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, or `Space`.
- Slides reverse via `ArrowLeft` or `ArrowUp`.
- `Home` jumps to the first slide; `End` to the last.
- Touch swipe (horizontal): swipe distance >50px advances or reverses.
- The active slide carries `.active` (opacity 1); non-active slides are opacity 0 + pointer-events none.
- Nav dots are a vertical column at the right edge; the slide counter is at bottom-right; a keyboard hint is at bottom-left.

### Print / Export
Not explicitly handled; opacity-toggling means a naïve print captures only the active slide. Export workflows should snapshot each slide individually at 1920×1080.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin font | Recommended Chinese pairing | Source |
|---|---|---|---|
| Display / Headline (Bodoni Moda 700–800) | Bodoni Moda | 站酷小薇体 ZCOOL XiaoWei | Google Fonts |
| Body / Pill text (Space Grotesk 400–600) | Space Grotesk | 悠哉字体 Yozai | cn-fontsource CDN |

### Mixed-Content Strategy

Use **Strategy A — single-font-stack with fallback**: declare the CJK font *after* the Latin font in the same `font-family` stack so Latin glyphs render in Bodoni Moda / Space Grotesk and CJK glyphs fall through to the Chinese face automatically. One CSS rule per role, no manual class switching.

### 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=Bodoni+Moda:ital,opsz,wght@0,6..96,400..900;1,6..96,400..900&family=Space+Grotesk:wght@300..700&family=ZCOOL+XiaoWei&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/cn-fontsource-yozai-regular/font.css" rel="stylesheet">
```

```css
:root {
  --font-display: "Bodoni Moda", "ZCOOL XiaoWei", serif;
  --font-body: "Space Grotesk", "Yozai", sans-serif;
}
```

### Universal CJK Adjustments

- **Line-height**: bump CJK body line-height to ~1.7 (from 1.6) — Hanzi need more vertical breathing than Latin lowercase.
- **Letter-spacing**: zero out `letter-spacing` on Hanzi runs (negative tracking that flatters Bodoni capitals jams Hanzi strokes together). Keep tight tracking only on Latin spans.
- **Text-transform**: drop `text-transform: uppercase` on any pill/label/subtitle when content is Hanzi — Chinese has no case; forcing uppercase does nothing for Hanzi but breaks the rendering of any mixed Latin acronyms inside.
- **Punctuation**: use Chinese full-width punctuation (，。：；「」) for Chinese sentences, half-width (`,.:;""`) for Latin. Never mix half-width punctuation into a Chinese sentence.
- **No period on headlines**: Chinese headline convention omits the terminal 。 — strip it from display strings.
- **Pangu spacing**: insert a thin space (or a regular space) between adjacent Hanzi and Latin/digit runs (e.g. `2026 年`, `AI 产品`). Improves readability of mixed runs.
- **One font per sentence**: don't switch CJK families mid-sentence. Pick ZCOOL XiaoWei *or* Yozai for a given text run based on its role, never both inside one phrase.

### Aesthetic Notes

ZCOOL XiaoWei is a high-contrast literary serif-leaning Hanzi face whose thin-thick stroke modulation echoes Bodoni Moda's didone register — it gives display headlines the same editorial-glamour weight as the Latin original. Yozai is a friendly rounded Hanzi sans whose open counters and modest stroke contrast mirror Space Grotesk's geometric grotesque, so pill text, labels, and body paragraphs retain the "clean modern sans" feel rather than reverting to a stiff system Hanzi. Both pair cleanly with the candy palette: ZCOOL XiaoWei in `{colors.ink}` keeps the rule "Bodoni headlines are never colored" intact, and Yozai sits inside coral / lime / yellow pills without losing legibility against the 2px ink outline. The decorative floating pill wallpaper still works in Chinese — substitute single-character or two-character atmospheric words (愿景, 未来, 下一步) for the English uppercase confetti.

### Known CJK Gap

ZCOOL XiaoWei is a display face with limited weight axis (single weight) and a smaller glyph set than Noto family — exotic or technical Hanzi (rare surnames, classical characters, simplified-only variants outside GB2312) may fall back to system font. For Traditional Chinese decks, swap Yozai for `LXGW WenKai TC` (Google Fonts) which has fuller TC coverage and a similar friendly humanist register. The ZCOOL XiaoWei italic / heavy moments that Bodoni achieves via the opsz axis have no equivalent in the Chinese face — use scale and color to compensate when Latin would have leaned on italic Bodoni.

## Iteration Guide

1. Any new container that holds text uses the pill geometry — 9999px radius for small, 2rem radius for cards. Don't introduce a sharp-cornered text container.
2. Any new pill carries the 2px solid `{colors.outline}` stroke. Don't render an unstroked pill.
3. Any new headline uses Bodoni Moda in `{colors.ink}`. Don't color a serif headline; don't switch to Space Grotesk for display.
4. Any new card carries a `8px 8px 0 {colors.shadow}` offset shadow (4px for small nodes, 12px for the visual frame). Don't blur; don't re-color.
5. Any new accent uses the nine-color candy palette in the coral → lime → sky → violet → yellow → lavender → peach → mint default sequence. Don't introduce a tenth color.
6. Any new declarative slide (cover, closing, quote, statement) gets 5–8 floating decorative pills as atmospheric wallpaper.
7. Any new data slide gets one or two radial accent glows in the canvas background. Don't leave the cream surface flat.
8. Any inline emphasis inside a Bodoni quote body uses a `quote-highlight` pill. Don't bold; don't italicize except via the Bodoni italic axis inside `<em>`.
9. New components inherit the pill geometry + 2px outline + 4–12px shadow pattern. If a new component breaks any of these three rules, redesign it before adding it.

## Known Gaps

- Two Bodoni font axes (italic and opsz 6..96) are loaded but the template only exercises the upright axis at fixed sizes; the optical-size variation across display sizes is not explicitly opted into.
- Bar-chart values are inline-styled via `style="width: NN%"` — there is no data-binding layer.
- The decorative floating pill positions and rotations are all hand-tuned via inline style on each instance; there is no generative placement system.
- The visual-frame's tri-stop gradient (lavender → sky → mint) is a hardcoded "default" — alternate gradient combinations are valid but need to be authored per instance.
- The grain overlay uses an inline SVG data URL; replacing or removing it requires editing the markup, not a CSS variable.
- The chart-bar-fill border-right at 2px solid outline is what gives bars their pill-end-cap definition; removing it loses the pill aesthetic on bars.
- The system inherits all 9 candy accent CSS variables but only ~6 are actively used across the source — peach and mint are present in the palette but used sparingly. They are available for new compositions.
- Decorative floating pills include their text content as part of the visual identity (single uppercase Space-Grotesk words). The words are not informational; new compositions should pick neutral single-word atmospheres ("VISION", "FUTURE", "NEXT", etc.) rather than content-specific text.
````

---

## 2. 글씨체

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

---

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

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

**1장(표지)에서 처음 나오는 부품**
- `.aline` — 1장 — 예: `<i class="aline">`
- `.cv` — 1장 — 예: `<div class="cv">`
- `.disp` — 1장 — 예: `<h1 class="disp">`
- `.fpill` — 1·5장 — 예: `<span class="fpill" style="left:100px;top:90px;width:160px;height:70px;transform:rotate(-12deg);background:#F2…`
- `.glow` — 1·2·3·4·5·6장 — 예: `<div class="glow" style="left:-10%;top:-20%;background:radial-gradient(circle,rgba(232,93,78,.13),transparent …`
- `.grain` — 1·2·3·4·5·6장 — 예: `<div class="grain">`
- `.lav` — 1·2·3·4·5·6장 — 예: `<span class="pill lav">`
- `.meta` — 1장 — 예: `<span class="meta">`
- `.pill` — 1·2·3·4·5·6장 — 예: `<span class="pill lav">`
- `.qh` — 1·4장 — 예: `<span class="qh" style="background:#C4D94E">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide">`
- `.sub` — 1장 — 예: `<p class="sub">`
- `.tp` — 1장 — 예: `<span class="pill yellow tp">`
- `.yellow` — 1·2·5·6장 — 예: `<span class="pill yellow tp">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.btn` — 2·5장 — 예: `<button class="pill coral btn" data-act="step">`
- `.btns` — 2장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03…`
- `.coral` — 2·6장 — 예: `<button class="pill coral btn" data-act="step">`
- `.def` — 2장 — 예: `<p class="def">`
- `.inner` — 2장 — 예: `<div class="inner">`
- `.node` — 2장 — 예: `<span class="node">`
- `.note` — 2장 — 예: `<span class="pill yellow note">`
- `.sm` — 2·3·4·5·6장 — 예: `<span class="pill lav sm" style="left:110px;top:70px">`
- `.tl` — 2장 — 예: `<div class="tl">`
- `.tstep` — 2장 — 예: `<div class="tstep" data-s="1" style="--c:#E85D4E">`
- `.vframe` — 2장 — 예: `<div class="vframe">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.ab` — 3장 — 예: `<i class="ab" style="background:#E85D4E">`
- `.brow` — 3장 — 예: `<div class="brow">`
- `.ch` — 3장 — 예: `<div class="ch">`
- `.chart` — 3장 — 예: `<div class="pcard chart">`
- `.lb` — 3장 — 예: `<span class="lb">`
- `.mini` — 3·5장 — 예: `<span class="mini" style="background:#E85D4E">`
- `.pcard` — 3·4·5·6장 — 예: `<div class="pcard chart">`
- `.sn` — 3장 — 예: `<b class="sn" style="color:#E85D4E">`
- `.spill` — 3장 — 예: `<div class="spill">`
- `.src` — 3장 — 예: `<p class="src">`
- `.stats` — 3장 — 예: `<div class="stats">`
- `.tm` — 3장 — 예: `<span class="tm">`
- `.track` — 3장 — 예: `<span class="track">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cmp` — 4장 — 예: `<div class="cmp">`
- `.icon` — 4·5·6장 — 예: `<span class="icon" style="background:#E85D4E">`
- `.lst` — 4장 — 예: `<div class="pcard lst">`
- `.nr` — 4·5장 — 예: `<p class="nr">`
- `.pc` — 4장 — 예: `<div class="pcard pc">`
- `.qt` — 4장 — 예: `<blockquote class="qt">`
- `.tbl` — 4장 — 예: `<div class="tbl">`
- `.th` — 4장 — 예: `<div class="tr th">`
- `.tr` — 4장 — 예: `<div class="tr th">`
- `.xs` — 4장 — 예: `<span class="icon xs" style="background:#F2D160">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bl` — 5장 — 예: `<p class="bl">`
- `.blank` — 5장 — 예: `<button class="pill blank" data-blank aria-pressed="false" style="--c:#C4D94E">`
- `.blk` — 5장 — 예: `<div class="pcard blk">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.lbw` — 5장 — 예: `<span class="lbw">`
- `.opt` — 5장 — 예: `<button class="opt" data-opt="0">`
- `.opts` — 5장 — 예: `<div class="opts">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.quiz` — 5장 — 예: `<div class="pcard quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="…`
- `.rt` — 5장 — 예: `<button class="pill yellow btn rt" data-act="retry">`
- `.words` — 5장 — 예: `<div class="words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.a` — 6장 — 예: `<div class="pcard d6 a">`
- `.b` — 6장 — 예: `<div class="pcard d6 b">`
- `.btn6` — 6장 — 예: `<button class="pill sm btn6" data-demo="#cp-sh" data-mode="toggle" aria-pressed="false">`
- `.c` — 6장 — 예: `<div class="pcard d6 c">`
- `.d6` — 6장 — 예: `<div class="pcard d6 a">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.dr` — 6장 — 예: `<div class="dr">`
- `.g6` — 6장 — 예: `<div class="pcard g6">`
- `.nd6` — 6장 — 예: `<div class="dr nd6" id="cp-node">`
- `.qh6` — 6장 — 예: `<h3 class="qh6" id="cp-qh">`
- `.r6` — 6장 — 예: `<div class="r6">`
- `.shp` — 6장 — 예: `<span class="pill coral shp" id="cp-sh">`
- `.sl6` — 6장 — 예: `<span class="pill yellow sm sl6">`
- `.sw6` — 6장 — 예: `<span class="sw6">`

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

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="capsule">
<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=Bodoni+Moda:ital,opsz,wght@0,6..96,700;0,6..96,800;1,6..96,500&family=Space+Grotesk:wght@400;500;700&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/capsule.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide">
  <div class="glow" style="left:-10%;top:-20%;background:radial-gradient(circle,rgba(232,93,78,.13),transparent 60%)"></div>
  <div class="glow" style="right:-15%;bottom:-25%;background:radial-gradient(circle,rgba(139,180,247,.15),transparent 60%)"></div>
  <span class="fpill" style="left:100px;top:90px;width:160px;height:70px;transform:rotate(-12deg);background:#F2D160;">태양</span><span class="fpill" style="left:1600px;top:110px;width:170px;height:70px;transform:rotate(18deg);background:#8BB4F7;">그림자</span><span class="fpill" style="left:1700px;top:470px;width:96px;height:96px;transform:rotate(0deg);background:#C4D94E;border-radius:50%">9:30</span>
  <span class="fpill" style="left:1560px;top:860px;width:150px;height:64px;transform:rotate(-20deg);background:#A06CE8;">기온</span><span class="fpill" style="left:150px;top:880px;width:130px;height:60px;transform:rotate(22deg);background:#F5B895;">남중</span><span class="fpill" style="left:70px;top:500px;width:84px;height:84px;transform:rotate(0deg);background:#A8E6CF;border-radius:50%">☀</span>
  <div class="cv">
    <span class="pill lav">계절의 변화 · Sun, Shadow & Temperature</span>
    <i class="aline"></i>
    <span class="pill yellow tp">학습 목표</span>
    <h1 class="disp">하루 동안 <span class="qh" style="background:#C4D94E">태양 고도</span>,<br><span class="qh" style="background:#8BB4F7">그림자 길이</span>, <span class="qh" style="background:#E85D4E">기온</span>의 관계</h1>
    <p class="sub">초등 과학 · 6학년 2학기 · 1단원 · 3~4차시</p>
  </div>
  <span class="meta">00초등학교 · 2026</span>
  <div class="grain"></div>
</section>
<section class="slide" data-steps="4">
  <div class="glow" style="right:-20%;top:-30%;background:radial-gradient(circle,rgba(196,217,78,.14),transparent 60%)"></div>
  <span class="pill lav sm" style="left:110px;top:70px">측정 준비</span>
  <h2 style="left:110px;top:150px">태양 고도 측정기 만들기</h2>
  <div class="vframe"><div class="inner"><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></div>
  <span class="pill yellow note">막대기의 그림자와 실이 이루는 각 = 태양 고도</span>
  <p class="def"><b>태양 고도</b> = 태양이 지표면과 이루는 각</p>
  <div class="tl"><div class="tstep" data-s="1" style="--c:#E85D4E"><span class="node">I</span><div><h3>자 붙이기</h3><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div></div><div class="tstep" data-s="2" style="--c:#C4D94E"><span class="node">II</span><div><h3>수수깡 꽂기</h3><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div></div><div class="tstep" data-s="3" style="--c:#8BB4F7"><span class="node">III</span><div><h3>실 묶기</h3><p>수수깡 끝에 실을 묶어요</p></div></div><div class="tstep" data-s="4" style="--c:#A06CE8"><span class="node">IV</span><div><h3>각도기 끼우기</h3><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
  <div class="btns"><button class="pill coral btn" data-act="step">다음 단계 →</button><button class="pill btn" data-act="reset">처음부터</button></div>
  <p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03 실 묶기&quot;,&quot;04 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</p>
  <div class="grain"></div>
</section>
<section class="slide">
  <div class="glow" style="left:-15%;bottom:-30%;background:radial-gradient(circle,rgba(160,108,232,.12),transparent 60%)"></div>
  <span class="pill lav sm" style="left:110px;top:70px">측정 결과</span>
  <h2 style="left:110px;top:150px">하루 동안 무엇이 어떻게 변할까요?</h2>
  <div class="stats"><div class="spill"><b class="sn" style="color:#E85D4E">12:30</b><span class="lb">남중 시각</span><p>태양 고도가 가장 높아요 무렵 · 남중</p><i class="ab" style="background:#E85D4E"></i></div><div class="spill"><b class="sn" style="color:#A06CE8">정남</b><span class="lb">남중 방향</span><p>남중할 때 태양의 위치 쪽</p><i class="ab" style="background:#C4D94E"></i></div><div class="spill"><b class="sn" style="color:#8BB4F7">14:30</b><span class="lb">최고 기온</span><p>기온이 가장 높아요 무렵</p><i class="ab" style="background:#8BB4F7"></i></div><div class="spill"><b class="sn" style="color:#E85D4E">9:30</b><span class="lb">가장 긴 그림자</span><p>그림자가 가장 길어요 · 15:30</p><i class="ab" style="background:#A06CE8"></i></div></div>
  <div class="pcard chart">
    <div class="ch"><b>측정 시각별 태양 고도, 그림자 길이, 기온</b><span class="mini" style="background:#E85D4E">태양 고도(°)</span><span class="mini">그림자 길이(cm)</span><span class="mini">기온(℃)</span><span class="mini" style="background:#F2D160">예시 값</span></div>
    <div class="brow"><span class="tm">9:30</span><span class="track"><i style="width:63%"><b>38°</b></i></span><span class="mini">12.9</span><span class="mini">22</span></div><div class="brow"><span class="tm">10:30</span><span class="track"><i style="width:80%"><b>48°</b></i></span><span class="mini">9.1</span><span class="mini">23.8</span></div><div class="brow"><span class="tm">11:30</span><span class="track"><i style="width:92%"><b>55°</b></i></span><span class="mini">7</span><span class="mini">25.2</span></div><div class="brow"><span class="tm">12:30</span><span class="track"><i style="width:95%"><b>57°</b></i></span><span class="mini">6.4</span><span class="mini">26.3</span></div><div class="brow"><span class="tm">13:30</span><span class="track"><i style="width:90%"><b>54°</b></i></span><span class="mini">7.2</span><span class="mini">27</span></div><div class="brow"><span class="tm">14:30</span><span class="track"><i style="width:78%"><b>47°</b></i></span><span class="mini">9.4</span><span class="mini">27.4</span></div><div class="brow"><span class="tm">15:30</span><span class="track"><i style="width:62%"><b>37°</b></i></span><span class="mini">13.4</span><span class="mini">26.9</span></div>
  </div>
  <p class="src">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</p>
  <div class="grain"></div>
</section>
<section class="slide">
  <div class="glow" style="right:-15%;bottom:-30%;background:radial-gradient(circle,rgba(242,209,96,.14),transparent 60%)"></div>
  <span class="pill lav sm" style="left:110px;top:70px">관계 정리</span>
  <h2 style="left:110px;top:150px">태양 고도가 바뀌면 무엇이 달라질까요?</h2>
  <div class="cmp"><div class="pcard pc"><span class="icon" style="background:#E85D4E">I</span><h3>태양 고도가 높을 때</h3><p>그림자 길이는 짧아져요</p><p>기온은 높아져요</p></div><div class="pcard pc"><span class="icon" style="background:#8BB4F7">II</span><h3>태양 고도가 낮을 때</h3><p>그림자 길이는 길어져요</p><p>기온은 낮아져요</p></div></div>
  <div class="pcard lst"><span class="pill lav sm">남중</span><p><span class="icon xs" style="background:#F2D160">1</span>태양이 정남쪽에 있을 때 '남중했다'고 해요</p><p><span class="icon xs" style="background:#F5B895">2</span>이때의 태양 고도를 남중 고도라고 해요</p></div>
  <div class="tbl"><div class="tr th"><span>시각</span><span>태양 고도</span><span>그림자 길이</span><span>기온</span></div><div class="tr"><span>오전 9:30</span><span>낮아요</span><span>길어요</span><span>낮아요</span></div><div class="tr"><span>낮 12:30</span><span>가장 높아요</span><span>가장 짧아요</span><span>높아지는 중</span></div><div class="tr"><span>오후 14:30</span><span>낮아지는 중</span><span>길어지는 중</span><span>가장 높아요</span></div></div>
  <blockquote class="qt"><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 <span class="qh" style="background:#C4D94E">차이</span>가 있어요.</p><span>— 오늘의 정리</span></blockquote>
  <p class="nr">표 규칙 없음 → 알약 행으로 표현</p>
  <div class="grain"></div>
</section>
<section class="slide">
  <div class="glow" style="left:-10%;top:-25%;background:radial-gradient(circle,rgba(168,230,207,.18),transparent 60%)"></div>
  <span class="fpill" style="left:1710px;top:70px;width:140px;height:60px;transform:rotate(16deg);background:#F2D160;">확인</span><span class="fpill" style="left:940px;top:990px;width:120px;height:56px;transform:rotate(-10deg);background:#8BB4F7;">퀴즈</span><span class="fpill" style="left:1760px;top:900px;width:80px;height:80px;transform:rotate(0deg);background:#E85D4E;border-radius:50%">?</span>
  <span class="pill lav sm" style="left:110px;top:70px">확인하기</span>
  <h2 style="left:110px;top:150px">배운 내용을 확인해 볼까요?</h2>
  <div class="pcard quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
    <h3 class="q">하루 중 그림자 길이가 가장 짧을 때는?</h3>
    <div class="opts"><button class="opt" data-opt="0"><span class="icon sm" style="background:#C4D94E">A</span>오전 9시 30분</button><button class="opt" data-opt="1"><span class="icon sm" style="background:#8BB4F7">B</span>낮 12시 30분 무렵</button><button class="opt" data-opt="2"><span class="icon sm" style="background:#A06CE8">C</span>오후 3시 30분</button></div>
    <p class="fb" data-fb></p>
    <button class="pill yellow btn rt" data-act="retry">다시 풀기 ↺</button>
  </div>
  <div class="pcard blk">
    <span class="pill lav sm">빈칸을 눌러 확인해요</span>
    <p class="bl"><button class="pill blank" data-blank aria-pressed="false" style="--c:#C4D94E"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</p><p class="bl"><button class="pill blank" data-blank aria-pressed="false" style="--c:#8BB4F7"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</p><p class="bl"><button class="pill blank" data-blank aria-pressed="false" style="--c:#E85D4E"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</p>
    <span class="lbw">오늘의 낱말</span>
    <div class="words"><span class="mini" style="background:#E85D4E">태양 고도</span><span class="mini" style="background:#C4D94E">남중 고도</span><span class="mini" style="background:#8BB4F7">그림자 길이</span><span class="mini" style="background:#A06CE8">기온</span></div>
  </div>
  <p class="nr">빈칸 규칙 없음 → 알약으로 표현</p>
  <div class="grain"></div>
</section>
<section class="slide">
  <div class="glow" style="right:-20%;bottom:-30%;background:radial-gradient(circle,rgba(232,93,78,.12),transparent 60%)"></div>
  <span class="pill lav sm" style="left:110px;top:70px">디자인 안내</span>
  <h2 style="left:110px;top:150px">이 디자인 사용 설명서</h2>
  <div class="pcard g6">
    <div class="r6"><span class="icon sm" style="background:#E85D4E">I</span><div><h3>한눈에</h3><p>모든 것을 <b>알약 모양</b>(완전히 둥근 모서리)에 담고 <b>2px 외곽선 + 옅은 하드 그림자</b>를 붙여요. 크림 바탕에 캔디색을 차례로 씁니다.</p></div></div><div class="r6"><span class="icon sm" style="background:#C4D94E">II</span><div><h3>색</h3><p><span class="sw6"><span><i style="background:#E85D4E"></i>코랄</span><span><i style="background:#C4D94E"></i>라임</span><span><i style="background:#8BB4F7"></i>하늘</span><span><i style="background:#A06CE8"></i>바이올렛</span><span><i style="background:#F2D160"></i>노랑</span><span><i style="background:#C5B5E0"></i>라벤더</span></span></p></div></div><div class="r6"><span class="icon sm" style="background:#8BB4F7">III</span><div><h3>글꼴</h3><p>제목·숫자 Bodoni Moda → Noto Serif KR Black<br>본문·알약 Space Grotesk → Noto Sans KR Regular</p></div></div><div class="r6"><span class="icon sm" style="background:#A06CE8">IV</span><div><h3>이렇게 쓰면 좋아요</h3><p>낱말 카드·개념 정리처럼 짧은 덩어리가 많은 수업. 제목은 언제나 잉크색, 색은 알약에만.</p></div></div>
  </div>
  <span class="pill yellow sm sl6">대표 장치 — 눌러 보세요</span>
  <div class="pcard d6 a"><div class="dh"><h3>하드 그림자 크기</h3><button class="pill sm btn6" data-demo="#cp-sh" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>오른쪽 아래로 흐림 없는 그림자 — 작은 알약 4·6px, 큰 카드 8·12px.</p><div class="dr"><span class="pill coral shp" id="cp-sh">태양 고도</span></div></div>
  <div class="pcard d6 b"><div class="dh"><h3>낱말을 알약으로 감싸기</h3><button class="pill sm btn6" data-demo="#cp-qh" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>제목 속 핵심 낱말을 캔디색 알약으로 감싸 강조해요.</p><div class="dr"><h3 class="qh6" id="cp-qh">하루 동안 <span>그림자</span>의 길이</h3></div></div>
  <div class="pcard d6 c"><div class="dh"><h3>단계 원 켜기</h3><button class="pill sm btn6" data-demo="#cp-node" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>56px 원에 로마 숫자 — 단계가 켜지면 캔디색으로 칠해져요.</p><div class="dr nd6" id="cp-node"><span class="icon sm" style="--c:#E85D4E">I</span><i></i><span class="icon sm" style="--c:#C4D94E">II</span><i></i><span class="icon sm" style="--c:#8BB4F7">III</span><i></i><span class="icon sm" style="--c:#A06CE8">IV</span></div></div>
  <div class="grain"></div>
</section>
<nav class="dk-nav"><span class="dk-dots"><button class="dk-dot" aria-label="1장"></button><button class="dk-dot" aria-label="2장"></button><button class="dk-dot" aria-label="3장"></button><button class="dk-dot" aria-label="4장"></button><button class="dk-dot" aria-label="5장"></button><button class="dk-dot" aria-label="6장"></button></span><span class="dk-count" data-pad></span><span class="hint">← → 키로 넘기기</span></nav>
  </main>
</div>

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

---

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

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

```css
/* capsule — k-slide 공통 CSS v1 (채팅 AI용 받기 .md가 불러옴, 고치지 말 것) */
/* === KOREAN FONTS === */
@font-face{font-family:'kp-12';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/noto-serif-kr/NotoSerifKR-Black.woff2") format("woff2");font-weight:900}
@font-face{font-family:'kp-13';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/noto-sans-kr/NotoSansKR-Regular.woff2") format("woff2");font-weight:400}
/* === THEME === */
:root{--stage-bg:#F5F5F0;--slide-bg:#F5F5F0;
  --kt:'kp-12';--kb:'kp-13';--ka:'kp-13';
  --wt:900;--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 === */

/* --- 토큰: 2px 외곽선, 하드 그림자는 옅은 잉크(명세 rgba(26,26,26,.08)를 무대 크기에 맞춰 조금 진하게) --- */
:root{--cream:#F5F5F0;--ink:#1A1A1A;--ol:#1E1E1E;--coral:#E85D4E;--lime:#C4D94E;--sky:#8BB4F7;--violet:#A06CE8;--yellow:#F2D160;--lav:#C5B5E0;--peach:#F5B895;--mint:#A8E6CF;--sh:rgba(26,26,26,.14)}
.slide{background:var(--cream);color:var(--ink);font-family:'Space Grotesk',var(--kb),sans-serif}
.slide>*{position:absolute}
.glow{width:1100px;height:1100px;pointer-events:none}
.grain{inset:0;z-index:90;opacity:.04;mix-blend-mode:multiply;pointer-events:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E")}
.pill{display:inline-flex;align-items:center;border:2px solid var(--ol);border-radius:9999px;padding:12px 34px;font-weight:700;font-size:30px;box-shadow:6px 6px 0 var(--sh);background:#fff;color:var(--ink);white-space:nowrap}
.pill.sm{padding:8px 26px;font-size:26px;box-shadow:4px 4px 0 var(--sh)}
.pill.lav{background:var(--lav)}.pill.coral{background:var(--coral);color:#fff}.pill.sky{background:var(--sky)}.pill.yellow{background:var(--yellow)}
.pcard{background:#fff;border:2px solid var(--ol);border-radius:2rem;box-shadow:8px 8px 0 var(--sh)}
.fpill{display:grid;place-items:center;border:2px solid var(--ol);border-radius:9999px;font-weight:700;font-size:24px}
.icon{display:inline-grid;place-items:center;flex:none;width:72px;height:72px;border-radius:50%;border:2px solid var(--ol);font:700 28px 'Bodoni Moda',serif;color:var(--ink)}
.icon.sm{width:56px;height:56px;font-size:24px}
.icon.xs{width:46px;height:46px;font-size:22px;margin-right:16px}
.mini{display:inline-block;border:2px solid var(--ol);border-radius:9999px;padding:4px 16px;font-weight:600;font-size:24px;background:#fff;text-align:center}
h2{font-family:'Bodoni Moda',var(--kt),serif;font-weight:var(--wt);font-size:76px;line-height:1.15;letter-spacing:0;white-space:nowrap}
h3{font-family:'Bodoni Moda',var(--kt),serif;font-weight:var(--wt);letter-spacing:0}
.qh{display:inline-block;border:2px solid var(--ol);border-radius:9999px;padding:0 .3em;line-height:1.15}
.nr{left:110px;bottom:30px;font-size:18px;opacity:.55}
.btn:disabled{opacity:.4}

/* --- 1. 표지: 머리 태그(단원) + 강조선 + 노란 제목 알약 + 학습 목표 display(핵심 낱말 = 캔디 알약) + 떠 있는 단어 알약 --- */
.cv{left:0;right:0;top:150px;display:flex;flex-direction:column;align-items:center;text-align:center}
.aline{display:block;width:80px;height:6px;border-radius:9999px;background:var(--coral);margin:34px 0 30px}
.tp{padding:14px 48px}
.disp{margin-top:40px;font-family:'Bodoni Moda',var(--kt),serif;font-weight:var(--wt);font-size:120px;line-height:1.35;letter-spacing:0;white-space:nowrap}
.disp .qh{box-shadow:6px 6px 0 var(--sh)}
.sub{margin-top:36px;font-weight:500;font-size:30px;opacity:.7}
.meta{left:0;right:0;bottom:70px;text-align:center;font-weight:500;font-size:28px;opacity:.7}

/* --- 2. 흐름: 그림 틀(12px 그림자 · 안쪽 점선) 속 측정기 그림 + 노란 알약 메모 | 정의 + 단계 원 4개(4px 잉크 선, 켜지면 캔디색) + 알약 버튼 --- */
.vframe{left:110px;top:270px;width:860px;padding:18px;background:#fff;border:2px solid var(--ol);border-radius:2rem;box-shadow:12px 12px 0 var(--sh)}
.vframe .inner{border:2px dashed var(--ol);border-radius:1.5rem;padding:14px 26px;
  --g-ink:var(--ink);--g-acc:var(--coral);--g-stick:var(--yellow);--g-board:var(--lav);--g-ruler:#fff;--g-prot:rgba(139,180,247,.35);--g-shadow:var(--ink);--g-font:'Space Grotesk',var(--kb),sans-serif;--g-sw:2}
.note{left:110px;top:900px;font-size:30px}
.def{left:1040px;right:110px;top:276px;font-size:30px;line-height:1.5;opacity:.85}
.def b{font-weight:700}
.tl{left:1040px;right:110px;top:340px;display:flex;flex-direction:column;gap:20px}
.tl::before{content:'';position:absolute;left:26px;top:30px;bottom:30px;width:4px;background:var(--ink)}
.tstep{position:relative;display:grid;grid-template-columns:56px 1fr;gap:22px;align-items:start}
.node{position:relative;display:grid;place-items:center;width:56px;height:56px;border-radius:50%;border:2px solid var(--ol);background:#fff;box-shadow:4px 4px 0 var(--sh);font:700 22px 'Bodoni Moda',serif}
.tstep.on .node{background:var(--c)}
.tstep h3{font-size:38px;line-height:1.25}
.tstep p{margin-top:2px;font-size:28px;line-height:1.5;opacity:.7}
.slide[data-step]:not([data-step="0"]) .tstep:not(.on) div{opacity:.4}
.btns{left:1040px;top:880px;display:flex;gap:20px}
.cap{left:1040px;right:110px;top:968px;font-size:28px;line-height:1.4;opacity:.7}

/* --- 3. 숫자와 그래프: 통계 알약 카드 4장(색 숫자 + 40×4 막대) + 차트 카드(알약 막대 트랙 · 코랄 채움 · 값은 채움 안쪽 오른쪽) + 숫자 알약 --- */
.stats{left:110px;right:110px;top:270px;display:grid;grid-template-columns:repeat(4,1fr);gap:30px}
.spill{background:#fff;border:2px solid var(--ol);border-radius:2rem;box-shadow:6px 6px 0 var(--sh);padding:22px 28px;display:flex;flex-direction:column;gap:6px}
.sn{font:800 60px/1 'Bodoni Moda',var(--kt),serif}
.lb{font-weight:700;font-size:26px}
.spill p{font-size:28px;line-height:1.4;opacity:.7}
.ab{display:block;width:40px;height:4px;border-radius:9999px;margin-top:6px}
.chart{left:110px;right:110px;top:530px;padding:20px 34px;display:flex;flex-direction:column;gap:8px}
.ch{display:flex;align-items:center;gap:14px;margin-bottom:4px}
.ch b{margin-right:auto;font-family:'Bodoni Moda',var(--kt),serif;font-weight:var(--wt);font-size:32px}
.brow{display:grid;grid-template-columns:110px 1fr 120px 120px;gap:20px;align-items:center}
.tm{font-weight:700;font-size:26px}
.track{height:36px;background:var(--cream);border:2px solid var(--ol);border-radius:9999px;overflow:hidden}
.track i{display:flex;justify-content:flex-end;align-items:center;height:100%;padding-right:14px;background:var(--coral);border-right:2px solid var(--ol);border-radius:9999px}
.track b{font-weight:700;font-size:22px;color:#fff}
.src{left:110px;right:300px;bottom:30px;font-size:20px;opacity:.6}

/* --- 4. 비교와 표: 기둥 카드 둘(원형 아이콘) + 남중 카드 / 알약 행 표 + 인용(강조 알약) --- */
.cmp{left:110px;width:1060px;top:270px;display:grid;grid-template-columns:1fr 1fr;gap:30px}
.pc{padding:28px 32px}
.pc h3{margin:16px 0 8px;font-size:38px;line-height:1.25}
.pc p{font-size:28px;line-height:1.55;opacity:.75}
.lst{left:1220px;right:110px;top:270px;padding:26px 30px;display:flex;flex-direction:column;align-items:flex-start;gap:14px}
.lst p{display:flex;align-items:center;font-size:28px;line-height:1.45}
.tbl{left:110px;width:1060px;top:620px;display:flex;flex-direction:column;gap:10px}
.tr{display:grid;grid-template-columns:1.2fr 1fr 1fr 1fr;gap:12px;padding:8px 28px;border:2px solid var(--ol);border-radius:9999px;background:#fff;font-size:28px;line-height:1.35}
.tr.th{background:var(--lav);font-weight:700;font-size:24px}
.qt{left:1220px;right:110px;top:620px}
.qt p{font-family:'Bodoni Moda',var(--kt),serif;font-weight:var(--wt);font-size:40px;line-height:1.5}
.qt>span{display:block;margin-top:14px;font-weight:700;font-size:24px}

/* --- 5. 확인하기: 둥근 퀴즈 카드(알약 보기 · 정답 = 라임) + 노란 알약 다시 풀기 | 빈칸 카드(알약 → 캔디색) + 낱말 알약 + 떠 있는 단어 알약 --- */
.quiz{left:110px;width:900px;top:270px;bottom:110px;padding:38px 44px;display:flex;flex-direction:column}
.q{font-size:50px;line-height:1.3}
.opts{margin-top:26px;display:flex;flex-direction:column;gap:16px}
.opt{display:flex;align-items:center;gap:20px;text-align:left;border:2px solid var(--ol);border-radius:9999px;padding:8px 28px 8px 10px;font-weight:700;font-size:34px;background:#fff;box-shadow:4px 4px 0 var(--sh)}
.opt.right{background:var(--lime)}
.opt.wrong{background:var(--peach)}
.opt:disabled:not(.right){opacity:.5}
.fb{margin-top:20px;min-height:84px;font-size:30px;line-height:1.5}
.rt{align-self:flex-start;margin-top:auto}
.blk{left:1070px;right:110px;top:270px;bottom:110px;padding:34px 40px;display:flex;flex-direction:column;align-items:flex-start;gap:20px}
.bl{font-size:30px;line-height:1.6}
.blank{position:relative;min-width:180px;justify-content:center;margin-right:10px;padding:6px 20px;font-size:28px;box-shadow:4px 4px 0 var(--sh)}
.blank span{visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0;text-align:center}
.blank.open{background:var(--c)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.lbw{margin-top:auto;font-weight:700;font-size:26px}
.words{display:flex;flex-wrap:wrap;gap:12px}
.words .mini{font-size:28px;padding:6px 20px}

/* --- 내비: 오른쪽 세로 점 + 오른쪽 아래 번호 + 왼쪽 아래 키 안내 --- */
.dk-nav{inset:0;pointer-events:none}
.dk-dots{position:absolute;right:36px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:16px;pointer-events:auto}
.dk-dot{width:18px;height:18px;border-radius:50%;border:2px solid var(--ol);background:transparent}
.dk-dot.on{background:var(--ink)}
.dk-count{position:absolute;right:40px;bottom:30px;font:500 24px 'Space Grotesk',monospace;letter-spacing:.08em}
.hint{position:absolute;left:40px;bottom:30px;font:500 22px 'Space Grotesk',var(--kb),sans-serif;opacity:.5}
[data-slide="2"] .hint,[data-slide="3"] .hint,[data-slide="4"] .hint,[data-slide="5"] .hint{display:none}
/* --- 6. 디자인 안내: 알약 카드(원형 아이콘 줄) | 알약 카드 시연 3개 --- */
.g6{left:110px;width:900px;top:270px;bottom:110px;padding:30px 40px;display:flex;flex-direction:column;justify-content:space-between}
.r6{display:grid;grid-template-columns:56px 1fr;gap:22px;align-items:start}
.r6 h3{font-size:36px;line-height:1.2}
.r6 p{margin-top:4px;font-size:24px;line-height:1.5}
.r6 b{font-weight:700}
.sw6{display:flex;flex-wrap:wrap;gap:6px 20px}
.sw6 i{display:inline-block;width:26px;height:26px;margin-right:8px;vertical-align:-6px;border:2px solid var(--ol);border-radius:50%}
.sl6{left:1080px;top:270px}
.d6{left:1080px;right:110px;height:200px;padding:18px 30px}
.d6.a{top:340px}.d6.b{top:566px}.d6.c{top:792px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:16px}
.d6 h3{font-size:32px}
.d6 p{margin-top:4px;font-size:21px;line-height:1.4;opacity:.8}
.btn6{font-size:20px;padding:6px 18px;box-shadow:4px 4px 0 var(--sh);background:#fff}
.btn6[aria-pressed="true"]{background:var(--lime)}
.dr{margin-top:12px;height:64px;display:flex;align-items:center;gap:10px}
.shp{box-shadow:none}
.shp.play{box-shadow:12px 12px 0 var(--sh)}
.qh6{font-size:36px}
.qh6 span{display:inline-block;padding:0 .3em;line-height:1.15;border:2px solid transparent;border-radius:9999px}
.qh6.play span{border-color:var(--ol);background:var(--sky);box-shadow:6px 6px 0 var(--sh)}
.nd6 i{flex:1;height:4px;background:var(--ink)}
.nd6 .icon{background:#fff}
.nd6.play .icon{background:var(--c)}

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