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

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

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

## 라이선스

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

- Paperlogy 9Black: Paperlogy — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright © 2024 PT&
  파일: Paperlogy-9Black.ttf
- 프리텐다드 Pretendard-Regular: 프리텐다드 — 프리텐다드 (Pretendard) — 길형진 (orioncactus) / 눈누: https://noonnu.cc/font_page/694
  파일: Pretendard-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/block-frame.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/block-frame.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 Paperlogy 9Black(900) · 본문 프리텐다드 Pretendard-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. 디자인 규칙 (`block-frame` design.md)

````markdown
---
version: alpha
name: BlockFrame
description: "A maximalist neobrutalist presentation system built on 4px solid black borders, 8px hard offset shadows, and a high-key candy palette of five saturated pastels plus cream and off-white. Display type runs Inter at weight 800-900 in tight uppercase; secondary chrome uses Space Grotesk as a quasi-monospace label face. Tilted decorative shapes (rotated stars, rectangles, badges) puncture the borders and break the grid intentionally. Pastels are paired loudly: pink + blue + green + yellow + cream cycle through every region with deliberate juxtaposition. The aesthetic borrows from zine layout, 1990s-revival sticker books, and contemporary toy packaging — bold, joyful, slightly chaotic, never timid."

colors:
  black: "#000000"
  white: "#FFFFFF"
  offwhite: "#FFFDF5"
  pink: "#FE90E8"
  blue: "#C0F7FE"
  green: "#99E885"
  yellow: "#F7CB46"
  cream: "#FFDC8B"

borders:
  primary: "4px solid {colors.black}"
  thin: "3px solid {colors.black}"

shadows:
  default: "8px 8px 0px {colors.black}"
  small: "4px 4px 0px {colors.black}"
  hover: "6px 6px 0px {colors.black}"
  close-yellow: "12px 12px 0px {colors.yellow}"
  close-white: "6px 6px 0px {colors.white}"

typography:
  heading-xl:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: "clamp(48px, 6vw, 96px)"
    lineHeight: 0.95
    letterSpacing: -0.03em
    textTransform: uppercase
  heading-lg:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 800
    fontSize: "clamp(32px, 4vw, 64px)"
    lineHeight: 1
    letterSpacing: -0.02em
    textTransform: uppercase
  heading-md:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 700
    fontSize: "clamp(24px, 2.5vw, 40px)"
    lineHeight: 1.1
    letterSpacing: -0.01em
  close-title:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: "clamp(40px, 5vw, 80px)"
    lineHeight: 0.95
    letterSpacing: -0.03em
    textTransform: uppercase
  quote-text:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: "clamp(28px, 3.5vw, 52px)"
    lineHeight: 1.15
    letterSpacing: -0.02em
    textTransform: uppercase
  stat-number:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: "clamp(36px, 4vw, 64px)"
    lineHeight: 1
  card-title:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 700
    fontSize: 22px
    lineHeight: 1.2
    textTransform: uppercase
  step-num:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: 48px
    lineHeight: 1
  body:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 500
    fontSize: "clamp(16px, 1.2vw, 20px)"
    lineHeight: 1.6
  body-card:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 500
    fontSize: 15px
    lineHeight: 1.6
  list-body:
    fontFamily: "'Inter', sans-serif"
    fontWeight: 500
    fontSize: 16px
    lineHeight: 1.5
  label:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 600
    fontSize: 13px
    lineHeight: 1
    letterSpacing: 0.08em
    textTransform: uppercase
  mono-tag:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 600
    fontSize: 14px
    lineHeight: 1
    letterSpacing: 0.05em
    textTransform: uppercase
  mono-meta:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 500
    fontSize: 15px
    letterSpacing: 0.02em
  subtitle-mono:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 500
    fontSize: 18px
    lineHeight: 1.5
  counter:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 700
    fontSize: 14px
    lineHeight: 1
    letterSpacing: 0.1em
    textTransform: uppercase
  legend-item:
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 600
    fontSize: 13px

spacing:
  slide-pad: 60px
  card-pad-lg: 60px
  card-pad-md: 36px
  card-pad-sm: 28px
  card-pad-xs: 22px
  gap-lg: 48px
  gap-md: 32px
  gap-sm: 24px
  gap-xs: 16px
  pad-bottom-clearance: 110px

canvas:
  width: 100vw
  height: 100vh
  default-background: "{colors.offwhite}"

components:
  card-elevated:
    border: "4px solid {colors.black}"
    background: "{colors.white}"
    boxShadow: "{shadows.default}"
    description: "Primary elevated card. 4px ink border + 8px ink offset shadow. Background is white by default; on darker surfaces background may shift to offwhite or to a colored fill."
  card-flat:
    border: "4px solid {colors.black}"
    background: "{colors.white}"
    description: "Bordered card without elevation shadow. Used for secondary content cells inside multi-card grids where the shadow would compound."
  card-small:
    border: "3px solid {colors.black}"
    background: "{colors.white}"
    boxShadow: "{shadows.small}"
    description: "Compact card with thinner border + smaller offset shadow. Used for intro-cards, stat-cards, team-cards, and timeline-steps."
  label-pill:
    border: "3px solid {colors.black}"
    padding: "6px 16px"
    fontFamily: "'Space Grotesk', monospace"
    fontSize: 13px
    fontWeight: 600
    letterSpacing: 0.08em
    textTransform: uppercase
    background: "{colors.white}"
    boxShadow: "{shadows.small}"
    description: "Universal section eyebrow. White base by default; pink, blue, green, yellow, cream variants swap background. Always sits on a 3px black border with a 4px hard offset shadow."
  button-primary:
    border: "3px solid {colors.black}"
    background: "{colors.yellow}"
    color: "{colors.black}"
    padding: "14px 32px"
    fontFamily: "'Inter', sans-serif"
    fontWeight: 700
    fontSize: 16px
    boxShadow: "{shadows.small}"
    description: "Primary CTA. Yellow fill with black text, 3px black border, 4px offset shadow. Hover lifts the button -2/-2 and grows shadow to 6px."
  corner-bracket:
    width: 24px
    height: 24px
    border: "3px solid {colors.black}"
    description: "Two L-shaped brackets at opposite corners of a card or frame (tl + br + tr + bl pattern available). Sits inside the card edge as a decorative frame-within-frame."
  icon-square:
    width: 64px
    height: 64px
    border: "3px solid {colors.black}"
    description: "Solid pastel square (pink/blue/green) holding a single uppercase letter glyph at weight 700 / 28px. Used as feature-card icons."
  feature-deco:
    width: 48px
    height: 48px
    border: "3px solid {colors.black}"
    background: "{colors.yellow}"
    position: "absolute top -12px right 24px"
    description: "Yellow square notch that protrudes from the top edge of a feature card, breaking the card's top border line."
  stat-deco-dot:
    width: 12px
    height: 12px
    borderRadius: 50%
    border: "2px solid {colors.black}"
    description: "Small black-bordered colored circle pinned to the top-right of a stat card. The only round shape used on cards. Fill cycles through the pastel palette."
  avatar-square:
    width: 72px
    height: 72px
    border: "3px solid {colors.black}"
    background: "{colors.pink}"
    fontFamily: "'Inter', sans-serif"
    fontWeight: 900
    fontSize: 28px
    textTransform: uppercase
    description: "Square avatar with two-letter initials, used in team grids. Fill cycles through the pastel palette."
  list-number:
    width: 36px
    height: 36px
    border: "3px solid {colors.black}"
    background: "{colors.yellow}"
    fontFamily: "'Space Grotesk', monospace"
    fontWeight: 700
    fontSize: 14px
    description: "Square numerical bullet pinned to the left of each list item. Black border, yellow fill, mono numeral."
  star-burst:
    clipPath: "polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%)"
    border: "3px solid"
    background: "{colors.pink}"
    description: "10-point star clipped via CSS clip-path with a 3px border. Decorative attention-grabber pinned to corners of close-frames and feature cards."
  stripe-block:
    background: "repeating-linear-gradient(45deg, {colors.black}, {colors.black} 4px, {colors.green} 4px, {colors.green} 12px)"
    border: "3px solid {colors.black}"
    description: "Black-and-color diagonal stripe panel used as decorative attention block on poster-class surfaces."
  bg-dot-grid:
    backgroundImage: "radial-gradient(circle, {colors.black} 1.2px, transparent 1.2px)"
    backgroundSize: "24px 24px"
    description: "Faint dot-grid background pattern used as an overlay on light surfaces or as decoration in corners of cards."
  tilt-card:
    transform: "rotate(±2deg) or rotate(±8deg)"
    description: "Card with intentional tilt. Stat cards alternate -2deg / +2deg; decorative rectangles tilt up to ±12deg. The tilt is the system's playful structural signature."
  nav-btn:
    width: 48px
    height: 48px
    border: "3px solid {colors.black}"
    background: "{colors.white}"
    boxShadow: "{shadows.small}"
    description: "Square nav arrow button. Hover translates -2/-2 and grows shadow; active translates 2/2 and shrinks shadow."
  slide-counter:
    border: "3px solid {colors.black}"
    background: "{colors.white}"
    padding: "10px 18px"
    boxShadow: "{shadows.small}"
    description: "Persistent slide counter pill at bottom-left. Space Grotesk uppercase NN / NN format."
---

## 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

BlockFrame is a **maximalist neobrutalist presentation system** built on five structural laws: every region has a 4px black border, every elevated element has an 8px hard offset shadow, every corner is square, every accent color is a saturated pastel, and every layout is allowed to be a little bit crooked. The system's joy comes from the deliberate collision of these laws — bordered cards meet bordered cards, shadows stack against shadows, tilted decorations puncture the grid intentionally.

The type system pivots on **Inter** (weights 400-900) for display, body, and stats — set at weight 800-900 in tight uppercase with negative letter-spacing for headlines, weight 500 sentence case for body, and weight 700 uppercase for card titles. **Space Grotesk** (weights 400-700) is the secondary face, used as a quasi-monospace label voice for eyebrows, slide counters, stat labels, mono tags, and any chrome that should read as "system" rather than "editorial". The face combination is deliberately ordinary — both are widely-available open sans-serifs — but the treatment (heavy uppercase Inter + wide-tracked Space Grotesk) gives them a distinct neobrutalist register.

The palette is built around **five saturated pastels** (pink `#FE90E8`, blue `#C0F7FE`, green `#99E885`, yellow `#F7CB46`, cream `#FFDC8B`) plus **pure black** (`#000000`) for borders and text, **white** (`#FFFFFF`) for clean card fills, and **off-white** (`#FFFDF5`) for warm canvas. The pastels are not subtle accents — they are full-bleed surface fills. A typical deck cycles every slide through a different colored ground (offwhite cover → blue intro → offwhite content → green chart → pink quote → yellow split → offwhite timeline → blue stats → cream team → black close). This color cycling is the system's primary rhythm.

Depth is **hard offset shadow at 4px and 8px**, always solid black, always zero blur, always positioned bottom-right. Larger elements get 8px, smaller chrome gets 4px. The close-frame uses a single 12px offset in **yellow** (the only colored shadow in the system) as the system's loudest depth statement, and inverted close-frames pair 6px **white** shadows on black surfaces. Borders are 4px solid black on primary cards, 3px solid black on secondary chrome. Border weight and shadow size are tightly coupled — a 4px border carries an 8px shadow; a 3px border carries a 4px shadow.

**Density philosophy: comfortably dense.** This system reads as authoritative when packed and timid when sparse. A typical surface holds: a label-pill eyebrow + a large headline + a multi-card grid (3-6 cards) + at least one decorative element (tilted rectangle, star burst, stripe block, corner bracket, deco dots). Empty space within a region reads as "broken" — every card should be filled, every grid should be complete. The system's joy depends on the visual chatter of many bordered objects existing in the same frame.

