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

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

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

## 라이선스

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

- Cafe24 PRO UP: Cafe24 PRO UP — KERIS 학교 안심폰트(https://copyright.keris.or.kr/wft/fntDwnld, 전체 OFL 안내)에서 받은 TTF (2026-10-07) / 파일 안 저작권: Copyright ⓒ Cafe24 Corp. All Rights Reserved. Cafe24 Cafe24 PRO UP is a trademark of Cafe24.
  파일: Cafe24PROUP.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/neo-grid-bold.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/neo-grid-bold.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 Cafe24 PRO UP(400) · 본문 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. 디자인 규칙 (`neo-grid-bold` design.md)

````markdown
---
version: alpha
name: Neo-Grid Bold
description: A heavy editorial poster system built on a strict 12-column × 8-row block grid with neon-yellow accents on putty-ecru. Space Grotesk at weight 700 in strict uppercase carries every display moment; JetBrains Mono carries every label and metadata tag. Each slide reads as a magazine spread divided into colored panels — paper-ecru, ink-black, and electric lemon-yellow trading roles across cells. The aesthetic borrows from contemporary editorial print, brutalist annual reports, and the populist-poster end of design week showcases.

colors:
  paper: "#F5F4EF"
  bg: "#ECECE8"
  ink: "#0A0A0A"
  accent-lemon: "#E6FF3D"
  muted: "#8A8A85"
  stage-bg: "#1A1A1A"

color-aliases:
  line: ink
  primary-bg: bg
  card-bg: paper

typography:
  display:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 132px
    fontWeight: 700
    lineHeight: 0.92
    letterSpacing: -0.02em
    textTransform: uppercase
  title:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 88px
    fontWeight: 700
    lineHeight: 0.95
    letterSpacing: -0.015em
    textTransform: uppercase
  subtitle:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 56px
    fontWeight: 700
    lineHeight: 1.0
    letterSpacing: -0.01em
    textTransform: uppercase
  section-num:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 320px
    fontWeight: 700
    lineHeight: 0.85
    letterSpacing: -0.05em
  stat-num:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 156px
    fontWeight: 700
    lineHeight: 0.9
    letterSpacing: -0.03em
  stat-num-lg:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 240px
    fontWeight: 700
    lineHeight: 0.85
    letterSpacing: -0.04em
  stat-num-sm:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 96px
    fontWeight: 700
    lineHeight: 0.9
    letterSpacing: -0.03em
  card-headline:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 44px
    fontWeight: 700
    lineHeight: 1.0
    letterSpacing: -0.01em
    textTransform: uppercase
  card-h3:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 30px
    fontWeight: 700
    lineHeight: 1.05
    letterSpacing: -0.005em
    textTransform: uppercase
  body:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 28px
    fontWeight: 400
    lineHeight: 1.35
  body-sm:
    fontFamily: "Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"
    fontSize: 22px
    fontWeight: 400
    lineHeight: 1.45
  label:
    fontFamily: "JetBrains Mono, ui-monospace, monospace"
    fontSize: 24px
    fontWeight: 400
    letterSpacing: 0.08em
    textTransform: uppercase
  label-sm:
    fontFamily: "JetBrains Mono, ui-monospace, monospace"
    fontSize: 16px
    fontWeight: 400
    letterSpacing: 0.08em
    textTransform: uppercase
  label-xs:
    fontFamily: "JetBrains Mono, ui-monospace, monospace"
    fontSize: 14px
    fontWeight: 400
    letterSpacing: 0.12em
    textTransform: uppercase
  pagenum:
    fontFamily: "JetBrains Mono, ui-monospace, monospace"
    fontSize: 24px
    fontWeight: 400
    letterSpacing: 0.04em

spacing:
  frame-inset: 40px
  grid-gap: 12px
  grid-gap-lg: 18px
  card-pad-sm: "24px 28px"
  card-pad-md: "28px 32px"
  card-pad-lg: "36px 32px"
  card-pad-xl: "40px 44px"

canvas:
  width: 1920px
  height: 1080px

components:
  frame:
    position: "absolute; inset: 40px"
    display: grid
    gridTemplateColumns: "repeat(12, 1fr)"
    gridTemplateRows: "repeat(8, 1fr)"
    gap: "{spacing.grid-gap}"
    description: "The universal slide frame — a 12-column × 8-row CSS grid inset 40px from each slide edge with 12px gaps between cells. Every slide composes its layout by spanning cells inside this frame."
  card:
    background: "{colors.paper}"
    position: relative
    overflow: hidden
    description: "Generic colored panel. Paper is the default fill; .ink switches to black with paper text; .lemon switches to yellow with ink text; .photo switches to deep-black with white text for image regions."
  card-ink:
    background: "{colors.ink}"
    color: "{colors.paper}"
    description: "Inverted card — black background, paper text. Used as a contrast block in any composition."
  card-lemon:
    background: "{colors.accent-lemon}"
    color: "{colors.ink}"
    description: "Yellow accent card — full neon-yellow fill with ink text. The system's loudest signal."
  pagenum:
    position: "absolute; left: 0; bottom: 0"
    background: "{colors.paper}"
    color: "{colors.ink}"
    padding: "14px 22px"
    fontFamily: "JetBrains Mono, monospace"
    fontSize: 24px
    letterSpacing: 0.04em
    description: "Bottom-left page-number tag in the format '01 / 12'. Three variants: default (paper bg), .invert (ink bg), .lemon (yellow bg)."
  corner-mark:
    position: "absolute; top: 22px; right: 22px"
    width: 36px
    height: 36px
    display: "grid 2x2"
    gap: 4px
    description: "Top-right 2x2 block mark — three solid currentColor squares plus one transparent. A small structural identity stamp."
  blockmark:
    width: 56px
    height: 56px
    display: "grid 2x2"
    gap: 4px
    description: "Larger 2x2 block stamp with diagonal squares filled — used as a brand mark on covers and dividers. May be sized 56px, 96px, or larger."
  qr-tile:
    width: 90px
    height: 90px
    display: "grid 5x5"
    description: "Decorative QR-pattern tile composed of a 5x5 grid of black squares with some accent-lemon squares interspersed. Decorative, not a real scannable code."
  table-cell:
    padding: "18px 22px"
    borderBottom: "1.5px solid {colors.ink}"
    borderRight: "1.5px solid {colors.ink}"
    fontSize: 24px
    lineHeight: 1.35
    description: "Comparison-matrix cell. Solid hairline ink dividers on bottom and right; last column has no right border."
  table-head-row:
    background: "{colors.ink}"
    color: "{colors.paper}"
    fontFamily: "JetBrains Mono, monospace"
    fontSize: 14px
    letterSpacing: 0.12em
    textTransform: uppercase
    description: "Inverted table header — black row with paper mono uppercase text."
  pill-yes:
    background: "{colors.accent-lemon}"
    color: "{colors.ink}"
    padding: "6px 14px"
    description: "Affirmative pill in a comparison cell — yellow fill, ink text, mono uppercase."
  pill-part:
    background: "{colors.paper}"
    color: "{colors.ink}"
    border: "1.5px solid {colors.ink}"
    description: "Partial-state pill — paper fill, ink border, ink text."
  pill-no:
    background: "{colors.ink}"
    color: "{colors.paper}"
    description: "Negative pill — black fill, paper text."
  arrow:
    width: 64px
    height: 64px
    description: "Inline SVG arrow glyph (right-pointing) at 64px square. Used as a flow indicator between process steps and as an out-of-cell pointer on stat cards."
  highlight-mark:
    background: "{colors.accent-lemon}"
    color: "{colors.ink}"
    padding: "0 6px"
    description: "Inline <mark> element — yellow background swatch wrapping one or more words inside a headline for emphasis."
  bar-fill-ink:
    background: "{colors.ink}"
    description: "Solid black vertical bar for chart series A."
  bar-fill-lemon:
    background: "{colors.accent-lemon}"
    border: "1.5px solid {colors.ink}"
    description: "Yellow vertical bar with ink border for chart series B."
  copyright:
    position: "absolute; left: 22px; bottom: 22px"
    fontFamily: "JetBrains Mono, ui-monospace, monospace"
    fontSize: 16px
    lineHeight: 1.4
    color: "{colors.ink}"
    opacity: 0.85
---

## 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

Neo-Grid Bold is a **heavy editorial poster system** built on a single structural premise: every slide is a 12-column × 8-row CSS grid inset 40px from the slide edges, with 12px gaps between cells. Composition happens by assigning colored panels to grid spans — `grid-column: 4 / span 5` and `grid-row: 1 / span 5` is how layout is described. The grid is rigid; the visual variety comes from how panels of `{colors.paper}`, `{colors.ink}`, and `{colors.accent-lemon}` are arranged across cells.

The typeface stack is intentionally narrow. **Space Grotesk** at weight 700 carries every display moment in strict uppercase with negative letter-spacing. Body copy runs at weight 400 in mixed case. **JetBrains Mono** at weight 400 carries every label, page number, axis tag, and metadata string — always uppercase with 0.08–0.12em positive tracking. There is no third face. The contrast between heavy Space Grotesk uppercase and JetBrains Mono uppercase is the system's primary typographic rhythm.

The palette has three working colors plus a putty surface. **Paper** (`{colors.paper}` — a warm ecru off-white) is the default panel fill. **Ink** (`{colors.ink}` — a near-black) is the structural color: text on paper, fills for inverted panels, all dividers, all rules. **Accent Lemon** (`{colors.accent-lemon}` — an electric neon-yellow #E6FF3D) is the loud signal — used as panel fill, as a highlight `<mark>` swatch inside headlines, and as the second series in charts. **Putty BG** (`{colors.bg}`) is the slightly cooler ecru that sits behind the 40px slide inset, framing the composition like a passe-partout. **Muted graphite** is present in the token list but rarely used in practice.

Depth is created entirely through **panel adjacency and color contrast**, not shadows. Cards do not carry box-shadows; cards do not have rounded corners; cards do not have borders (except for table cells and pill outlines, which use 1.5px solid ink). The visual weight of a slide is determined by how many cells are filled with `{colors.ink}` vs. `{colors.accent-lemon}` vs. `{colors.paper}`. A composition with three yellow panels reads as much more aggressive than one with a single yellow panel.

**Density philosophy: dense.** Neo-Grid Bold reads as authoritative when the 12×8 grid is fully populated with panels of varying span and color. A slide with only one or two panels and large empty grid areas reads as broken; the system was designed as an editorial poster, and posters are dense. The expected pattern is 4–8 panels per slide, each occupying a non-trivial cell span, with the grid fully used corner-to-corner. The exception is a section-divider slide where a single 320px section number occupies an entire pane of the grid — but even there, the rest of the canvas is filled with a second panel of contrasting color.

**Key Characteristics:**
- Universal 12-column × 8-row CSS grid (`{components.frame}`) inset 40px from each slide edge, with 12px gaps between cells.
- Three-color panel system: paper ecru (`{colors.paper}`) as default, ink black (`{colors.ink}`) for inverted blocks, accent lemon (`{colors.accent-lemon}`) for signal blocks.
- Space Grotesk weight 700 uppercase with negative letter-spacing for every display element.
- JetBrains Mono uppercase with 0.08–0.12em tracking for every label, page number, axis tag.
- A signature corner-mark and blockmark — small 2×2 block stamps that act as decorative identity tags.
- Inline `<mark>` element that wraps words inside a headline in a neon-yellow swatch — the system's headline emphasis mechanism.
- A persistent page-number tag (`{components.pagenum}`) anchored bottom-left of every slide.
- No rounded corners, no drop shadows, no gradients (apart from photo-region stylized noise textures).
- Stat numerals scale up to 240px and even 320px — type is allowed to dominate entire panels.

## Colors

### Palette

- **Paper** (`{colors.paper}` — #F5F4EF): Warm ecru off-white. The default panel fill, the default text color when inverted, and the canvas of any "neutral" card. Slightly creamier than pure white — chosen so the neon-yellow accent doesn't vibrate against it.
- **BG (Putty)** (`{colors.bg}` — #ECECE8): A cooler ecru that sits behind the 40px slide inset, framing the grid composition like a passe-partout. The 40px border of putty around every slide is the system's universal frame.
- **Ink** (`{colors.ink}` — #0A0A0A): The structural near-black. Used for all text on paper, all inverted panel fills, all dividers, all table cell borders, all pill outlines. Not pure #000 — slightly softer.
- **Accent Lemon** (`{colors.accent-lemon}` — #E6FF3D): Electric neon-yellow. The signal color. Used as a panel fill, as the inline `<mark>` highlight swatch inside headlines, as the second chart series, as the affirmative pill fill, and as page-number variant background. Never as a text color (the yellow is too light to read as type against any surface).
- **Muted** (`{colors.muted}` — #8A8A85): A reserved graphite tone present in the token list but used only at low opacity on photo-region tags. Available for de-emphasized text but rarely deployed.
- **Stage BG** (`{colors.stage-bg}` — #1A1A1A): The viewport background outside the 1920×1080 slide canvas. This is the deck-stage container color, not part of slide design.

### Defaults

- **Default slide canvas background**: `{colors.bg}` — visible as the 40px putty frame around every grid composition.
- **Default panel fill**: `{colors.paper}`. When in doubt, a panel is paper.
- **Default primary headline color**: `{colors.ink}` on paper or lemon panels; `{colors.paper}` on ink panels.
- **Default body text color**: `{colors.ink}` on paper/lemon; `{colors.paper}` on ink.
- **Default label / metadata color**: `{colors.ink}` on paper, at opacity 0.7–0.85 to mute; `{colors.paper}` on ink, at opacity 0.7–0.85.
- **Default chart series color**: `{colors.ink}` for series A; `{colors.accent-lemon}` for series B (with 1.5px ink border).
- **Default emphasis mechanism inside a headline**: wrap in `<mark>` for a neon-yellow swatch on ink text. This is the system's primary headline-level emphasis.
- **Default affirmative state**: `{colors.accent-lemon}` fill. Default negative state: `{colors.ink}` fill. Default neutral state: `{colors.paper}` fill with `{colors.ink}` border.

Neon yellow is the system's only chromatic accent — never substitute red, blue, or any third color. Yellow's role is to draw the eye, not to communicate meaning (it is not "warning" or "highlight" in the semantic sense; it is simply the signal).

## Typography

### Font Family

The system uses two web fonts: **Space Grotesk** (weights 400, 500, 700) for all display and body, and **JetBrains Mono** (weights 400, 500) for all labels and metadata. There is no third face — no serif, no italic, no display script. The system's character lives in the weight contrast between Space Grotesk 700 uppercase and Space Grotesk 400 mixed case, plus the structural mono labels in JetBrains Mono.

A specific inline mixing rule: **the `<em>` tag inside a Space Grotesk headline switches color to `{colors.accent-lemon}` and stays upright** (font-style is normalized to non-italic). Em is repurposed as a yellow inline color switch, like the `<mark>` swatch but without the background fill.

A second inline mixing rule: **the `<mark>` element wraps words inside a Space Grotesk headline in a neon-yellow swatch with 0 6px padding**, creating the highlighter-pen emphasis that is a recurring signature of the system.

### Type Scale

| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.section-num}` | 320px | Space Grotesk | 700 | Hero section ordinal in a section-divider panel |
| `{typography.stat-num-lg}` | 240px | Space Grotesk | 700 | Featured large numerical stat |
| `{typography.stat-num}` | 156px | Space Grotesk | 700 | Standard stat numeral |
| `{typography.display}` | 132px | Space Grotesk | 700 | Cover, section, or hero display headline |
| `{typography.stat-num-sm}` | 96px | Space Grotesk | 700 | Compact stat numeral inside a small card |
| `{typography.title}` | 88px | Space Grotesk | 700 | Primary content-slide headline |
| `{typography.subtitle}` | 56px | Space Grotesk | 700 | Secondary headline, region heading |
| `{typography.card-headline}` | 44px | Space Grotesk | 700 | Card title at panel-fill scale |
| `{typography.card-h3}` | 30px | Space Grotesk | 700 | Sub-headline inside a smaller card |
| `{typography.body}` | 28px | Space Grotesk | 400 | Body paragraph inside a feature card |
| `{typography.label}` | 24px | JetBrains Mono | 400 | Standard mono label or kicker |
| `{typography.body-sm}` | 22px | Space Grotesk | 400 | Compact body inside dense cards |
| `{typography.pagenum}` | 24px | JetBrains Mono | 400 | Page-number tag (e.g. "01 / 12") |
| `{typography.label-sm}` | 16px | JetBrains Mono | 400 | Secondary metadata label, copyright text |
| `{typography.label-xs}` | 14px | JetBrains Mono | 400 | Axis labels, table header text, fine print |

### Defaults

- **Default primary section headline**: `{typography.title}` (88px) — the workhorse content-slide headline.
- **Default cover or section-opening display**: `{typography.display}` (132px) for a cover; `{typography.section-num}` (320px) for a section-divider ordinal.
- **Default body paragraph size**: `{typography.body}` (28px). For dense multi-card slides, drop to `{typography.body-sm}` (22px).
- **Default label / metadata size**: `{typography.label}` (24px) for standalone mono tags; `{typography.label-sm}` (16px) for inline metadata.
- **Default stat numeral**: `{typography.stat-num}` (156px). Reach for `{typography.stat-num-lg}` (240px) only when the stat occupies an entire featured panel.
- **Default weight for any display element**: 700. Display in any other weight does not exist in this system.
- **Default weight for body**: 400.

When unsure, reach for `{typography.title}` for the slide's primary text moment and pair it with `{typography.body}` for supporting copy.

### Signature Treatments

These treatments are **non-optional whenever the corresponding element type is used**:

- **Every Space Grotesk display, title, subtitle, card-headline, and stat numeral is uppercase** with negative letter-spacing (-0.005 to -0.05em depending on scale). Mixed-case display does not exist in this system.
- **Body copy is mixed case at weight 400.** Never uppercase body.
- **Every JetBrains Mono element is uppercase** with at least 0.08em positive tracking.
- **The `<mark>` element inside a headline always uses `{colors.accent-lemon}` background with `{colors.ink}` text and 0 6px padding.** The yellow highlighter swatch is the system's headline emphasis signal.
- **The `<em>` element inside a headline switches to `{colors.accent-lemon}` color and stays upright (font-style: normal).** Italic letterforms are not used.
- **Negative letter-spacing scales with size**: smaller headlines use -0.005em to -0.015em; larger displays use -0.02 to -0.05em. The tighter the tracking, the more compressed and brutalist the headline reads — at 320px size, -0.05em is correct.
- **Page numbers are always JetBrains Mono at 24px with 0.04em tracking** in the format `01 / 12` with a single padded zero and slash separator.

### Typography Principles

The rhythm is **heavy uppercase display + light mixed-case body + small uppercase mono label**. Switching any of those three modes breaks the editorial register. Body in uppercase reads as a shouting paragraph. Display in mixed case reads as a different design system. Mono in mixed case reads as code, not editorial metadata.

Italic letterforms are not used. The `<em>` and `<mark>` tags are repurposed as color/highlight switches, not italic emphasis. Underline is not used. Bold inside body text is not used — emphasis is achieved by isolating the headline in its own cell.

## Layout

### Canvas System

The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component that handles scaling to fit the viewport. All sizes are in `px` (not vw/vh) — typography sizes, padding values, grid gaps, and inset values are all pixel-fixed. The composition is designed at 1920×1080 and the stage scales the entire deck proportionally.

The viewport background outside the deck stage is `{colors.stage-bg}` (#1A1A1A) — a dark gray frame that visually anchors the bright slide against the browser chrome.

### The Universal Frame

Every slide carries a `.frame` div positioned `absolute; inset: 40px` with `display: grid; grid-template-columns: repeat(12, 1fr); grid-template-rows: repeat(8, 1fr); gap: 12px`. This is the structural constant of the system: a 12-column × 8-row grid with 12px gaps, inset 40px from the slide edges. Some slide variants increase the grid gap to 16–18px for breathing room, but the column/row counts and the 40px inset never change.

Composition happens entirely by spanning cells inside this grid. A panel occupying `grid-column: 1 / span 4; grid-row: 1 / span 3` is a 4-cell-wide × 3-row-tall card in the upper-left. The grid is the only layout language — flexbox is used only for internal alignment inside a single cell.

### Padding Inside Cells

Internal padding inside a cell varies with cell size and purpose:
- Compact cards (small stat tiles): 24px × 28px
- Standard cards (feature panels): 28px × 32px
- Large cards (chapter panels): 36px × 32px
- Hero cards (section dividers): 40px × 44px

These are not rigid tokens — they're a practical scale. Choose the padding that gives the card's internal type room to breathe without losing the panel's identity.

### Persistent Chrome

Every slide carries a `{components.pagenum}` tag bottom-left in the format `01 / 12`. Three variants:
- Default: paper background, ink text.
- `.invert`: ink background, paper text.
- `.lemon`: yellow background, ink text.

Some slides also carry a `{components.corner-mark}` (small 2×2 block) top-right, a `{components.copyright}` bottom-left, or a `{components.blockmark}` (larger 2×2 stamp) as a brand identifier.

## Depth and Elevation

### No Shadows, Color-Block Adjacency Only

The system uses **zero box-shadow declarations** on any structural panel. Depth is entirely a function of color adjacency: a paper panel next to an ink panel reads as elevated (paper toward viewer); a yellow panel next to an ink panel reads as the loudest signal in the composition. The 12px grid gap between panels reveals the putty `{colors.bg}` between cells, which acts as a unifying frame color.

### No Gradients (Except Photo Regions)

The only gradients in the system are inside photo-region placeholder textures, where a `radial-gradient` plus a `repeating-linear-gradient` creates a stylized B&W-grain texture as a stand-in for photography. These textures live inside cells classed `.photo` or `.ph`, never on a structural panel.

### Borders on Tables and Pills

- Table cells (`{components.table-cell}`) use 1.5px solid ink dividers on bottom and right edges to create a wireframe grid.
- Comparison pills (`{components.pill-part}`) use a 1.5px solid ink border as the partial-state outline.
- Chart axes use 2px solid ink as the bottom-left wireframe.
- The yellow bar in a bar chart (`{components.bar-fill-lemon}`) carries a 1.5px solid ink border to prevent the bright fill from vibrating against the paper background.

No other elements carry borders. Cards are borderless and rely on fill contrast.

## Shapes and Treatment

### Border Radius

| Value | Use |
|---|---|
| 0px | Every element — cards, pills, tags, page numbers, table cells, chart bars, blockmarks |

The system has **zero border-radius** on any element. Every shape is a strict rectangle or square. The block-stamp and corner-mark glyphs are composed of right-angle squares.

### Border Weights

- **1.5px solid `{colors.ink}`** — used on table cell dividers, pill outlines, and the yellow bar's border. The most common border weight.
- **2px solid `{colors.ink}`** — used on chart axes (left and bottom of the plot area) for slightly stronger wireframe.

No other border weights exist. There are no muted-color borders, no dashed borders (except a very specific `1px dashed rgba(0,0,0,.18)` chart grid line used internally).

### Decorative Element Types

**Block stamp (`{components.blockmark}`)** — A 2×2 grid of small squares with the top-left and bottom-right cells filled (and the other two transparent). A diagonal-fill stamp that acts as a brand identity mark. Sized from 36px (corner-mark) up to 96px (block stamp on quote slides). May render in ink or accent-lemon.

**Corner mark (`{components.corner-mark}`)** — A 36px × 36px version of the block stamp anchored top-right of a panel. Acts as a small structural identity tag.

**QR tile (`{components.qr-tile}`)** — A 5×5 grid of small squares with a checkerboard-like pattern of ink and accent-lemon fills. Decorative QR-pattern visual, not a real scannable code. Used as a cover-slide flourish.

**Arrow (`{components.arrow}`)** — An inline SVG right-pointing arrow at 64px × 64px (or 24px × 24px for small flow indicators). Used as a flow signal between process steps and as an out-pointing indicator on stat panels.

**Highlight mark (`{components.highlight-mark}`)** — A neon-yellow swatch wrapping one or more words inside a headline via the `<mark>` element. The system's headline emphasis mechanism. Padding is `0 6px` (or `0 8px` at larger sizes).

**Page number (`{components.pagenum}`)** — Bottom-left position-tag in the format `01 / 12` with a colored background. The three background variants (paper, ink, lemon) let the page number adapt to whichever color is most visible against the active slide's dominant panels.

**Photo region** — A cell classed `.photo` with a deep-black background (#111) containing a `.ph` child that renders a stylized B&W noise texture (radial + diagonal stripes). A small mono tag inside the cell labels the region (e.g., "PORTRAIT / B&W"). Used as a placeholder until real photography arrives.

**Pills (`{components.pill-yes}`, `{components.pill-part}`, `{components.pill-no}`)** — Inline mono uppercase labels in a comparison cell with three color states: yellow fill (affirmative), paper with ink border (partial), ink fill with paper text (negative). All three are 0-radius rectangles, not rounded pills despite the name.

**Section ordinal panel** — A panel containing a 320px Space Grotesk weight-700 numeral as the entire content. Used as the visual identity of a section-divider slide; the rest of the slide carries a complementary headline panel in ink.

**Chart bar pair** — Vertical bars in groups of two (series A in solid ink, series B in yellow with ink border). The bars share equal width inside their column and the column gap is set by the parent grid.

## Do's and Don'ts

### Do
- Compose every slide on the 12-column × 8-row grid (`{components.frame}`) with 40px inset and 12px (or 18px for breathing room) gaps. The grid is the system's identity.
- Fill the grid corner to corner. The system reads as authoritative when the grid is densely populated with panels of varying span.
- Use `{colors.paper}` as your default panel fill, `{colors.ink}` for contrast blocks, and `{colors.accent-lemon}` for one to three signal panels per slide.
- Set every display, title, subtitle, and stat numeral in Space Grotesk 700 uppercase with negative letter-spacing. The combination is the system's typographic voice.
- Use `<mark>` inside a headline to wrap one or more words in a yellow highlighter swatch — the system's primary headline emphasis.
- Use `<em>` inside a headline to switch one word to accent-lemon color (stays upright, no italic).
- Place a `{components.pagenum}` tag bottom-left of every slide. Choose the background variant (paper / ink / lemon) that contrasts with the lower-left panel.
- Use JetBrains Mono uppercase with at least 0.08em tracking for every label, page number, axis tag, and metadata string.
- Render pills (yes / part / no) in their canonical three-color treatment inside comparison tables.
- Allow stat numerals to scale to 156–320px when they occupy a featured panel. Large numbers are part of the editorial poster identity.

### Don't
- Don't add box-shadow to any panel. Depth comes from color adjacency only.
- Don't round any corner on any element. The system is strictly rectangular.
- Don't put display headlines in mixed case. Space Grotesk display is always uppercase.
- Don't put body copy in uppercase. Mixed case at weight 400 is the body voice.
- Don't introduce a second accent color. Neon yellow is the only chromatic accent — adding red, blue, or green breaks the system.
- Don't use the yellow as a text color. The accent is too light to read as type; it's a fill color only.
- Don't compose layouts outside the 12×8 grid. Absolutely-positioned elements that break the grid (page number, corner mark, copyright) are explicitly the only exceptions.
- Don't use italic letterforms. The `<em>` tag is repurposed as a color switch — italic visual style does not exist here.
- Don't use rounded "pill" shapes despite the pill component naming. Pills are 0-radius rectangles.
- Don't sparsely populate the grid. A slide with one panel and seven empty cells reads as broken — the system needs density to function as an editorial poster.

## Responsive Behavior

The system targets a **fixed 1920×1080 canvas** rendered inside a `<deck-stage>` web component (loaded via `deck-stage.js`). The stage scales the entire 1920×1080 composition proportionally to fit the browser viewport — type sizes, panel positions, grid gaps, and inset values are all pixel-fixed inside the canvas, and the stage handles the responsive transform.

This means: every typographic and layout decision in the system is made at 1920×1080 resolution. Sizes do not scale per breakpoint; the entire canvas scales as a single unit. There are no media queries inside slide styles.

### Presenter Behavior
- The `<deck-stage>` web component manages slide-to-slide navigation, viewport scaling, and presenter chrome.
- Keyboard navigation, touch swipe, and mouse wheel are handled by the stage component, not by inline scripts.
- The slide canvas is constant 1920×1080 regardless of browser viewport; the stage proportionally scales it.

### Frontend Slides Integration Note

When using this design system inside the `frontend-slides` skill, preserve the
fixed 1920×1080 canvas model. Do not translate the 12-column × 8-row grid,
fixed typography, and fixed spacing into independent viewport-responsive
`clamp()` values. That breaks the relationship between panel size and type
scale, especially with CJK text, and can create clipping even when the original
template would have scaled cleanly.

The safe single-file implementation is:

1. Render each slide as a 1920×1080 `.stage`.
2. Scale that stage proportionally to fit the current viewport.
3. Keep the internal `.frame` grid at `inset: 40px`, `12` columns, `8` rows,
   and `12px` gaps.
4. Fit content at the 1920×1080 design size first, then scale the whole stage.
5. Verify both text overflow and panel overlap in the rendered browser. A
   `scrollHeight` check can pass while one grid panel visually covers another.

### Print Behavior
The template uses the deck-stage component for rendering. Print export depends on the component's print handling, which may render slide-per-page or capture the active slide only.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin face | Chinese face | Weight |
|---|---|---|---|
| Display / title / stat (Space Grotesk 700 UPPERCASE) | Space Grotesk | Noto Sans SC (思源黑体) | 900 |
| Body (Space Grotesk 400) | Space Grotesk | Noto Sans SC | 400 |
| Label / page number (JetBrains Mono UPPERCASE) | JetBrains Mono | Noto Sans SC | 400 (do not force monospace on CJK) |

### Mixed-Content Strategy

Strategy A — single `font-family` stack with Latin-first fallback. Update each token's `fontFamily` from `"Space Grotesk, Helvetica Neue, Helvetica, Arial, sans-serif"` to `"Space Grotesk, Noto Sans SC, Helvetica Neue, Helvetica, Arial, sans-serif"`. Latin glyphs render in Space Grotesk 700; CJK characters fall through to Noto Sans SC 900 automatically. Mixed strings like `THE CLAUDE 模型` render correctly inline.

### 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=Space+Grotesk:wght@400;500;700&family=JetBrains+Mono:wght@400;500&family=Noto+Sans+SC:wght@400;500;700;900&display=swap" rel="stylesheet">
```

### 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 (Chinese typography convention)
- Pangu spacing 盘古之白 (space between CJK and Latin: `使用 Claude` not `使用Claude`)
- One font per sentence

### Aesthetic Notes for This System

Neo-Grid Bold is heavy uppercase Space Grotesk 700 with negative letter-spacing at sizes up to 320px. **Chinese has no concept of uppercase**, so the system's primary typographic signature (uppercase brutalist headlines) must transfer through *weight and density* instead. Set every Chinese display moment in **Noto Sans SC 900** — the heaviest available weight — to match the visual weight of Space Grotesk 700 ALL CAPS at large sizes. Chinese headlines should also drop the negative letter-spacing entirely; CJK glyphs are designed on a square em-box and tightening them causes glyph collision.

The `<mark>` neon-yellow swatch highlighting one word inside a headline is a perfect transfer to Chinese — wrap one CJK character or one phrase in `<mark>` and the lemon swatch reads the same. **Keep the highlighter mechanism as the system's primary headline emphasis in CJK.** The `<em>` color switch (yellow inline) also transfers cleanly.

JetBrains Mono uppercase labels (page numbers in `01 / 12` format) are pure Latin / numeric — keep them in JetBrains Mono. Don't try to render Chinese in monospace; CJK glyphs are already monospaced by design and forcing JetBrains Mono produces missing glyphs. For mixed mono labels containing CJK, fall through to Noto Sans SC 400 at the same size.

Section numerals (320px Space Grotesk 700) and stat numerals (156–240px) are pure digits — they transfer unchanged. The neon-yellow accent panel system is script-agnostic; the brutalist poster aesthetic survives the script switch as long as the weight stays at 900.

### Known CJK Gap

The negative letter-spacing (-0.005 to -0.05em) scales with display size in this system and is part of the "brutalist compressed" signature. **Removing it for Chinese characters breaks visual parity with Latin slides in a mixed deck.** Accept this: pure-CJK slides will read as slightly less compressed than pure-Latin slides. Don't try to compensate by tightening Chinese — glyph collision is a worse failure than tonal mismatch.

## Iteration Guide

1. Every new slide composes its layout on the 12×8 grid via `grid-column` and `grid-row` span declarations. Never break the grid with absolute positioning except for the page-number tag, corner-mark, and copyright stamp.
2. Every new panel uses one of three fill colors: paper (default), ink (inverted), or accent-lemon (signal). Don't introduce a fourth panel color.
3. Every new display headline is Space Grotesk weight 700 uppercase with negative letter-spacing scaled to the headline size (-0.005em at 30px, up to -0.05em at 320px).
4. Every new body element is Space Grotesk weight 400 mixed case at one of the three body sizes (28px, 24px, 22px).
5. Every new label or metadata tag is JetBrains Mono uppercase with at least 0.08em tracking.
6. Every new chart-series color is either `{colors.ink}` (series A) or `{colors.accent-lemon}` with an ink border (series B). Don't add a third series color.
7. Every new card uses 0 border-radius. Square corners are non-negotiable.
8. To emphasize a word inside a headline, wrap it in `<mark>` for a yellow swatch or `<em>` for a yellow color switch. Don't use bold, italic, or underline.
9. Every new comparison cell uses the three-state pill system: yellow fill (yes), paper with ink border (partial), ink fill (no).
10. Densely populate the grid. If a composition leaves more than two cells empty in a row, reconsider whether a card is missing.

## Known Gaps

- The system relies on a `<deck-stage>` web component loaded via `deck-stage.js`. Without this script, the 1920×1080 canvas will not scale to the viewport and slides will render at native pixel size.
- Photo regions use stylized CSS-generated noise textures (radial + diagonal stripe gradients) as placeholders. Real photography must be inserted by replacing the `.photo` cell contents with an `<img>` and ensuring the surrounding panel colors complement the photo's negative space.
- The QR-pattern tile is decorative — the 5×5 grid of squares does not encode a real scannable code. Real QR codes would need a separate SVG generated externally.
- Bar chart heights are set via inline `style="height: XX%"` declarations on each bar fill. There is no data-binding layer.
- The arrow SVG used between process steps is hand-pathed inside each slide template; if a slide adds or removes process nodes, the arrow positions must be recomputed manually.
- The `<deck-stage>` component is not loaded directly by this template's script tag — it's expected to be globally available via `deck-stage.js`. Missing the script will silently render slides as flat absolute-positioned divs.
- The system uses fixed pixel sizes throughout (no `vw`/`vh`). At unusual viewport aspect ratios, the deck-stage proportional scaling may letterbox the canvas with putty bars.
- The `{colors.muted}` (#8A8A85) token is defined but used only in low-opacity overlays on photo region tags — it has no role in the main type or panel system.
````

---

## 2. 글씨체

- 이 디자인의 한글 글씨체: 제목 Cafe24 PRO UP(400) · 본문 Noto Sans KR Regular(400). (쓰는 폰트: Cafe24 PRO UP, 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장(표지)에서 처음 나오는 부품**
- `.big` — 1·4장 — 예: `<i class="blk big l">`
- `.blk` — 1·2·3·4·5·6장 — 예: `<i class="blk cm">`
- `.ch3` — 1장 — 예: `<b class="ch3">`
- `.chips` — 1·5장 — 예: `<div class="chips">`
- `.cm` — 1·2·3·4·5·6장 — 예: `<i class="blk cm">`
- `.frame` — 1·2·3·4·5·6장 — 예: `<div class="frame">`
- `.gl` — 1장 — 예: `<span class="lab gl">`
- `.hero` — 1장 — 예: `<div class="p paper hero" style="grid-column:1/span 12;grid-row:1/span 5" >`
- `.ink` — 1·2·3·4·5·6장 — 예: `<div class="p ink lp" style="grid-column:1/span 5;grid-row:6/span 3" >`
- `.k` — 1장 — 예: `<b class="k">`
- `.l` — 1·4·5장 — 예: `<b class="l">`
- `.lab` — 1·2·3·4·5·6장 — 예: `<span class="lab">`
- `.lemon` — 1·2·3·4·5·6장 — 예: `<div class="p lemon" style="grid-column:6/span 3;grid-row:6/span 3" >`
- `.lp` — 1장 — 예: `<div class="p ink lp" style="grid-column:1/span 5;grid-row:6/span 3" >`
- `.p` — 1·2·3·4·5·6장 — 예: `<div class="p paper hero" style="grid-column:1/span 12;grid-row:1/span 5" >`
- `.paper` — 1·2·3·4·5·6장 — 예: `<div class="p paper hero" style="grid-column:1/span 12;grid-row:1/span 5" >`
- `.qr` — 1장 — 예: `<div class="qr">`
- `.sch` — 1장 — 예: `<span class="lab sch">`
- `.sec` — 1장 — 예: `<b class="sec">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide">`
- `.t1` — 1장 — 예: `<h1 class="t1">`
- `.unit` — 1장 — 예: `<p class="unit">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.arw` — 2·4장 — 예: `<svg class="arw" viewBox="0 0 64 64">`
- `.bt` — 2·5·6장 — 예: `<button class="bt go" data-act="step">`
- `.btns` — 2장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01 — 자 붙이기&quot;,&quot;02 — 수수깡 꽂기&quot;,&quo…`
- `.ctl` — 2장 — 예: `<div class="p lemon ctl" style="grid-column:8/span 5;grid-row:1/span 2" >`
- `.def` — 2장 — 예: `<p class="def">`
- `.fig` — 2장 — 예: `<div class="p paper fig" style="grid-column:1/span 7;grid-row:3/span 6" >`
- `.go` — 2장 — 예: `<button class="bt go" data-act="step">`
- `.note` — 2장 — 예: `<div class="p ink note" style="grid-column:8/span 5;grid-row:8/span 1" >`
- `.nr` — 2·5장 — 예: `<span class="lab nr">`
- `.sn` — 2·5장 — 예: `<b class="sn">`
- `.st` — 2장 — 예: `<div class="st" data-s="1">`
- `.steps` — 2장 — 예: `<div class="p paper steps" style="grid-column:8/span 5;grid-row:3/span 5" >`
- `.title` — 2·3·4·5·6장 — 예: `<h2 class="title">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.a` — 3·6장 — 예: `<i class="sw a">`
- `.b` — 3·6장 — 예: `<i class="sw b">`
- `.bar` — 3장 — 예: `<i class="bar a" style="height:63%">`
- `.chart` — 3장 — 예: `<div class="p paper chart" style="grid-column:1/span 8;grid-row:5/span 4" >`
- `.hi` — 3장 — 예: `<div class="tr hi">`
- `.lg` — 3장 — 예: `<div class="lg">`
- `.pair` — 3장 — 예: `<div class="pair">`
- `.plot` — 3장 — 예: `<div class="plot">`
- `.sc` — 3장 — 예: `<div class="p ink sc" style="grid-column:1/span 3;grid-row:3/span 2" >`
- `.src` — 3장 — 예: `<span class="lab src">`
- `.srcl` — 3장 — 예: `<span class="lab srcl">`
- `.stat` — 3·6장 — 예: `<b class="stat">`
- `.sv` — 3장 — 예: `<b class="sv">`
- `.sw` — 3장 — 예: `<i class="sw a">`
- `.t3` — 3장 — 예: `<div class="tbl t3">`
- `.tbl` — 3·4장 — 예: `<div class="tbl t3">`
- `.tblp` — 3·4장 — 예: `<div class="p paper tblp" style="grid-column:9/span 4;grid-row:5/span 4" >`
- `.th` — 3·4장 — 예: `<div class="tr th">`
- `.tr` — 3·4장 — 예: `<div class="tr th">`
- `.xl` — 3장 — 예: `<div class="xl">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.cp` — 4장 — 예: `<div class="p lemon cp" style="grid-column:1/span 4;grid-row:3/span 3" >`
- `.it` — 4장 — 예: `<p class="it">`
- `.lst` — 4장 — 예: `<div class="p paper lst" style="grid-column:9/span 4;grid-row:5/span 4" >`
- `.part` — 4장 — 예: `<span class="pill part">`
- `.pill` — 4·5·6장 — 예: `<span class="pill yes">`
- `.qt` — 4장 — 예: `<div class="p ink qt" style="grid-column:9/span 4;grid-row:1/span 4" >`
- `.t4` — 4장 — 예: `<div class="tbl t4">`
- `.t4p` — 4장 — 예: `<div class="p paper tblp t4p" style="grid-column:1/span 8;grid-row:6/span 3" >`
- `.yes` — 4장 — 예: `<span class="pill yes">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.blank` — 5장 — 예: `<button class="blank" data-blank aria-pressed="false">`
- `.blk5` — 5장 — 예: `<div class="p paper blk5" style="grid-column:8/span 5;grid-row:3/span 6" >`
- `.br` — 5장 — 예: `<p class="br">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.opt` — 5장 — 예: `<button class="opt" data-opt="0">`
- `.ot` — 5장 — 예: `<span class="ot">`
- `.pk` — 5장 — 예: `<span class="pill pk">`
- `.qb` — 5장 — 예: `<div class="p paper qb">`
- `.qh` — 5장 — 예: `<div class="p ink qh">`
- `.quiz` — 5장 — 예: `<div class="quiz" style="grid-column:1/span 7;grid-row:3/span 6" data-quiz data-answer="1" data-right="정답! 태양 …`
- `.rty` — 5장 — 예: `<button class="bt rty" data-act="retry">`
- `.wd` — 5장 — 예: `<div class="p lemon wd" style="grid-column:9/span 4;grid-row:1/span 2" >`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.d6` — 6장 — 예: `<div class="p paper d6" style="grid-column:9/span 4;grid-row:3/span 2" >`
- `.dh` — 6장 — 예: `<div class="dh">`
- `.f6` — 6장 — 예: `<div class="p paper i6 f6" style="grid-column:1/span 4;grid-row:6/span 3" >`
- `.i6` — 6장 — 예: `<div class="p ink i6" style="grid-column:1/span 4;grid-row:3/span 3" >`
- `.m6` — 6장 — 예: `<p class="m6" id="ng-mark">`
- `.pl6` — 6장 — 예: `<div class="pl6" id="ng-pill">`
- `.pr6` — 6장 — 예: `<div class="pr6" id="ng-bar">`
- `.sm` — 6장 — 예: `<button class="bt sm" data-demo="#ng-mark" data-mode="toggle" aria-pressed="false">`
- `.sw6` — 6장 — 예: `<div class="sw6">`

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

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.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="neo-grid-bold">
<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=Space+Grotesk:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/neo-grid-bold.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide"><div class="frame">
  <div class="p paper hero" style="grid-column:1/span 12;grid-row:1/span 5" ><i class="blk cm"><b></b><b></b><b></b><b></b></i><span class="lab">초등 과학 · 6학년 2학기</span><p class="unit">계절의 변화<span>Sun, Shadow & Temperature</span></p><span class="lab gl">학습 목표</span><h1 class="t1">하루 동안 <mark>태양 고도</mark>,<br><mark>그림자 길이</mark>, <mark>기온</mark>의 관계</h1></div>
  <div class="p ink lp" style="grid-column:1/span 5;grid-row:6/span 3" ><span class="lab">FLOW · 태양 고도 측정기 만들기</span><div class="chips"><span>자 붙이기</span><i>→</i><span>수수깡 꽂기</span><i>→</i><span>실 묶기</span><i>→</i><span>각도기 끼우기</span></div></div>
  <div class="p lemon" style="grid-column:6/span 3;grid-row:6/span 3" ><span class="lab">1단원 · 3~4차시</span><b class="sec">03</b></div>
  <div class="p paper" style="grid-column:9/span 2;grid-row:6/span 3" ><div class="qr"><b class="k"></b><b class="k"></b><b class=""></b><b class="l"></b><b class="k"></b><b class="k"></b><b class=""></b><b class=""></b><b class="k"></b><b class="k"></b><b class=""></b><b class="k"></b><b class="k"></b><b class="k"></b><b class=""></b><b class=""></b><b class="k"></b><b class=""></b><b class="k"></b><b class="k"></b><b class="k"></b><b class=""></b><b class="k"></b><b class="k"></b><b class="l"></b></div><span class="lab">EDITION 2026</span></div>
  <div class="p ink" style="grid-column:11/span 2;grid-row:6/span 3" ><i class="blk big l"><b></b><b></b><b></b><b></b></i><span class="lab sch">SCHOOL</span><b class="ch3">00초등학교</b></div>
</div></section>
<section class="slide" data-steps="4"><div class="frame">
  <div class="p paper" style="grid-column:1/span 7;grid-row:1/span 2" ><span class="lab">측정 준비</span><h2 class="title">태양 고도 <mark>측정기</mark> 만들기</h2></div>
  <div class="p lemon ctl" style="grid-column:8/span 5;grid-row:1/span 2" ><i class="blk cm"><b></b><b></b><b></b><b></b></i><div class="btns"><button class="bt go" data-act="step">다음 단계 →</button><button class="bt" 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><span class="lab nr">버튼 규칙 없음 → 알약으로 표현</span></div>
  <div class="p paper fig" style="grid-column:1/span 7;grid-row:3/span 6" ><span class="lab">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><p class="def"><b>태양 고도</b> — 태양이 지표면과 이루는 각</p></div>
  <div class="p paper steps" style="grid-column:8/span 5;grid-row:3/span 5" ><div class="st" data-s="1"><b class="sn">01</b><div><h3>자 붙이기</h3><p>우드록 한쪽에 양면테이프로 자를 붙여요</p></div><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg></div><div class="st" data-s="2"><b class="sn">02</b><div><h3>수수깡 꽂기</h3><p>수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</p></div><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg></div><div class="st" data-s="3"><b class="sn">03</b><div><h3>실 묶기</h3><p>수수깡 끝에 실을 묶어요</p></div><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg></div><div class="st" data-s="4"><b class="sn">04</b><div><h3>각도기 끼우기</h3><p>실의 다른 끝을 각도기 가운데 구멍에 끼워요</p></div></div></div>
  <div class="p ink note" style="grid-column:8/span 5;grid-row:8/span 1" ><p>막대기의 그림자와 실이 이루는 각 = <em>태양 고도</em></p></div>
</div></section>
<section class="slide"><div class="frame">
  <div class="p paper" style="grid-column:1/span 8;grid-row:1/span 2" ><span class="lab">측정 결과</span><span class="lab srcl">예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</span><h2 class="title">하루 동안 무엇이 <mark>어떻게</mark> 변할까요?</h2></div>
  <div class="p lemon" style="grid-column:9/span 4;grid-row:1/span 2" ><i class="blk cm"><b></b><b></b><b></b><b></b></i><b class="stat">57°</b><span class="lab">태양 고도 최고 · 12:30</span></div>
  <div class="p ink sc" style="grid-column:1/span 3;grid-row:3/span 2" ><span class="lab">남중 시각</span><b class="sv">12:30</b><p>태양 고도가 가장 높아요</p></div><div class="p paper sc" style="grid-column:4/span 3;grid-row:3/span 2" ><span class="lab">남중 방향</span><b class="sv">정남</b><p>남중할 때 태양의 위치</p></div><div class="p ink sc" style="grid-column:7/span 3;grid-row:3/span 2" ><span class="lab">최고 기온</span><b class="sv">14:30</b><p>기온이 가장 높아요</p></div><div class="p paper sc" style="grid-column:10/span 3;grid-row:3/span 2" ><span class="lab">가장 긴 그림자</span><b class="sv">9:30</b><p>그림자가 가장 길어요</p></div>
  <div class="p paper chart" style="grid-column:1/span 8;grid-row:5/span 4" ><div class="lg"><span class="lab"><i class="sw a"></i>태양 고도 (°)</span><span class="lab"><i class="sw b"></i>그림자 길이 (cm)</span><span class="lab src">예시 값</span></div>
    <div class="plot"><div class="grp"><div class="pair"><i class="bar a" style="height:63%"><span>38</span></i><i class="bar b" style="height:86%"><span>12.9</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:80%"><span>48</span></i><i class="bar b" style="height:61%"><span>9.1</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:92%"><span>55</span></i><i class="bar b" style="height:47%"><span>7</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:95%"><span>57</span></i><i class="bar b" style="height:43%"><span>6.4</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:90%"><span>54</span></i><i class="bar b" style="height:48%"><span>7.2</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:78%"><span>47</span></i><i class="bar b" style="height:63%"><span>9.4</span></i></div></div><div class="grp"><div class="pair"><i class="bar a" style="height:62%"><span>37</span></i><i class="bar b" style="height:89%"><span>13.4</span></i></div></div></div>
    <div class="xl"><span>9:30</span><span>10:30</span><span>11:30</span><span>12:30</span><span>13:30</span><span>14:30</span><span>15:30</span></div></div>
  <div class="p paper tblp" style="grid-column:9/span 4;grid-row:5/span 4" ><div class="tbl t3"><div class="tr th"><span>시각</span><span>기온(℃)</span></div><div class="tr"><span>9:30</span><span>22</span></div><div class="tr"><span>10:30</span><span>23.8</span></div><div class="tr"><span>11:30</span><span>25.2</span></div><div class="tr"><span>12:30</span><span>26.3</span></div><div class="tr"><span>13:30</span><span>27</span></div><div class="tr hi"><span>14:30</span><span>27.4</span></div><div class="tr"><span>15:30</span><span>26.9</span></div></div></div>
</div></section>
<section class="slide"><div class="frame">
  <div class="p paper" style="grid-column:1/span 8;grid-row:1/span 2" ><span class="lab">관계 정리</span><h2 class="title">태양 고도가 바뀌면 무엇이 <mark>달라질까요</mark>?</h2></div>
  <div class="p ink qt" style="grid-column:9/span 4;grid-row:1/span 4" ><i class="blk big l"><b></b><b></b><b></b><b></b></i><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span class="lab">오늘의 정리</span></div>
  <div class="p lemon cp" style="grid-column:1/span 4;grid-row:3/span 3" ><span class="lab">A / HIGH</span><h3>태양 고도가 높을 때</h3><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>그림자 길이는 짧아져요</p><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>기온은 높아져요</p></div><div class="p paper cp" style="grid-column:5/span 4;grid-row:3/span 3" ><span class="lab">B / LOW</span><h3>태양 고도가 낮을 때</h3><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>그림자 길이는 길어져요</p><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>기온은 낮아져요</p></div>
  <div class="p paper tblp t4p" style="grid-column:1/span 8;grid-row:6/span 3" ><div class="tbl t4"><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 class="pill yes">가장 높아요</span></span><span><span class="pill yes">가장 짧아요</span></span><span><span class="pill part">높아지는 중</span></span></div><div class="tr"><span>오후 14:30</span><span><span class="pill part">낮아지는 중</span></span><span><span class="pill part">길어지는 중</span></span><span><span class="pill yes">가장 높아요</span></span></div></div></div>
  <div class="p paper lst" style="grid-column:9/span 4;grid-row:5/span 4" ><i class="blk cm"><b></b><b></b><b></b><b></b></i><span class="lab">남중</span><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>태양이 정남쪽에 있을 때 '남중했다'고 해요</p><p class="it"><svg class="arw" viewBox="0 0 64 64"><path d="M8 32h44M36 16l16 16-16 16" fill="none" stroke="currentColor" stroke-width="6" stroke-linecap="square"/></svg>이때의 태양 고도를 남중 고도라고 해요</p></div>
</div></section>
<section class="slide"><div class="frame">
  <div class="p paper" style="grid-column:1/span 8;grid-row:1/span 2" ><span class="lab">확인하기</span><h2 class="title">배운 내용을 <mark>확인해</mark> 볼까요?</h2></div>
  <div class="p lemon wd" style="grid-column:9/span 4;grid-row:1/span 2" ><span class="lab">오늘의 낱말</span><div class="chips"><span>태양 고도</span><i>/</i><span>남중 고도</span><i>/</i><span>그림자 길이</span><i>/</i><span>기온</span></div></div>
  <div class="quiz" style="grid-column:1/span 7;grid-row:3/span 6" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요">
    <div class="p ink qh"><i class="blk cm l"><b></b><b></b><b></b><b></b></i><span class="lab">QUESTION</span><h3>하루 중 그림자 길이가 가장 짧을 때는?</h3></div>
    <div class="p paper qb"><button class="opt" data-opt="0"><span class="lab">01</span><span class="ot">오전 9시 30분</span><span class="pill pk"></span></button><button class="opt" data-opt="1"><span class="lab">02</span><span class="ot">낮 12시 30분 무렵</span><span class="pill pk"></span></button><button class="opt" data-opt="2"><span class="lab">03</span><span class="ot">오후 3시 30분</span><span class="pill pk"></span></button><p class="fb" data-fb></p><button class="bt rty" data-act="retry">다시 풀기 ↺</button></div>
  </div>
  <div class="p paper blk5" style="grid-column:8/span 5;grid-row:3/span 6" ><span class="lab">빈칸을 눌러 확인해요</span><p class="br"><b class="sn">01</b><span><button class="blank" data-blank aria-pressed="false"><span>태양 고도</span></button>는 점점 높아졌다가 다시 낮아진다</span></p><p class="br"><b class="sn">02</b><span><button class="blank" data-blank aria-pressed="false"><span>그림자 길이</span></button>는 점점 짧아졌다가 다시 길어진다</span></p><p class="br"><b class="sn">03</b><span><button class="blank" data-blank aria-pressed="false"><span>기온</span></button>은 점점 높아졌다가 다시 낮아진다</span></p><span class="lab nr">빈칸 규칙 없음 → PART 알약으로 표현</span></div>
</div></section>
<section class="slide"><div class="frame">
  <div class="p paper" style="grid-column:1/span 8;grid-row:1/span 2" ><span class="lab">디자인 안내</span><h2 class="title">이 디자인 사용 <mark>설명서</mark></h2></div>
  <div class="p lemon" style="grid-column:9/span 4;grid-row:1/span 2" ><i class="blk cm"><b></b><b></b><b></b><b></b></i><b class="stat">06</b><span class="lab">GUIDE · 대표 장치 — 눌러 보세요</span></div>
  <div class="p ink i6" style="grid-column:1/span 4;grid-row:3/span 3" ><span class="lab">한눈에</span><p>무거운 편집 포스터 — <em>12칸×8줄 격자</em>에 종이·잉크·네온 레몬 판을 모서리까지 채워요. 그림자·둥근 모서리 없음.</p></div>
  <div class="p paper i6" style="grid-column:5/span 4;grid-row:3/span 3" ><span class="lab">색</span><div class="sw6"><span><i style="background:#F5F4EF"></i>종이</span><span><i style="background:#0A0A0A"></i>잉크</span><span><i style="background:#E6FF3D"></i>네온 레몬(채움만)</span><span><i style="background:#ECECE8"></i>퍼티(틈)</span></div></div>
  <div class="p paper i6 f6" style="grid-column:1/span 4;grid-row:6/span 3" ><span class="lab">글꼴</span><p>제목·숫자 Space Grotesk 700 → Cafe24 PRO UP<br>본문 → Noto Sans KR Regular · 라벨 JetBrains Mono</p></div>
  <div class="p lemon i6" style="grid-column:5/span 4;grid-row:6/span 3" ><span class="lab">이렇게 쓰면 좋아요</span><p>한눈에 많은 정보를 보여 주는 정리 장, 모둠 발표 포스터. 판은 장마다 5~7개.</p></div>
  <div class="p paper d6" style="grid-column:9/span 4;grid-row:3/span 2" ><div class="dh"><h3>형광펜 mark</h3><button class="bt sm" data-demo="#ng-mark" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><p class="m6" id="ng-mark">하루 동안 <span>태양 고도</span></p></div>
  <div class="p paper d6" style="grid-column:9/span 4;grid-row:5/span 2" ><div class="dh"><h3>막대 한 쌍</h3><button class="bt sm" data-demo="#ng-bar" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><div class="pr6" id="ng-bar"><span><i class="a" style="height:38px"></i><i class="b" style="height:52px"></i></span><span><i class="a" style="height:57px"></i><i class="b" style="height:24px"></i></span><span><i class="a" style="height:37px"></i><i class="b" style="height:52px"></i></span></div></div>
  <div class="p paper d6" style="grid-column:9/span 4;grid-row:7/span 2" ><div class="dh"><h3>알약 세 상태</h3><button class="bt sm" data-demo="#ng-pill" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div><div class="pl6" id="ng-pill"><span class="pill">YES</span><span class="pill">PART</span><span class="pill">NO</span></div></div>
</div></section>
<nav class="dk-nav"><span class="dk-count" data-pad></span><button class="dk-prev" aria-label="이전">←</button><button class="dk-next" aria-label="다음">→</button></nav>
  </main>
</div>

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

---

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

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

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

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


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

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

/* --- 토큰 · 12×8 격자 틀(칸 142px · 줄 114px) --- */
:root{--paper:#F5F4EF;--bg:#ECECE8;--ink:#0A0A0A;--lemon:#E6FF3D}
.slide{background:var(--bg);color:var(--ink);font-family:'Space Grotesk',var(--kb),sans-serif;font-weight:var(--wb)}
.frame{position:absolute;inset:40px;display:grid;grid-template-columns:repeat(12,1fr);grid-template-rows:repeat(8,1fr);gap:12px}
.p{position:relative;overflow:hidden;padding:28px 32px;display:flex;flex-direction:column}
.paper{background:var(--paper);color:var(--ink)}.ink{background:var(--ink);color:var(--paper)}.lemon{background:var(--lemon);color:var(--ink)}
.lab{font:400 22px/1.25 'JetBrains Mono',var(--kb),monospace;letter-spacing:.08em;text-transform:uppercase;opacity:.8}
mark{background:var(--lemon);color:var(--ink);padding:0 8px}
.slide em{font-style:normal;color:var(--lemon)}
h1,h2,h3,.unit,.ch3,.chips span,.sv,.qt p,.xl span{font-family:'Space Grotesk',var(--kt),sans-serif;font-weight:var(--wt);letter-spacing:0}
.arw{width:64px;height:64px;flex:none}
.pill{display:inline-block;font:400 22px/1 'JetBrains Mono',var(--kb),monospace;letter-spacing:.08em;text-transform:uppercase;padding:8px 14px;border:1.5px solid var(--ink)}
.pill.yes{background:var(--lemon)}
.pill.part{background:var(--paper)}
.pill.no{background:var(--ink);color:var(--paper)}
.bt{padding:14px 24px;font:700 28px/1 'Space Grotesk',var(--kb),sans-serif;border:1.5px solid var(--ink);color:var(--ink);background:var(--paper)}
.bt.go{background:var(--ink);color:var(--paper)}
.bt:disabled{opacity:.3}
.nr{margin-top:auto;font-size:18px;opacity:.7}

/* 블록 도장(2×2 대각) · 모서리 표지(셋 채움) */
.blk{display:grid;grid-template-columns:1fr 1fr;gap:4px;width:56px;height:56px;flex:none}
.blk b{background:currentColor}
.blk b:nth-child(2),.blk b:nth-child(3){background:transparent}
.blk.cm{position:absolute;top:22px;right:22px;width:36px;height:36px}
.blk.cm b:nth-child(3){background:currentColor}
.blk.big{width:96px;height:96px}
.blk.l{color:var(--lemon)}

/* --- 1. 표지: 큰 종이 판(단원 + 학습 목표 h1, 핵심 낱말 = mark) | 잉크 흐름 칩 · 레몬 차시 숫자 · QR · 잉크 학교 --- */
.hero{padding:36px 44px}
.unit{margin-top:22px;display:flex;align-items:baseline;gap:28px;font-size:64px;line-height:1.1;white-space:nowrap}
.unit span{font:700 44px/1 'Space Grotesk',sans-serif;letter-spacing:-.01em;text-transform:uppercase;opacity:.55}
.gl{margin-top:auto}
.t1{margin-top:14px;font-size:118px;line-height:1.16;white-space:nowrap}
.t1 mark{padding:0 10px}
.lp{padding-bottom:96px}
.chips{margin-top:auto;display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px}
.chips span{font-size:44px;line-height:1.15}
.chips i{font:700 34px/1 'Space Grotesk',sans-serif;font-style:normal}
.sec{margin-top:auto;font:700 250px/.85 'Space Grotesk',sans-serif;letter-spacing:-.05em}
.qr{display:grid;grid-template-columns:repeat(5,1fr);gap:4px;width:150px;height:150px}
.qr b{background:transparent}.qr b.k{background:var(--ink)}.qr b.l{background:var(--lemon);outline:1.5px solid var(--ink);outline-offset:-1.5px}
.p .qr+.lab{margin-top:auto}
.sch{margin-top:auto}
.ch3{display:block;margin-top:8px;font-size:40px;line-height:1.15}

/* --- 2. 만들기: 제목 판(mark) + 레몬 조작 판 | 종이 그림 판(측정기) + 종이 단계 판(지금 단계 = 레몬 띠, 64px 화살표) + 잉크 메모 띠 --- */
.title{margin-top:auto;font-size:76px;line-height:1.12}
.ctl{padding:24px 32px}
.btns{display:flex;gap:12px}
.cap{margin-top:14px;font-size:28px;line-height:1.35;font-weight:500}
.fig{padding:24px 32px 96px;
  --g-ink:var(--ink);--g-acc:var(--ink);--g-stick:var(--ink);--g-board:var(--bg);--g-ruler:var(--lemon);--g-prot:rgba(10,10,10,.04);--g-shadow:#8A8A85;--g-font:'Space Grotesk',var(--kb),sans-serif;--g-sw:2.5;--g-dim:.15}
.fig .gauge{width:860px;margin:4px auto 0}
.def{font-size:28px;line-height:1.4}
.def b{font-weight:700}
.steps{padding:12px 32px;justify-content:space-around}
.st{display:grid;grid-template-columns:96px 1fr 64px;align-items:center;gap:14px;padding:10px 12px;margin:0 -12px;transition:background .2s,opacity .2s}
.st .sn{font:700 64px/.9 'Space Grotesk',sans-serif;letter-spacing:-.03em}
.st h3{font-size:40px;line-height:1.1}
.st p{margin-top:6px;font-size:23px;line-height:1.4}
.st .arw{width:40px;height:40px;transform:rotate(90deg);justify-self:end}
.slide[data-step]:not([data-step="0"]) .st:not(.on){opacity:.3}
.st.now{background:var(--lemon)}
.note{justify-content:center;padding:0 32px}
.note p{font-family:'Space Grotesk',var(--kt),sans-serif;font-weight:var(--wt);font-size:34px;line-height:1.2}

/* --- 3. 숫자와 그래프: 제목 판 + 레몬 큰 숫자 | 통계 판 4개 | 막대 한 쌍(잉크 / 레몬 + 테두리, 2px 축) + 기온 표(잉크 머리줄) --- */
.stat{margin-top:auto;font:700 150px/.9 'Space Grotesk',sans-serif;letter-spacing:-.03em}
.p .stat+.lab{margin-top:10px}
.sc{padding:22px 28px}
.sv{margin-top:auto;font-size:72px;line-height:1}
.sc p{margin-top:8px;font-size:24px;line-height:1.3}
.chart{padding:22px 32px 64px}
.srcl{margin-top:6px;font-size:17px;letter-spacing:.02em;opacity:.6;text-transform:none}
.lg{display:flex;align-items:center;gap:30px}
.lg .src{margin-left:auto;opacity:.6}
.sw{display:inline-block;width:20px;height:20px;margin-right:10px;vertical-align:-3px}
.sw.a{background:var(--ink)}.sw.b{background:var(--lemon);outline:1.5px solid var(--ink);outline-offset:-1.5px}
.plot{flex:1;display:grid;grid-template-columns:repeat(7,1fr);gap:22px;padding:30px 20px 0;margin-top:10px;border-left:2px solid var(--ink);border-bottom:2px solid var(--ink)}
.pair{height:100%;display:flex;align-items:flex-end;gap:6px}
.bar{position:relative;flex:1;display:block}
.bar.a{background:var(--ink)}
.bar.b{background:var(--lemon);outline:1.5px solid var(--ink);outline-offset:-1.5px}
.bar span{position:absolute;left:50%;bottom:100%;transform:translateX(-50%);margin-bottom:4px;font:400 19px/1 'JetBrains Mono',monospace;color:var(--ink)}
.xl{display:grid;grid-template-columns:repeat(7,1fr);gap:22px;padding:10px 20px 0 22px}
.xl span{text-align:center;font:700 26px/1 'Space Grotesk',sans-serif}
.tblp{padding:0}
.tbl{width:100%;height:100%;display:flex;flex-direction:column}
.tr{flex:1;display:grid;align-items:center;border-bottom:1.5px solid var(--ink)}
.tr>span{height:100%;display:flex;align-items:center;padding:0 20px;border-right:1.5px solid var(--ink);font-size:26px}
.tr>span:last-child{border-right:0}
.tr.th{flex:none;background:var(--ink);color:var(--paper)}
.tr.th>span{padding:12px 20px;font:400 20px/1.2 'JetBrains Mono',var(--kb),monospace;letter-spacing:.12em;text-transform:uppercase;border-color:var(--paper)}
.t3 .tr{grid-template-columns:1fr 1fr}
.t3 .tr>span:first-child{font-weight:700}
.t3 .tr.hi{background:var(--lemon)}
.tr:last-child{border-bottom:0}

/* --- 4. 비교와 표: 제목 판 + 잉크 인용 판(레몬 도장) | 레몬 A · 종이 B 판(화살표 줄) + 비교 표(YES/PART 알약) | 종이 남중 판 --- */
.qt{padding:32px 36px}
.qt p{margin-top:auto;font-size:44px;line-height:1.25}
.qt .lab{margin-top:18px}
.cp h3{margin-top:auto;font-size:44px;line-height:1.15}
.it{display:grid;grid-template-columns:40px 1fr;align-items:center;gap:12px;margin-top:10px;font-size:28px;line-height:1.35}
.it .arw{width:32px;height:32px}
.t4p{padding-bottom:64px}
.t4 .tr{grid-template-columns:1.1fr 1fr 1fr 1fr}
.t4 .tr>span:first-child{font-family:'Space Grotesk',var(--kt),sans-serif;font-weight:var(--wt)}
.t4 .pill{font-size:21px;letter-spacing:.02em}
.lst .lab{margin-bottom:auto}

/* --- 5. 확인하기: 제목 판 + 레몬 낱말 판 | 잉크 질문 판 + 종이 보기 판(PICK → YES/NO 알약) | 종이 빈칸 판(PART 알약 → 열면 YES) --- */
.wd .chips span{font-size:36px}
.quiz{display:grid;grid-template-rows:2fr 4fr;gap:12px}
.qh h3{margin-top:auto;font-size:54px;line-height:1.15}
.qb{padding:6px 32px 96px}
.opt{display:grid;grid-template-columns:70px 1fr auto;align-items:center;text-align:left;padding:16px 0;border-bottom:1.5px solid var(--ink);gap:12px}
.opt .ot{font-size:36px;font-weight:500}
.pk::after{content:'PICK'}
.opt.right .pk{background:var(--lemon)}
.opt.right .pk::after{content:'YES'}
.opt.right .ot{background:var(--lemon);padding:0 8px;margin-left:-8px;justify-self:start}
.opt.wrong .pk{background:var(--ink);color:var(--paper)}
.opt.wrong .pk::after{content:'NO'}
.opt:disabled:not(.right){opacity:.4}
.fb{margin-top:14px;font-size:27px;line-height:1.4;font-weight:500}
.rty{position:absolute;right:32px;bottom:24px}
.blk5{padding:28px 32px 24px}
.br{display:grid;grid-template-columns:90px 1fr;align-items:center;padding:20px 0;border-bottom:1.5px solid var(--ink);font-size:30px;line-height:1.55}
.br:first-of-type{margin-top:16px;border-top:1.5px solid var(--ink)}
.br .sn{font:700 56px/.9 'Space Grotesk',sans-serif;letter-spacing:-.03em}
.blank{position:relative;min-width:180px;margin-right:10px;padding:4px 14px;border:1.5px solid var(--ink);background:var(--paper);font:500 28px/1.3 'Space Grotesk',var(--kb),sans-serif;color:var(--ink);text-align:center}
.blank span{visibility:hidden}
.blank::after{content:'PART ?';position:absolute;left:0;right:0;top:6px;font:400 22px/1.3 'JetBrains Mono',monospace;letter-spacing:.08em}
.blank.open{background:var(--lemon)}
.blank.open span{visibility:visible}
.blank.open::after{content:none}

/* --- 쪽번호 태그(왼쪽 아래, 판 위에 겹침) + 사각 화살표 --- */
.dk-nav{position:absolute;left:40px;bottom:40px;display:flex;z-index:60}
.dk-count{background:var(--paper);color:var(--ink);padding:14px 22px;font:400 24px/1 'JetBrains Mono',monospace;letter-spacing:.04em}
.dk-prev,.dk-next{width:52px;background:var(--ink);color:var(--paper);font:700 24px/1 'JetBrains Mono',monospace;border-left:1px solid #333}
.dk-prev:disabled,.dk-next:disabled{color:#555}
[data-slide="2"] .dk-count,[data-slide="4"] .dk-count{background:var(--lemon)}
/* --- 6. 디자인 안내: 격자 판 설명 넷 | 세로 시연 판 3개 --- */
.i6{padding:24px 30px;gap:10px}
.i6 p{font-size:27px;line-height:1.5}
.i6 em{font-style:normal;background:var(--lemon);color:var(--ink);padding:0 6px}
.f6 p{font-size:25px}
.sw6{display:flex;flex-direction:column;gap:10px;font-size:25px}
.sw6 i{display:inline-block;width:28px;height:28px;margin-right:10px;vertical-align:-6px;border:1.5px solid var(--ink)}
.d6{padding:16px 24px;gap:8px}
.d6 .dh{display:flex;justify-content:space-between;align-items:center;gap:12px}
.d6 h3{font-size:30px}
.bt.sm{font-size:18px;padding:6px 12px;border-width:1.5px}
.bt.sm[aria-pressed="true"]{background:var(--lemon)}
.m6{margin-top:auto;font-family:'Space Grotesk',var(--kt),sans-serif;font-weight:var(--wt);font-size:40px}
.m6 span{padding:0 8px}
.m6.play span{background:var(--lemon)}
.pr6{margin-top:auto;height:60px;display:flex;align-items:flex-end;gap:30px;border-left:2px solid var(--ink);border-bottom:2px solid var(--ink);padding-left:16px}
.pr6 span{display:flex;align-items:flex-end;gap:4px}
.pr6 i{width:26px;display:block}
.pr6 .a{background:var(--ink)}
.pr6 .b{background:var(--lemon);outline:1.5px solid var(--ink);outline-offset:-1.5px;visibility:hidden}
.pr6.play .b{visibility:visible}
.pl6{margin-top:auto;display:flex;gap:12px}
.pl6 .pill{background:var(--paper)}
.pl6.play .pill:nth-child(1){background:var(--lemon)}.pl6.play .pill:nth-child(3){background:var(--ink);color:var(--paper)}
[data-slide="6"] .dk-count{background:var(--lemon)}

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