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

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

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

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

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

알아 둘 점
- 이 디자인의 한글 글씨체는 제목 Paperlogy 9Black(900) · 본문 Noto Sans KR 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
- Noto Sans KR Regular: Noto Sans KR — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: (c) 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'.
  파일: NotoSansKR-Regular.ttf

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

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

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

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

---

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

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

## 0. 당신(AI)의 일

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

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

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

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

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

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

---

## 1. 디자인 규칙 (`raw-grid` design.md)

````markdown
---
version: alpha
name: Raw Grid
description: A neobrutalist presentation system where 3px solid black borders ARE the layout. Display type runs in the native system sans-serif stack (Segoe UI / system-ui) at weight 900 in strict uppercase — no web fonts loaded. The palette is white canvas + black structure + two muted pastel accents (blush pink #F2D4CF and sage green #E5EDD6) + a neutral gray. Depth comes from hard offset shadows in solid black at 4px and 6px — never blurred, never colored. The aesthetic borrows from brutalist editorial web design and zine layout: borders meet without gaps, contrast is high but warmed by the pastel accents, and large numerals sit at very low opacity behind content as decorative wallpaper. The effect is sharp, system-native, and unmistakably digital — closer to a Notion-meets-protest-poster than a polished pitch deck.

colors:
  black: "#0A0A0A"
  white: "#FFFFFF"
  pink: "#F2D4CF"
  green: "#E5EDD6"
  gray: "#F5F5F5"
  darkgray: "#333333"

borders:
  primary: "3px solid {colors.black}"

shadows:
  default: "6px 6px 0 {colors.black}"
  small: "4px 4px 0 {colors.black}"

typography:
  display:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(48px, 7vw, 96px)"
    fontWeight: 900
    lineHeight: 1.05
    letterSpacing: -0.02em
    textTransform: uppercase
  headline:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(32px, 4.5vw, 64px)"
    fontWeight: 900
    lineHeight: 1.1
    letterSpacing: -0.01em
    textTransform: uppercase
  title:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(24px, 2.5vw, 36px)"
    fontWeight: 800
    lineHeight: 1.2
    letterSpacing: 0.01em
    textTransform: uppercase
  subtitle:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(16px, 1.4vw, 22px)"
    fontWeight: 700
    lineHeight: 1.3
    letterSpacing: 0.04em
    textTransform: uppercase
  body:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(16px, 1.3vw, 20px)"
    fontWeight: 500
    lineHeight: 1.6
    letterSpacing: 0
  caption:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(11px, 1vw, 13px)"
    fontWeight: 700
    lineHeight: 1.2
    letterSpacing: 0.08em
    textTransform: uppercase
  number:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(64px, 8vw, 120px)"
    fontWeight: 900
    lineHeight: 1.0
    letterSpacing: -0.04em
  number-md:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(36px, 4vw, 56px)"
    fontWeight: 900
    lineHeight: 1.0
    letterSpacing: -0.02em
  number-lg:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: "clamp(48px, 6vw, 80px)"
    fontWeight: 900
    lineHeight: 1.0
    letterSpacing: -0.02em
  label-text:
    fontFamily: "Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif"
    fontSize: 11px
    fontWeight: 800
    lineHeight: 1.0
    letterSpacing: 0.08em
    textTransform: uppercase

spacing:
  pad-lg: "clamp(32px, 4vw, 64px)"
  pad-md: "clamp(20px, 2.5vw, 40px)"
  pad-sm: "clamp(12px, 1.5vw, 20px)"
  gap-lg: "clamp(24px, 3vw, 48px)"
  gap-md: "clamp(16px, 2vw, 32px)"
  gap-sm: "clamp(8px, 1vw, 16px)"

canvas:
  width: 100vw
  height: 100vh

components:
  label:
    background: "{colors.black}"
    color: "{colors.white}"
    padding: "6px 14px"
    fontSize: 11px
    fontWeight: 800
    letterSpacing: 0.08em
    textTransform: uppercase
  line-h:
    width: 60px
    height: 4px
    background: "{colors.black}"
  line-v:
    width: 4px
    height: 60px
    background: "{colors.black}"
  line-full:
    width: "100%"
    height: 4px
    background: "{colors.black}"
  arrow-prefix:
    content: "→\\00a0"
    description: "Inline right-arrow glyph (U+2192) followed by a non-breaking space. Prepended via ::before on CTAs and interactive list items."
  icon-box:
    width: 48px
    height: 48px
    border: "3px solid {colors.black}"
    background: "{colors.white}"
    fontSize: "18px–20px"
    fontWeight: 900
    description: "Square white box with 3px black border, used for logos and feature icons. Contains 1–3 character glyph or Roman numeral."
  bar-track:
    width: "100%"
    height: 32px
    border: "3px solid {colors.black}"
    background: "{colors.white}"
  bar-fill-pink:
    background: "{colors.pink}"
  bar-fill-green:
    background: "{colors.green}"
  bar-fill-black:
    background: "{colors.black}"
    color: "{colors.white}"
  stat-box:
    border: "3px solid {colors.black}"
    padding: "clamp(16px, 2vw, 28px)"
    background: "{colors.white}"
  card:
    padding: "clamp(24px, 3vw, 48px)"
    border: "3px solid {colors.black}"
    description: "Generic content card. Background may be white, pink, green, or gray."
  decorative-numeral:
    fontWeight: 900
    fontSize: "clamp(40px, 5vw, 72px)"
    lineHeight: 1.0
    opacity: 0.2–0.35
    description: "Oversized numeral placed inside a card at very low opacity as decorative wallpaper behind the actual content."
  decorative-quote-mark:
    fontSize: "clamp(80px, 12vw, 160px)"
    fontWeight: 900
    opacity: 0.15
    description: "Oversized opening quotation mark placed absolutely at the top-left of a quote region at very low opacity."
  connector-node:
    width: 32px
    height: 32px
    border: "3px solid {colors.black}"
    background: "{colors.black}"
    color: "{colors.white}"
    fontSize: 16px
    fontWeight: 900
    description: "Small black square with white arrow glyph, used as a connector between sequential items in a horizontal flow."
  legend-swatch:
    width: 16px
    height: 16px
    border: "3px solid {colors.black}"
  donut-stroke-width: 24
  donut-track-stroke-width: 1.5
  table-cell:
    border: "3px solid {colors.black}"
    padding: "clamp(12px, 1.5vw, 20px)"
    fontWeight: 600
  table-header:
    background: "{colors.black}"
    color: "{colors.white}"
    fontWeight: 800
    letterSpacing: 0.06em
    textTransform: uppercase
  table-zebra-row:
    background: "{colors.gray}"
  hover-highlight:
    background: "{colors.green}"
    transition: "background 0.15s"
---

## 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

Raw Grid is a **neobrutalist presentation system** built on a single structural premise: **3px solid black borders are the layout**. There are no margins between regions, no gaps between cells, no rounded corners, no gradients. When two regions meet, a 3px black line separates them — that line is the entire grid system.

The typeface choice is deliberately non-decorative. The system uses the **native system sans-serif stack** (`Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif`) — no Google Fonts, no web fonts, no licensing. Display text runs at weight 900 in strict uppercase with tight negative letter-spacing. Body text runs at weight 500 in sentence case. The visual contrast between heavy uppercase display and light sentence-case body is the typographic rhythm of the system. The choice of system fonts is itself an aesthetic statement: it reads as "this is software, not a print artifact" — the digital-native counterpart to the printed-zine aesthetic of most brutalist systems.

The palette has six tokens but functions in four roles. **White** (`{colors.white}`) is the canvas. **Black** (`{colors.black}`) is the structure: borders, headlines, body text, label fills, shadow color. **Pink** (`{colors.pink}` — a muted blush #F2D4CF) and **green** (`{colors.green}` — a sage celadon #E5EDD6) are the accent surfaces — warm and cool counterparts, never used on text, always used as region fills. **Gray** (`{colors.gray}` — #F5F5F5) is the neutral fill for table zebra-striping and tertiary surfaces. The pastels are pale enough that black text remains fully legible on them, which is essential: the system never inverts text color over accent surfaces.

Depth is entirely **hard offset shadow** at 6px and 4px offsets in solid black with zero blur. No `rgba(...)`, no `0 4px 12px`. Either the shadow is hard-edged solid black or there is no shadow at all.

**Density philosophy: medium.** The system uses borders to wall off regions cleanly, but each region holds restrained content — typically one display element paired with one body paragraph, or one stat paired with one caption. The borders are loud (3px solid black, no compromise); the content within each region is quiet. A slide that feels broken in this system is one where a region is *empty* or *over-stuffed*; the correct density is one substantive element per bordered region.

**Key Characteristics:**
- White (`{colors.white}`) canvas with 3px solid black (`{colors.black}`) borders dividing every region. No gaps between cells — borders meet edge-to-edge.
- System sans-serif at weight 900 uppercase for all display type; weight 500 sentence case for all body type.
- Hard offset shadows at 6px and 4px in solid black, no blur, ever.
- Two muted pastel accent surfaces — blush pink and sage green — used as region fills, never as text colors.
- A signature black-pill `label` component (`{components.label}`) — white uppercase text in a small black rectangle — appears as the universal section tag.
- Oversized decorative numerals at 0.15–0.35 opacity sit behind content as wallpaper.
- An arrow glyph (→ with non-breaking space) prepended via `::before` on CTAs and interactive list items.
- No rounded corners anywhere in the system. Every shape is a strict rectangle, square, or circle.
- The system loads zero external fonts; rendering is identical in any browser with default fonts available.

## Colors

### Palette
- **Black** (`{colors.black}` — #0A0A0A): The structural color. All borders, all headline text, all body text, all label fills, all shadow values. Slightly softer than pure #000000 but reads as black at any reasonable size.
- **White** (`{colors.white}` — #FFFFFF): The canvas. Used as the default slide background, the default card background, and the text color inside black surfaces (labels, table headers, the dark stat tile).
- **Pink** (`{colors.pink}` — #F2D4CF): Muted blush. The warm accent surface — region backgrounds, bar fills, stat tile fills. The pastel saturation keeps black text fully legible without inversion.
- **Green** (`{colors.green}` — #E5EDD6): Sage celadon. The cool accent surface — region backgrounds, bar fills, hover-state highlight, alternating cards. Always paired with pink as the two halves of the accent system; rarely appear without each other in the same composition.
- **Gray** (`{colors.gray}` — #F5F5F5): Off-white neutral. Used for table zebra-stripe rows and tertiary card backgrounds where a region needs separation from white without committing to a colored accent.
- **Dark Gray** (`{colors.darkgray}` — #333333): A reserved tertiary text color, present in the token system but used sparingly. Available for de-emphasized text that needs to read softer than pure black.

### Defaults
- **Default surface background**: `{colors.white}`.
- **Default headline color**: `{colors.black}` — always. Headlines never appear in pink, green, or gray; only in black (on light surfaces) or white (on the black surface).
- **Default body text color**: `{colors.black}`.
- **Default border color**: `{colors.black}` — always.
- **Default accent surface for warm regions**: `{colors.pink}`.
- **Default accent surface for cool regions**: `{colors.green}`.
- **Default neutral fill for tertiary regions**: `{colors.gray}`.
- **Default text color on `{colors.black}` surfaces**: `{colors.white}` — the only color inversion in the system.

The accent surfaces (pink, green) are interchangeable — neither has a fixed semantic role (e.g., pink is not "warning" and green is not "success"). Use whichever color contrast best serves the composition. When two accent regions appear adjacent, pair pink with green for warm/cool balance rather than doubling on one color.

## Typography

### Font Family
The entire system runs on the **native system sans-serif stack**: `Segoe UI, system-ui, -apple-system, Helvetica, Arial, sans-serif`. No web fonts are loaded. This is intentional — the digital-native aesthetic depends on the type rendering in the user's actual system font, not a downloaded display face. The result is consistent only in spirit, not in exact letterform: a macOS render will look slightly different from a Windows render, and that variability is acceptable inside the system's tolerance.

The weight axis is the entire expressive tool. Display text uses weight 900 (the heaviest), titles use 800, subtitles use 700, body uses 500, with no italic variants and no alternate faces. The contrast between weight 900 uppercase and weight 500 sentence case is the system's primary typographic rhythm.

### Display and Numerical Scale

| Token | Size (clamp) | Weight | Tracking | Use |
|---|---|---|---|---|
| `{typography.number}` | 64–120px | 900 | -0.04em | Hero numerical stat |
| `{typography.display}` | 48–96px | 900 | -0.02em | Section-opening or cover display |
| `{typography.number-lg}` | 48–80px | 900 | -0.02em | Large decorative or featured numeral |
| `{typography.headline}` | 32–64px | 900 | -0.01em | Primary section headline |
| `{typography.number-md}` | 36–56px | 900 | -0.02em | Stat tile or metric numeral |
| `{typography.title}` | 24–36px | 800 | 0.01em | Region or section title |
| `{typography.subtitle}` | 16–22px | 700 | 0.04em | Subtitle, intra-region heading |
| `{typography.body}` | 16–20px | 500 | 0 | Paragraph body |
| `{typography.caption}` | 11–13px | 700 | 0.08em | Caption, fine print, footnote |
| `{typography.label-text}` | 11px | 800 | 0.08em | Text inside black label pills |

### Defaults
- **Default size for a primary section headline**: `{typography.headline}` (32–64px clamp).
- **Default size for a cover or opening display**: `{typography.display}` (48–96px clamp).
- **Default size for paragraph body**: `{typography.body}` (16–20px clamp).
- **Default size for any inline label or caption**: `{typography.caption}` (11–13px clamp).
- **Default weight for any display element**: 900.
- **Default weight for any body element**: 500.
- **Default size for a hero numerical figure**: `{typography.number}` (64–120px clamp).

When unsure, reach for `{typography.headline}` for the slide's primary text moment, not `{typography.title}` (which is for region-level headings within a slide).

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every display, headline, title, and subtitle element is uppercase.** Sentence-case display type does not exist in this system. If text is `{typography.display}`, `{typography.headline}`, `{typography.title}`, or `{typography.subtitle}`, it must be uppercase.
- **Every body element is sentence case.** Never uppercase a `{typography.body}` element — the uppercase/sentence-case contrast between display and body is the system's typographic signal.
- **Every display element uses negative letter-spacing.** Display (–0.02em), headline (–0.01em), number (–0.04em). Display type with default tracking reads as untreated; the negative tracking is what gives the type its compressed, brutalist density.
- **Every caption and label uses positive letter-spacing of at least 0.06em.** Caption and label glyphs without tracking read as code, not editorial.
- **All numerical figures use weight 900 with negative letter-spacing.** Even small stat numerals (36–56px) follow the display-weight convention.

### Typography Principles
The weight 900 + uppercase + negative tracking combination is the system's primary "voice." Switching any of those three properties (e.g., using weight 700 uppercase, or weight 900 sentence case) reads as a different design system. Weight 800 is reserved for `{typography.title}` and labels; weight 700 is for `{typography.subtitle}` and `{typography.caption}`; weight 500 is for body. Do not use intermediate weights (400, 600) — the weight ladder is fixed.

Italic is not used anywhere in the system. Underline is not used. The only emphasis mechanism is weight contrast.

## Layout

### Canvas System
The system targets `100vw × 100vh` — full viewport. Each `.slide` is absolutely positioned to fill the viewport and only one slide is `display: flex` at a time (slide navigation is JS-driven via keyboard arrow keys, spacebar, and touch swipe). All sizes use CSS `clamp()` so the layout fluidly scales between minimum and maximum without breakpoints.

### Padding and Gap Scale
| Token | Range | Use |
|---|---|---|
| `{spacing.pad-lg}` | 32–64px | Outer slide-region padding, full-region cells |
| `{spacing.pad-md}` | 20–40px | Header bands, secondary regions |
| `{spacing.pad-sm}` | 12–20px | Compact regions, table cells |
| `{spacing.gap-lg}` | 24–48px | Large flex/grid gaps |
| `{spacing.gap-md}` | 16–32px | Standard flex/grid gaps |
| `{spacing.gap-sm}` | 8–16px | Tight inline gaps |

### Border-as-Layout Principle
The defining structural pattern: **regions are separated by 3px solid black borders, not by gaps**. When a slide is divided into a 2-column grid, the two columns share a 3px black vertical border between them and the cells meet that border directly — no `gap` property, no margin. When a header band sits above a content area, a 3px black horizontal line separates them and both regions abut the line. This is the system's most distinctive structural choice.

Internal padding within a region (`{spacing.pad-lg}`, etc.) provides the breathing room inside cells. Gaps between cells do not exist.

## Depth and Elevation

### Hard Offset Shadow (Only Technique)
The system uses exactly two shadow values:
- **`{shadows.default}`** = `6px 6px 0 {colors.black}` — the standard hard offset shadow for elevated elements (large cards, primary callouts).
- **`{shadows.small}`** = `4px 4px 0 {colors.black}` — the lighter offset for smaller elevated elements.

Both shadows are **solid black, zero blur, fixed offset bottom-right**. There is no shadow variation by color, no blurred drop shadow, no soft elevation. An element either casts a hard offset shadow or it casts no shadow.

### Border-Based Depth
Most of the system's apparent "depth" actually comes from borders, not shadows. A 3px solid black border around a card on a colored background reads as elevated regardless of whether the card carries a shadow. Use shadow only when an element needs to feel "lifted off" the surface beneath it — typically a card that overlaps or floats above its containing region.

### Decorative Wallpaper (Atmospheric Depth)
A signature treatment: oversized numerals placed inside a card at very low opacity (0.15 for the largest quote mark, 0.20 for step numerals, 0.35 for card ordinals) sit behind the actual content as decorative wallpaper. The numeral fills the upper-left or upper portion of the region, and the actual title sits in front of it at full opacity. This creates a layered effect — content over decoration — without using any z-index trickery.

## Shapes and Treatment

### Border Radius
| Value | Use |
|---|---|
| 0px | Everything except circles |
| 50% (circle) | Donut chart shapes only |

The system has **no rounded corners**. Cards, buttons, labels, icon boxes, stat tiles, table cells, image frames — all strict rectangles or squares. The only round shape is the SVG donut chart, which is a circle by geometric necessity.

### Border Weights
- **3px solid `{colors.black}`** — the universal border. Used on every structural division: region separators, card outlines, table cells, icon boxes, connector nodes, swatches, bar tracks, stat tile borders. Never thinner, never thicker, never colored, never dashed.
- **4px solid `{colors.black}`** — used only for the `{components.line-h}` and `{components.line-v}` decorative rule elements (60px stub lines).
- **4px solid `{colors.white}`** — used only on the image placeholder frame inside black image regions (inverted border treatment for white-on-black contexts).
- **1.5px stroke** — used only on the inner stroke of the SVG donut chart at 0.1 opacity (a barely-visible inner ring).

### Decorative Element Types

**Black label pill** — A small black rectangle containing white uppercase text at 11px / weight 800 / 0.08em letter-spacing, with 6px × 14px padding. The system's universal section tag, fiscal-year marker, or status chip. May be prepended with the `{components.arrow-prefix}` for CTA variants.

**Horizontal rule stub** — A 60px × 4px solid black rectangle (`{components.line-h}`) used as an inline visual separator or accent next to a label. Functions as a "section break" mark in editorial layouts.

**Icon box** — A 48px × 48px white square with 3px black border containing a 1–3 character glyph (initials, Roman numeral, single letter) at 18–20px weight 900. Used as logo marks and feature icons.

**Decorative oversized numeral** — A large numeric character (typically a step number or section ordinal) at weight 900 placed inside a card at 0.15–0.35 opacity. Sits behind or above the card's actual content as wallpaper.

**Connector node** — A 32px × 32px solid black square containing a white arrow glyph at weight 900. Positioned absolutely between sequential items in a horizontal flow (e.g., between timeline steps). Acts as the visual "→" between stages.

**Bar track** — A 32px-tall horizontal rectangle with 3px black border and white interior. The fill (in pink, green, or black) is a child `div` whose `width` percentage represents the data value, with the value label printed inside the fill at 12px weight 800. Bars in black get inverted text color (white).

**Stat tile** — A bordered card (`{components.stat-box}`) containing a large numeral (`{typography.number-md}`) above a small caption (`{typography.caption}`). Background may be white, pink, green, gray, or black (with appropriate text inversion).

**Arrow-prefixed text** — Text elements (CTAs, interactive list rows) get a `→` (U+2192) prepended via `::before` with a non-breaking space, indicating action or navigation. This is the system's interactivity signal.

**Donut chart** — Multi-segment SVG ring at 24px stroke width with a 1.5px inner divider ring at 0.1 opacity. Segments use the palette colors (black, pink, green) and the center holds a value + label pair.

## Do's and Don'ts

### Do
- Use 3px solid black borders on every structural division. The border weight is the system's identity — thinner reads as generic web app, thicker reads as broken.
- Set headline color to `{colors.black}` by default. Headlines in pink, green, or gray do not exist in this system.
- Pair pink and green as opposites when two accent surfaces appear together — warm with cool, never two pinks or two greens adjacent.
- Apply uppercase + negative letter-spacing + weight 900 together on every display element. The three traits are inseparable — using them individually loses the brutalist character.
- Use the black label pill (`{components.label}`) as the universal section tag. It is the system's most distinctive small component and should appear generously.
- Use the arrow-prefix (`→ + nbsp`) on every CTA and interactive list row. It is the system's interactivity signal.
- Render shadows as `6px 6px 0 {colors.black}` or `4px 4px 0 {colors.black}`. There are only two shadow values — pick one.
- Place oversized decorative numerals at 0.15–0.35 opacity behind content in cards that have a numerical identity (step number, ordinal, quote mark). The wallpaper-numeral pattern is a system signature.
- Let borders touch directly. Two regions meeting at a 3px black line is correct; a gap between them is wrong.
- Use weight 500 sentence case for body and weight 900 uppercase for display. The contrast between the two is the typographic rhythm.

### Don't
- Don't load any web fonts. The system runs on the native sans-serif stack — Segoe UI / system-ui / Helvetica. Adding Google Fonts breaks the digital-native aesthetic.
- Don't round any corner. Cards, buttons, labels, icon boxes — all strict rectangles. Border-radius is permitted only for circles (the donut chart).
- Don't use blurred shadows. `0 4px 12px rgba(0,0,0,0.1)` does not exist here. Either a 4px/6px hard solid black offset or nothing.
- Don't use color on borders. All structural borders are black. A colored border breaks the system.
- Don't use intermediate font weights (400, 600). The weight ladder is fixed at 500 / 700 / 800 / 900.
- Don't use italic or underline. The only emphasis mechanism is weight contrast.
- Don't put display-weight text in sentence case. Uppercase is non-negotiable on display, headline, title, subtitle, and caption tokens.
- Don't introduce a third accent surface color. Pink and green are the only accent surfaces. Adding a yellow or blue card breaks the warm/cool pairing system.
- Don't use gap properties between border-divided regions. Regions meet at borders; they do not have margins between them.
- Don't invert text color over pink, green, or gray surfaces. The pastels are designed for black text on top — inverted treatments only apply to the `{colors.black}` surface.

## Responsive Behavior

Unlike most templates in this library, Raw Grid is **viewport-fluid by design**. The entire system uses CSS `clamp()` for sizes and there is no fixed canvas dimension. Every `font-size`, `padding`, `gap`, and `width` value scales linearly between a minimum and maximum based on viewport width. The same composition renders correctly on a 1280×720 laptop, a 1920×1080 monitor, and a 2560×1440 display without media queries.

### Scaling Behavior
- Display headline scales from 48px at minimum viewport to 96px at maximum.
- Body text scales from 16px to 20px.
- Padding scales from 32px to 64px on `{spacing.pad-lg}`.
- Borders, label pill padding, and shadow offsets are fixed (3px, 6px 14px, 6px 6px) — they do not scale, which means at larger viewports the borders appear proportionally finer.

### Presenter Behavior
- Slides advance via `ArrowDown`, `ArrowRight`, or `Space`.
- Slides go back via `ArrowUp` or `ArrowLeft`.
- `Home` jumps to first, `End` to last.
- Touch swipe (vertical) advances/reverses on mobile.
- The active slide carries the `.active` class; non-active slides are `display: none`.

### Print Behavior
A `@media print` rule sets all slides to `display: flex` with `page-break-after: always` — printing the deck produces a sequential page-per-slide PDF.

### Hover States
The system uniquely has interactive hover states baked into the design — list items and table rows highlight to `{colors.green}` on hover via a 0.15s transition. This is unusual for a presentation system; it reflects Raw Grid's hybrid identity as both presentation and product mockup.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Display / Headline / Title / Subtitle | Segoe UI / system-ui (900) | **思源黑体 Noto Sans SC** | 900 |
| Body / Caption / Label | Segoe UI / system-ui (500–800) | **思源黑体 Noto Sans SC** | 500 (body), 700–800 (caption / label) |

### Mixed-Content Strategy

**Strategy A — single CJK family across the entire system.** Raw Grid is intentionally a one-family system: every weight (900 / 800 / 700 / 500) comes from the same Latin stack. Mirroring that with a single CJK family — Noto Sans SC — preserves the system's most defining property: typographic uniformity. Because the Latin stack is `system-ui` (Segoe UI on Windows, San Francisco on macOS), pairing with a single high-quality CJK web font keeps the rendering as close to "system-native" as the digital-native aesthetic demands. Using two CJK families would fracture the neobrutalist monoculture.

### Loading

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@500;700;800;900&display=swap" rel="stylesheet">
```

Then append `'Noto Sans SC'` after the Latin stack in every font-family token:
```css
font-family: 'Segoe UI', system-ui, -apple-system, Helvetica, Arial, 'Noto Sans SC', sans-serif;
```

### Universal CJK Adjustments

- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence

### Aesthetic Notes for This System

- **The negative tracking that defines the Latin display voice does not transfer.** Set `letter-spacing: 0` on every CJK display element. Noto Sans SC at weight 900 already reads as dense and brutalist; negative tracking will jam glyphs together and read as a rendering bug, not as a design choice.
- **Uppercase is the entire Latin display voice — and it does not exist in Chinese.** Compensate by leaning harder on the weight contrast (900 display vs. 500 body) and on the label pill's white-on-black inversion. The brutalist density comes from the weight ladder, not from case.
- **The black label pill (`{components.label}`) survives the translation beautifully.** A 2–4 character Chinese label (品牌, 信号源, 第四季度) in Noto Sans SC 800 reads as more compact and arguably more striking than the English equivalent.
- **Decorative oversized numerals at 0.15–0.35 opacity should stay Latin** (Arabic numerals look correct in this system; full-width Chinese numerals 零一二三 do not carry the same wallpaper-numeral signal).
- **The arrow-prefix (`→`) renders identically in CJK contexts** and is the right interactivity signal for both languages.

### Known CJK Gap

Raw Grid's whole aesthetic argument is "this is the user's actual system font, not a downloaded display face." Loading Noto Sans SC technically violates that purity — but there is no acceptable substitute. macOS ships PingFang SC and Windows ships Microsoft YaHei, but the two render at noticeably different weights at "900," and the digital-native aesthetic depends on weight 900 reading consistently. Noto Sans SC is the smallest acceptable concession to web fonts; treat it as the one exception to the no-web-fonts rule, only for CJK content.

## Iteration Guide

1. Any new structural region uses a 3px solid black border to separate from its neighbor. Never use a gap or a margin between regions — borders are the separators.
2. Any new card or panel inherits the bordered-rectangle pattern: 3px solid black border, square corners, padding from the `{spacing.pad-*}` scale, background from the palette (white, pink, green, gray, or black).
3. Any new headline uses `{typography.headline}` (or `{typography.display}` for cover-level moments) in `{colors.black}` with uppercase. Don't reach for `{typography.title}` for the primary moment — that's a sub-headline.
4. Any new label or chip uses the `{components.label}` pattern: black background, white uppercase text at 11px / weight 800 / 0.08em.
5. Any new numerical figure follows the weight-900 + negative-tracking convention. Stat tiles use `{typography.number-md}`; hero stats use `{typography.number}`.
6. Any new accent surface picks pink or green based on warm/cool need. Don't introduce a third color.
7. Any new CTA or interactive element gets the `→` arrow prefix and, if elevated, a `6px 6px 0 {colors.black}` shadow.
8. If a card needs a "personality" element, add an oversized decorative numeral at 0.15–0.35 opacity rather than a graphic or icon. The wallpaper-numeral treatment is the system's signature decorative move.
9. Tables follow the bordered-cells + zebra-stripe + black-header pattern. Don't restyle them — the brutalist table aesthetic is part of the system identity.

## Known Gaps

- The `--darkgray` (#333333) CSS variable is defined but not actively used in any rule. It is available as a reserved tertiary text color but not deployed anywhere in the source.
- The system loads no external fonts — the rendered letterforms will differ between operating systems. macOS renders system-ui as San Francisco, Windows renders Segoe UI, Linux renders whatever sans-serif is configured. This visual inconsistency is by design but is worth noting.
- Hover states (list items → green, table rows → green) are interactive web behaviors that have no analog in print or static export. Treat them as bonus interactivity, not core design system.
- The slide navigation JavaScript is embedded inline — it handles keyboard, touch, and the active-class system. Any new slide must follow the `<div class="slide sN">` pattern and respect the `current` index.
- The SVG donut chart uses hardcoded `stroke-dasharray` values that must be computed manually based on segment percentages and the chart's 80px radius circumference (~502.4). There is no data-binding layer.
- The image placeholder on image-paired regions is just a 4px-white-bordered div with "[ Image Placeholder ]" text — actual image insertion requires replacing the placeholder div with an `<img>` and matching the parent background to the image's negative space.
- The `.s5-image-placeholder` includes the word "Cohots" (sic) which appears to be a typo for "Cohorts" in the source. Flag this when reusing content.
````

---

## 2. 글씨체

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

---

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

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

**1장(표지)에서 처음 나오는 부품**
- `.arw` — 1·2·4·6장 — 예: `<p class="arw">`
- `.black` — 1·2·3·6장 — 예: `<div class="cell black cta">`
- `.cell` — 1·2·3·4·5·6장 — 예: `<div class="cell hdr">`
- `.cta` — 1장 — 예: `<div class="cell black cta">`
- `.f1` — 1장 — 예: `<div class="frame f1">`
- `.frame` — 1·2·3·4·5·6장 — 예: `<div class="frame f1">`
- `.ghost` — 1·2·5장 — 예: `<span class="lbl ghost">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.gl` — 1장 — 예: `<span class="lbl gl">`
- `.green` — 1·3·4·6장 — 예: `<div class="cell green lede">`
- `.hdr` — 1장 — 예: `<div class="cell hdr">`
- `.icon` — 1·2·5·6장 — 예: `<span class="icon">`
- `.lbl` — 1·2·3·4·5·6장 — 예: `<span class="lbl">`
- `.lede` — 1장 — 예: `<div class="cell green lede">`
- `.main` — 1장 — 예: `<div class="cell main">`
- `.pink` — 1·3·4·6장 — 예: `<div class="cell pink side">`
- `.side` — 1장 — 예: `<div class="cell pink side">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide">`
- `.stat` — 1장 — 예: `<b class="stat">`
- `.stub` — 1·2·3·4·5·6장 — 예: `<i class="stub">`
- `.t1` — 1장 — 예: `<h1 class="t1">`
- `.unit` — 1장 — 예: `<p class="unit">`
- `.wall` — 1·4·6장 — 예: `<b class="wall">`
- `.yr` — 1장 — 예: `<span class="yr">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.band` — 2장 — 예: `<div class="cell black band">`
- `.btns` — 2장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quo…`
- `.cta-b` — 2·5·6장 — 예: `<button class="cta-b" data-act="step">`
- `.ctl` — 2장 — 예: `<div class="cell gray ctl">`
- `.f2` — 2장 — 예: `<div class="frame f2">`
- `.fig` — 2장 — 예: `<div class="cell fig">`
- `.gray` — 2·4장 — 예: `<div class="cell gray ctl">`
- `.hd` — 2·3·4·5·6장 — 예: `<h2 class="hd">`
- `.hdr2` — 2·3·4·5·6장 — 예: `<div class="cell hdr2">`
- `.hl` — 2·3·4·5·6장 — 예: `<div class="hl">`
- `.li` — 2장 — 예: `<div class="li" data-s="1">`
- `.list` — 2장 — 예: `<div class="cell list">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.bars` — 3장 — 예: `<div class="cell bars">`
- `.bh` — 3장 — 예: `<div class="br bh">`
- `.br` — 3장 — 예: `<div class="br bh">`
- `.cp` — 3·5장 — 예: `<span class="cp">`
- `.f3` — 3장 — 예: `<div class="frame f3">`
- `.fill` — 3·6장 — 예: `<i class="fill pink" style="width:63%">`
- `.nm` — 3장 — 예: `<b class="nm">`
- `.src` — 3장 — 예: `<p class="src">`
- `.tile` — 3장 — 예: `<div class="cell white tile">`
- `.tm` — 3장 — 예: `<span class="tm">`
- `.track` — 3·6장 — 예: `<div class="track">`
- `.v` — 3장 — 예: `<span class="v">`
- `.white` — 3장 — 예: `<div class="cell white tile">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cmp` — 4장 — 예: `<div class="cell pink cmp">`
- `.f4` — 4장 — 예: `<div class="frame f4">`
- `.hv` — 4·6장 — 예: `<p class="hv arw">`
- `.lst` — 4장 — 예: `<div class="cell lst">`
- `.qm` — 4장 — 예: `<b class="qm">`
- `.qt` — 4장 — 예: `<div class="cell gray qt">`
- `.tbl` — 4장 — 예: `<div class="tbl">`
- `.tblc` — 4장 — 예: `<div class="cell tblc">`
- `.th` — 4장 — 예: `<div class="tr th">`
- `.tr` — 4장 — 예: `<div class="tr th">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bk` — 5장 — 예: `<div class="bk">`
- `.blank` — 5장 — 예: `<button class="blank" data-blank aria-pressed="false">`
- `.blk` — 5장 — 예: `<div class="cell blk">`
- `.f5` — 5장 — 예: `<div class="frame f5">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.mk` — 5장 — 예: `<span class="mk">`
- `.nr` — 5장 — 예: `<p class="nr">`
- `.ot` — 5장 — 예: `<span class="ot">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.qh` — 5장 — 예: `<div class="qh">`
- `.quiz` — 5장 — 예: `<div class="cell quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다…`
- `.rk` — 5장 — 예: `<span class="rk">`
- `.row` — 5장 — 예: `<button class="row" data-opt="0">`
- `.rty` — 5장 — 예: `<button class="cta-b ghost rty" data-act="retry">`
- `.words` — 5장 — 예: `<div class="words">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.d6` — 6장 — 예: `<div class="cell d6">`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.f6` — 6장 — 예: `<div class="frame f6">`
- `.hv6` — 6장 — 예: `<div class="cell d6 hv6">`
- `.i6` — 6장 — 예: `<div class="cell i6">`
- `.r6` — 6장 — 예: `<div class="r6">`
- `.sh6` — 6장 — 예: `<div class="sh6" id="rg-sh">`
- `.sm` — 6장 — 예: `<button class="cta-b sm" data-demo="#rg-sh" data-mode="toggle" aria-pressed="false">`
- `.sw6` — 6장 — 예: `<span class="sw6">`
- `.tr6` — 6장 — 예: `<div class="tr6" id="rg-tr">`
- `.w6` — 6장 — 예: `<b class="wall w6">`

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="raw-grid">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>계절의 변화</title>

<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/raw-grid.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide"><div class="frame f1">
  <div class="cell hdr"><span class="lbl">초등 과학 · 6학년 2학기</span><i class="stub"></i><span class="lbl ghost">1단원 · 3~4차시</span><span class="icon">III</span></div>
  <div class="cell main"><p class="unit">계절의 변화<span>Sun, Shadow & Temperature</span></p><span class="lbl gl">학습 목표</span><h1 class="t1">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1></div>
  <div class="cell green lede"><p class="arw">자 붙이기 → 수수깡 꽂기 → 실 묶기 → 각도기 끼우기</p></div>
  <div class="cell pink side"><b class="wall">03</b><span class="lbl">LESSON</span><b class="stat">3~4차시</b></div>
  <div class="cell black cta"><span class="arw">00초등학교</span><span class="yr">2026</span></div>
</div></section>
<section class="slide" data-steps="4"><div class="frame f2">
  <div class="cell hdr2"><div class="hl"><span class="lbl">측정 준비</span><i class="stub"></i></div><h2 class="hd">태양 고도 측정기 만들기</h2></div>
  <div class="cell fig"><span class="lbl">FIG. 01 · 태양 고도 측정기</span><svg class="gauge" viewBox="0 0 1000 660" role="img" aria-label="태양 고도 측정기: 태양 빛, 수수깡, 실, 태양 고도, 그림자 길이, 자, 각도기">
  <line class="g-ground" x1="20" x2="980" y1="580" y2="580"/>
  <rect class="g-board" x="80" y="540" width="860" height="40"/>
  <g class="g-part" data-s="1"><rect class="g-ruler" x="110" y="524" width="800" height="16"/><line class="g-tick" x1="120" x2="120" y1="524" y2="536"/><line class="g-tick" x1="140" x2="140" y1="524" y2="530"/><line class="g-tick" x1="160" x2="160" y1="524" y2="530"/><line class="g-tick" x1="180" x2="180" y1="524" y2="530"/><line class="g-tick" x1="200" x2="200" y1="524" y2="530"/><line class="g-tick" x1="220" x2="220" y1="524" y2="536"/><line class="g-tick" x1="240" x2="240" y1="524" y2="530"/><line class="g-tick" x1="260" x2="260" y1="524" y2="530"/><line class="g-tick" x1="280" x2="280" y1="524" y2="530"/><line class="g-tick" x1="300" x2="300" y1="524" y2="530"/><line class="g-tick" x1="320" x2="320" y1="524" y2="536"/><line class="g-tick" x1="340" x2="340" y1="524" y2="530"/><line class="g-tick" x1="360" x2="360" y1="524" y2="530"/><line class="g-tick" x1="380" x2="380" y1="524" y2="530"/><line class="g-tick" x1="400" x2="400" y1="524" y2="530"/><line class="g-tick" x1="420" x2="420" y1="524" y2="536"/><line class="g-tick" x1="440" x2="440" y1="524" y2="530"/><line class="g-tick" x1="460" x2="460" y1="524" y2="530"/><line class="g-tick" x1="480" x2="480" y1="524" y2="530"/><line class="g-tick" x1="500" x2="500" y1="524" y2="530"/><line class="g-tick" x1="520" x2="520" y1="524" y2="536"/><line class="g-tick" x1="540" x2="540" y1="524" y2="530"/><line class="g-tick" x1="560" x2="560" y1="524" y2="530"/><line class="g-tick" x1="580" x2="580" y1="524" y2="530"/><line class="g-tick" x1="600" x2="600" y1="524" y2="530"/><line class="g-tick" x1="620" x2="620" y1="524" y2="536"/><line class="g-tick" x1="640" x2="640" y1="524" y2="530"/><line class="g-tick" x1="660" x2="660" y1="524" y2="530"/><line class="g-tick" x1="680" x2="680" y1="524" y2="530"/><line class="g-tick" x1="700" x2="700" y1="524" y2="530"/><line class="g-tick" x1="720" x2="720" y1="524" y2="536"/><line class="g-tick" x1="740" x2="740" y1="524" y2="530"/><line class="g-tick" x1="760" x2="760" y1="524" y2="530"/><line class="g-tick" x1="780" x2="780" y1="524" y2="530"/><line class="g-tick" x1="800" x2="800" y1="524" y2="530"/><line class="g-tick" x1="820" x2="820" y1="524" y2="536"/><line class="g-tick" x1="840" x2="840" y1="524" y2="530"/><line class="g-tick" x1="860" x2="860" y1="524" y2="530"/><line class="g-tick" x1="880" x2="880" y1="524" y2="530"/><line class="g-tick" x1="900" x2="900" y1="524" y2="530"/><text class="g-lb" x="922" y="516" text-anchor="start">자</text></g>
  <g class="g-meas"><rect class="g-shadow" x="220" y="524" width="446" height="16"/>
    <path class="g-dim" d="M220 600v24M666 600v24M220 612H666"/><text class="g-lb" x="443" y="652" text-anchor="middle">그림자 길이</text></g>
  <g class="g-part" data-s="2"><rect class="g-stick" x="196" y="150" width="24" height="374"/><path class="g-mark" d="M220 504h20v20"/>
    <path class="g-lead" d="M182 330H196"/><text class="g-lb" x="174" y="342" text-anchor="end">수수깡</text></g>
  <g class="g-part" data-s="4"><path class="g-prot" d="M546 524A120 120 0 0 1 786 524Z"/><path class="g-prot2" d="M588 524A78 78 0 0 1 744 524"/><line class="g-tick" x1="570" y1="524" x2="546" y2="524"/><line class="g-tick" x1="561.6" y1="505.6" x2="547.8" y2="503.2"/><line class="g-tick" x1="566.4" y1="487.7" x2="553.2" y2="483"/><line class="g-tick" x1="582.9" y1="476" x2="562.1" y2="464"/><line class="g-tick" x1="584.8" y1="455.9" x2="574.1" y2="446.9"/><line class="g-tick" x1="597.9" y1="442.8" x2="588.9" y2="432.1"/><line class="g-tick" x1="618" y1="440.9" x2="606" y2="420.1"/><line class="g-tick" x1="629.7" y1="424.4" x2="625" y2="411.2"/><line class="g-tick" x1="647.6" y1="419.6" x2="645.2" y2="405.8"/><line class="g-tick" x1="666" y1="428" x2="666" y2="404"/><line class="g-tick" x1="684.4" y1="419.6" x2="686.8" y2="405.8"/><line class="g-tick" x1="702.3" y1="424.4" x2="707" y2="411.2"/><line class="g-tick" x1="714" y1="440.9" x2="726" y2="420.1"/><line class="g-tick" x1="734.1" y1="442.8" x2="743.1" y2="432.1"/><line class="g-tick" x1="747.2" y1="455.9" x2="757.9" y2="446.9"/><line class="g-tick" x1="749.1" y1="476" x2="769.9" y2="464"/><line class="g-tick" x1="765.6" y1="487.7" x2="778.8" y2="483"/><line class="g-tick" x1="770.4" y1="505.6" x2="784.2" y2="503.2"/><line class="g-tick" x1="762" y1="524" x2="786" y2="524"/><circle class="g-hole" cx="666" cy="524" r="5"/><text class="g-lb" x="800" y="456" text-anchor="start">각도기</text></g>
  <g class="g-part" data-s="3"><line class="g-string" x1="220" y1="150" x2="666" y2="524"/><text class="g-lb" x="478" y="344" text-anchor="start">실</text></g>
  <g class="g-meas"><path class="g-angle" d="M616 524A50 50 0 0 1 627.7 491.9"/><path class="g-lead" d="M542 498L615 506.9"/><text class="g-lb" x="536" y="508" text-anchor="end">태양 고도</text>
    <line class="g-ray" x1="74.5" y1="27.9" x2="187.8" y2="123"/><polygon class="g-rayh" points="209.3,141 179.5,133 196.2,113"/><text class="g-lb" x="150" y="60" text-anchor="start">태양 빛</text></g>
</svg></div>
  <div class="cell list"><div class="li" data-s="1"><span class="icon">I</span><div><h3>자 붙이기</h3><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div></div><div class="li" data-s="2"><span class="icon">II</span><div><h3>수수깡 꽂기</h3><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div></div><div class="li" data-s="3"><span class="icon">III</span><div><h3>실 묶기</h3><p>수수깡 끝에 실을 묶어요</p></div></div><div class="li" data-s="4"><span class="icon">IV</span><div><h3>각도기 끼우기</h3><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
  <div class="cell black band"><p><b>태양 고도</b> — 태양이 지표면과 이루는 각</p><p class="arw">막대기의 그림자와 실이 이루는 각 = 태양 고도</p></div>
  <div class="cell gray ctl"><div class="btns"><button class="cta-b" data-act="step">다음 단계</button><button class="cta-b ghost" data-act="reset">처음부터</button></div><p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quot;03 — 실 묶기&quot;,&quot;04 — 각도기 끼우기&quot;]">버튼을 눌러 순서대로 만들어 보세요</p></div>
</div></section>
<section class="slide"><div class="frame f3">
  <div class="cell hdr2"><div class="hl"><span class="lbl">측정 결과</span><i class="stub"></i></div><h2 class="hd">하루 동안 무엇이 어떻게 변할까요?</h2></div>
  <div class="cell white tile"><b class="nm">12:30</b><span class="cp">남중 시각</span><p>태양 고도가 가장 높아요</p></div><div class="cell pink tile"><b class="nm">정남</b><span class="cp">남중 방향</span><p>남중할 때 태양의 위치</p></div><div class="cell green tile"><b class="nm">14:30</b><span class="cp">최고 기온</span><p>기온이 가장 높아요</p></div><div class="cell black tile"><b class="nm">9:30</b><span class="cp">가장 긴 그림자</span><p>그림자가 가장 길어요</p></div>
  <div class="cell bars">
    <div class="br bh"><span>시각</span><span>태양 고도(°)</span><span>그림자 길이(cm)</span><span>기온(℃)</span></div>
    <div class="br"><span class="tm">9:30</span><div class="track"><i class="fill pink" style="width:63%"><em>38°</em></i></div><span class="v">12.9</span><span class="v">22</span></div><div class="br"><span class="tm">10:30</span><div class="track"><i class="fill green" style="width:80%"><em>48°</em></i></div><span class="v">9.1</span><span class="v">23.8</span></div><div class="br"><span class="tm">11:30</span><div class="track"><i class="fill pink" style="width:92%"><em>55°</em></i></div><span class="v">7</span><span class="v">25.2</span></div><div class="br"><span class="tm">12:30</span><div class="track"><i class="fill black" style="width:95%"><em>57°</em></i></div><span class="v">6.4</span><span class="v">26.3</span></div><div class="br"><span class="tm">13:30</span><div class="track"><i class="fill pink" style="width:90%"><em>54°</em></i></div><span class="v">7.2</span><span class="v">27</span></div><div class="br"><span class="tm">14:30</span><div class="track"><i class="fill green" style="width:78%"><em>47°</em></i></div><span class="v">9.4</span><span class="v">27.4</span></div><div class="br"><span class="tm">15:30</span><div class="track"><i class="fill pink" style="width:62%"><em>37°</em></i></div><span class="v">13.4</span><span class="v">26.9</span></div>
    <p class="src">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</p>
  </div>
</div></section>
<section class="slide"><div class="frame f4">
  <div class="cell hdr2"><div class="hl"><span class="lbl">관계 정리</span><i class="stub"></i></div><h2 class="hd">태양 고도가 바뀌면 무엇이 달라질까요?</h2></div>
  <div class="cell pink cmp"><b class="wall">A</b><span class="lbl">HIGH</span><h3>태양 고도가 높을 때</h3><p class="arw">그림자 길이는 짧아져요</p><p class="arw">기온은 높아져요</p></div><div class="cell green cmp"><b class="wall">B</b><span class="lbl">LOW</span><h3>태양 고도가 낮을 때</h3><p class="arw">그림자 길이는 길어져요</p><p class="arw">기온은 낮아져요</p></div>
  <div class="cell lst"><span class="lbl">남중</span><p class="hv arw">태양이 정남쪽에 있을 때 '남중했다'고 해요</p><p class="hv arw">이때의 태양 고도를 남중 고도라고 해요</p></div>
  <div class="cell tblc"><div class="tbl"><div class="tr th"><span>시각</span><span>태양 고도</span><span>그림자 길이</span><span>기온</span></div><div class="tr"><span>오전 9:30</span><span>낮아요</span><span>길어요</span><span>낮아요</span></div><div class="tr"><span>낮 12:30</span><span>가장 높아요</span><span>가장 짧아요</span><span>높아지는 중</span></div><div class="tr"><span>오후 14:30</span><span>낮아지는 중</span><span>길어지는 중</span><span>가장 높아요</span></div></div></div>
  <div class="cell gray qt"><b class="qm">“</b><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span class="lbl">오늘의 정리</span></div>
</div></section>
<section class="slide"><div class="frame f5">
  <div class="cell hdr2"><div class="hl"><span class="lbl">확인하기</span><i class="stub"></i></div><h2 class="hd">배운 내용을 확인해 볼까요?</h2></div>
  <div class="cell quiz" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
    <div class="qh">QUESTION</div>
    <h3 class="q">하루 중 그림자 길이가 가장 짧을 때는?</h3>
    <button class="row" data-opt="0"><span class="rk">A</span><span class="ot">오전 9시 30분</span><span class="mk"></span></button><button class="row" data-opt="1"><span class="rk">B</span><span class="ot">낮 12시 30분 무렵</span><span class="mk"></span></button><button class="row" data-opt="2"><span class="rk">C</span><span class="ot">오후 3시 30분</span><span class="mk"></span></button>
    <p class="fb" data-fb></p>
    <button class="cta-b ghost rty" data-act="retry">다시 풀기</button>
  </div>
  <div class="cell blk">
    <span class="lbl">빈칸을 눌러 확인해요</span>
    <div class="bk"><span class="icon">I</span><p><button class="blank" data-blank aria-pressed="false"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</p></div><div class="bk"><span class="icon">II</span><p><button class="blank" data-blank aria-pressed="false"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</p></div><div class="bk"><span class="icon">III</span><p><button class="blank" data-blank aria-pressed="false"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</p></div>
    <div class="words"><span class="cp">오늘의 낱말</span><span class="lbl">태양 고도</span><span class="lbl">남중 고도</span><span class="lbl">그림자 길이</span><span class="lbl">기온</span></div>
  </div>
</div><p class="nr">빈칸 규칙 없음 → 막대 트랙으로 표현</p></section>
<section class="slide"><div class="frame f6">
  <div class="cell hdr2"><div class="hl"><span class="lbl">디자인 안내</span><i class="stub"></i></div><h2 class="hd">이 디자인 사용 설명서</h2></div>
  <div class="cell i6"><div class="r6"><span class="icon">I</span><div><h3>한눈에</h3><p>네오브루탈리즘 — <b>3px 검정 테두리가 곧 레이아웃</b>. 칸 사이 틈 없이 선이 맞닿고, 그림자는 흐림 없이 6px.</p></div></div><div class="r6"><span class="icon">II</span><div><h3>색</h3><p><span class="sw6"><span><i style="background:#FFFFFF"></i>흰 바탕</span><span><i style="background:#0A0A0A"></i>검정</span><span><i style="background:#F2D4CF"></i>분홍 면</span><span><i style="background:#E5EDD6"></i>세이지 면</span><span><i style="background:#F5F5F5"></i>회색 면</span></span></p></div></div><div class="r6"><span class="icon">III</span><div><h3>글꼴</h3><p>웹폰트 없음 — 시스템 산세리프 900(제목) → Paperlogy 9Black<br>500(본문) → Noto Sans KR Regular</p></div></div><div class="r6"><span class="icon">IV</span><div><h3>이렇게 쓰면 좋아요</h3><p>정리·비교·체크리스트처럼 칸을 나눠 보여 주는 수업. 분홍과 초록은 면에만, 글자는 늘 검정.</p></div></div></div>
  <div class="cell d6"><div class="dh"><h3>단단한 오프셋 그림자</h3><button class="cta-b sm" data-demo="#rg-sh" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>흐림 0 — 판은 6px, 버튼은 4px 아래오른쪽으로.</p><div class="sh6" id="rg-sh"><span class="lbl">CARD</span><b>계절의 변화</b></div></div>
  <div class="cell pink d6"><b class="wall w6">II</b><div class="dh"><h3>막대 트랙 채움</h3><button class="cta-b sm" data-demo="#rg-tr" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p>3px 테두리 트랙 안을 분홍·초록·검정으로 즉시 채워요.</p><div class="tr6" id="rg-tr"><div class="track"><i class="fill pink" style="width:63%"></i></div><div class="track"><i class="fill green" style="width:92%"></i></div><div class="track"><i class="fill black" style="width:95%"></i></div></div></div>
  <div class="cell d6 hv6"><div class="dh"><h3>마우스 올리면 초록</h3><span class="lbl">HOVER</span></div><p>목록 줄·표 줄 위에서만 0.15초 — 명세의 유일한 반응.</p><p class="hv arw">관찰한 내용을 적어요</p><p class="hv arw">결과를 비교해요</p></div>
</div></section>
<nav class="dk-nav"><button class="dk-prev" aria-label="이전">←</button><span class="dk-count" data-pad></span><button class="dk-next" aria-label="다음">→</button></nav>
  </main>
</div>

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

---

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

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

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

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


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

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

/* --- 토큰 --- */
:root{--k:#0A0A0A;--w:#FFFFFF;--pink:#F2D4CF;--green:#E5EDD6;--gray:#F5F5F5;--bd:3px solid #0A0A0A;--sys:'Segoe UI',Helvetica,Arial}
.slide{background:var(--w);color:var(--k);font-family:var(--sys),var(--kb),sans-serif;font-weight:500}
.frame{position:absolute;left:44px;right:50px;top:44px;bottom:110px;display:grid;border:var(--bd);box-shadow:6px 6px 0 var(--k)}
.cell{position:relative;overflow:hidden;padding:28px 40px;border-right:var(--bd);border-bottom:var(--bd);display:flex;flex-direction:column}
.pink{background:var(--pink)}.green{background:var(--green)}.gray{background:var(--gray)}.white{background:var(--w)}.black{background:var(--k);color:var(--w)}
h1,h2,h3,.unit,.stat,.nm,.qt p{font-family:var(--sys),var(--kt),sans-serif;font-weight:var(--wt);letter-spacing:-.01em}
.lbl{align-self:flex-start;background:var(--k);color:var(--w);padding:8px 16px;font:800 22px/1.1 var(--sys),var(--kb),sans-serif;letter-spacing:.08em;text-transform:uppercase}
.black .lbl{background:var(--w);color:var(--k)}
.lbl.ghost{background:var(--w);color:var(--k);box-shadow:inset 0 0 0 3px var(--k)}
.stub{display:block;width:60px;height:4px;background:var(--k)}
.icon{display:grid;place-items:center;width:52px;height:52px;border:var(--bd);background:var(--w);color:var(--k);font:900 20px/1 var(--sys),sans-serif;flex:none}
.wall{position:absolute;font:900 300px/1 var(--sys),sans-serif;letter-spacing:-.04em;opacity:.2;pointer-events:none}
.arw::before{content:'→ '}
.cp{font:700 20px/1.2 var(--sys),var(--kb),sans-serif;letter-spacing:.08em;text-transform:uppercase}
.nr{position:absolute;left:44px;bottom:40px;font:700 20px/1.2 var(--sys),var(--kb),sans-serif;letter-spacing:.06em}
.cta-b{border:var(--bd);background:var(--k);color:var(--w);padding:12px 24px;font:800 28px/1 var(--sys),var(--kb),sans-serif;box-shadow:4px 4px 0 var(--k)}
.cta-b::before{content:'→ '}
.cta-b.ghost{background:var(--w);color:var(--k)}
.cta-b:disabled{opacity:.35}

/* --- 머리 칸(라벨 + 선 토막 + 제목) --- */
.hdr2{grid-column:1/-1;border-right:0;justify-content:center;gap:14px}
.hl{display:flex;align-items:center;gap:18px}
.hd{font-size:72px;line-height:1.1;white-space:nowrap}

/* --- 1. 표지: 머리 띠 / 큰 흰 칸(단원 + 학습 목표, 핵심 낱말 = 분홍 면) / 초록 칸(단계) + 분홍 칸(벽지 숫자·차시) + 검정 칸(학교) --- */
.f1{grid-template-columns:1fr 470px 420px;grid-template-rows:100px 1fr 220px}
.hdr{grid-column:1/-1;flex-direction:row;align-items:center;gap:22px;padding:0 40px;border-right:0}
.hdr .icon{margin-left:auto}
.main{grid-column:1/-1;border-right:0;justify-content:center}
.unit{display:flex;align-items:baseline;gap:28px;font-size:68px;line-height:1.1;white-space:nowrap}
.unit span{font:900 44px/1 var(--sys),sans-serif;letter-spacing:-.02em;text-transform:uppercase;opacity:.55}
.gl{margin-top:30px}
.t1{margin-top:18px;font-size:114px;line-height:1.2;white-space:nowrap}
.t1 .gk{font-style:normal;background:var(--pink);padding:0 .1em;box-shadow:inset 0 0 0 3px var(--k)}
.lede{border-bottom:0;justify-content:center}
.lede p{font-size:34px;line-height:1.45;font-weight:700}
.side{border-bottom:0;justify-content:flex-end}
.side .wall{right:-10px;top:-60px;font-size:280px}
.stat{margin-top:14px;font-size:64px;line-height:1}
.cta{border-right:0;border-bottom:0;justify-content:center;gap:10px}
.cta .arw{font-family:var(--sys),var(--kt),sans-serif;font-weight:var(--wt);font-size:44px}
.yr{font:800 26px/1 var(--sys),sans-serif;letter-spacing:.08em;opacity:.7}

/* --- 2. 만들기: 머리 / 그림 칸(측정기) | 목록 줄 4개(아이콘 상자, 켜지면 또렷, 지금 = 초록) / 검정 띠(정의·메모) | 회색 칸(버튼) --- */
.f2{grid-template-columns:1fr 760px;grid-template-rows:170px 1fr 130px}
.fig{padding:20px 30px 10px;
  --g-ink:var(--k);--g-acc:var(--k);--g-stick:var(--k);--g-board:var(--gray);--g-ruler:var(--pink);--g-prot:var(--green);--g-shadow:rgba(10,10,10,.4);--g-font:var(--sys),var(--kb),sans-serif;--g-sw:3}
.fig .gauge{width:900px;display:block;margin:6px auto 0}
.list{border-right:0;padding:0}
.li{flex:1;display:grid;grid-template-columns:52px 1fr;gap:24px;align-items:center;padding:12px 36px;border-bottom:var(--bd);transition:background .15s}
.li:last-child{border-bottom:0}
.li h3{font-size:38px;line-height:1.1}
.li p{margin-top:6px;font-size:25px;line-height:1.45}
.li:hover{background:var(--green)}
.slide[data-step]:not([data-step="0"]) .li:not(.on){opacity:.3}
.li.now{background:var(--green)}
.band{border-bottom:0;justify-content:center;gap:6px}
.band p{font-size:28px;line-height:1.35}
.band b{font-weight:900}
.ctl{border-right:0;border-bottom:0;flex-direction:row;align-items:center;gap:22px;padding:0 30px}
.btns{display:flex;gap:16px;flex:none}
.cap{font-size:24px;line-height:1.35;font-weight:700}

/* --- 3. 숫자와 그래프: 머리 / 통계 칸 4개(흰·분홍·초록·검정) / 막대 트랙 7줄(태양 고도, 가장 높은 값 = 검정) + 그림자·기온 값 --- */
.f3{grid-template-columns:repeat(4,1fr);grid-template-rows:170px 200px 1fr}
.tile{justify-content:center;gap:6px}
.f3 .tile:nth-child(5){border-right:0}
.nm{font-size:64px;line-height:1}
.tile p{font-size:24px;line-height:1.35}
.bars{grid-column:1/-1;border:0;padding:14px 40px;justify-content:space-between}
.br{display:grid;grid-template-columns:140px 1fr 220px 200px;gap:24px;align-items:center}
.br.bh{font:800 20px/1 var(--sys),var(--kb),sans-serif;letter-spacing:.08em;text-transform:uppercase}
.tm{font:900 28px/1 var(--sys),sans-serif;letter-spacing:-.02em}
.track{height:42px;border:var(--bd);background:var(--w);position:relative}
.fill{position:absolute;left:0;top:0;bottom:0;display:flex;align-items:center;border-right:var(--bd)}
.fill em{font-style:normal;padding-left:14px;font:800 22px/1 var(--sys),sans-serif}
.fill.black em{color:var(--w)}
.v{font-size:28px;font-weight:700}
.src{font:700 18px/1.3 var(--sys),var(--kb),sans-serif;letter-spacing:.04em;opacity:.75}

/* --- 4. 비교와 표: 머리 / 분홍 A · 초록 B 칸(벽지 글자) | 남중 목록 / 표(검정 머리 + 줄무늬, 올리면 초록) | 회색 인용 칸(옅은 따옴표) --- */
.f4{grid-template-columns:1fr 1fr 620px;grid-template-rows:170px 330px 1fr}
.cmp{gap:10px}
.cmp .wall{right:10px;top:-60px;font-size:240px;opacity:.25}
.cmp h3{margin-top:6px;font-size:42px;line-height:1.15}
.cmp p{font-size:28px;line-height:1.45}
.lst{border-right:0;gap:4px;padding:28px 0 0}
.lst .lbl{margin:0 0 10px 36px}
.hv{padding:12px 36px;border-top:var(--bd);font-size:27px;line-height:1.45;transition:background .15s}
.hv:hover{background:var(--green)}
.tblc{grid-column:1/3;border-bottom:0;padding:0}
.tbl{height:100%;display:flex;flex-direction:column}
.tr{flex:1;display:grid;grid-template-columns:1.2fr 1fr 1fr 1fr;align-items:stretch;border-bottom:var(--bd);transition:background .15s}
.tr:last-child{border-bottom:0}
.tr>span{display:flex;align-items:center;padding:0 22px;border-right:var(--bd);font-size:27px;font-weight:600}
.tr>span:last-child{border-right:0}
.tr.th{flex:none;background:var(--k);color:var(--w)}
.tr.th>span{padding:14px 22px;font-size:22px;font-weight:800;letter-spacing:.06em;border-color:var(--w)}
.tr:nth-child(odd):not(.th){background:var(--gray)}
.tr:not(.th):hover{background:var(--green)}
.tr:not(.th)>span:first-child{font-family:var(--sys),var(--kt),sans-serif;font-weight:var(--wt)}
.qt{border-right:0;border-bottom:0;justify-content:center;gap:20px}
.qm{position:absolute;left:24px;top:-10px;font:900 160px/1 var(--sys),sans-serif;opacity:.15}
.qt p{font-size:44px;line-height:1.25}

/* --- 5. 확인하기: 머리 / 표 퀴즈(검정 머리, 줄무늬, 올리면 초록, 정답 = 초록 ✓ · 오답 = 분홍 ✕) | 빈칸 칸(막대 트랙) + 라벨 낱말 --- */
.f5{grid-template-columns:1fr 760px;grid-template-rows:170px 1fr}
.quiz{border-bottom:0;padding:0}
.qh{background:var(--k);color:var(--w);padding:16px 30px;font:800 24px/1 var(--sys),sans-serif;letter-spacing:.08em}
.q{padding:22px 30px;font-size:50px;line-height:1.15;border-bottom:var(--bd)}
.row{display:grid;grid-template-columns:70px 1fr 60px;align-items:center;text-align:left;border-bottom:var(--bd);font-size:34px;font-weight:500;transition:background .15s}
.row:nth-of-type(even){background:var(--gray)}
.row>*{padding:16px 0}
.rk{align-self:stretch;display:grid;place-items:center;border-right:var(--bd);font:900 28px/1 var(--sys),sans-serif}
.ot{padding-left:22px}
.mk{font:900 32px/1 var(--sys),sans-serif}
.row:hover:not(:disabled){background:var(--green)}
.row.right{background:var(--green)}
.row.right .mk::after{content:'✓'}
.row.wrong{background:var(--pink)}
.row.wrong .ot{text-decoration:line-through;text-decoration-thickness:3px}
.row.wrong .mk::after{content:'✕'}
.row:disabled:not(.right){opacity:.55}
.fb{padding:18px 30px 0;font-size:28px;line-height:1.45}
.rty{align-self:flex-start;margin:auto 30px 26px}
.blk{border:0;gap:22px}
.bk{display:grid;grid-template-columns:52px 1fr;gap:20px;align-items:center}
.bk p{font-size:30px;line-height:1.6}
.blank{position:relative;min-width:180px;height:44px;margin-right:10px;padding:0 14px;border:var(--bd);background:var(--w);font:800 26px/38px var(--sys),var(--kb),sans-serif;color:var(--k);text-align:center;vertical-align:middle}
.blank span{visibility:hidden}
.blank::after{content:'?';position:absolute;left:0;right:0;top:0;font-weight:900}
.blank.open{background:var(--green)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.words{margin-top:auto;display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.words .cp{width:100%;margin-bottom:4px}

/* --- 내비: 틀 아래 검정 라벨식 버튼 + 번호 --- */
.dk-nav{position:absolute;right:50px;bottom:28px;display:flex;align-items:center;gap:0;border:var(--bd);box-shadow:4px 4px 0 var(--k);background:var(--w)}
.dk-prev,.dk-next{width:60px;height:52px;background:var(--k);color:var(--w);font:900 26px/1 var(--sys),sans-serif}
.dk-count{padding:0 22px;font:800 26px/1 var(--sys),sans-serif;letter-spacing:.08em}
.dk-prev:disabled,.dk-next:disabled{background:var(--gray);color:#aaa}
/* --- 6. 디자인 안내: 아이콘 상자 줄 넷 | 시연 칸 셋 --- */
.f6{grid-template-columns:1fr 760px;grid-template-rows:170px repeat(3,1fr)}
.i6{grid-row:2/5;padding:0;border-bottom:0}
.r6{flex:1;display:grid;grid-template-columns:52px 1fr;gap:24px;align-items:center;padding:10px 36px;border-bottom:var(--bd)}
.r6:last-child{border-bottom:0}
.r6 h3{font-size:34px;line-height:1.1}
.r6 p{margin-top:6px;font-size:25px;line-height:1.45}
.r6 b{font-weight:800}
.sw6{display:flex;flex-wrap:wrap;gap:6px 20px}
.sw6 i{display:inline-block;width:24px;height:24px;margin-right:8px;vertical-align:-5px;border:var(--bd)}
.d6{border-right:0;padding:18px 32px;gap:4px}
.f6 .d6:last-child{border-bottom:0;padding:18px 0 0}
.d6 .dh{position:relative;display:flex;justify-content:space-between;align-items:center;gap:16px}
.hv6 .dh,.hv6>p:not(.hv){padding:0 32px}
.d6 h3{font-size:32px;line-height:1.1}
.d6>p{font-size:21px;line-height:1.4}
.cta-b.sm{font-size:19px;padding:8px 14px}
.cta-b.sm[aria-pressed="true"]{background:var(--green);color:var(--k)}
.w6{right:-10px;top:-70px;font-size:240px}
.sh6{position:relative;margin-top:10px;align-self:flex-start;display:flex;align-items:center;gap:16px;padding:12px 20px;border:var(--bd);background:var(--w)}
.sh6 b{font-size:28px;font-weight:900}
.sh6.play{box-shadow:6px 6px 0 var(--k)}
.tr6{position:relative;margin-top:10px;display:flex;flex-direction:column;gap:8px}
.tr6 .track{height:26px}
.tr6 .fill{visibility:hidden}
.tr6.play .fill{visibility:visible}
.hv6 .hv{padding:8px 32px;font-size:23px}

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