**Key Characteristics:**
- 4px solid black borders on primary cards, 3px on secondary chrome — never thinner.
- 8px hard offset shadows on primary cards, 4px on secondary chrome — solid black, zero blur.
- Five-pastel palette (pink, blue, green, yellow, cream) plus black, white, off-white — cycled across surfaces.
- Inter weight 800-900 uppercase with negative tracking is the display voice; Space Grotesk weight 600 uppercase with 0.08em tracking is the label voice.
- Square corners everywhere except a single circular accent dot on stat cards.
- Tilted decorative elements (rotated rectangles, stars, badges) puncture the grid intentionally.
- Label pills (`{components.label-pill}`) carry a 3px border, 4px offset shadow, and a pastel fill variant — the universal section eyebrow.
- Colored fills are bold and saturated; pastels are used as panel grounds, not as light accents.
- Yellow is the default CTA color; black is the default close-surface color.
- Star bursts, stripe blocks, and dot grids are reusable decorative attention units.

## Colors

### Palette

- **Black** (`{colors.black}` — `#000000`): The structural color. Every border, every primary text moment, every shadow. Pure black, no warm bias. The system's contrast anchor.
- **White** (`{colors.white}` — `#FFFFFF`): The default card fill. Used on every primary card and as the background of label-pills and nav-buttons. Pure white, no warmth.
- **Off-white** (`{colors.offwhite}` — `#FFFDF5`): The warm canvas tone. The default body/slide background when no pastel ground is in play. Subtly warmer than pure white so that white cards sitting on top still feel layered.
- **Pink** (`{colors.pink}` — `#FE90E8`): A high-key candy magenta. Used as a full-surface ground, as label-pill fill, as icon-square fill, as star-burst fill, and as one of the pastel chart series. The most saturated of the five pastels.
- **Blue** (`{colors.blue}` — `#C0F7FE`): A pale cyan-ice blue. Used as a full-surface ground (the "intro" and "stats" feel), as label-pill fill, as icon-square fill, and as a chart series.
- **Green** (`{colors.green}` — `#99E885`): A bright spring green. Used as a full-surface ground, as label-pill fill, as icon-square fill, in the stripe-block diagonal pattern, and as a chart series.
- **Yellow** (`{colors.yellow}` — `#F7CB46`): The CTA color. Used as the default button fill, as the close-frame shadow color, as list-number squares, as the feature-deco notch, and as label-pill fill. The brightest, most attention-pulling pastel.
- **Cream** (`{colors.cream}` — `#FFDC8B`): A warm yellow-cream. Softer than yellow, more saturated than offwhite. Used as a full-surface ground (the "team" or "cover" feel), as label-pill fill, and as a tertiary chart accent.

### Defaults

- **Default surface background**: `{colors.offwhite}` for content-heavy surfaces; cycle through `{colors.cream}`, `{colors.blue}`, `{colors.pink}`, `{colors.green}`, `{colors.yellow}` for surfaces that need a stronger ground. The cycle is the rhythm; staying on one ground for many slides flattens the system.
- **Default headline color**: `{colors.black}` on all light/pastel surfaces; `{colors.white}` on the black close-surface.
- **Default body text color**: `{colors.black}` on all light/pastel surfaces; `{colors.white}` or `{colors.cream}` on dark surfaces.
- **Default border color**: `{colors.black}` — always. There are no colored borders anywhere except the 4px white border on the inverted close-frame.
- **Default card fill**: `{colors.white}`. Use a pastel fill only when the card is part of a multi-card row where each card needs distinct color identity (e.g., the timeline-step row where each step is a different pastel).
- **Default button fill**: `{colors.yellow}`. Other pastels work, but yellow is the system's primary "click here" signal.
- **Default label-pill base**: `{colors.white}`; pastel variants (`{colors.pink}`, `{colors.blue}`, `{colors.green}`, `{colors.yellow}`, `{colors.cream}`) signal section type or decorate the eyebrow.
- **Default decorative accent on stat cards**: a 12px circle (`{components.stat-deco-dot}`) in a pastel fill — cycling pink, blue, green, yellow across cards.
- **Default chart palette order**: pink → blue → green (three-series), with yellow and cream available for additional series.

The pastels are interchangeable in role — none of them carry fixed semantic meaning (green isn't "success", red doesn't exist in the palette at all). Pair them by visual juxtaposition: pink + blue + green is the most common trio; cream + yellow is the warm pair; blue + pink is the cool-warm contrast.

## Typography

### Font Family Stack
The system runs two faces.

**Inter** (weights 400-900) is the display, body, headline, and stat face. Used at weight 900 for hero/close titles and quote text, weight 800 for primary headlines, weight 700 for medium headlines and card titles, weight 500 for body. Display weights are always uppercase with negative letter-spacing (-0.02 to -0.03em); body weights are always sentence case with default tracking. The contrast between heavy uppercase display and weight-500 sentence body is the system's typographic rhythm.

**Space Grotesk** (weights 400-700) is the label and chrome face. Used at weight 600 for label-pills (13px, 0.08em tracking, uppercase) and at weight 500 for monospace meta callouts. The face is technically not monospace, but its slightly geometric character + the wide tracking treatment makes it read as the system's "code" voice.

Don't introduce a third face. The Inter + Space Grotesk pairing is the entire typographic palette.

### Typography Scale

| Token | Size (clamp / px) | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.heading-xl}` | 48–96px clamp | Inter | 900 | Hero or cover-scale headline |
| `{typography.heading-lg}` | 32–64px clamp | Inter | 800 | Primary section headline |
| `{typography.heading-md}` | 24–40px clamp | Inter | 700 | Region headline, chart title |
| `{typography.close-title}` | 40–80px clamp | Inter | 900 | Closing-statement title (inverted surface) |
| `{typography.quote-text}` | 28–52px clamp | Inter | 900 | Quote body — always uppercase |
| `{typography.stat-number}` | 36–64px clamp | Inter | 900 | Stat numeral |
| `{typography.card-title}` | 22px | Inter | 700 | Feature card title — uppercase |
| `{typography.step-num}` | 48px | Inter | 900 | Numeral inside a timeline-step (opacity 0.6) |
| `{typography.body}` | 16–20px clamp | Inter | 500 | Standard body paragraph |
| `{typography.body-card}` | 15px | Inter | 500 | Body inside compact cards |
| `{typography.list-body}` | 16px | Inter | 500 | Numbered list body |
| `{typography.label}` | 13px | Space Grotesk | 600 | Text inside label-pill |
| `{typography.mono-tag}` | 14px | Space Grotesk | 600 | Mono tag/badge, slide-counter |
| `{typography.mono-meta}` | 15px | Space Grotesk | 500 | Inline mono metadata |
| `{typography.subtitle-mono}` | 18px | Space Grotesk | 500 | Hero subtitle / close subtitle |
| `{typography.counter}` | 14px | Space Grotesk | 700 | Persistent slide counter (NN / NN) |
| `{typography.legend-item}` | 13px | Space Grotesk | 600 | Chart legend label |

### Defaults

- **Default size for a hero or cover title**: `{typography.heading-xl}` (48–96px). Always uppercase, always weight 900, always with -0.03em tracking.
- **Default size for a primary section headline**: `{typography.heading-lg}` (32–64px). Uppercase, weight 800, -0.02em.
- **Default size for a region or chart title**: `{typography.heading-md}` (24–40px). The only Inter heading not in uppercase by default — though uppercase is permitted.
- **Default size for a stat numeral**: `{typography.stat-number}` (36–64px). Weight 900, line-height 1.
- **Default size for body paragraph**: `{typography.body}` (16–20px clamp). Weight 500, sentence case, line-height 1.6.
- **Default size for an eyebrow label**: `{typography.label}` (13px) inside the `{components.label-pill}`.
- **Default weight for any Inter display**: 800 or 900. Inter display at weight 700 reads as "almost there"; only use 700 for `{typography.heading-md}` or card titles.
- **Default weight for any Inter body**: 500. Body at 400 reads as too light, body at 700 reads as oversized.
- **Default tracking for any Space Grotesk label/chrome**: 0.05-0.10em. Wide tracking is the face's "chrome" signal.
- **Default tracking for any Inter display**: -0.01em (heading-md) to -0.03em (heading-xl). Display without negative tracking reads as untreated.

When unsure which heading token to reach for, default to `{typography.heading-lg}` (32–64px) for the slide's primary text moment. `{typography.heading-md}` is for region or chart titles within a slide.

### Signature Treatments

These treatments are **non-optional whenever the corresponding element type is used**:

- **Every Inter display element (heading-xl, heading-lg, quote-text, close-title) is uppercase.** Sentence-case Inter display at weights 800+ does not exist in this system. The uppercase + heavy-weight + negative-tracking combination is the visual identity.
- **Every Inter display element uses negative letter-spacing** (-0.01 to -0.03em). Display without negative tracking reads as default Inter, which is a fundamentally different aesthetic.
- **Every label-pill carries the 3px border + 4px shadow + uppercase Space Grotesk text** combination. A label without all three properties is not a label-pill — it's a stray text element.
- **Every card-title is uppercase Inter weight 700.** Card titles in sentence case break the brutalist rhythm.
- **Every Space Grotesk label/chrome/counter is uppercase with 0.05-0.1em tracking.** Sentence-case Space Grotesk does not exist in this system except for body-adjacent metadata (mono-meta, mono inline).
- **Every stat numeral is Inter weight 900 with line-height 1.** Stat numerals are display moments, not data chrome.
- **Every Inter body block is sentence case with line-height 1.6 (or 1.5 for compact card body).** Body in uppercase or with tight line-height reads as broken.
- **Step numbers inside timeline-step cards are 48px weight 900 at opacity 0.6.** The reduced opacity is mandatory — full-opacity step numbers overwhelm the step title.

### Typography Principles

The voice contrast is **bold uppercase display ↔ sentence body ↔ wide-tracked label**. Italic is never used. Underline is never used. The only emphasis mechanism is weight contrast within the Inter ladder and the uppercase/sentence-case switch.

Display elements should be allowed to **dominate the canvas**. The system is built for poster-scale typography; reading a heading-xl at small size collapses its character. Lean into the upper bound of every clamp.

## Layout

### Canvas System
The system targets `100vw × 100vh` per slide. Slides are absolutely positioned and toggled via `display: none` / `display: flex` on the `.active` class. Default slide padding is 60px on all sides. Slides that contain bottom-anchored grids (timeline, team grid, chart with stat column) carry an additional `padding-bottom: 110px` to clear the fixed slide-counter and nav-controls chrome.

The default slide flex direction is column with `justify-content: center`. For two-column splits (intro slide, split image+text), flex direction switches to row.

### Padding and Gap Scale

| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 60px | Default slide padding from edge to content |
| `{spacing.card-pad-lg}` | 60px | Hero-frame and quote-frame internal padding |
| `{spacing.card-pad-md}` | 36px | Feature-card internal padding |
| `{spacing.card-pad-sm}` | 28px | Intro-card internal padding |
| `{spacing.card-pad-xs}` | 22px | Team-card and small-cell padding |
| `{spacing.gap-lg}` | 48px | Gap between major sections (header-to-grid) |
| `{spacing.gap-md}` | 32px | Gap between feature cards |
| `{spacing.gap-sm}` | 24px | Gap between intro cards, stat cards |
| `{spacing.gap-xs}` | 16px | Gap inside list items, intra-card content |
| `{spacing.pad-bottom-clearance}` | 110px | Bottom padding reserve to clear fixed nav chrome |

### Persistent Chrome
Three elements appear on every slide:
- **Slide counter** at bottom-left — 3px black border, white fill, 4px shadow, Space Grotesk 14px weight 700 uppercase, NN / NN format.
- **Nav controls** at bottom-right — two 48px square nav buttons with 3px borders, white fills, 4px shadows.
- The slide-counter and nav-controls are not part of the slide composition — they live outside `.slides-container` and overlap the bottom edge.

### Card-on-Card Structure
The system's primary layout pattern is **cards on grounds on grounds**. A typical slide places a colored-ground surface, on which sits a white card with 4px black border + 8px shadow, which may contain smaller cards or icon-squares. Each level of nesting carries its own border weight: 4px for the outer card, 3px for inner chrome. This nested-bordered structure is what gives the system its dense, packed feel.

### Decorative Disruption
Tilted decorative elements (rotated rectangles, stars, badges, dot grids) are placed absolutely on slide and card surfaces to puncture the grid intentionally. These are not "background decoration" — they are part of the composition. A surface without any decorative element reads as too clean.

## Depth and Elevation

### Hard Offset Shadow Stack
The system uses three primary shadow values:
- **`{shadows.default}`** = `8px 8px 0px {colors.black}` — primary card shadow. Used on hero-frame, feature-card, quote-frame, chart-frame, and any elevated card.
- **`{shadows.small}`** = `4px 4px 0px {colors.black}` — secondary chrome shadow. Used on intro-card, stat-card, team-card, timeline-step, label-pill, button-primary, nav-btn, slide-counter.
- **`{shadows.hover}`** = `6px 6px 0px {colors.black}` — hover state for buttons and nav. Triggered with a -2/-2 transform.

All shadows are solid black, zero blur, fixed offset bottom-right. The shadow + transform pairing on hover creates a "lifting off the page" interaction signature — the element translates -2/-2 while the shadow grows to 6/6, simulating a peel-up.

### Inverted Shadows
On the dark close-surface, shadows invert their color but keep the offset logic:
- **`{shadows.close-yellow}`** = `12px 12px 0px {colors.yellow}` — the loudest depth statement in the system. Used on close-frame to make the inverted surface read as still "elevated" despite its dark ground.
- **`{shadows.close-white}`** = `6px 6px 0px {colors.white}` — used on the close-btn to maintain elevation on the black ground.

These colored shadows are the only exceptions to the "shadows are always black" rule, and they appear only on the dark surface.

### Border-Based Depth
Most of the system's apparent layering comes from the 4px or 3px ink borders, not from shadow. A card with a border but no shadow still reads as "an object on a surface" — the shadow is what makes it read as "lifted". Use shadow for elevated cards; use border-only for secondary cards inside a multi-card grid where stacked shadows would compound into noise.

### Tilted Elements as Depth
The system's playful depth signature is **tilt**. Stat cards alternate -2deg / +2deg rotation. Decorative pink rectangles tilt up to ±12deg. The yellow button tab on the hero frame tilts -3deg. These tilts break the grid alignment intentionally and create perceived dimensionality without using actual perspective or shadow.

## Shapes and Treatment

### Border Radius
- **0px** on everything structural — cards, label-pills, buttons, icon-squares, list-numbers, avatars, badges. Square corners are non-negotiable.
- **50% (circle)** used only for the stat-deco dot (12×12 circular accent pinned to stat cards). This is the only round shape in the system.

The square-corner discipline is the system's structural identity. Adding rounded corners to any card or chip immediately reads as a different aesthetic.

### Border Weights
- **4px solid `{colors.black}`** — used on primary cards (hero-frame, feature-card, quote-frame, chart-frame, team-card border, timeline-step border, stat-card border) and the close-frame inverse (4px solid white on black ground).
- **3px solid `{colors.black}`** — used on secondary chrome (label-pill, button, intro-card, icon-square, list-number, avatar, corner-bracket, nav-btn, slide-counter, stripe-block, star-burst). The 3px weight signals "secondary structural" vs. the 4px "primary structural".
- **2px solid `{colors.black}`** — used only on legend swatches (16×16 chart swatches) and stat-deco dots. The thinnest border weight, reserved for atomic chrome.
- **4px solid `{colors.white}`** — used only on the inverted close-frame, the visual-box, and its ::after offset frame on the dark split-visual surface.

The border weight ladder (2 / 3 / 4) is fixed. No 1px borders, no 5px+ borders.

### Decorative Element Types

**Label-pill** — Square bordered pill (3px black border, 4px shadow), pastel or white fill, Space Grotesk 13px weight 600 uppercase text with 0.08em tracking. The universal section eyebrow.

**Corner-bracket** — Two L-shaped brackets (or four for full enclosure) at the corners of a card, 3px black border. Creates a frame-within-frame decorative motif.

**Star-burst** — 10-point star clipped via CSS clip-path with a 3px border, pastel fill. Decorative attention-grabber pinned to corners of close-frames and feature cards.

**Stripe-block** — Diagonal 4px-on, 8px-off stripe pattern in black + a pastel color, framed with a 3px black border. Decorative attention block used on poster-class surfaces.

**Dot-grid** — 1.2px radial-gradient dot pattern at 24×24 spacing. Used as a faint decorative overlay in corners of slides, at 30-40% opacity.

**Feature-deco notch** — 48×48 yellow square with 3px black border, positioned absolutely to protrude from the top edge of a feature card. The notch breaks the card's top border, suggesting it's been "stapled on".

**Icon-square** — 64×64 pastel square with 3px black border holding a single uppercase letter glyph at Inter weight 700 / 28px. Used as feature-card icons.

**Stat-deco dot** — 12×12 circle with 2px black border, pastel fill, pinned to the top-right of a stat card. The system's only round shape.

**List-number** — 36×36 yellow square with 3px black border holding a Space Grotesk 14px weight 700 numeral. Used as bullets on numbered lists.

**Avatar-square** — 72×72 pastel square with 3px black border holding two uppercase initials at Inter weight 900 / 28px. Used in team grids; fills cycle through pastels.

**Step-connector** — A 28×4 horizontal black bar pinned to the right edge of a timeline-step card, mid-height. Visually links adjacent steps in a horizontal flow.

**Tilted decoration** — Any rectangle, badge, or star with a rotate(±2deg to ±12deg) transform. The tilt is intentional disruption of the grid; without it, the system reads as too uniform.

## Do's and Don'ts

### Do

- Apply 4px solid black borders to primary cards (`{components.card-elevated}`, hero-frame, quote-frame) and 3px to secondary chrome. The border weight ladder is the system's structural backbone.
- Pair every 4px border with an 8px offset shadow, and every 3px border with a 4px offset shadow. The border/shadow coupling is non-negotiable.
- Cycle slide backgrounds through the pastel palette — offwhite, cream, blue, pink, green, yellow — to keep the deck visually rhythmic. Staying on one color for many slides flattens the system.
- Set every Inter display element in uppercase with negative letter-spacing (-0.01 to -0.03em) and weight 800+. The combination is the typographic identity.
- Use the `{components.label-pill}` (3px border, 4px shadow, pastel fill, Space Grotesk uppercase 0.08em) as the universal section eyebrow on every region.
- Apply tilt to decorative rectangles, stat cards, stars, and badges (±2deg to ±12deg). The intentional misalignment is the system's playful signature.
- Use `{colors.yellow}` as the default button color. Yellow with a 3px black border and 4px black shadow is the system's "click here" voice.
- Render shadows as solid black with zero blur, always offset bottom-right. The hard-edge shadow is the depth language.
- Add a decorative element (star-burst, stripe-block, dot-grid, corner-bracket, tilted rectangle) to every surface. The visual chatter is part of the system's energy.
- Use pure black `{colors.black}` for the closing surface, with white text and a 12px yellow offset shadow on the close-frame. The inverted dark surface is the system's loudest contrast moment.

### Don't

- Don't round any corner on cards, buttons, label-pills, icon-squares, or avatars. Border-radius is forbidden except on the stat-deco dot (12px circle).
- Don't blur any shadow. Every shadow is hard-edged at zero blur. `box-shadow: 0 4px 12px rgba(0,0,0,0.1)` does not exist in this system.
- Don't use colored borders. Borders are always pure black, except for the inverted 4px white border on the close-frame.
- Don't use Inter display weights in sentence case. Uppercase is mandatory on heading-xl, heading-lg, quote-text, close-title, and card-title.
- Don't set Inter display without negative letter-spacing. Default-tracked Inter at heavy weights reads as a different system.
- Don't introduce a sixth pastel color. The palette is locked at pink, blue, green, yellow, cream. Adding purple, orange, or red breaks the curated candy palette.
- Don't omit the label-pill on a region. Going straight from background to headline without an eyebrow tag breaks the system's editorial rhythm.
- Don't render label-pills as plain text. The 3px border + 4px shadow + pastel fill combination is what defines the pill.
- Don't use blurred or colored body text. Body is solid black on light surfaces, solid white or cream on dark surfaces.
- Don't keep every card perfectly aligned. The tilt on stat cards, decorations, and badges is what gives the system its hand-made energy.

## Responsive Behavior

BlockFrame is designed as a **1920×1080 presentation system** (effective 100vw × 100vh). Sizing uses CSS `clamp()` for type and fixed px for borders, shadows, and structural padding. The system has three component-level breakpoints for narrow viewports.

### Scaling Behavior
- Heading-xl scales 48px → 96px on viewport width.
- Heading-lg scales 32px → 64px.
- Body scales 16px → 20px.
- Borders (3px, 4px), shadows (4px, 8px), and structural padding (60px slide-pad) are fixed and do not scale.

### Component Breakpoints
- `max-width: 1024px` — slide padding shrinks 60px → 40px, two-column splits stack vertically, feature card row stacks vertically, timeline track stacks vertically with step-connectors hidden, stats grid collapses to 2 columns, team grid collapses to 2 columns. Split visual loses left border and gains a top border.
- `max-width: 640px` — stats grid collapses to 1 column, team grid collapses to 1 column, hero-frame padding shrinks to 32px, quote-frame padding shrinks to 32px.

### Presenter Behavior
- Slides advance via `ArrowRight` or `Space`.
- Slides reverse via `ArrowLeft`.
- Horizontal touch swipe with a 50px threshold advances/reverses.
- Slide transitions are instant (`display: none` ↔ `display: flex` on the `.active` class), with no crossfade.

### Print Behavior
The system has no `@media print` rule. Slides are absolute-positioned and only one is visible at a time — printing produces only the active slide. For static export, screenshots of each slide preserve all borders, shadows, and decorations (all are CSS, not image assets).

### Interactive States
- Buttons and nav-buttons translate -2/-2 on hover and shadow grows to 6px (`{shadows.hover}`); on active, translate 2/2 and shadow shrinks to 2px. The hover-press behavior is unusual for a presentation system; it reflects BlockFrame's hybrid identity as both deck and interactive product mockup.

## CJK & International Content

When using this template for Chinese (or other CJK) content, swap the Latin typeface stack for an equivalent Chinese pairing and apply universal CJK adjustments. All recommended Chinese fonts load via CDN — no install required.

### Recommended Chinese Pairing

| Role | Latin (default) | Chinese counterpart |
|---|---|---|
| Display / hero / quote / close title / stat numerals | Inter 800–900 (uppercase, negative tracking) | 思源黑体 Noto Sans SC 900 (sentence case, 0 tracking) |
| Card title | Inter 700 (uppercase) | 思源黑体 Noto Sans SC 700 (no transform) |
| Body / list body | Inter 500 | 思源黑体 Noto Sans SC 400 |
| Label / mono tag / counter / legend | Space Grotesk 600–700 (uppercase, 0.05–0.1em tracking) | 思源黑体 Noto Sans SC 600 (no transform, no tracking) |

### Mixed-Content Strategy

**Strategy A** — single CJK family with built-in Latin glyph coverage. Set every text element to `font-family: 'Noto Sans SC', sans-serif`. 思源黑体 ships Latin glyphs that pair cleanly with its Chinese characters, so mixed sentences render in one consistent face. The Inter / Space Grotesk distinction in the Latin original is preserved through weight contrast: weight 900 carries the brutalist display role, weight 600 carries the label role, weight 400–500 carries body. Visual hierarchy survives even though the face contrast is gone.

### Loading

Add to the template's `<head>`:

```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+Sans+SC:wght@400;500;600;700;900&display=swap" rel="stylesheet">
```

### Universal CJK Adjustments

- **Line-height**: increase by ~15–25% from the Latin spec. Body 1.75–1.85 (up from 1.6), display 1.15–1.25 (up from 0.95–1). The Latin display compresses to 0.95 line-height; CJK at that compression collides vertically.
- **Letter-spacing**: set to 0 on every CJK run. The template's negative display tracking (−0.02 to −0.03em on Inter) overlaps CJK strokes and reads as broken; the positive 0.05–0.1em tracking on Space Grotesk labels reads as gappy on square glyphs.
- **Text transform**: don't apply `uppercase` to Chinese text — CJK has no case. Every Inter display heading (heading-xl, heading-lg, quote-text, close-title, card-title) uses `text-transform: uppercase` in the Latin original; remove it for CJK runs. Every label-pill, counter, and chrome element also uses uppercase; remove that too.
- **Punctuation**: use full-width Chinese punctuation （，。：；！？「」（））.
- **No period on display headlines**: Chinese typography convention omits trailing 。 on display-scale headlines.
- **Space between CJK and Latin (盘古之白)**: insert an ASCII space between every Chinese character and adjacent Latin character or digit. Write `BlockFrame 设计系统` not `BlockFrame设计系统`.
- **One font per sentence**: 思源黑体 covers both CJK and Latin glyphs in a unified style — let it handle mixed sentences. Don't let the browser font-switch to Inter or Space Grotesk mid-word.

### Aesthetic Notes for This System

The Latin original's typographic identity rests entirely on the **heavy uppercase + negative tracking** combination on Inter display. CJK has no case, so this signal disappears. The system survives because its identity is **80% structural, 20% typographic**: the 4px black borders, 8px hard offset shadows, five-pastel palette, tilted decorations, label-pills, star bursts, stripe blocks, and dot grids do the brutalist work. Set 思源黑体 900 in sentence case at the same large sizes; the chunky black-on-pastel + hard-shadow framing reads as brutalist regardless of whether the type is in caps.

The label-pill (Space Grotesk 600 uppercase, 0.08em tracking, 3px border + 4px shadow, pastel fill) loses the uppercase + tracked-mono character. Render Chinese label-pills with 思源黑体 weight 600 at 0 tracking and a slightly tighter fontSize (11–12px instead of 13px) — the bordered pill shape and shadow do the chrome-recognition work. Keep the pastel fill rotation (pink / blue / green / yellow / cream) intact; it's the system's most recognizable signal after the borders themselves.

### Known CJK Gap

- **No CDN Chinese monospace face for the "system readout" voice.** Space Grotesk's quasi-mono role (label-pills, counters, mono-tags, slide counter NN / NN) depends on its slightly geometric character plus the wide-tracked uppercase treatment. Neither survives the CJK translation. The slide counter and chart legend can keep Latin digits + Latin labels intact; for purely Chinese chrome, lean on the pill border + shadow + pastel fill to signal "label" rather than the typographic treatment.
- **The "uppercase brutalist" identity weakens.** The system's most distinctive typographic decision is "heavy uppercase Inter with negative tracking" — and that signal is irreplaceable in CJK. Compensate by leaning harder on the structural elements: more decorative disruption (extra tilted rectangles, star bursts, stripe blocks), more saturated pastel-ground rotation across slides, and slightly tighter shadow offsets to compensate for the calmer typographic baseline.

## Iteration Guide

1. Any new card uses a 4px or 3px solid black border + the matched-weight offset shadow (8px or 4px). Never use a card without both.
2. Any new region begins with a `{components.label-pill}` eyebrow in pastel fill, then the headline in uppercase Inter weight 800+, then content. The label-headline-content sequence is the system's editorial rhythm.
3. Any new headline uses uppercase Inter with negative letter-spacing and weight 800-900. Reach for `{typography.heading-lg}` (32-64px) for primary moments and `{typography.heading-xl}` (48-96px) for cover/hero scale.
4. Any new accent or surface fill picks from the 5-pastel palette (pink, blue, green, yellow, cream) — never introduce a sixth pastel.
5. Any new CTA uses the `{components.button-primary}` pattern: 3px black border, yellow fill, 4px black shadow, Inter weight 700 / 16px. Hover lifts -2/-2 with shadow growing to 6px.
6. Any new chart cycles through pink → blue → green for series order, with yellow/cream available for additional series. Legend swatches use 2px black border.
7. Any new stat or metric uses Inter weight 900 + line-height 1 for the numeral, paired with Space Grotesk uppercase label below. Decorate the card with a `{components.stat-deco-dot}` in a pastel color.
8. Any new slide adds at least one decorative disruption (tilted rectangle, star-burst, stripe-block, dot-grid corner, corner-bracket frame) — empty surfaces feel timid.
9. Any new closing-style surface uses pure `{colors.black}` ground with white text, a 4px white-bordered close-frame, and a 12px yellow offset shadow. This is the only colored shadow allowed.
10. If a surface feels too noisy, drop a decoration — don't drop a border or shadow. The borders and shadows are structural; the decorations are tunable.

## Known Gaps

- **Inter and Space Grotesk are loaded from Google Fonts** via inline `@import`. There are no system fallbacks beyond `sans-serif` and `monospace` — in environments where Google Fonts fail, the system collapses to system defaults and loses its identity.
- **The system uses `@import` inside the `<style>` block** rather than a `<link>` preconnect. This is slower than the standard `<link>` approach and may delay first paint of typography.
- **The chart is rendered as inline SVG with hardcoded coordinates** (`viewBox="0 0 800 360"`, hardcoded `x/y/width/height` per `<rect>`). Adding new chart slides requires manual coordinate math; there is no data-binding layer.
- **The hover/active state on buttons assumes a pointing device.** On touch devices the lift-and-press feedback only triggers on tap and may feel inconsistent.
- **The tilt on stat cards is hardcoded with `:nth-child(odd)` -2deg and `:nth-child(even)` +2deg.** Re-ordering cards changes which tilts which direction — there's no per-card tilt control beyond ordering.
- **The decorative star uses a CSS clip-path polygon with 10 points.** Browsers without clip-path support (very old IE/Edge) will render the star as a colored rectangle.
- **The slide-counter and nav-controls overlap the slide content area at the bottom edge.** The 110px bottom padding on certain slides (slide-4, slide-9) reserves space, but other slides may have content that crowds the bottom-left counter pill.
- **The black close-surface uses pure `#000000` ground with white text** — accessibility-wise this is high-contrast and fine, but the colored decorations on this surface (yellow shadow, white border) don't pass the WCAG color contrast checks at small sizes.
- **The dot-grid background is a CSS radial-gradient.** At very large viewport sizes the dots may look too small to read as a grid; at very small sizes they may visually merge into solid noise.
- **There is no transition between slides** other than the binary display toggle. Adding a fade or slide animation requires modifying the JS and adding transition CSS.
````

---

## 2. 글씨체

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

---

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

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

**1장(표지)에서 처음 나오는 부품**
- `.bc` — 1·2·3·4·6장 — 예: `<p class="bc">`
- `.big` — 1·2·3·4·5·6장 — 예: `<div class="card big hero" style="left:100px;top:110px;width:1400px;height:760px;background:#F7CB46">`
- `.br` — 1·2·4·6장 — 예: `<i class="cb br">`
- `.card` — 1·2·3·4·5·6장 — 예: `<div class="card big hero" style="left:100px;top:110px;width:1400px;height:760px;background:#F7CB46">`
- `.cb` — 1·2·4·6장 — 예: `<i class="cb tl">`
- `.ct` — 1·2·4·6장 — 예: `<b class="ct">`
- `.dotgrid` — 1·3·5장 — 예: `<div class="deco dotgrid" style="left:1560px;top:700px">`
- `.foot1` — 1장 — 예: `<div class="card small foot1">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.hero` — 1장 — 예: `<div class="card big hero" style="left:100px;top:110px;width:1400px;height:760px;background:#F7CB46">`
- `.lbl` — 1·3·4·6장 — 예: `<span class="lbl">`
- `.pill` — 1·2·3·4·5·6장 — 예: `<span class="pill">`
- `.pk` — 1·6장 — 예: `<span class="pill pk">`
- `.rect` — 1장 — 예: `<div class="deco rect" style="left:1560px;top:80px;width:260px;height:150px;background:#C0F7FE;transform:rotat…`
- `.sdot` — 1·2·3·6장 — 예: `<i class="sdot" style="background:#99E885">`
- `.side1` — 1장 — 예: `<div class="card small tilt-r side1" style="background:#FE90E8">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide">`
- `.small` — 1·2·3·4·6장 — 예: `<div class="card small tilt-r side1" style="background:#FE90E8">`
- `.star` — 1·2·4·5·6장 — 예: `<div class="star" style="left:1400px;top:770px;width:190px;height:190px;background:#FE90E8;transform:rotate(14…`
- `.stripe` — 1장 — 예: `<span class="stripe">`
- `.tab` — 1장 — 예: `<span class="tab">`
- `.tilt-r` — 1·3장 — 예: `<div class="card small tilt-r side1" style="background:#FE90E8">`
- `.tl` — 1·2·4·6장 — 예: `<i class="cb tl">`
- `.unit` — 1장 — 예: `<p class="unit">`
- `.xl` — 1장 — 예: `<h1 class="xl">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.b2` — 2장 — 예: `<div class="btns b2">`
- `.blue` — 2장 — 예: `<section class="slide blue" data-steps="4">`
- `.btn` — 2·5·6장 — 예: `<button class="btn yel" data-act="step">`
- `.btns` — 2장 — 예: `<div class="btns b2">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03…`
- `.def` — 2장 — 예: `<p class="def">`
- `.fig` — 2장 — 예: `<div class="card big fig">`
- `.fnote` — 2장 — 예: `<p class="fnote">`
- `.lg` — 2·3·4·5·6장 — 예: `<h2 class="lg" style="left:100px;top:134px">`
- `.notch` — 2·4·6장 — 예: `<i class="notch">`
- `.sn` — 2장 — 예: `<span class="sn">`
- `.step` — 2장 — 예: `<div class="card small step" data-s="1" style="--c:#FE90E8">`
- `.steps` — 2장 — 예: `<div class="steps">`
- `.stripe-big` — 2·4·6장 — 예: `<div class="deco stripe-big" style="left:1640px;top:60px;width:190px;height:100px;transform:rotate(-8deg)">`
- `.yel` — 2·5·6장 — 예: `<button class="btn yel" data-act="step">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.ax` — 3장 — 예: `<text x="68" y="368" class="ax" text-anchor="end">`
- `.base` — 3장 — 예: `<line x1="80" x2="1620" y1="360" y2="360" class="base"/>`
- `.bn` — 3장 — 예: `<rect x="154" y="203.25" width="72" height="156.75" class="bn"/>`
- `.bvl` — 3장 — 예: `<text x="190" y="235.25" class="bvl" text-anchor="middle">`
- `.chartc` — 3장 — 예: `<div class="card big chartc">`
- `.cv` — 3장 — 예: `<svg class="cv" viewBox="0 0 1640 400">`
- `.gl` — 3장 — 예: `<line x1="80" x2="1620" y1="360" y2="360" class="gl"/>`
- `.green` — 3장 — 예: `<section class="slide green">`
- `.k` — 3장 — 예: `<i class="k" style="background:#FE90E8">`
- `.lg2` — 3장 — 예: `<div class="lg2">`
- `.lo` — 3장 — 예: `<polyline class="lo" points="190,253.575 410,284.925 630,302.25 850,307.2 1070,300.6 1290,282.45 1510,249.45"/…`
- `.ls` — 3장 — 예: `<polyline class="ls" points="190,253.575 410,284.925 630,302.25 850,307.2 1070,300.6 1290,282.45 1510,249.45"/…`
- `.lsp` — 3장 — 예: `<rect x="181" y="244.575" width="18" height="18" class="lsp"/>`
- `.lt` — 3장 — 예: `<polyline class="lt" points="190,162 410,132.3 630,109.19999999999999 850,91.05000000000001 1070,79.5 1290,72.…`
- `.ltp` — 3장 — 예: `<rect x="181" y="153" width="18" height="18" class="ltp"/>`
- `.md` — 3·4·5장 — 예: `<b class="md">`
- `.pv` — 3장 — 예: `<text x="234" y="262.575" class="pv">`
- `.sm` — 3·6장 — 예: `<span class="pill sm">`
- `.src` — 3장 — 예: `<p class="src">`
- `.stat` — 3장 — 예: `<div class="card small stat tilt-l">`
- `.stats` — 3장 — 예: `<div class="stats">`
- `.sv` — 3장 — 예: `<b class="sv">`
- `.tilt-l` — 3·4장 — 예: `<div class="card small stat tilt-l">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cmp` — 4장 — 예: `<div class="cmp">`
- `.fc` — 4장 — 예: `<div class="card big fc">`
- `.g` — 4·6장 — 예: `<div class="deco stripe-big g" style="left:1660px;top:50px;width:170px;height:96px;transform:rotate(6deg)">`
- `.icon` — 4장 — 예: `<span class="icon" style="background:#F7CB46">`
- `.li` — 4장 — 예: `<div class="li">`
- `.ln` — 4·5장 — 예: `<span class="ln">`
- `.lst` — 4장 — 예: `<div class="card small lst" style="background:#FFDC8B">`
- `.nr` — 4·5장 — 예: `<p class="nr">`
- `.pink` — 4장 — 예: `<section class="slide pink">`
- `.qt` — 4장 — 예: `<div class="card big qt tilt-l">`
- `.tbl` — 4장 — 예: `<div class="card big tbl">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bl` — 5장 — 예: `<p class="bl">`
- `.blank` — 5장 — 예: `<button class="pill blank" data-blank aria-pressed="false">`
- `.blk` — 5장 — 예: `<div class="card big blk" style="background:#C0F7FE">`
- `.cbtn` — 5장 — 예: `<button class="btn yel cbtn" data-act="retry">`
- `.close` — 5장 — 예: `<div class="close quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="…`
- `.dark` — 5장 — 예: `<section class="slide dark">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.opt` — 5장 — 예: `<button class="opt" data-opt="0">`
- `.opts` — 5장 — 예: `<div class="opts">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.w` — 5장 — 예: `<div class="deco dotgrid w" style="left:60px;top:40px">`
- `.win` — 5장 — 예: `<div class="star win" style="right:-50px;top:-70px;width:170px;height:170px;background:#99E885">`
- `.wl` — 5장 — 예: `<b class="md wl">`
- `.words` — 5장 — 예: `<div class="words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.a` — 6장 — 예: `<div class="card small d6 a">`
- `.ab6` — 6장 — 예: `<p class="bc ab6">`
- `.b` — 6장 — 예: `<div class="card small d6 b">`
- `.c` — 6장 — 예: `<div class="card small d6 c">`
- `.cream6` — 6장 — 예: `<section class="slide cream6">`
- `.d6` — 6장 — 예: `<div class="card small d6 a">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.dr` — 6장 — 예: `<div class="dr">`
- `.g6` — 6장 — 예: `<div class="card big g6">`
- `.shc6` — 6장 — 예: `<div class="shc6" id="bf-sh">`
- `.sl6` — 6장 — 예: `<span class="pill pk sl6">`
- `.st6` — 6장 — 예: `<div class="star st6">`
- `.sw6` — 6장 — 예: `<div class="sw6">`
- `.tc6` — 6장 — 예: `<div class="card small tc6" id="bf-tilt">`

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

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="block-frame">
<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=Inter:wght@500;700;800;900&family=Space+Grotesk:wght@500;600;700&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/block-frame.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide">
  <div class="deco dotgrid" style="left:1560px;top:700px"><svg width="260" height="200"><circle cx="6" cy="6" r="3.5" fill="currentColor"/><circle cx="28" cy="6" r="3.5" fill="currentColor"/><circle cx="50" cy="6" r="3.5" fill="currentColor"/><circle cx="72" cy="6" r="3.5" fill="currentColor"/><circle cx="94" cy="6" r="3.5" fill="currentColor"/><circle cx="116" cy="6" r="3.5" fill="currentColor"/><circle cx="138" cy="6" r="3.5" fill="currentColor"/><circle cx="160" cy="6" r="3.5" fill="currentColor"/><circle cx="182" cy="6" r="3.5" fill="currentColor"/><circle cx="204" cy="6" r="3.5" fill="currentColor"/><circle cx="226" cy="6" r="3.5" fill="currentColor"/><circle cx="6" cy="28" r="3.5" fill="currentColor"/><circle cx="28" cy="28" r="3.5" fill="currentColor"/><circle cx="50" cy="28" r="3.5" fill="currentColor"/><circle cx="72" cy="28" r="3.5" fill="currentColor"/><circle cx="94" cy="28" r="3.5" fill="currentColor"/><circle cx="116" cy="28" r="3.5" fill="currentColor"/><circle cx="138" cy="28" r="3.5" fill="currentColor"/><circle cx="160" cy="28" r="3.5" fill="currentColor"/><circle cx="182" cy="28" r="3.5" fill="currentColor"/><circle cx="204" cy="28" r="3.5" fill="currentColor"/><circle cx="226" cy="28" r="3.5" fill="currentColor"/><circle cx="6" cy="50" r="3.5" fill="currentColor"/><circle cx="28" cy="50" r="3.5" fill="currentColor"/><circle cx="50" cy="50" r="3.5" fill="currentColor"/><circle cx="72" cy="50" r="3.5" fill="currentColor"/><circle cx="94" cy="50" r="3.5" fill="currentColor"/><circle cx="116" cy="50" r="3.5" fill="currentColor"/><circle cx="138" cy="50" r="3.5" fill="currentColor"/><circle cx="160" cy="50" r="3.5" fill="currentColor"/><circle cx="182" cy="50" r="3.5" fill="currentColor"/><circle cx="204" cy="50" r="3.5" fill="currentColor"/><circle cx="226" cy="50" r="3.5" fill="currentColor"/><circle cx="6" cy="72" r="3.5" fill="currentColor"/><circle cx="28" cy="72" r="3.5" fill="currentColor"/><circle cx="50" cy="72" r="3.5" fill="currentColor"/><circle cx="72" cy="72" r="3.5" fill="currentColor"/><circle cx="94" cy="72" r="3.5" fill="currentColor"/><circle cx="116" cy="72" r="3.5" fill="currentColor"/><circle cx="138" cy="72" r="3.5" fill="currentColor"/><circle cx="160" cy="72" r="3.5" fill="currentColor"/><circle cx="182" cy="72" r="3.5" fill="currentColor"/><circle cx="204" cy="72" r="3.5" fill="currentColor"/><circle cx="226" cy="72" r="3.5" fill="currentColor"/><circle cx="6" cy="94" r="3.5" fill="currentColor"/><circle cx="28" cy="94" r="3.5" fill="currentColor"/><circle cx="50" cy="94" r="3.5" fill="currentColor"/><circle cx="72" cy="94" r="3.5" fill="currentColor"/><circle cx="94" cy="94" r="3.5" fill="currentColor"/><circle cx="116" cy="94" r="3.5" fill="currentColor"/><circle cx="138" cy="94" r="3.5" fill="currentColor"/><circle cx="160" cy="94" r="3.5" fill="currentColor"/><circle cx="182" cy="94" r="3.5" fill="currentColor"/><circle cx="204" cy="94" r="3.5" fill="currentColor"/><circle cx="226" cy="94" r="3.5" fill="currentColor"/><circle cx="6" cy="116" r="3.5" fill="currentColor"/><circle cx="28" cy="116" r="3.5" fill="currentColor"/><circle cx="50" cy="116" r="3.5" fill="currentColor"/><circle cx="72" cy="116" r="3.5" fill="currentColor"/><circle cx="94" cy="116" r="3.5" fill="currentColor"/><circle cx="116" cy="116" r="3.5" fill="currentColor"/><circle cx="138" cy="116" r="3.5" fill="currentColor"/><circle cx="160" cy="116" r="3.5" fill="currentColor"/><circle cx="182" cy="116" r="3.5" fill="currentColor"/><circle cx="204" cy="116" r="3.5" fill="currentColor"/><circle cx="226" cy="116" r="3.5" fill="currentColor"/><circle cx="6" cy="138" r="3.5" fill="currentColor"/><circle cx="28" cy="138" r="3.5" fill="currentColor"/><circle cx="50" cy="138" r="3.5" fill="currentColor"/><circle cx="72" cy="138" r="3.5" fill="currentColor"/><circle cx="94" cy="138" r="3.5" fill="currentColor"/><circle cx="116" cy="138" r="3.5" fill="currentColor"/><circle cx="138" cy="138" r="3.5" fill="currentColor"/><circle cx="160" cy="138" r="3.5" fill="currentColor"/><circle cx="182" cy="138" r="3.5" fill="currentColor"/><circle cx="204" cy="138" r="3.5" fill="currentColor"/><circle cx="226" cy="138" r="3.5" fill="currentColor"/><circle cx="6" cy="160" r="3.5" fill="currentColor"/><circle cx="28" cy="160" r="3.5" fill="currentColor"/><circle cx="50" cy="160" r="3.5" fill="currentColor"/><circle cx="72" cy="160" r="3.5" fill="currentColor"/><circle cx="94" cy="160" r="3.5" fill="currentColor"/><circle cx="116" cy="160" r="3.5" fill="currentColor"/><circle cx="138" cy="160" r="3.5" fill="currentColor"/><circle cx="160" cy="160" r="3.5" fill="currentColor"/><circle cx="182" cy="160" r="3.5" fill="currentColor"/><circle cx="204" cy="160" r="3.5" fill="currentColor"/><circle cx="226" cy="160" r="3.5" fill="currentColor"/><circle cx="6" cy="182" r="3.5" fill="currentColor"/><circle cx="28" cy="182" r="3.5" fill="currentColor"/><circle cx="50" cy="182" r="3.5" fill="currentColor"/><circle cx="72" cy="182" r="3.5" fill="currentColor"/><circle cx="94" cy="182" r="3.5" fill="currentColor"/><circle cx="116" cy="182" r="3.5" fill="currentColor"/><circle cx="138" cy="182" r="3.5" fill="currentColor"/><circle cx="160" cy="182" r="3.5" fill="currentColor"/><circle cx="182" cy="182" r="3.5" fill="currentColor"/><circle cx="204" cy="182" r="3.5" fill="currentColor"/><circle cx="226" cy="182" r="3.5" fill="currentColor"/></svg></div>
  <div class="deco rect" style="left:1560px;top:80px;width:260px;height:150px;background:#C0F7FE;transform:rotate(8deg)"></div>
  <div class="card big hero" style="left:100px;top:110px;width:1400px;height:760px;background:#F7CB46">
    <i class="cb tl"></i><i class="cb br"></i>
    <span class="pill">초등 과학 · 6학년 2학기 · 1단원 · 3~4차시</span>
    <p class="unit">계절의 변화<span>SUN, SHADOW & TEMPERATURE</span></p>
    <span class="pill pk">학습 목표</span>
    <h1 class="xl">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1>
    <span class="tab">2026</span>
  </div>
  <div class="card small tilt-r side1" style="background:#FE90E8"><i class="sdot" style="background:#99E885"></i><b class="ct">00초등학교</b><p class="bc">태양 고도 · 그림자 길이 · 기온</p></div>
  <div class="card small foot1"><span class="lbl">00초등학교 × 초등 과학 · 6학년 2학기</span><span class="stripe"></span></div>
  <div class="star" style="left:1400px;top:770px;width:190px;height:190px;background:#FE90E8;transform:rotate(14deg)"></div>
</section>
<section class="slide blue" data-steps="4">
  <div class="deco stripe-big" style="left:1640px;top:60px;width:190px;height:100px;transform:rotate(-8deg)"></div>
  <span class="pill" style="left:100px;top:64px">측정 준비</span>
  <h2 class="lg" style="left:100px;top:134px">태양 고도 측정기 만들기</h2>
  <div class="card big fig"><i class="notch"></i><i class="cb tl"></i><i class="cb br"></i><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><p class="fnote">막대기의 그림자와 실이 이루는 각 = 태양 고도</p></div>
  <div class="btns b2"><button class="btn yel" data-act="step">다음 단계 →</button><button class="btn" data-act="reset">처음부터</button></div>
  <p class="def"><b>태양 고도</b> = 태양이 지표면과 이루는 각</p>
  <div class="steps"><div class="card small step" data-s="1" style="--c:#FE90E8"><i class="sdot" style="background:#99E885"></i><span class="sn">01</span><div><h3 class="ct">자 붙이기</h3><p class="bc">우드록 한쪽에 양면테이프로 자를 붙여요</p></div></div><div class="card small step" data-s="2" style="--c:#C0F7FE"><i class="sdot" style="background:#F7CB46"></i><span class="sn">02</span><div><h3 class="ct">수수깡 꽂기</h3><p class="bc">수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div></div><div class="card small step" data-s="3" style="--c:#99E885"><i class="sdot" style="background:#FFDC8B"></i><span class="sn">03</span><div><h3 class="ct">실 묶기</h3><p class="bc">수수깡 끝에 실을 묶어요</p></div></div><div class="card small step" data-s="4" style="--c:#F7CB46"><i class="sdot" style="background:#FE90E8"></i><span class="sn">04</span><div><h3 class="ct">각도기 끼우기</h3><p class="bc">실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
  <p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 자 붙이기&quot;,&quot;02 수수깡 꽂기&quot;,&quot;03 실 묶기&quot;,&quot;04 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</p>
  <div class="star" style="left:1010px;top:150px;width:110px;height:110px;background:#99E885;transform:rotate(-12deg)"></div>
</section>
<section class="slide green">
  <div class="deco dotgrid" style="left:1600px;top:60px"><svg width="220" height="130"><circle cx="6" cy="6" r="3.5" fill="currentColor"/><circle cx="28" cy="6" r="3.5" fill="currentColor"/><circle cx="50" cy="6" r="3.5" fill="currentColor"/><circle cx="72" cy="6" r="3.5" fill="currentColor"/><circle cx="94" cy="6" r="3.5" fill="currentColor"/><circle cx="116" cy="6" r="3.5" fill="currentColor"/><circle cx="138" cy="6" r="3.5" fill="currentColor"/><circle cx="160" cy="6" r="3.5" fill="currentColor"/><circle cx="182" cy="6" r="3.5" fill="currentColor"/><circle cx="204" cy="6" r="3.5" fill="currentColor"/><circle cx="6" cy="28" r="3.5" fill="currentColor"/><circle cx="28" cy="28" r="3.5" fill="currentColor"/><circle cx="50" cy="28" r="3.5" fill="currentColor"/><circle cx="72" cy="28" r="3.5" fill="currentColor"/><circle cx="94" cy="28" r="3.5" fill="currentColor"/><circle cx="116" cy="28" r="3.5" fill="currentColor"/><circle cx="138" cy="28" r="3.5" fill="currentColor"/><circle cx="160" cy="28" r="3.5" fill="currentColor"/><circle cx="182" cy="28" r="3.5" fill="currentColor"/><circle cx="204" cy="28" r="3.5" fill="currentColor"/><circle cx="6" cy="50" r="3.5" fill="currentColor"/><circle cx="28" cy="50" r="3.5" fill="currentColor"/><circle cx="50" cy="50" r="3.5" fill="currentColor"/><circle cx="72" cy="50" r="3.5" fill="currentColor"/><circle cx="94" cy="50" r="3.5" fill="currentColor"/><circle cx="116" cy="50" r="3.5" fill="currentColor"/><circle cx="138" cy="50" r="3.5" fill="currentColor"/><circle cx="160" cy="50" r="3.5" fill="currentColor"/><circle cx="182" cy="50" r="3.5" fill="currentColor"/><circle cx="204" cy="50" r="3.5" fill="currentColor"/><circle cx="6" cy="72" r="3.5" fill="currentColor"/><circle cx="28" cy="72" r="3.5" fill="currentColor"/><circle cx="50" cy="72" r="3.5" fill="currentColor"/><circle cx="72" cy="72" r="3.5" fill="currentColor"/><circle cx="94" cy="72" r="3.5" fill="currentColor"/><circle cx="116" cy="72" r="3.5" fill="currentColor"/><circle cx="138" cy="72" r="3.5" fill="currentColor"/><circle cx="160" cy="72" r="3.5" fill="currentColor"/><circle cx="182" cy="72" r="3.5" fill="currentColor"/><circle cx="204" cy="72" r="3.5" fill="currentColor"/><circle cx="6" cy="94" r="3.5" fill="currentColor"/><circle cx="28" cy="94" r="3.5" fill="currentColor"/><circle cx="50" cy="94" r="3.5" fill="currentColor"/><circle cx="72" cy="94" r="3.5" fill="currentColor"/><circle cx="94" cy="94" r="3.5" fill="currentColor"/><circle cx="116" cy="94" r="3.5" fill="currentColor"/><circle cx="138" cy="94" r="3.5" fill="currentColor"/><circle cx="160" cy="94" r="3.5" fill="currentColor"/><circle cx="182" cy="94" r="3.5" fill="currentColor"/><circle cx="204" cy="94" r="3.5" fill="currentColor"/></svg></div>
  <span class="pill" style="left:100px;top:64px;background:#C0F7FE">측정 결과</span>
  <h2 class="lg" style="left:100px;top:134px">하루 동안 무엇이 어떻게 변할까요?</h2>
  <div class="stats"><div class="card small stat tilt-l"><i class="sdot" style="background:#FE90E8"></i><span class="lbl">남중 시각</span><b class="sv">12:30</b><p class="bc">태양 고도가 가장 높아요 무렵 · 남중</p></div><div class="card small stat tilt-r"><i class="sdot" style="background:#C0F7FE"></i><span class="lbl">남중 방향</span><b class="sv">정남</b><p class="bc">남중할 때 태양의 위치 쪽</p></div><div class="card small stat tilt-l"><i class="sdot" style="background:#99E885"></i><span class="lbl">최고 기온</span><b class="sv">14:30</b><p class="bc">기온이 가장 높아요 무렵</p></div><div class="card small stat tilt-r"><i class="sdot" style="background:#F7CB46"></i><span class="lbl">가장 긴 그림자</span><b class="sv">9:30</b><p class="bc">그림자가 가장 길어요 · 15:30</p></div></div>
  <div class="card big chartc">
    <div class="lg2"><b class="md">측정 시각별 태양 고도, 그림자 길이, 기온</b><span><i class="k" style="background:#FE90E8"></i>태양 고도(°)</span><span><i class="k" style="background:#C0F7FE"></i>그림자 길이(cm)</span><span><i class="k" style="background:#99E885"></i>기온(℃)</span><span class="pill sm">예시 값</span></div>
    <svg class="cv" viewBox="0 0 1640 400"><line x1="80" x2="1620" y1="360" y2="360" class="gl"/><text x="68" y="368" class="ax" text-anchor="end">0°</text><line x1="80" x2="1620" y1="277.5" y2="277.5" class="gl"/><text x="68" y="285.5" class="ax" text-anchor="end">20°</text><line x1="80" x2="1620" y1="195" y2="195" class="gl"/><text x="68" y="203" class="ax" text-anchor="end">40°</text><line x1="80" x2="1620" y1="112.5" y2="112.5" class="gl"/><text x="68" y="120.5" class="ax" text-anchor="end">60°</text><line x1="80" x2="1620" y1="30" y2="30" class="gl"/><text x="68" y="38" class="ax" text-anchor="end">80°</text><rect x="154" y="203.25" width="72" height="156.75" class="bn"/><text x="190" y="235.25" class="bvl" text-anchor="middle">38</text><rect x="374" y="162" width="72" height="198" class="bn"/><text x="410" y="194" class="bvl" text-anchor="middle">48</text><rect x="594" y="133.125" width="72" height="226.875" class="bn"/><text x="630" y="165.125" class="bvl" text-anchor="middle">55</text><rect x="814" y="124.875" width="72" height="235.125" class="bn"/><text x="850" y="156.875" class="bvl" text-anchor="middle">57</text><rect x="1034" y="137.25" width="72" height="222.75" class="bn"/><text x="1070" y="169.25" class="bvl" text-anchor="middle">54</text><rect x="1254" y="166.125" width="72" height="193.875" class="bn"/><text x="1290" y="198.125" class="bvl" text-anchor="middle">47</text><rect x="1474" y="207.375" width="72" height="152.625" class="bn"/><text x="1510" y="239.375" class="bvl" text-anchor="middle">37</text><polyline class="lo" points="190,253.575 410,284.925 630,302.25 850,307.2 1070,300.6 1290,282.45 1510,249.45"/><polyline class="ls" points="190,253.575 410,284.925 630,302.25 850,307.2 1070,300.6 1290,282.45 1510,249.45"/><rect x="181" y="244.575" width="18" height="18" class="lsp"/><text x="234" y="262.575" class="pv">12.9</text><rect x="401" y="275.925" width="18" height="18" class="lsp"/><text x="454" y="293.925" class="pv">9.1</text><rect x="621" y="293.25" width="18" height="18" class="lsp"/><text x="674" y="311.25" class="pv">7</text><rect x="841" y="298.2" width="18" height="18" class="lsp"/><text x="894" y="316.2" class="pv">6.4</text><rect x="1061" y="291.6" width="18" height="18" class="lsp"/><text x="1114" y="309.6" class="pv">7.2</text><rect x="1281" y="273.45" width="18" height="18" class="lsp"/><text x="1334" y="291.45" class="pv">9.4</text><rect x="1501" y="240.45" width="18" height="18" class="lsp"/><text x="1554" y="258.45" class="pv">13.4</text><polyline class="lo" points="190,162 410,132.3 630,109.19999999999999 850,91.05000000000001 1070,79.5 1290,72.90000000000003 1510,81.15000000000003"/><polyline class="lt" points="190,162 410,132.3 630,109.19999999999999 850,91.05000000000001 1070,79.5 1290,72.90000000000003 1510,81.15000000000003"/><rect x="181" y="153" width="18" height="18" class="ltp"/><text x="190" y="142" class="pv" text-anchor="middle">22</text><rect x="401" y="123.30000000000001" width="18" height="18" class="ltp"/><text x="410" y="112.30000000000001" class="pv" text-anchor="middle">23.8</text><rect x="621" y="100.19999999999999" width="18" height="18" class="ltp"/><text x="630" y="89.19999999999999" class="pv" text-anchor="middle">25.2</text><rect x="841" y="82.05000000000001" width="18" height="18" class="ltp"/><text x="850" y="71.05000000000001" class="pv" text-anchor="middle">26.3</text><rect x="1061" y="70.5" width="18" height="18" class="ltp"/><text x="1070" y="59.5" class="pv" text-anchor="middle">27</text><rect x="1281" y="63.900000000000034" width="18" height="18" class="ltp"/><text x="1290" y="52.900000000000034" class="pv" text-anchor="middle">27.4</text><rect x="1501" y="72.15000000000003" width="18" height="18" class="ltp"/><text x="1510" y="61.150000000000034" class="pv" text-anchor="middle">26.9</text><line x1="80" x2="1620" y1="360" y2="360" class="base"/><text x="190" y="400" class="ax" text-anchor="middle">9:30</text><text x="410" y="400" class="ax" text-anchor="middle">10:30</text><text x="630" y="400" class="ax" text-anchor="middle">11:30</text><text x="850" y="400" class="ax" text-anchor="middle">12:30</text><text x="1070" y="400" class="ax" text-anchor="middle">13:30</text><text x="1290" y="400" class="ax" text-anchor="middle">14:30</text><text x="1510" y="400" class="ax" text-anchor="middle">15:30</text></svg>
  </div>
  <p class="src">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</p>
</section>
<section class="slide pink">
  <div class="deco stripe-big g" style="left:1660px;top:50px;width:170px;height:96px;transform:rotate(6deg)"></div>
  <span class="pill" style="left:100px;top:64px;background:#F7CB46">관계 정리</span>
  <h2 class="lg" style="left:100px;top:134px">태양 고도가 바뀌면 무엇이 달라질까요?</h2>
  <div class="cmp"><div class="card big fc"><i class="notch"></i><span class="icon" style="background:#F7CB46">H</span><h3 class="ct">태양 고도가 높을 때</h3><p class="bc">그림자 길이는 짧아져요</p><p class="bc">기온은 높아져요</p></div><div class="card big fc"><span class="icon" style="background:#C0F7FE">L</span><h3 class="ct">태양 고도가 낮을 때</h3><p class="bc">그림자 길이는 길어져요</p><p class="bc">기온은 낮아져요</p></div></div>
  <div class="card big tbl"><b class="md">시각별 변화</b><table><tr><th>시각</th><th>태양 고도</th><th>그림자 길이</th><th>기온</th></tr><tr><td>오전 9:30</td><td>낮아요</td><td>길어요</td><td>낮아요</td></tr><tr><td>낮 12:30</td><td>가장 높아요</td><td>가장 짧아요</td><td>높아지는 중</td></tr><tr><td>오후 14:30</td><td>낮아지는 중</td><td>길어지는 중</td><td>가장 높아요</td></tr></table></div>
  <div class="card small lst" style="background:#FFDC8B"><b class="md">남중</b><div class="li"><span class="ln">1</span><p>태양이 정남쪽에 있을 때 '남중했다'고 해요</p></div><div class="li"><span class="ln">2</span><p>이때의 태양 고도를 남중 고도라고 해요</p></div></div>
  <div class="card big qt tilt-l"><i class="cb tl"></i><i class="cb br"></i><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span class="lbl">— 오늘의 정리</span></div>
  <div class="star" style="left:1700px;top:540px;width:150px;height:150px;background:#99E885;transform:rotate(18deg)"></div>
  <p class="nr">표 규칙 없음 → 검정 테두리 칸으로 표현</p>
</section>
<section class="slide dark">
  <div class="deco dotgrid w" style="left:60px;top:40px"><svg width="200" height="110"><circle cx="6" cy="6" r="3.5" fill="currentColor"/><circle cx="28" cy="6" r="3.5" fill="currentColor"/><circle cx="50" cy="6" r="3.5" fill="currentColor"/><circle cx="72" cy="6" r="3.5" fill="currentColor"/><circle cx="94" cy="6" r="3.5" fill="currentColor"/><circle cx="116" cy="6" r="3.5" fill="currentColor"/><circle cx="138" cy="6" r="3.5" fill="currentColor"/><circle cx="160" cy="6" r="3.5" fill="currentColor"/><circle cx="182" cy="6" r="3.5" fill="currentColor"/><circle cx="6" cy="28" r="3.5" fill="currentColor"/><circle cx="28" cy="28" r="3.5" fill="currentColor"/><circle cx="50" cy="28" r="3.5" fill="currentColor"/><circle cx="72" cy="28" r="3.5" fill="currentColor"/><circle cx="94" cy="28" r="3.5" fill="currentColor"/><circle cx="116" cy="28" r="3.5" fill="currentColor"/><circle cx="138" cy="28" r="3.5" fill="currentColor"/><circle cx="160" cy="28" r="3.5" fill="currentColor"/><circle cx="182" cy="28" r="3.5" fill="currentColor"/><circle cx="6" cy="50" r="3.5" fill="currentColor"/><circle cx="28" cy="50" r="3.5" fill="currentColor"/><circle cx="50" cy="50" r="3.5" fill="currentColor"/><circle cx="72" cy="50" r="3.5" fill="currentColor"/><circle cx="94" cy="50" r="3.5" fill="currentColor"/><circle cx="116" cy="50" r="3.5" fill="currentColor"/><circle cx="138" cy="50" r="3.5" fill="currentColor"/><circle cx="160" cy="50" r="3.5" fill="currentColor"/><circle cx="182" cy="50" r="3.5" fill="currentColor"/><circle cx="6" cy="72" r="3.5" fill="currentColor"/><circle cx="28" cy="72" r="3.5" fill="currentColor"/><circle cx="50" cy="72" r="3.5" fill="currentColor"/><circle cx="72" cy="72" r="3.5" fill="currentColor"/><circle cx="94" cy="72" r="3.5" fill="currentColor"/><circle cx="116" cy="72" r="3.5" fill="currentColor"/><circle cx="138" cy="72" r="3.5" fill="currentColor"/><circle cx="160" cy="72" r="3.5" fill="currentColor"/><circle cx="182" cy="72" r="3.5" fill="currentColor"/><circle cx="6" cy="94" r="3.5" fill="currentColor"/><circle cx="28" cy="94" r="3.5" fill="currentColor"/><circle cx="50" cy="94" r="3.5" fill="currentColor"/><circle cx="72" cy="94" r="3.5" fill="currentColor"/><circle cx="94" cy="94" r="3.5" fill="currentColor"/><circle cx="116" cy="94" r="3.5" fill="currentColor"/><circle cx="138" cy="94" r="3.5" fill="currentColor"/><circle cx="160" cy="94" r="3.5" fill="currentColor"/><circle cx="182" cy="94" r="3.5" fill="currentColor"/></svg></div>
  <span class="pill" style="left:100px;top:64px;background:#99E885">확인하기</span>
  <h2 class="lg" style="left:100px;top:134px;color:#fff">배운 내용을 확인해 볼까요?</h2>
  <div class="close 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="ln">A</span>오전 9시 30분</button><button class="opt" data-opt="1"><span class="ln">B</span>낮 12시 30분 무렵</button><button class="opt" data-opt="2"><span class="ln">C</span>오후 3시 30분</button></div>
    <p class="fb" data-fb></p>
    <button class="btn yel cbtn" data-act="retry">다시 풀기 ↺</button>
    <div class="star win" style="right:-50px;top:-70px;width:170px;height:170px;background:#99E885"></div>
  </div>
  <div class="card big blk" style="background:#C0F7FE">
    <b class="md">빈칸을 눌러 확인해요</b>
    <p class="bl"><button class="pill blank" data-blank aria-pressed="false"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</p><p class="bl"><button class="pill blank" data-blank aria-pressed="false"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</p><p class="bl"><button class="pill blank" data-blank aria-pressed="false"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</p>
    <b class="md wl">오늘의 낱말</b>
    <div class="words"><span class="pill" style="background:#FE90E8">태양 고도</span><span class="pill" style="background:#C0F7FE">남중 고도</span><span class="pill" style="background:#99E885">그림자 길이</span><span class="pill" style="background:#F7CB46">기온</span></div>
  </div>
  <div class="star" style="left:1760px;top:90px;width:120px;height:120px;background:#FE90E8;transform:rotate(-10deg)"></div>
  <p class="nr">빈칸 규칙 없음 → 라벨 알약으로 표현</p>
</section>
<section class="slide cream6">
  <div class="deco stripe-big g" style="left:1640px;top:60px;width:190px;height:100px;transform:rotate(-8deg)"></div>
  <span class="pill" style="left:100px;top:64px">디자인 안내</span>
  <h2 class="lg" style="left:100px;top:134px">이 디자인 사용 설명서</h2>
  <div class="card big g6"><i class="notch"></i><i class="cb tl"></i><i class="cb br"></i>
    <span class="pill sm">한눈에</span><p class="bc ab6">네오브루탈리즘 — <b>굵은 검정 테두리(4px)와 흐림 없는 그림자(8px)</b>로 칸을 또렷하게 나눕니다. 모서리는 모두 직각, 색은 흰 카드 + 파스텔 다섯 가지예요.</p>
    <span class="pill sm">색</span><div class="sw6"><span><i style="background:#FE90E8"></i>분홍</span><span><i style="background:#C0F7FE"></i>하늘</span><span><i style="background:#99E885"></i>초록</span><span><i style="background:#F7CB46"></i>노랑</span><span><i style="background:#FFDC8B"></i>크림</span><span><i style="background:#000"></i>검정 테두리</span></div>
    <span class="pill sm">글꼴</span><p class="bc">제목 Inter 800~900 → Paperlogy 9Black<br>본문 Inter 500 → 프리텐다드 Pretendard-Regular · 라벨·번호 Space Grotesk</p>
    <span class="pill sm">이렇게 쓰면 좋아요</span><p class="bc">활동지·모둠 미션 카드처럼 칸이 분명한 수업에 좋아요. 장마다 바탕 색을 바꿔 주제를 나누고, 중요한 버튼만 노랑으로.</p>
  </div>
  <span class="pill pk sl6">대표 장치 — 눌러 보세요</span>
  <div class="card small d6 a"><div class="dh"><h3 class="ct">버튼 반응</h3><span class="lbl">직접 올리고 눌러 보세요</span></div><p class="bc">올리면 −2/−2로 들리며 그림자 6px, 누르면 +2/+2로 눌리며 그림자 2px.</p><div class="dr"><button class="btn yel">마우스를 올려 보세요</button></div></div>
  <div class="card small d6 b"><div class="dh"><h3 class="ct">하드 그림자</h3><button class="btn sm" data-demo="#bf-sh" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p class="bc">주요 칸 4px 테두리 + 8px, 보조 칸 3px + 4px. 흐림은 0이에요.</p><div class="dr"><div class="shc6" id="bf-sh">주요 칸</div></div></div>
  <div class="card small d6 c"><div class="dh"><h3 class="ct">기울어진 카드</h3><button class="btn sm" data-demo="#bf-tilt" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p class="bc">통계 카드는 ±2°, 장식 사각형은 최대 12°까지 비뚤게 놓아요.</p><div class="dr"><div class="card small tc6" id="bf-tilt"><i class="sdot" style="background:#FE90E8"></i><b>57°</b></div><div class="star st6"></div></div></div>
</section>
<nav class="dk-nav"><span class="dk-count" data-pad></span><span class="nb"><button class="dk-prev" aria-label="이전">←</button><button class="dk-next" aria-label="다음">→</button></span></nav>
  </main>
</div>

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

---

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

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

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

/* --- 토큰(테두리·그림자는 명세 값, 글자는 1920 무대·교실 화면용으로 키움) --- */
:root{--k:#000;--ow:#FFFDF5;--pink:#FE90E8;--blue:#C0F7FE;--green:#99E885;--yel:#F7CB46;--cream:#FFDC8B;--sh:8px 8px 0 #000;--sh-s:4px 4px 0 #000;--sh-h:6px 6px 0 #000;--sh-a:2px 2px 0 #000}
.slide{background:var(--ow);color:var(--k);font-family:'Inter',var(--kb),sans-serif;font-weight:500}
.slide.blue{background:var(--blue)}.slide.green{background:var(--green)}.slide.pink{background:var(--pink)}.slide.dark{background:#000;color:#fff}
.slide>*{position:absolute}
.card{background:#fff;color:var(--k)}
.card.big{border:4px solid var(--k);box-shadow:var(--sh);padding:50px 60px}
.card.small{border:3px solid var(--k);box-shadow:var(--sh-s)}
.tilt-l{transform:rotate(-2deg)}.tilt-r{transform:rotate(2deg)}
.pill{display:inline-block;align-self:flex-start;background:#fff;color:var(--k);border:3px solid var(--k);box-shadow:var(--sh-s);padding:8px 22px;font:600 28px 'Space Grotesk',var(--kb),sans-serif;letter-spacing:0}
.pill.pk{background:var(--pink)}
.pill.sm{font-size:24px;padding:4px 14px}
.lbl{font:600 28px 'Space Grotesk',var(--kb),sans-serif}
.lg{font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:80px;line-height:1.15;letter-spacing:0;white-space:nowrap}
.md{display:block;font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:36px;line-height:1.2}
.ct{display:block;font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:40px;line-height:1.2}
.bc{margin-top:8px;font-size:28px;line-height:1.55}
.ln{display:inline-grid;place-items:center;flex:none;width:52px;height:52px;border:3px solid var(--k);background:var(--yel);color:var(--k);font:700 26px 'Space Grotesk',monospace}
.nr{left:330px;bottom:46px;font-size:18px;opacity:.65}

/* --- 장식: 모서리 괄호 / 위로 튀어나온 노란 칸 / 통계 점 / 별 / 사선 줄무늬 / 점 격자 / 기울어진 사각형 --- */
.cb{position:absolute;width:24px;height:24px;border:0 solid var(--k)}
.cb.tl{left:14px;top:14px;border-width:3px 0 0 3px}.cb.br{right:14px;bottom:14px;border-width:0 3px 3px 0}
.notch{position:absolute;right:24px;top:-14px;width:48px;height:48px;border:3px solid var(--k);background:var(--yel)}
.sdot{position:absolute;right:16px;top:16px;width:16px;height:16px;border-radius:50%;border:2px solid var(--k)}
.star{clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
.stripe{display:block;width:180px;height:40px;border:3px solid var(--k);background:repeating-linear-gradient(45deg,#000 0 4px,#99E885 4px 12px)}
.stripe-big{border:3px solid var(--k);background:repeating-linear-gradient(45deg,#000 0 4px,#FE90E8 4px 12px)}
.stripe-big.g{background:repeating-linear-gradient(45deg,#000 0 4px,#99E885 4px 12px)}
.rect{border:4px solid var(--k);box-shadow:var(--sh)}
.dotgrid{opacity:.8;color:#000}.dotgrid.w{color:#fff;opacity:.35}
.icon{display:inline-grid;place-items:center;width:64px;height:64px;border:3px solid var(--k);font:700 28px 'Inter',sans-serif}

/* --- 1. 표지(오프화이트): 노란 히어로 틀(괄호) — 라벨 알약 · 단원 · '학습 목표' 분홍 알약 · 학습 목표 heading-xl · 기울어진 연도 탭 + 분홍 카드 · 아래 띠 · 별 · 점 격자 --- */
.hero{display:flex;flex-direction:column;align-items:flex-start}
.unit{margin-top:34px;display:flex;align-items:baseline;gap:28px;font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:64px;line-height:1.15;white-space:nowrap}
.unit span{font:600 28px 'Space Grotesk',monospace;letter-spacing:.08em}
.hero .pill.pk{margin-top:44px}
.xl{margin-top:24px;font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:112px;line-height:1.18;letter-spacing:0;white-space:nowrap}
.xl .gk{font-style:normal}
.tab{position:absolute;right:60px;bottom:44px;background:#fff;border:3px solid var(--k);box-shadow:var(--sh-s);padding:10px 28px;font:700 30px 'Space Grotesk',monospace;transform:rotate(-3deg)}
.side1{left:1550px;top:320px;width:290px;padding:30px}
.side1 .ct{font-size:36px}
.foot1{left:100px;top:910px;width:1400px;padding:18px 32px;display:flex;justify-content:space-between;align-items:center}

/* --- 2. 흐름(하늘): 흰 카드 속 측정기 그림(노란 칸 · 괄호) + 노랑/흰 버튼 | 정의 + 단계 카드 4장(켜지면 파스텔 · 번호 60%) --- */
.fig{left:100px;top:270px;width:880px;padding:22px 40px 18px;--g-ink:#000;--g-acc:#000;--g-stick:var(--yel);--g-board:var(--pink);--g-ruler:#fff;--g-prot:var(--blue);--g-shadow:#000;--g-font:'Inter',var(--kb),sans-serif;--g-sw:3}
.fnote{margin-top:4px;font-weight:700;font-size:30px;line-height:1.4}
.b2{left:100px;top:908px;display:flex;gap:26px}
.def{left:1060px;right:100px;top:270px;font-size:30px;line-height:1.5}
.def b{font-weight:800}
.steps{left:1060px;right:100px;top:326px;display:flex;flex-direction:column;gap:14px}
.step{position:relative;display:grid;grid-template-columns:72px 1fr;gap:16px;padding:12px 26px 12px 22px;opacity:.55}
.step .ct{font-size:36px}
.step .bc{margin-top:2px}
.step.on{opacity:1;background:var(--c)}
.step.now{box-shadow:var(--sh)}
.sn{font:900 48px/1 'Inter',sans-serif;opacity:.6}
.cap{left:1060px;right:260px;top:906px;font-weight:700;font-size:30px;line-height:1.4}
.btns{display:flex;gap:26px}
.btn{border:3px solid var(--k);background:#fff;color:var(--k);box-shadow:var(--sh-s);padding:16px 36px;font:700 32px 'Inter',var(--kb),sans-serif}
.btn.yel{background:var(--yel)}
.btn:hover:not(:disabled),.dk-nav button:hover:not(:disabled),.opt:hover:not(:disabled){transform:translate(-2px,-2px);box-shadow:var(--sh-h)}
.btn:active:not(:disabled),.dk-nav button:active:not(:disabled),.opt:active:not(:disabled){transform:translate(2px,2px);box-shadow:var(--sh-a)}
.btn:disabled{opacity:.4}

/* --- 3. 숫자와 그래프(초록): 통계 카드 4장(-2°/+2° · 점) + 흰 차트 틀(분홍 막대 · 하늘/초록 꺾은선, 범례 2px) --- */
.stats{left:100px;right:100px;top:268px;display:grid;grid-template-columns:repeat(4,1fr);gap:36px}
.stat{position:relative;padding:22px 28px;display:flex;flex-direction:column;gap:6px}
.sv{font:900 64px/1 'Inter',var(--kt),sans-serif}
.stat .bc{margin-top:4px;font-size:28px;line-height:1.4}
.chartc{left:100px;right:100px;top:520px;bottom:120px;padding:22px 36px 14px;display:flex;flex-direction:column;gap:8px}
.lg2{display:flex;align-items:center;gap:30px;font:600 26px 'Space Grotesk',var(--kb),sans-serif}
.lg2 .md{margin-right:auto;font-size:32px}
.k{display:inline-block;width:20px;height:20px;border:2px solid #000;margin-right:10px;vertical-align:-3px}
.cv{flex:1;min-height:0;width:100%}
.cv .gl{stroke:#000;stroke-opacity:.12;stroke-width:2}
.cv .base{stroke:#000;stroke-width:4}
.cv .ax{font:600 22px 'Space Grotesk',monospace;fill:#000}
.cv .bn{fill:var(--pink);stroke:#000;stroke-width:3}
.cv .bvl{font:900 24px 'Inter',sans-serif;fill:#000}
.cv .lo{fill:none;stroke:#000;stroke-width:10;stroke-linejoin:miter}
.cv .ls,.cv .lt{fill:none;stroke-width:5;stroke-linejoin:miter}
.cv .ls{stroke:var(--blue)}.cv .lt{stroke:var(--green)}
.cv .lsp{fill:var(--blue);stroke:#000;stroke-width:2}.cv .ltp{fill:var(--green);stroke:#000;stroke-width:2}
.cv .pv{font:700 22px 'Space Grotesk',monospace;fill:#000;paint-order:stroke;stroke:#fff;stroke-width:6px}
.src{left:280px;right:300px;bottom:44px;font:500 20px 'Space Grotesk',var(--kb),sans-serif;line-height:1.35}

/* --- 4. 비교와 표(분홍): 기능 카드 둘(아이콘 사각 · 노란 칸) + 크림 번호 목록 / 표(검정 테두리 칸) + 기울어진 인용 틀(괄호) + 별 --- */
.cmp{left:100px;width:1060px;top:270px;display:grid;grid-template-columns:1fr 1fr;gap:40px}
.fc{position:relative;padding:30px 34px}
.fc .ct{margin:18px 0 6px}
.lst{left:1210px;right:100px;top:270px;padding:26px 28px;display:flex;flex-direction:column;gap:14px}
.li{display:flex;gap:16px;align-items:flex-start}
.li p{font-size:28px;line-height:1.5}
.tbl{left:100px;width:1060px;top:600px;padding:24px 30px}
.tbl table{width:100%;margin-top:14px;border-collapse:collapse;border:3px solid #000}
.tbl th,.tbl td{border:3px solid #000;padding:10px 16px;text-align:left;font-size:28px;line-height:1.35}
.tbl th{background:var(--yel);font:700 24px 'Space Grotesk',var(--kb),sans-serif}
.qt{left:1210px;right:150px;top:640px;padding:36px 40px;background:var(--yel)}
.qt p{font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:40px;line-height:1.3}
.qt .lbl{display:block;margin-top:16px;font-size:24px}

/* --- 5. 확인하기(검정 마무리 장): 마무리 틀 퀴즈(흰 4px 테두리 + 노랑 12px 그림자, 보기·버튼 = 흰 6px 그림자) | 하늘 카드 빈칸(알약) + 낱말 알약 --- */
.close{left:100px;width:940px;top:270px;bottom:120px;border:4px solid #fff;box-shadow:12px 12px 0 var(--yel);padding:40px 44px;display:flex;flex-direction:column;align-items:flex-start}
.q{font-family:'Inter',var(--kt),sans-serif;font-weight:var(--wt);font-size:48px;line-height:1.3;color:#fff}
.opts{margin-top:26px;width:100%;display:flex;flex-direction:column;gap:18px}
.opt{display:flex;align-items:center;gap:20px;width:100%;text-align:left;background:#fff;color:#000;border:3px solid #000;box-shadow:6px 6px 0 #fff;padding:8px 20px;font-weight:700;font-size:32px}
.dark .opt:hover:not(:disabled){box-shadow:8px 8px 0 #fff}.dark .opt:active:not(:disabled){box-shadow:2px 2px 0 #fff}
.opt.right{background:var(--green);transform:rotate(-2deg)}
.opt.wrong{background:var(--pink);transform:rotate(2deg)}
.opt:disabled:not(.right){opacity:.5}
.fb{margin-top:20px;min-height:84px;font-weight:700;font-size:30px;line-height:1.45;color:#fff}
.cbtn{margin-top:auto;box-shadow:6px 6px 0 #fff}
.dark .cbtn:hover:not(:disabled){box-shadow:8px 8px 0 #fff}.dark .cbtn:active:not(:disabled){box-shadow:2px 2px 0 #fff}
.win{position:absolute;opacity:0;transform:rotate(14deg)}
.solved .win{opacity:1}
.blk{left:1100px;right:90px;top:270px;bottom:120px;padding:36px 40px;display:flex;flex-direction:column;gap:20px;box-shadow:8px 8px 0 #fff}
.bl{font-size:29px;line-height:1.6}
.blank{min-width:170px !important}
.blank{position:relative;min-width:190px;margin-right:12px;text-align:center;box-shadow:var(--sh-s)}
.blank span{visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0}
.blank.open{background:var(--yel)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.wl{margin-top:auto}
.words{display:flex;flex-wrap:wrap;gap:16px}
.dark .nr{color:#fff}

/* --- 내비: 왼쪽 아래 번호 알약 + 오른쪽 아래 정사각 화살표 2개 --- */
.dk-nav{left:60px;right:60px;bottom:30px;height:56px}
.dk-count{position:absolute;left:0;bottom:0;background:#fff;border:3px solid var(--k);box-shadow:var(--sh-s);padding:10px 20px;font:700 26px 'Space Grotesk',monospace;letter-spacing:.1em}
.nb{position:absolute;right:0;bottom:0;display:flex;gap:16px}
.dk-nav button{width:56px;height:56px;border:3px solid var(--k);background:#fff;box-shadow:var(--sh-s);font:700 30px 'Space Grotesk',monospace}
.dk-nav button:disabled{opacity:.35}
[data-slide="5"] .dk-count,[data-slide="5"] .dk-nav button{box-shadow:4px 4px 0 #fff}
/* --- 6. 디자인 안내(크림): 큰 카드 설명 | 작은 카드 시연 3개 --- */
.slide.cream6{background:var(--cream)}
.g6{left:100px;width:940px;top:270px;bottom:120px;display:flex;flex-direction:column;align-items:flex-start;gap:10px;padding:40px 48px}
.g6 .pill.sm{margin-top:6px}
.g6 .bc{margin-top:0;font-size:26px;line-height:1.5}
.ab6 b{font-weight:800}
.sw6{display:flex;flex-wrap:wrap;gap:8px 22px;font-size:24px}
.sw6 i{display:inline-block;width:28px;height:28px;margin-right:8px;vertical-align:-7px;border:3px solid var(--k)}
.sl6{left:1100px;top:272px}
.d6{left:1100px;right:100px;padding:18px 26px 20px}
.d6.a{top:340px}.d6.b{top:560px}.d6.c{top:780px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:16px}
.d6 .ct{font-size:34px}
.d6 .lbl{font-size:20px}
.d6 .bc{font-size:22px;line-height:1.45;margin-top:6px}
.btn.sm{font-size:20px;padding:8px 16px}
.btn.sm[aria-pressed="true"]{background:var(--yel)}
.dr{margin-top:12px;height:70px;display:flex;align-items:center;gap:30px}
.dr .btn{font-size:24px;padding:12px 26px}
.shc6{border:3px solid var(--k);background:#fff;box-shadow:var(--sh-s);padding:12px 34px;font:700 24px 'Inter',var(--kb),sans-serif}
.shc6.play{border-width:4px;box-shadow:var(--sh);background:var(--pink)}
.tc6{position:relative;padding:8px 44px 8px 22px;font:700 36px 'Inter',sans-serif}
.tc6 b{font-weight:800}
.tc6.play{transform:rotate(-2deg)}
.st6{position:relative;width:60px;height:60px;background:var(--green);border:0}
.tc6.play+.st6{transform:rotate(-12deg)}

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