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

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

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

## 라이선스

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

- 물마루: 물마루 — 물마루 (Mulmaru) — Mushsooni / 눈누: https://noonnu.cc/font_page/1763
  파일: Mulmaru.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/retro-windows.css">`(head 안)와 `<script src="https://k-slide.web.app/kit/v1/retro-windows.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. **글씨체는 바꾸지 마세요.** 한글 글씨체(제목 물마루(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. 디자인 규칙 (`retro-windows` design.md)

````markdown
---
version: alpha
name: Retro Windows
description: A Windows 95 / 98 desktop-OS aesthetic rendered as a presentation system. Every slide is a window — beveled chrome, navy gradient title bar, MS Sans Serif body type, with chart areas, group boxes, and panels arranged as if they were software UI from 1995. The palette is the original Win9x system colors (gray button-face, navy title bars, white sunken inputs) with retro accent hues (DOS green, brick red, mustard yellow, teal cyan) reserved for status text and chart data. Pixel-font (Press Start 2P) and terminal-font (VT323) appear sparingly for nostalgic punctuation. The effect is half playful nostalgia, half functional dashboard — a deck that reads as a software product running on a CRT monitor.

colors:
  bg-gray: "#c0c0c0"
  bg-light: "#d4d0c8"
  bg-dark: "#808080"
  white: "#ffffff"
  black: "#000000"
  text-dark: "#222222"
  blue-navy: "#000080"
  blue-bright: "#0000a0"
  blue-light: "#1084d0"
  green-retro: "#008000"
  red-retro: "#800000"
  yellow-retro: "#808000"
  cyan-retro: "#008080"
  text-gray: "#555555"

color-aliases:
  btn-face: bg-light
  btn-highlight: white
  btn-shadow: "#404040"
  btn-dark-shadow: black

typography:
  body:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.5
  text-xl:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 32px
    fontWeight: 700
    lineHeight: 1.2
  text-lg:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 22px
    fontWeight: 700
    lineHeight: 1.3
  text-md:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.6
  text-sm:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.5
  text-xs:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 12px
    fontWeight: 400
    lineHeight: 1.4
  metric-xl:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 30px
    fontWeight: 700
    lineHeight: 1.1
  title-bar:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 14px
    fontWeight: 700
    lineHeight: 1.0
    letterSpacing: 0.5px
  group-box-title:
    fontFamily: "MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif"
    fontSize: 13px
    fontWeight: 700
    lineHeight: 1.0
  pixel-display:
    fontFamily: "'Press Start 2P', cursive"
    fontSize: "20–24px"
    fontWeight: 400
    lineHeight: 1.8
  terminal:
    fontFamily: "'VT323', monospace"
    fontSize: 22px
    fontWeight: 400
    lineHeight: 1.2
  nav-hint:
    fontFamily: "'VT323', monospace"
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.0

spacing:
  slide-pad: "24px 32px 44px 32px"
  win-body-pad: "20px 24px 24px 24px"
  panel-pad: 16px
  group-box-pad: "20px 18px 16px 18px"
  panel-sunken-pad: 12px
  gap-1: 6px
  gap-2: 10px
  gap-3: 16px
  gap-4: 24px

canvas:
  width: 100vw
  height: 100vh

components:
  crt-overlay:
    backgroundImage: "repeating-linear-gradient(0deg, rgba(0,0,0,0.03) 0px, rgba(0,0,0,0.03) 1px, transparent 1px, transparent 3px)"
    zIndex: 9999
    description: "Fixed, full-viewport scanline overlay at 3% black opacity that sits above all content. Imitates the horizontal phosphor lines of a CRT monitor. Pointer-events disabled."
  win-window:
    background: "{colors.bg-light}"
    border: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    boxShadow: "inset 1px 1px 0 {colors.white}, inset -1px -1px 0 #404040"
    description: "The signature framing element. Every slide is one (or more) win-window. The asymmetric border + double inset shadow creates the Win9x beveled raised effect — top-left highlighted, bottom-right shadowed."
  win-titlebar:
    background: "linear-gradient(90deg, {colors.blue-navy} 0%, {colors.blue-bright} 100%)"
    color: "{colors.white}"
    padding: "4px 8px"
    fontSize: 14px
    fontWeight: 700
    description: "Navy-blue gradient bar at the top of every window. Contains a left lockup (icon + filename in caps) and a right cluster of three minimize/maximize/close buttons (_, [], X)."
  win-titlebar-inactive:
    background: "linear-gradient(90deg, #808080 0%, #a0a0a0 100%)"
    description: "Grayed-out title bar variant for inactive/secondary windows (used when a slide contains multiple stacked windows representing different states)."
  win-btn:
    width: 20px
    height: 18px
    background: "{colors.bg-light}"
    border: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    description: "Beveled-raised mini button used inside the title bar (_, [], X) and elsewhere. Active state inverts the bevel."
  btn-retro:
    background: "{colors.bg-light}"
    border: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    padding: "6px 24px"
    fontSize: 14px
    description: "Standard Win9x command button. Beveled raised; active state inverts the bevel so the button appears pressed in."
  group-box:
    border: "2px solid #404040 (top/left) + 2px solid {colors.white} (right/bottom)"
    padding: "20px 18px 16px 18px"
    background: "{colors.bg-light}"
    description: "Sunken-bevel framed container with a title label that breaks the top border (the title sits in a small background-painted notch at top-left). The Win9x equivalent of a fieldset/legend."
  group-box-title:
    position: absolute
    top: -10px
    left: 12px
    background: "{colors.bg-light}"
    padding: "0 8px"
    fontSize: 13px
    fontWeight: 700
    description: "The title label that sits on top of a group-box's upper border, painted with the parent background to mask the border behind it."
  panel-raised:
    background: "{colors.bg-light}"
    border: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    padding: 16px
    description: "Raised-bevel panel. Used for tool palettes, button strips, and elevated content regions inside a window body."
  panel-sunken:
    background: "{colors.white}"
    border: "2px solid #404040 (top/left) + 2px solid {colors.white} (right/bottom)"
    padding: 12px
    description: "Sunken-bevel panel with a white interior. Used for text input fields, read-only data displays, and status regions. The white interior is the system's signal for 'this is content, not chrome.'"
  progress-bar:
    width: "100%"
    height: 24px
    background: "{colors.white}"
    border: "2px solid #404040 (top/left) + 2px solid {colors.white} (right/bottom)"
    padding: 2px
    description: "Sunken white well containing a solid navy fill div whose width represents the data value. The fill is `{colors.blue-navy}` solid — no gradient, no animation beyond width transition."
  retro-list:
    listStyle: none
    marker: "> (chevron)"
    markerColor: "{colors.blue-navy}"
    description: "Custom-bullet list where each item is prefixed with a navy '>' character. The chevron is set via ::before, never via list-style."
  retro-check:
    checkBoxSize: "16px"
    checkBoxBorder: "2px solid {colors.black} (top/left) + 2px solid {colors.white} (right/bottom)"
    checkMarker: "x"
    description: "Sunken white square checkbox with a literal lowercase 'x' character as the checked-state marker. Inset-beveled the opposite direction from buttons."
  retro-table:
    borderCollapse: collapse
    fontSize: 14px
    headerBackground: "{colors.bg-gray}"
    headerBorder: "1px solid #404040"
    cellBackground: "{colors.white}"
    cellBorder: "1px solid {colors.bg-gray}"
    zebraRowBackground: "#f0f0f0"
    description: "Pixel-flat data table with gray headers, white cells, light-gray border lines, and a barely-different zebra fill on alternate rows."
  marquee:
    background: "{colors.white}"
    border: "1px inset {colors.bg-gray}"
    padding: "3px 0"
    animation: "marquee 14s linear infinite"
    description: "Scrolling text inside a sunken white well. The animation translates the text from 100% right to -100% left over 14 seconds. The original Win marquee element re-implemented in CSS."
  win-icon:
    width: 18px
    height: 18px
    background: "{colors.white}"
    border: "1px solid {colors.black}"
    fontSize: 11px
    color: "{colors.blue-navy}"
    fontWeight: 700
    description: "Tiny 18px square icon next to a title-bar filename — a navy-on-white letter glyph that imitates an application icon. The glyph is a 1-character mnemonic of the window's role (P for Presentation, R for README, D for Dataview, etc.)."
  tree-item:
    fontSize: 14px
    indent: "24px per level"
    folderGlyph: "📁 (U+1F4C1)"
    fileGlyph: "📄 (U+1F4C4)"
    expandedMarker: "-"
    collapsedMarker: "+"
    description: "Explorer-style hierarchical tree view. Each row carries an expand marker (+/−), a folder or file emoji glyph, and the label text. Indentation steps by 24px per nesting level."
  separator-vertical:
    width: 2px
    background: "#404040"
    borderLeft: "1px solid {colors.white}"
    margin: "0 12px"
    description: "Beveled vertical separator between inline elements — the Win9x equivalent of a vertical rule."
  hr-retro:
    borderTop: "1px solid #404040"
    borderBottom: "1px solid {colors.white}"
    margin: "14px 0"
    description: "Beveled horizontal rule. Two stacked 1px lines (dark on top, white on bottom) create the engraved-in look."
  nav-dot:
    width: 12px
    height: 12px
    background: "{colors.bg-gray}"
    border: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    activeBackground: "{colors.blue-navy}"
    description: "Beveled square mini-dot used as a slide-indicator chip. Active state fills navy with a 4px white center square."
  chart-canvas-host:
    background: "{colors.bg-light}"
    description: "Chart.js canvas embedded inside a panel-raised. Chart colors use {colors.blue-navy}, {colors.blue-bright}, {colors.blue-light}, {colors.green-retro}, {colors.cyan-retro}, {colors.yellow-retro}. Axis labels use MS Sans Serif at 11–12px in {colors.text-dark}. Gridlines in {colors.bg-gray}."
  scrollbar:
    width: 16px
    trackBackground: "{colors.bg-gray}"
    thumbBackground: "{colors.bg-gray}"
    thumbBorder: "2px solid {colors.white} (top/left) + 2px solid {colors.black} (right/bottom)"
    description: "Custom webkit scrollbar styled as a beveled-raised gray thumb on a flat gray track. Width is fixed 16px to match Win9x default."
---

## Frontend Slides Fixed-Stage Policy

When this design system is used by the `frontend-slides` skill, generate the final deck as a **fixed 1920×1080 stage** that scales uniformly to the browser viewport. The deck should preserve a 16:9 slide canvas on every screen, including phones; it may letterbox or pillarbox, but it should not reflow slide content for mobile.

This policy has higher priority than any source-template responsive behavior described later in this file. If a later section says the original template is viewport-fluid, treat that as source history only, not as the target generation model for `frontend-slides`.

This policy applies even if the source template was originally implemented with viewport-fluid CSS such as `100vw`, `100vh`, `vw`, `vh`, or `clamp()`. Treat those values as design proportions to translate into 1920×1080 stage coordinates, not as live responsive rules in the generated deck.

Use `deck-stage.js` or an equivalent inline stage scaler for final output: render each slide at 1920×1080, scale the whole stage with one transform, and verify rendered screenshots for both text overflow and panel overlap.


## Overview

Retro Windows is a **Windows 95 / 98 desktop-OS aesthetic** rendered as a slide template. Every slide is structured as a `win-window` — a beveled rectangular chrome with a navy-gradient title bar, three button icons in the upper right (`_`, `[]`, `X`), and a body region containing application-style content. The composition is "this slide is software running on a 1995 desktop, and the content is what the software displays." The conceit is total: there are no slide titles in the modern presentation sense, only window titles styled as filenames (`README.DOC`, `DATAVIEW.CSV`, `METRICS.LOG`).

The typeface stack is **MS Sans Serif** (and its modern fallbacks Segoe UI / Tahoma / Verdana) as the system font for nearly all content, with **Press Start 2P** (an 8-bit pixel display face) and **VT323** (a chunky CRT terminal monospace) reserved for nostalgic punctuation — splash-screen headings, navigation hints, marquee text. The body face is small by modern standards (16px default, with most working text at 14px) which is part of the OS-UI aesthetic: software UI of the era ran at fixed pixel sizes, and the deck inherits that constraint.

The palette is the **original Win9x system color set**: button-face gray (`{colors.bg-light}` #d4d0c8), highlight white, shadow dark-gray, and a navy/blue gradient (`{colors.blue-navy}` → `{colors.blue-bright}`) reserved for active title bars and primary data fills. A second cluster of "retro accent" hues — DOS green (#008000), brick red (#800000), mustard yellow (#808000), teal cyan (#008080) — is the system's status palette: green for OK / success / live, red for warnings, yellow for "moderate" risk, cyan for tertiary chart data. Charts pull from this status palette plus the navy ladder. There are no modern saturated hues.

Depth is achieved through **bevel illusions** — every surface is either raised (highlight on top-left, shadow on bottom-right) or sunken (the inverse). The system uses no blurred drop-shadows; instead, two-tone asymmetric borders plus inset box-shadows create the illusion of bevels. This is the foundational depth grammar: buttons are raised, text inputs are sunken, group-boxes are sunken with a notch-mounted title, the active button-press state inverts the bevel.

**Density philosophy: high.** Win9x application UIs were dense — every pixel served a purpose, group-boxes were packed with controls, status bars carried multiple readouts, dialogs were tightly composed. The deck aesthetic depends on that density. A slide with one centered headline and lots of empty space reads as broken or unfinished. The correct density is the window body packed with stacked panels, group-boxes, tables, charts, button strips, and status footers — every slide should feel like an application screen with multiple regions doing concurrent work. The CRT scanline overlay reinforces this: the texture only reads when there is dense content underneath it.

**Key Characteristics:**
- Every slide is a `{components.win-window}` — beveled chrome with navy-gradient title bar and three system buttons (`_`, `[]`, `X`).
- A fixed 3px-period CRT scanline overlay (`{components.crt-overlay}`) sits above all content at 3% opacity.
- Bevel-based depth: raised (`{components.panel-raised}`, `{components.btn-retro}`) and sunken (`{components.panel-sunken}`, `{components.group-box}`) — no blurred shadows.
- The font stack is MS Sans Serif / Segoe UI / Tahoma fallback, with Press Start 2P and VT323 as nostalgic accents.
- Status colors (green / red / yellow / cyan) carry semantic meaning: green = OK, red = warning, yellow = moderate, cyan = tertiary data.
- Navy `{colors.blue-navy}` is the primary data color — progress bars, chart bars, key headlines, active nav dots.
- Lists use a navy `>` chevron prefix; checkboxes use a literal `x` character; tree views use `📁` / `📄` emoji glyphs.
- Window title text reads as filenames in uppercase with extensions (`AGENDA.TXT`, `METRICS.LOG`, `EXPLORER.EXE`).

## Colors

### Palette
- **Button Face Light** (`{colors.bg-light}` — #d4d0c8): The base chrome color for windows, panels, group boxes, buttons. The Win9x "3D Objects" system color. Slightly warm gray. The default fill for any non-content region.
- **Background Gray** (`{colors.bg-gray}` — #c0c0c0): Slightly darker gray. Used for table headers, scrollbar tracks, nav-dot inactive fills. The "Gray Background" system color.
- **Background Dark** (`{colors.bg-dark}` — #808080): Dark gray for desktop fills outside windows and for inactive title bar starts. The "Inactive Title Bar" color.
- **White** (`{colors.white}` — #ffffff): The content fill — used inside sunken panels, text inputs, table cells, progress bar wells, and as the title-bar text color. White signals "this is content, not chrome."
- **Black** (`{colors.black}` — #000000): The deepest shadow color in bevel borders and the strongest text color. Also used as button border for raised-bevel right/bottom edges.
- **Text Dark** (`{colors.text-dark}` — #222222): The default body text color. Slightly softer than pure black so body type doesn't compete with the bevel-dark shadow.
- **Text Gray** (`{colors.text-gray}` — #555555): A muted gray for secondary text, captions, and status hints.
- **Navy** (`{colors.blue-navy}` — #000080): The primary brand color — title bar starts, chart bars, progress fills, headline text, active nav dots, retro-list chevron markers. The system's "primary" color.
- **Blue Bright** (`{colors.blue-bright}` — #0000a0): Title bar gradient end. Slightly brighter and bluer than navy. Used as the second chart-bar variant.
- **Blue Light** (`{colors.blue-light}` — #1084d0): A lighter blue used as a tertiary chart-bar variant.
- **Green Retro** (`{colors.green-retro}` — #008000): DOS green. Reserved for OK status, success messages, growth percentages, "READY" / "LIVE" badges, "On Track" labels.
- **Red Retro** (`{colors.red-retro}` — #800000): Brick red. Reserved for error/warning text and the brick-red status family.
- **Yellow Retro** (`{colors.yellow-retro}` — #808000): Mustard yellow. Reserved for "moderate" risk labels and warning chart segments.
- **Cyan Retro** (`{colors.cyan-retro}` — #008080): Teal cyan. Reserved for tertiary chart segments and secondary status accents.

### Defaults
- **Default surface background**: `{colors.bg-dark}` for the desktop region behind a window, `{colors.bg-light}` for the window body.
- **Default headline / primary text color**: `{colors.blue-navy}`. Headlines in this system are navy, not black — that is the dashboard / application-title voice.
- **Default body text color**: `{colors.text-dark}` (#222222), not pure black.
- **Default secondary / caption text color**: `{colors.text-gray}` (#555555).
- **Default chart primary color**: `{colors.blue-navy}`. Secondary bars use `{colors.blue-bright}` and `{colors.blue-light}` first; categorical-segment charts then pull `{colors.green-retro}`, `{colors.cyan-retro}`, `{colors.yellow-retro}`.
- **Default progress-bar fill color**: `{colors.blue-navy}` (solid, no gradient).
- **Default status-OK color**: `{colors.green-retro}` — used on `READY`, `LIVE`, `Approved`, growth percentages, and any "things are good" badge.
- **Default status-warning color**: `{colors.red-retro}` or `{colors.yellow-retro}` — red for hard errors, yellow for moderate concerns.
- **Default title-bar background**: navy → blue-bright horizontal gradient on active windows; gray (`{colors.bg-dark}` → `#a0a0a0`) on inactive windows when the slide stacks multiple windows.
- **Default text color inside a navy title bar**: `{colors.white}` — always white-on-navy in title bars.
- **Default text color inside a sunken white panel**: `{colors.text-dark}` — dark-on-white for content text.

The accent palette (green / red / yellow / cyan) has fixed semantic meanings — do not use green for arbitrary decoration, do not use red for non-warning text. The accents are status signals, not paint.

## Typography

### Font Family
The system has three faces, each with a distinct role:

- **MS Sans Serif / Segoe UI / Tahoma / Geneva / Verdana stack** (system body): The default for nearly all text. The fallback chain works on any OS — macOS lands on Geneva or Verdana, Windows lands on Segoe UI or MS Sans Serif, Linux lands on a sans-serif fallback. The aesthetic is "what software UI looked like in 1995," and the system font stack is critical to that — never substitute a custom display sans.
- **Press Start 2P** (pixel display): An 8-bit pixel display face used sparingly. Reserved for splash-screen titles, the closing slide's send-off message, and any oversized nostalgic title moment. Always rendered in `{colors.blue-navy}`, always center-aligned. Use it once or twice per deck, not on every slide.
- **VT323** (CRT terminal monospace): A chunky monospace face that imitates a CRT terminal. Reserved for the bottom-edge navigation hint (`<-- ARROW KEYS to navigate -->`) and any "terminal output" body region. Optional — the deck functions without it.

Italic is not used. Underline is not used (interactive links can be underlined but no decorative underlining). Emphasis is achieved by weight (400 → 700) and by switching color (default → navy or default → green/red).

### Type Scale

| Token | Size | Family | Weight | Use |
|---|---|---|---|---|
| `{typography.text-xl}` | 32px | MS Sans Serif | 700 | Primary slide headline inside a window body |
| `{typography.metric-xl}` | 30px | MS Sans Serif | 700 | Hero metric value in a KPI tile |
| `{typography.text-lg}` | 22px | MS Sans Serif | 700 | Section heading / subheading inside a window body |
| `{typography.text-md}` | 18px | MS Sans Serif | 400 | Standard body paragraph |
| `{typography.body}` | 16px | MS Sans Serif | 400 | Default working body |
| `{typography.text-sm}` | 14px | MS Sans Serif | 400 | Captions, list items, button labels, table cells |
| `{typography.text-xs}` | 12px | MS Sans Serif | 400 | Fine print, status hints, slide counter |
| `{typography.title-bar}` | 14px | MS Sans Serif | 700 | Window title bar filename — always uppercase |
| `{typography.group-box-title}` | 13px | MS Sans Serif | 700 | Notch-mounted group-box title label |
| `{typography.pixel-display}` | 20–24px | Press Start 2P | 400 | Nostalgic splash-screen or closing display title |
| `{typography.terminal}` | 22px | VT323 | 400 | Terminal-style body or marquee text |
| `{typography.nav-hint}` | 16px | VT323 | 400 | Bottom-edge keyboard hint text |

### Defaults
- **Default size for a primary slide headline (inside window body)**: `{typography.text-lg}` (22px) in `{colors.blue-navy}` weight 700 — the application-title voice. For an oversized hero headline use `{typography.text-xl}` (32px).
- **Default size for a body paragraph**: `{typography.text-md}` (18px) for prose paragraphs; `{typography.text-sm}` (14px) for working text and list rows.
- **Default size for a window title bar filename**: `{typography.title-bar}` (14px weight 700), always uppercase, always in `{colors.white}`.
- **Default size for a metric or hero number**: `{typography.metric-xl}` (30px weight 700) in `{colors.blue-navy}`.
- **Default size for a section heading inside a window**: `{typography.text-lg}` (22px weight 700) in `{colors.blue-navy}`.
- **Default size for any caption, fine print, or status hint**: `{typography.text-xs}` (12px) in `{colors.text-gray}`.
- **Default weight for any headline or label that should command attention**: 700.
- **Default weight for body text**: 400.

When a slide carries multiple stacked windows or panels, the primary slide message goes inside the first window's body at `{typography.text-lg}`-weight-700-navy. Do not reach for a larger size unless it's an explicit hero / splash moment.

### Signature Treatments
These treatments are **non-optional whenever the corresponding element type is used**:

- **Every window title bar text is uppercase and styled as a filename** (with extension): `PRESENTATION.EXE`, `README.DOC`, `METRICS.LOG`, `AGENDA.TXT`, `DATAVIEW.CSV`, `FEATURES.INI`, `EXPLORER.EXE`, `TIMELINE.PRJ`. The filename convention is part of the aesthetic — never use modern title-case window names.
- **Every title bar carries the three-button cluster** (`_` minimize, `[]` maximize, `X` close) in the top-right. The buttons are decorative, not interactive, but they must always be present.
- **Every title bar carries a `{components.win-icon}` lockup** on the left — an 18px white-with-black-border square containing a single navy letter that mnemonically identifies the window (P, A, R, D, F, G, M, E, T).
- **Every window uses the beveled-raised chrome treatment** (white top/left + black bottom/right border + double inset shadow). Removing the bevel breaks the Windows aesthetic entirely.
- **Every body headline inside a window is `{colors.blue-navy}` weight 700.** Navy is the application-title voice; black headlines read as "wrong era."
- **Status text uses the assigned status color** with weight 700: green for OK/success/growth, red for errors, yellow for moderate. A green status word at default weight reads as incidental rather than as a label.
- **Group-box titles sit in a 0–8px-padded notch over the upper border.** The title's background is painted in `{colors.bg-light}` (the parent fill) to mask the border behind it — never let the border run through the title.

### Typography Principles
The aesthetic depends on **fixed pixel sizes**, not fluid type. The system was designed for the Win9x 96-DPI rendering environment, and the deck preserves that feel by using integer pixel font-sizes (12, 13, 14, 16, 18, 22, 30, 32). Avoid `rem`/`em`/`clamp` for body type — the OS-UI illusion breaks at sub-pixel rendered sizes.

The pixel-font (Press Start 2P) and terminal-font (VT323) are nostalgic accents, not workhorses. Using Press Start 2P for body text becomes illegible quickly; using VT323 for headlines reads as overproduced. Reserve each for one or two moments per deck.

## Layout

### Canvas System
The system targets `100vw × 100vh` with each slide positioned `position: fixed; top: 0; left: 0`. Only the `.active` slide is `display: flex`; others are `display: none`. Inside each slide, a single `{components.win-window}` (or a few stacked windows) provides the framing chrome. The window is `max-width: 1200px` and `max-height: calc(100vh - 68px)` so the desktop gray border is always visible around the chrome.

Slide outer padding is `24px 32px 44px 32px` — the extra bottom padding clears the persistent navigation chrome (nav-dots and slide-counter at the viewport's bottom edge).

### Window Anatomy
Every window has three regions stacked vertically:
1. **Title bar** (`{components.win-titlebar}`) — fixed 4px-8px padding, navy gradient, contains left icon-lockup + filename and right three-button cluster.
2. **Body** (`{components.win-body}`) — 20px 24px 24px 24px padding, fills remaining height, contains the slide's content composition.
3. **Optional status panel** at the body's bottom — a `{components.panel-raised}` or `{components.panel-sunken}` strip carrying meta info (data source, last updated, count, status badge).

A slide may contain multiple windows side-by-side (typically for timeline quarters or multi-screen comparisons). When multiple windows appear, only one carries the active navy title bar; the others carry the inactive gray gradient.

### Padding Scale
| Token | Value | Use |
|---|---|---|
| `{spacing.slide-pad}` | 24px 32px 44px 32px | Outer slide padding |
| `{spacing.win-body-pad}` | 20px 24px 24px 24px | Inside a window body |
| `{spacing.group-box-pad}` | 20px 18px 16px 18px | Inside a group-box (extra top to clear notched title) |
| `{spacing.panel-pad}` | 16px | Inside a raised panel |
| `{spacing.panel-sunken-pad}` | 12px | Inside a sunken white panel |

### Persistent Chrome
Three persistent elements live outside the slide composition:
- **Nav dots** at bottom-center — beveled square indicators, one per slide, with the active one filled navy and carrying a 4px white center square.
- **Slide counter** at bottom-right — sunken-bevel chip with `N / TOTAL` text in 12px.
- **Nav hint** at bottom-left — VT323 16px text reading `<-- ARROW KEYS to navigate -->`.

The CRT scanline overlay sits above everything at z-index 9999 — every slide, every chrome element, every chart canvas is rendered beneath it.

## Depth and Elevation

### Bevel Illusion (Primary Technique)
The system uses **two-tone asymmetric borders** plus **inset box-shadows** to simulate the Windows 95 beveled UI. There are two states:

- **Raised**: 2px solid white on top + left, 2px solid black on right + bottom, plus `inset 1px 1px 0 white, inset -1px -1px 0 #404040`. Reads as a button or panel sitting up off the surface. Used on windows, raised panels, buttons, nav dots.
- **Sunken**: 2px solid `#404040` on top + left, 2px solid white on right + bottom. Reads as a recessed input field or content well. Used on group-boxes, sunken panels, text inputs, progress-bar tracks, checkbox boxes, scrollbar tracks.

The active button press state inverts the bevel — a button that is "pressed in" swaps the highlight/shadow border directions. Hover states are absent; the OS aesthetic predates universal hover affordances.

### No Modern Shadows
The system uses **no blurred `box-shadow` values**, no `drop-shadow` filters, no rgba shadow tints. Every depth cue comes from the bevel-border technique. Adding a soft modern shadow to a window or button breaks the era immediately.

### Color-Block Depth
Beyond the bevels, **white-vs-gray contrast** provides regional depth: white panels visually project as "content / data," gray panels recede as "chrome / structure." A slide's hierarchy emerges naturally from where the white wells sit.

### CRT Scanline Overlay
The system carries one atmospheric layer: the CRT scanline overlay. A 3px-period horizontal repeating gradient at 3% black opacity sits over every slide. The overlay does not add depth, but it adds **texture** — every surface in the deck reads as "rendered on a 1995 CRT monitor" rather than "rendered on a flat screen." Removing the overlay is permissible but loses a meaningful slice of the aesthetic.

## Shapes and Treatment

### Border Radius
The system has **no rounded corners anywhere**. Every box, button, panel, window, table cell, checkbox, nav-dot, progress-bar — strict rectangles. Border-radius is `0` system-wide.

### Border Weights and Styles
- **2px solid** — the universal bevel border weight on windows, panels, buttons, nav-dots. Used in the two-tone asymmetric pattern (white+black or darkgray+white) that creates the bevel illusion.
- **1px solid** — used for thinner element borders (table cell borders, win-icon outline, hr-retro stacked lines).
- **`1px inset`** — used on the marquee container border.

Borders are never colored (no navy borders, no green borders); the bevel two-tone pattern (white + black/darkgray) is the only border vocabulary.

### Decorative Element Types

**Window** (`{components.win-window}`) — The framing primitive. A beveled-raised rectangle with a navy title bar containing icon + filename + three system buttons, and a body region containing the content. Every slide is at least one window.

**Group box** (`{components.group-box}`) — Sunken-bevel container with a notch-mounted title at the upper-left. The title sits in a 0–8px padded background-painted region that masks the border behind it, mimicking the `<fieldset><legend>` pattern of native HTML forms. Used to cluster related controls or content blocks inside a window.

**Raised panel** (`{components.panel-raised}`) — Beveled-raised gray panel. Used for tool palettes, button strips, status footers, and elevated content regions.

**Sunken panel** (`{components.panel-sunken}`) — Beveled-sunken white panel. Used for text inputs, KPI displays, status readouts, and read-only data. White interior is the cue.

**Retro button** (`{components.btn-retro}`) — Beveled-raised gray button with 6px × 24px padding. Always carries text-md (14px) MS Sans Serif weight 400. Active state inverts the bevel.

**Progress bar** (`{components.progress-bar}`) — Sunken white well containing a solid navy fill div. The fill width represents the value; no animation beyond width transition. Always 24px tall (or 16px when embedded inside a feature card).

**Retro table** (`{components.retro-table}`) — Pixel-flat data table with gray headers, white cells, light-gray border lines, and a barely-different zebra fill on alternate rows. Cell padding is 6px × 10px.

**Retro list** (`{components.retro-list}`) — Unstyled list with a navy `>` chevron prefix on each row. The chevron is set via `::before`, never via list-style.

**Retro check** (`{components.retro-check}`) — A 16px sunken-bevel white square containing a literal lowercase `x` character when checked. The bevel is inverted relative to buttons (black on top/left, white on bottom/right).

**Tree view** (`{components.tree-item}`) — Explorer-style hierarchical list. Each row carries an expand marker (+/−), a folder (`📁`) or file (`📄`) emoji glyph, and the label. 24px indentation per nesting level.

**KPI tile (group-box variant)** — A square group-box with a title label (`Revenue`, `Customers`, `Retention`, `NPS Score`), a large 30px navy metric, a green delta line (`▲ +18.3%`), and a 12px gray context line (`vs previous quarter`). Used in 4-up rows for dashboards.

**Marquee** (`{components.marquee}`) — Sunken white well containing horizontally scrolling text. The animation runs 14s linear infinite; pause-on-hover is not implemented. Used on splash and closing slides.

**Win icon** (`{components.win-icon}`) — 18px square white-on-black-bordered miniature with a single navy letter glyph. Used in the title bar as a lockup mark.

**Separator** (vertical or hr-retro) — A beveled rule. Vertical: 2px dark-gray + 1px white-left border, 12px horizontal margin. Horizontal: stacked 1px dark-gray-on-top + 1px white-on-bottom lines, 14px vertical margin.

**Hourglass / sleep glyph** (`⌛` or `💤`) — Used as a single oversized character (40–52px) on splash / closing slides as a nostalgic OS-feel cue.

## Do's and Don'ts

### Do
- Wrap every slide in a `{components.win-window}` with a navy title bar carrying a filename-style title (e.g., `METRICS.LOG`) and the three-button cluster (`_`, `[]`, `X`).
- Use the bevel border technique (white top/left + black bottom/right + inset shadows for raised; the inverse for sunken) on every panel, button, and window. This is the system's identity.
- Set primary headlines in `{colors.blue-navy}` weight 700. Navy is the application-title voice — black headlines read as wrong-era.
- Pack each slide densely. Multiple group boxes, stacked panels, KPI strips, charts, and status footers should all coexist inside one window body. Empty space reads as broken.
- Use the status colors semantically: green for OK / live / growth, red for warnings / errors, yellow for moderate concerns, cyan for tertiary data. Each color carries a meaning — do not redecorate with them.
- Render charts with the navy ladder first (`{colors.blue-navy}`, `{colors.blue-bright}`, `{colors.blue-light}`), then pull from the status palette for categorical-segment differentiation.
- Use the `>` chevron retro-list pattern for bullet lists and the literal-`x` retro-check for checkboxes. Native browser bullets and form controls break the aesthetic.
- Apply integer pixel font sizes (12, 13, 14, 16, 18, 22, 30, 32). The fixed-pixel sizing is part of the OS-UI illusion.
- Keep the CRT scanline overlay (`{components.crt-overlay}`) on every slide. It is the texture that ties the deck to its CRT-monitor metaphor.
- Style window titles as uppercase filenames with extensions (`PRESENTATION.EXE`, `AGENDA.TXT`). Title-case window names break the conceit.

### Don't
- Don't round any corner. Every shape is a strict rectangle. Border-radius is 0 system-wide except for tiny round details inside chart canvases.
- Don't use blurred `box-shadow` or `drop-shadow`. All depth is bevel-based.
- Don't introduce modern brand colors (saturated purples, oranges, magentas). The palette is limited to Win9x system grays, navy, and the four retro accents.
- Don't use color on borders. Border two-tones are white + black or darkgray + white — never navy borders, never green borders.
- Don't use `rem`/`em`/`clamp` for body type sizes. Fixed integer pixel sizes preserve the OS-UI illusion.
- Don't use Press Start 2P or VT323 for body text. They are nostalgic accents — reserved for one or two moments per deck.
- Don't use modern title-case or sentence-case window titles. Window titles are uppercase filenames with extensions.
- Don't leave a window without its three-button cluster (`_`, `[]`, `X`). Even decorative, the cluster is part of every window's signature.
- Don't introduce a hover-state visual change on buttons. The Win9x era predates universal hover; an active-state bevel inversion is the only state change.
- Don't compose a sparse slide with one centered headline and lots of empty space. The system reads as broken when it does not feel like dense application UI.

## Responsive Behavior

The system is **viewport-fluid** but **fixed-pixel**: the window chrome and body sizes flex with the viewport (`max-width: 1200px`, `max-height: calc(100vh - 68px)`), but font-sizes are integer pixels, not clamped. A single media query at `max-width: 900px` reduces slide padding to 15px-20px and collapses 4-column grids to 2-column.

### Scaling Behavior
- The window grows to fill the viewport up to 1200×(100vh-68px), then stops scaling.
- All font-sizes stay fixed: a 14px label is 14px on any screen size.
- The CRT scanline overlay's 3px period is constant regardless of viewport.

### Presenter Behavior
- Slides advance via `ArrowRight`, `ArrowDown`, or `Space`.
- Slides reverse via `ArrowLeft` or `ArrowUp`.
- `Home` jumps to the first slide, `End` to the last.
- Nav dots at the bottom are clickable.
- No touch swipe support is implemented by default.

### Print Behavior
No `@media print` rule is defined. Printing will render the active slide only.

### Chart Rendering
Charts use Chart.js loaded from a CDN. Chart colors map directly to system tokens (`{colors.blue-navy}`, `{colors.blue-bright}`, `{colors.blue-light}`, `{colors.green-retro}`, `{colors.cyan-retro}`, `{colors.yellow-retro}`). Axis labels use MS Sans Serif at 11–12px in `{colors.text-dark}`. Gridlines are 1px `{colors.bg-gray}`. Charts are rendered lazily when their slide becomes active.

## CJK & International Content

### Recommended Chinese Pairing

| Role | Latin | Chinese | Weight mapping |
|---|---|---|---|
| Title-bar / Headlines / Metric / Section heading | MS Sans Serif → Segoe UI (700) | **思源黑体 Noto Sans SC** | 700 |
| Body / Caption / List / Table cell | MS Sans Serif → Segoe UI (400) | **思源黑体 Noto Sans SC** | 400 |
| Pixel display (Press Start 2P) — Latin only | Press Start 2P | *(no CJK substitute)* | n/a |
| Terminal / Nav hint (VT323) — Latin only | VT323 | *(no CJK substitute)* | n/a |

### Mixed-Content Strategy

**Strategy A — single CJK family for all Latin-system roles.** Retro Windows is a system-font deck (MS Sans Serif / Segoe UI / Tahoma). Pairing every Latin role with a single CJK family — Noto Sans SC — preserves the "this is software UI" register: a Win9x application would have rendered its Simplified Chinese localization in a single system CJK face (MS YaHei / SimSun), not in a multi-family display + body pairing. The two nostalgic accent fonts (Press Start 2P, VT323) are Latin-only by design; never attempt a pixel-font CJK substitute — there is no acceptable equivalent that maintains the era.

### Loading

```html
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
```

Then append `'Noto Sans SC'` to the body font stack:
```css
font-family: 'MS Sans Serif', 'Segoe UI', Tahoma, Geneva, Verdana, 'Noto Sans SC', sans-serif;
```

### Universal CJK Adjustments

- Line-height: body 1.75–1.85, display 1.15–1.25
- Letter-spacing: 0 on CJK
- Text-transform: no uppercase on CJK
- Full-width punctuation
- No period on display headlines
- Pangu spacing (盘古之白): `使用 Claude` not `使用Claude`
- One font per sentence

### Aesthetic Notes for This System

- **Window title bars become a translation puzzle.** The `FILENAME.EXT` convention is Latin-only — `METRICS.LOG` has no idiomatic Chinese equivalent. Options: (1) keep filenames in Latin (`METRICS.LOG`, `AGENDA.TXT`) for the system-UI nostalgia, and let the slide body carry Chinese content; (2) use a Chinese descriptor + Latin extension (`季度指标.LOG`, `议程.TXT`) which reads as a localized application. Option (1) is more authentic to the Win9x era; option (2) is more readable for Chinese audiences.
- **The 0.5px letter-spacing on `title-bar` typography must drop to 0** when the title bar contains CJK characters.
- **Status badges (READY, LIVE, OK, WARNING)** translate cleanly to short CJK words (就绪, 在线, 通过, 警告) at weight 700 in the assigned status color — the semantic green/red/yellow/cyan signal carries through.
- **Group-box notched titles work identically in Chinese** — `客户数据`, `销售指标`. The notch masking depends on background painting, not on glyph metrics.
- **The CRT scanline overlay is glyph-agnostic** and adds the same nostalgic texture to Chinese type as to Latin.
- **Charts axis labels and chip text** should drop to Noto Sans SC 400 at 11–12px; the fixed-pixel sizing convention applies equally to CJK.

### Known CJK Gap

The two nostalgic accent fonts (Press Start 2P, VT323) are fundamentally Latin-only — they exist as 8-bit pixel and CRT terminal callbacks to an era when CJK rendering required specialized bitmap fonts that have no modern web equivalent. If a deck needs a pixel display moment in Chinese, the only honest option is to use Noto Sans SC at large size and let go of the pixel-font character; do not substitute another "pixel-style" Chinese font (which will read as wrong-era and broken). Reserve Press Start 2P / VT323 for Latin-only moments (a splash screen with `LOADING...`, a footer with `ARROW KEYS to navigate`), and let CJK slides use Noto Sans SC throughout.

## Iteration Guide

1. Any new slide is wrapped in a `{components.win-window}` with a navy title bar containing a `{components.win-icon}` (single-letter glyph), an uppercase filename-style title (with extension like `.EXE`, `.DOC`, `.LOG`, `.TXT`, `.CSV`, `.INI`, `.PRJ`, `.BMP`), and the three-button cluster (`_`, `[]`, `X`).
2. Any new content region inside a window uses a `{components.group-box}` (sunken with notched title) for clustered related items, a `{components.panel-raised}` for tool strips and dashboards, or a `{components.panel-sunken}` for white-well content displays.
3. Any new primary headline uses `{typography.text-lg}` (22px) in `{colors.blue-navy}` weight 700. Hero / splash headlines use `{typography.text-xl}` (32px) or Press Start 2P (20–24px).
4. Any new metric tile uses the `{components.group-box}` + `{typography.metric-xl}` navy-700 + green delta + 12px gray context pattern.
5. Any new chart uses Chart.js with the navy ladder for primary data and the retro status colors for categorical segments. Always wrap the canvas in a `{components.panel-raised}`.
6. Any new bullet list uses the `{components.retro-list}` chevron pattern; any checkbox uses the `{components.retro-check}` pattern; any hierarchical tree uses the `{components.tree-item}` folder/file emoji pattern.
7. Any new button is a `{components.btn-retro}` — beveled gray, 6px × 24px padding, 14px MS Sans Serif. Buttons appear in clusters (OK / Cancel / Help, or Export / Print).
8. Any new status badge uses `{colors.green-retro}` weight 700 for OK, `{colors.red-retro}` for error, `{colors.yellow-retro}` for moderate. Always weight 700; never decorative.
9. Status footers (panel-raised strips at the bottom of a window body) carry three or four data points separated by `•` bullets — data source, last updated, count, classification.
10. Every slide must be visually dense — multiple panels stacked, a status footer at the bottom, button strips or nav-cluster decoration where space allows. Spareness breaks the aesthetic.

## Known Gaps

- The system loads two Google Fonts (Press Start 2P, VT323) from a CDN. These are optional nostalgic accents; the body font stack (MS Sans Serif, Segoe UI, Tahoma, Geneva, Verdana, sans-serif) renders correctly without any external dependency, and the deck remains aesthetically coherent if both Google fonts fail to load.
- Chart.js (4.4.7) loaded from a CDN provides the chart engine. Charts will not render if Chart.js fails to load. The slide will still render but with empty canvas regions.
- The CRT scanline overlay is a stylistic choice that does not match presenter-projector output well — on actual projection screens, the overlay can read as image noise rather than as nostalgic texture. Consider toggling the overlay off when projecting.
- The Win9x bevel illusion depends on rendering at the right zoom level — bevels are 1–2px wide and can appear as solid borders or disappear entirely at extreme zoom levels or on very high-DPI displays without browser sub-pixel rendering.
- Hover states are absent by design (the aesthetic predates universal hover). Modern audiences expecting hover affordances may find the deck unresponsive-feeling on mouse interaction.
- The retro-list `>` chevron, retro-check `x`, and tree-view emoji glyphs are character-based, not vector — they will render with whatever default font metrics the runtime provides for `>`, `x`, `📁`, `📄`.
- The marquee animation runs continuously and cannot be paused. Some accessibility audits will flag this as a `prefers-reduced-motion` violation.
- The `lib-cabinets` is set in `bgImage`-derived inline SVG noise / hatching patterns inside CSS — these are inlined data URIs and the rendered look will vary slightly across browsers.
````

---

## 2. 글씨체

- 이 디자인의 한글 글씨체: 제목 물마루(400) · 본문 Noto Sans KR Regular(400). (쓰는 폰트: 물마루, 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장(표지)에서 처음 나오는 부품**
- `.body` — 1·2·3·4·5·6장 — 예: `<div class="body splash">`
- `.desk` — 1·2·3·4·5·6장 — 예: `<section class="slide desk">`
- `.fn` — 1·2·3·4·5·6장 — 예: `<span class="fn">`
- `.gbox` — 1·2·3·4·5·6장 — 예: `<div class="gbox info">`
- `.gk` — 1장 — 예: `<em class="gk">`
- `.goal` — 1장 — 예: `<div class="sunk goal">`
- `.gt` — 1·2·3·4·5·6장 — 예: `<span class="gt">`
- `.gt2` — 1장 — 예: `<span class="gt2">`
- `.gtx` — 1장 — 예: `<h1 class="gtx">`
- `.hg` — 1장 — 예: `<span class="hg">`
- `.ic` — 1·2·3·4·5·6장 — 예: `<span class="ic">`
- `.info` — 1장 — 예: `<div class="gbox info">`
- `.li` — 1·4·5·6장 — 예: `<p class="li">`
- `.load` — 1장 — 예: `<div class="load">`
- `.logo` — 1장 — 예: `<div class="sunk logo">`
- `.lt` — 1·3장 — 예: `<p class="lt">`
- `.marq` — 1·5·6장 — 예: `<div class="marq">`
- `.ok` — 1·2장 — 예: `<b class="ok">`
- `.pf` — 1·2·6장 — 예: `<i class="pf">`
- `.prog` — 1·2·6장 — 예: `<div class="prog">`
- `.px` — 1장 — 예: `<p class="px">`
- `.raised` — 1·2·3장 — 예: `<div class="raised status">`
- `.slide` — 1·2·3·4·5·6장 — 예: `<section class="slide desk">`
- `.splash` — 1장 — 예: `<div class="body splash">`
- `.status` — 1·2·3장 — 예: `<div class="raised status">`
- `.sunk` — 1·2·4·5·6장 — 예: `<div class="sunk logo">`
- `.t1` — 1장 — 예: `<p class="t1">`
- `.tb` — 1·2·3·4·5·6장 — 예: `<div class="tb">`
- `.w1` — 1장 — 예: `<div class="win w1">`
- `.wb` — 1·2·3·4·5·6장 — 예: `<span class="wb">`
- `.win` — 1·2·3·4·5·6장 — 예: `<div class="win w1">`

**2장(흐름·단계)에서 처음 나오는 부품**
- `.btn` — 2·5·6장 — 예: `<button class="btn" data-act="step">`
- `.btns` — 2·5장 — 예: `<div class="btns">`
- `.cap` — 2장 — 예: `<p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01. 자 붙이기 — 완료&quot;,&quot;02. 수수깡 꽂기 — 완료&qu…`
- `.capw` — 2장 — 예: `<div class="sunk capw">`
- `.cb` — 2·5장 — 예: `<i class="cb">`
- `.chk` — 2장 — 예: `<div class="gbox chk">`
- `.cr` — 2장 — 예: `<div class="cr" data-s="1">`
- `.def` — 2장 — 예: `<div class="sunk def">`
- `.fig` — 2장 — 예: `<div class="sunk fig">`
- `.figc` — 2장 — 예: `<div class="figc">`
- `.hd` — 2·3·4·6장 — 예: `<h2 class="hd">`
- `.hrow` — 2장 — 예: `<div class="hrow">`
- `.main2` — 2장 — 예: `<div class="main2">`
- `.nr` — 2·4장 — 예: `<p class="nr">`
- `.p2` — 2장 — 예: `<div class="prog p2">`
- `.sd` — 2장 — 예: `<span class="sd">`
- `.side2` — 2장 — 예: `<div class="side2">`
- `.sn` — 2장 — 예: `<b class="sn">`
- `.tag` — 2장 — 예: `<b class="tag">`
- `.w2` — 2장 — 예: `<div class="win w2">`

**3장(숫자와 그래프)에서 처음 나오는 부품**
- `.ax` — 3장 — 예: `<text x="96" y="308" class="ax" text-anchor="end">`
- `.base` — 3장 — 예: `<line x1="110" x2="1440" y1="300" y2="300" class="base"/>`
- `.bn` — 3장 — 예: `<i class="k bn">`
- `.bvl` — 3장 — 예: `<text x="205" y="201.75" class="bvl" text-anchor="middle">`
- `.chartp` — 3장 — 예: `<div class="raised chartp">`
- `.ctx` — 3장 — 예: `<p class="ctx">`
- `.cv` — 3장 — 예: `<svg class="cv" viewBox="0 0 1600 360">`
- `.dl` — 3장 — 예: `<p class="dl">`
- `.gl` — 3장 — 예: `<line x1="110" x2="1440" y1="300" y2="300" class="gl"/>`
- `.grid4` — 3장 — 예: `<div class="grid4">`
- `.k` — 3장 — 예: `<i class="k bn">`
- `.kpi` — 3장 — 예: `<div class="gbox kpi">`
- `.lg` — 3장 — 예: `<div class="lg">`
- `.lgt` — 3장 — 예: `<span class="lgt">`
- `.ls` — 3장 — 예: `<i class="k ls">`
- `.lsp` — 3장 — 예: `<rect x="198" y="205.925" width="14" height="14" class="lsp"/>`
- `.lst` — 3장 — 예: `<text x="255" y="220.925" class="pv lst">`
- `.ltp` — 3장 — 예: `<rect x="198" y="131" width="14" height="14" class="ltp"/>`
- `.ltt` — 3장 — 예: `<text x="205" y="122" class="pv ltt" text-anchor="middle">`
- `.mx` — 3장 — 예: `<b class="mx">`
- `.nt` — 3장 — 예: `<span class="nt">`
- `.pv` — 3장 — 예: `<text x="255" y="220.925" class="pv lst">`
- `.w3` — 3장 — 예: `<div class="win w3">`

**4장(비교와 표)에서 처음 나오는 부품**
- `.off` — 4·5장 — 예: `<div class="tb off">`
- `.qt` — 4장 — 예: `<div class="sunk qt">`
- `.row4` — 4장 — 예: `<div class="row4">`
- `.rt` — 4장 — 예: `<table class="rt">`
- `.sh` — 4·5장 — 예: `<h3 class="sh">`
- `.tbx` — 4장 — 예: `<div class="gbox tbx">`
- `.wa` — 4장 — 예: `<div class="win wa">`
- `.wb2` — 4장 — 예: `<div class="win wb2">`
- `.wn` — 4장 — 예: `<div class="win wn">`
- `.wt` — 4장 — 예: `<div class="win wt">`

**5장(확인(퀴즈·빈칸))에서 처음 나오는 부품**
- `.bl` — 5장 — 예: `<p class="bl">`
- `.blank` — 5장 — 예: `<button class="sunk blank" data-blank aria-pressed="false">`
- `.fb` — 5장 — 예: `<p class="fb" data-fb>`
- `.fbw` — 5장 — 예: `<div class="sunk fbw">`
- `.opt` — 5장 — 예: `<button class="opt" data-opt="0">`
- `.opts` — 5장 — 예: `<div class="gbox opts">`
- `.q` — 5장 — 예: `<h3 class="q">`
- `.qi` — 5장 — 예: `<span class="qi">`
- `.qrow` — 5장 — 예: `<div class="qrow">`
- `.r` — 5장 — 예: `<div class="btns r">`
- `.w5a` — 5장 — 예: `<div class="win w5a" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 …`
- `.w5b` — 5장 — 예: `<div class="win w5b">`
- `.wd` — 5장 — 예: `<div class="gbox wd">`

**6장(디자인 안내(시연))에서 처음 나오는 부품**
- `.ab6` — 6장 — 예: `<p class="ab6">`
- `.crt6` — 6장 — 예: `<div class="sunk crt6" id="rw-crt">`
- `.d6` — 6장 — 예: `<div class="gbox d6">`
- `.dd` — 6장 — 예: `<p class="dd">`
- `.demo-btn` — 6장 — 예: `<span class="btn demo-btn" id="rw-btn">`
- `.dr` — 6장 — 예: `<div class="dr">`
- `.g6` — 6장 — 예: `<div class="gbox g6">`
- `.mq6` — 6장 — 예: `<div class="marq mq6" id="rw-mq">`
- `.pg6` — 6장 — 예: `<div class="prog pg6" id="rw-prog">`
- `.sg6` — 6장 — 예: `<div class="body sg6">`
- `.sm` — 6장 — 예: `<button class="btn sm" data-demo="#rw-btn" data-mode="toggle" aria-pressed="false">`
- `.sw6` — 6장 — 예: `<div class="sw6">`
- `.vt` — 6장 — 예: `<p class="vt">`
- `.w6a` — 6장 — 예: `<div class="win w6a">`
- `.w6b` — 6장 — 예: `<div class="win w6b">`

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

**직접 쓰지 말 것**: 엔진이 상태를 나타내려고 붙이는 클래스(`.on` `.now` `.open` `.right` `.wrong` `.play` `.solved` `.tried` `.active` `.visible` `.flash` `.in-frame`)와 내비 클래스(`.dk-…`)는 배치용으로 쓰지 마세요(뼈대의 내비 부분은 그대로 둡니다).

---

## 4. HTML 뼈대 (예시 덱 6장 — 부품 견본입니다. 장 구성은 따라 하지 말고, 공통 파일 두 줄은 그대로 두며, 장은 내용에 맞게 새로 구성)

```html
<!DOCTYPE html>
<html lang="ko" data-template="retro-windows">
<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=Press+Start+2P&family=VT323&display=swap">
<!-- 이 디자인의 공통 CSS(글씨체·색·부품 모양). 이 줄은 지우거나 바꾸지 마세요 -->
<link rel="stylesheet" href="https://k-slide.web.app/kit/v1/retro-windows.css">
<style>
/* === 추가 부품: 새 클래스가 꼭 필요할 때만 이 줄 아래에 정의하세요(공통 CSS는 위 <link>가 이미 불러옴 — 여기에 옮겨 쓰지 않음) === */
</style>
</head>
<body>
<div class="deck-viewport">
  <main class="deck-stage" id="deckStage">
<section class="slide desk">
  <div class="win w1"><div class="tb"><span class="ic">S</span><span class="fn">SEASONS.EXE</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body splash">
      <div class="sunk logo"><span class="hg">⌛</span><div><p class="px">SUN, SHADOW & TEMPERATURE</p><p class="t1">계절의 변화</p></div></div>
      <div class="gbox info"><span class="gt">정보</span><p class="li">초등 과학 · 6학년 2학기</p><p class="li">1단원 · 3~4차시</p><p class="li">00초등학교</p></div>
      <div class="sunk goal"><span class="gt2">학습 목표</span><h1 class="gtx">하루 동안 <em class="gk">태양 고도</em>,<br><em class="gk">그림자 길이</em>, <em class="gk">기온</em>의 관계</h1></div>
      <div class="load"><p class="lt">계절의 변화 — 1단원 · 3~4차시 불러오는 중...</p><div class="prog"><i class="pf"></i></div></div>
      <div class="marq"><span>하루 동안 태양 고도, 그림자 길이, 기온의 관계 ★ 태양 고도 · 그림자 길이 · 기온 ★ 태양 · 막대기 · 그림자</span></div>
      <div class="raised status"><span>00초등학교</span><span>•</span><span>초등 과학 · 6학년 2학기</span><span>•</span><span>2026</span><span>•</span><b class="ok">READY</b></div>
    </div>
  </div>
</section>
<section class="slide desk" data-steps="4">
  <div class="win w2"><div class="tb"><span class="ic">M</span><span class="fn">SUNMETER.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <div class="hrow"><h2 class="hd">태양 고도 측정기 만들기</h2><div class="sunk def"><b>태양 고도</b> = 태양이 지표면과 이루는 각</div></div>
      <div class="main2">
        <div class="figc"><div class="sunk fig"><svg class="gauge" viewBox="0 0 1000 660" role="img" aria-label="태양 고도 측정기: 태양 빛, 수수깡, 실, 태양 고도, 그림자 길이, 자, 각도기">
  <line class="g-ground" x1="20" x2="980" y1="580" y2="580"/>
  <rect class="g-board" x="80" y="540" width="860" height="40"/>
  <g class="g-part" data-s="1"><rect class="g-ruler" x="110" y="524" width="800" height="16"/><line class="g-tick" x1="120" x2="120" y1="524" y2="536"/><line class="g-tick" x1="140" x2="140" y1="524" y2="530"/><line class="g-tick" x1="160" x2="160" y1="524" y2="530"/><line class="g-tick" x1="180" x2="180" y1="524" y2="530"/><line class="g-tick" x1="200" x2="200" y1="524" y2="530"/><line class="g-tick" x1="220" x2="220" y1="524" y2="536"/><line class="g-tick" x1="240" x2="240" y1="524" y2="530"/><line class="g-tick" x1="260" x2="260" y1="524" y2="530"/><line class="g-tick" x1="280" x2="280" y1="524" y2="530"/><line class="g-tick" x1="300" x2="300" y1="524" y2="530"/><line class="g-tick" x1="320" x2="320" y1="524" y2="536"/><line class="g-tick" x1="340" x2="340" y1="524" y2="530"/><line class="g-tick" x1="360" x2="360" y1="524" y2="530"/><line class="g-tick" x1="380" x2="380" y1="524" y2="530"/><line class="g-tick" x1="400" x2="400" y1="524" y2="530"/><line class="g-tick" x1="420" x2="420" y1="524" y2="536"/><line class="g-tick" x1="440" x2="440" y1="524" y2="530"/><line class="g-tick" x1="460" x2="460" y1="524" y2="530"/><line class="g-tick" x1="480" x2="480" y1="524" y2="530"/><line class="g-tick" x1="500" x2="500" y1="524" y2="530"/><line class="g-tick" x1="520" x2="520" y1="524" y2="536"/><line class="g-tick" x1="540" x2="540" y1="524" y2="530"/><line class="g-tick" x1="560" x2="560" y1="524" y2="530"/><line class="g-tick" x1="580" x2="580" y1="524" y2="530"/><line class="g-tick" x1="600" x2="600" y1="524" y2="530"/><line class="g-tick" x1="620" x2="620" y1="524" y2="536"/><line class="g-tick" x1="640" x2="640" y1="524" y2="530"/><line class="g-tick" x1="660" x2="660" y1="524" y2="530"/><line class="g-tick" x1="680" x2="680" y1="524" y2="530"/><line class="g-tick" x1="700" x2="700" y1="524" y2="530"/><line class="g-tick" x1="720" x2="720" y1="524" y2="536"/><line class="g-tick" x1="740" x2="740" y1="524" y2="530"/><line class="g-tick" x1="760" x2="760" y1="524" y2="530"/><line class="g-tick" x1="780" x2="780" y1="524" y2="530"/><line class="g-tick" x1="800" x2="800" y1="524" y2="530"/><line class="g-tick" x1="820" x2="820" y1="524" y2="536"/><line class="g-tick" x1="840" x2="840" y1="524" y2="530"/><line class="g-tick" x1="860" x2="860" y1="524" y2="530"/><line class="g-tick" x1="880" x2="880" y1="524" y2="530"/><line class="g-tick" x1="900" x2="900" y1="524" y2="530"/><text class="g-lb" x="922" y="516" text-anchor="start">자</text></g>
  <g class="g-meas"><rect class="g-shadow" x="220" y="524" width="446" height="16"/>
    <path class="g-dim" d="M220 600v24M666 600v24M220 612H666"/><text class="g-lb" x="443" y="652" text-anchor="middle">그림자 길이</text></g>
  <g class="g-part" data-s="2"><rect class="g-stick" x="196" y="150" width="24" height="374"/><path class="g-mark" d="M220 504h20v20"/>
    <path class="g-lead" d="M182 330H196"/><text class="g-lb" x="174" y="342" text-anchor="end">수수깡</text></g>
  <g class="g-part" data-s="4"><path class="g-prot" d="M546 524A120 120 0 0 1 786 524Z"/><path class="g-prot2" d="M588 524A78 78 0 0 1 744 524"/><line class="g-tick" x1="570" y1="524" x2="546" y2="524"/><line class="g-tick" x1="561.6" y1="505.6" x2="547.8" y2="503.2"/><line class="g-tick" x1="566.4" y1="487.7" x2="553.2" y2="483"/><line class="g-tick" x1="582.9" y1="476" x2="562.1" y2="464"/><line class="g-tick" x1="584.8" y1="455.9" x2="574.1" y2="446.9"/><line class="g-tick" x1="597.9" y1="442.8" x2="588.9" y2="432.1"/><line class="g-tick" x1="618" y1="440.9" x2="606" y2="420.1"/><line class="g-tick" x1="629.7" y1="424.4" x2="625" y2="411.2"/><line class="g-tick" x1="647.6" y1="419.6" x2="645.2" y2="405.8"/><line class="g-tick" x1="666" y1="428" x2="666" y2="404"/><line class="g-tick" x1="684.4" y1="419.6" x2="686.8" y2="405.8"/><line class="g-tick" x1="702.3" y1="424.4" x2="707" y2="411.2"/><line class="g-tick" x1="714" y1="440.9" x2="726" y2="420.1"/><line class="g-tick" x1="734.1" y1="442.8" x2="743.1" y2="432.1"/><line class="g-tick" x1="747.2" y1="455.9" x2="757.9" y2="446.9"/><line class="g-tick" x1="749.1" y1="476" x2="769.9" y2="464"/><line class="g-tick" x1="765.6" y1="487.7" x2="778.8" y2="483"/><line class="g-tick" x1="770.4" y1="505.6" x2="784.2" y2="503.2"/><line class="g-tick" x1="762" y1="524" x2="786" y2="524"/><circle class="g-hole" cx="666" cy="524" r="5"/><text class="g-lb" x="800" y="456" text-anchor="start">각도기</text></g>
  <g class="g-part" data-s="3"><line class="g-string" x1="220" y1="150" x2="666" y2="524"/><text class="g-lb" x="478" y="344" text-anchor="start">실</text></g>
  <g class="g-meas"><path class="g-angle" d="M616 524A50 50 0 0 1 627.7 491.9"/><path class="g-lead" d="M542 498L615 506.9"/><text class="g-lb" x="536" y="508" text-anchor="end">태양 고도</text>
    <line class="g-ray" x1="74.5" y1="27.9" x2="187.8" y2="123"/><polygon class="g-rayh" points="209.3,141 179.5,133 196.2,113"/><text class="g-lb" x="150" y="60" text-anchor="start">태양 빛</text></g>
</svg></div><div class="sunk capw"><p class="cap" data-caps="[&quot;버튼을 눌러 순서대로 만들어 보세요&quot;,&quot;01. 자 붙이기 — 완료&quot;,&quot;02. 수수깡 꽂기 — 완료&quot;,&quot;03. 실 묶기 — 완료&quot;,&quot;04. 각도기 끼우기 — 완료&quot;]">버튼을 눌러 순서대로 만들어 보세요</p></div></div>
        <div class="side2">
          <div class="gbox chk"><span class="gt">만드는 순서</span><div class="cr" data-s="1"><i class="cb"></i><b class="sn">01. 자 붙이기</b><b class="tag">[준비]</b><span class="sd">우드록 한쪽에 양면테이프로 자를 붙여요</span></div><div class="cr" data-s="2"><i class="cb"></i><b class="sn">02. 수수깡 꽂기</b><b class="tag">[수직]</b><span class="sd">수수깡을 10cm 정도 잘라 자의 '0' 위치에 수직으로 꽂아요</span></div><div class="cr" data-s="3"><i class="cb"></i><b class="sn">03. 실 묶기</b><b class="tag">[실]</b><span class="sd">수수깡 끝에 실을 묶어요</span></div><div class="cr" data-s="4"><i class="cb"></i><b class="sn">04. 각도기 끼우기</b><b class="tag">[각도]</b><span class="sd">실의 다른 끝을 각도기 가운데 구멍에 끼워요</span></div></div>
          <div class="prog p2"><i class="pf"></i></div>
          <div class="btns"><button class="btn" data-act="step">다음 단계 &gt;</button><button class="btn" data-act="reset">처음부터</button></div>
        </div>
      </div>
      <div class="raised status"><span>막대기의 그림자와 실이 이루는 각 = 태양 고도</span><span>•</span><b class="ok">OK</b></div>
    </div>
  </div>
  <p class="nr">타임라인 규칙 없음 → 체크 상자 목록 + 진행 막대으로 표현</p>
</section>
<section class="slide desk">
  <div class="win w3"><div class="tb"><span class="ic">D</span><span class="fn">DATAVIEW.CSV</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <h2 class="hd">하루 동안 무엇이 어떻게 변할까요?</h2>
      <div class="grid4"><div class="gbox kpi"><span class="gt">남중 시각</span><b class="mx">12:30</b><p class="ctx">태양 고도가 가장 높아요</p><p class="dl">무렵 · 남중</p></div><div class="gbox kpi"><span class="gt">남중 방향</span><b class="mx">정남</b><p class="ctx">남중할 때 태양의 위치</p><p class="dl">쪽</p></div><div class="gbox kpi"><span class="gt">최고 기온</span><b class="mx">14:30</b><p class="ctx">기온이 가장 높아요</p><p class="dl">무렵</p></div><div class="gbox kpi"><span class="gt">가장 긴 그림자</span><b class="mx">9:30</b><p class="ctx">그림자가 가장 길어요</p><p class="dl">· 15:30</p></div></div>
      <div class="raised chartp">
        <div class="lg"><span class="lgt">측정 시각별 태양 고도, 그림자 길이, 기온</span><span><i class="k bn"></i>태양 고도(°)</span><span><i class="k ls"></i>그림자 길이(cm)</span><span><i class="k lt"></i>기온(℃)</span><span class="nt">예시 값</span></div>
        <svg class="cv" viewBox="0 0 1600 360"><line x1="110" x2="1440" y1="300" y2="300" class="gl"/><text x="96" y="308" class="ax" text-anchor="end">0°</text><line x1="110" x2="1440" y1="232.5" y2="232.5" class="gl"/><text x="96" y="240.5" class="ax" text-anchor="end">20°</text><line x1="110" x2="1440" y1="165" y2="165" class="gl"/><text x="96" y="173" class="ax" text-anchor="end">40°</text><line x1="110" x2="1440" y1="97.5" y2="97.5" class="gl"/><text x="96" y="105.5" class="ax" text-anchor="end">60°</text><line x1="110" x2="1440" y1="30" y2="30" class="gl"/><text x="96" y="38" class="ax" text-anchor="end">80°</text><rect x="163" y="171.75" width="84" height="128.25" class="bn"/><text x="205" y="201.75" class="bvl" text-anchor="middle">38</text><rect x="353" y="138" width="84" height="162" class="bn"/><text x="395" y="168" class="bvl" text-anchor="middle">48</text><rect x="543" y="114.375" width="84" height="185.625" class="bn"/><text x="585" y="144.375" class="bvl" text-anchor="middle">55</text><rect x="733" y="107.625" width="84" height="192.375" class="bn"/><text x="775" y="137.625" class="bvl" text-anchor="middle">57</text><rect x="923" y="117.75" width="84" height="182.25" class="bn"/><text x="965" y="147.75" class="bvl" text-anchor="middle">54</text><rect x="1113" y="141.375" width="84" height="158.625" class="bn"/><text x="1155" y="171.375" class="bvl" text-anchor="middle">47</text><rect x="1303" y="175.125" width="84" height="124.875" class="bn"/><text x="1345" y="205.125" class="bvl" text-anchor="middle">37</text><polyline class="ls" points="205,212.925 395,238.575 585,252.75 775,256.8 965,251.4 1155,236.55 1345,209.55"/><rect x="198" y="205.925" width="14" height="14" class="lsp"/><text x="255" y="220.925" class="pv lst">12.9</text><rect x="388" y="231.575" width="14" height="14" class="lsp"/><text x="445" y="246.575" class="pv lst">9.1</text><rect x="578" y="245.75" width="14" height="14" class="lsp"/><text x="635" y="260.75" class="pv lst">7</text><rect x="768" y="249.8" width="14" height="14" class="lsp"/><text x="825" y="264.8" class="pv lst">6.4</text><rect x="958" y="244.4" width="14" height="14" class="lsp"/><text x="1015" y="259.4" class="pv lst">7.2</text><rect x="1148" y="229.55" width="14" height="14" class="lsp"/><text x="1205" y="244.55" class="pv lst">9.4</text><rect x="1338" y="202.55" width="14" height="14" class="lsp"/><text x="1395" y="217.55" class="pv lst">13.4</text><polyline class="lt" points="205,138 395,113.69999999999999 585,94.80000000000001 775,79.94999999999999 965,70.5 1155,65.1 1345,71.85"/><rect x="198" y="131" width="14" height="14" class="ltp"/><text x="205" y="122" class="pv ltt" text-anchor="middle">22</text><rect x="388" y="106.69999999999999" width="14" height="14" class="ltp"/><text x="395" y="97.69999999999999" class="pv ltt" text-anchor="middle">23.8</text><rect x="578" y="87.80000000000001" width="14" height="14" class="ltp"/><text x="585" y="78.80000000000001" class="pv ltt" text-anchor="middle">25.2</text><rect x="768" y="72.94999999999999" width="14" height="14" class="ltp"/><text x="775" y="63.94999999999999" class="pv ltt" text-anchor="middle">26.3</text><rect x="958" y="63.5" width="14" height="14" class="ltp"/><text x="965" y="54.5" class="pv ltt" text-anchor="middle">27</text><rect x="1148" y="58.099999999999994" width="14" height="14" class="ltp"/><text x="1155" y="49.099999999999994" class="pv ltt" text-anchor="middle">27.4</text><rect x="1338" y="64.85" width="14" height="14" class="ltp"/><text x="1345" y="55.849999999999994" class="pv ltt" text-anchor="middle">26.9</text><line x1="110" x2="1440" y1="300" y2="300" class="base"/><text x="205" y="336" class="ax" text-anchor="middle">9:30</text><text x="395" y="336" class="ax" text-anchor="middle">10:30</text><text x="585" y="336" class="ax" text-anchor="middle">11:30</text><text x="775" y="336" class="ax" text-anchor="middle">12:30</text><text x="965" y="336" class="ax" text-anchor="middle">13:30</text><text x="1155" y="336" class="ax" text-anchor="middle">14:30</text><text x="1345" y="336" class="ax" text-anchor="middle">15:30</text></svg>
      </div>
      <div class="raised status"><span>예시 값 — 태양 고도·그림자(10cm 막대)는 9월 중순 북위 36° 기준 계산, 기온은 교과서 그래프 모양을 따른 값</span></div>
    </div>
  </div>
</section>
<section class="slide desk">
  <div class="win wa"><div class="tb off"><span class="ic">H</span><span class="fn">HIGH.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body"><h3 class="sh">태양 고도가 높을 때</h3><p class="li">그림자 길이는 짧아져요</p><p class="li">기온은 높아져요</p></div>
  </div>
  <div class="win wb2"><div class="tb off"><span class="ic">L</span><span class="fn">LOW.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body"><h3 class="sh">태양 고도가 낮을 때</h3><p class="li">그림자 길이는 길어져요</p><p class="li">기온은 낮아져요</p></div>
  </div>
  <div class="win wn"><div class="tb off"><span class="ic">N</span><span class="fn">NAMJUNG.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body"><h3 class="sh">남중</h3><p class="li">태양이 정남쪽에 있을 때 '남중했다'고 해요</p><p class="li">이때의 태양 고도를 남중 고도라고 해요</p></div>
  </div>
  <div class="win wt"><div class="tb"><span class="ic">R</span><span class="fn">RELATION.CSV</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <h2 class="hd">태양 고도가 바뀌면 무엇이 달라질까요?</h2>
      <div class="row4">
        <div class="gbox tbx"><span class="gt">시각별 변화</span><table class="rt"><tr><th>시각</th><th>태양 고도</th><th>그림자 길이</th><th>기온</th></tr><tr><td>오전 9:30</td><td>낮아요</td><td>길어요</td><td>낮아요</td></tr><tr><td>낮 12:30</td><td>가장 높아요</td><td>가장 짧아요</td><td>높아지는 중</td></tr><tr><td>오후 14:30</td><td>낮아지는 중</td><td>길어지는 중</td><td>가장 높아요</td></tr></table></div>
        <div class="sunk qt"><p>태양 고도가 가장 높은 시각과 기온이 가장 높은 시각에는 차이가 있어요.</p><span>— 오늘의 정리</span></div>
      </div>
    </div>
  </div>
  <p class="nr">인용 규칙 없음 → 오목 흰 패널으로 표현</p>
</section>
<section class="slide desk">
  <div class="win w5a" data-quiz data-answer="1" data-right="정답! 태양 고도가 가장 높을 때(남중) 그림자가 가장 짧아요" data-wrong="다시 생각해 볼까요? 태양 고도와 그림자 길이의 관계를 떠올려 보세요"><div class="tb"><span class="ic">?</span><span class="fn">QUIZ.DLG</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <div class="qrow"><span class="qi">?</span><h3 class="q">하루 중 그림자 길이가 가장 짧을 때는?</h3></div>
      <div class="gbox opts"><span class="gt">답 고르기</span><button class="opt" data-opt="0"><i class="cb"></i><span>오전 9시 30분</span></button><button class="opt" data-opt="1"><i class="cb"></i><span>낮 12시 30분 무렵</span></button><button class="opt" data-opt="2"><i class="cb"></i><span>오후 3시 30분</span></button></div>
      <div class="sunk fbw"><p class="fb" data-fb></p></div>
      <div class="btns r"><button class="btn" data-act="retry">다시 풀기</button></div>
    </div>
  </div>
  <div class="win w5b"><div class="tb off"><span class="ic">B</span><span class="fn">BLANKS.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <h3 class="sh">빈칸을 눌러 확인해요</h3>
      <p class="bl"><button class="sunk blank" data-blank aria-pressed="false"><span>태양 고도</span></button><span>는 점점 높아졌다가 다시 낮아진다</span></p><p class="bl"><button class="sunk blank" data-blank aria-pressed="false"><span>그림자 길이</span></button><span>는 점점 짧아졌다가 다시 길어진다</span></p><p class="bl"><button class="sunk blank" data-blank aria-pressed="false"><span>기온</span></button><span>은 점점 높아졌다가 다시 낮아진다</span></p>
      <div class="gbox wd"><span class="gt">오늘의 낱말</span><p class="li">태양 고도</p><p class="li">남중 고도</p><p class="li">그림자 길이</p><p class="li">기온</p></div>
      <div class="marq"><span>계절의 변화 ★ 태양 고도 · 남중 고도 · 그림자 길이 · 기온 ★ 00초등학교</span></div>
    </div>
  </div>
</section>
<section class="slide desk">
  <div class="win w6a"><div class="tb"><span class="ic">?</span><span class="fn">README.TXT</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body">
      <h2 class="hd">이 디자인 사용 설명서</h2>
      <div class="gbox g6"><span class="gt">한눈에</span><p class="ab6">모든 장이 <b>윈도우 95/98 창</b>입니다. 회색 단추면 · 흰 우물 · 남색 제목 표시줄로 만들고, 그림자 대신 <b>입체 테두리</b>(볼록/오목)로 깊이를 냅니다.</p></div>
      <div class="gbox g6"><span class="gt">색</span><div class="sw6"><span><i class="sunk" style="background:#d4d0c8"></i>단추면</span><span><i class="sunk" style="background:#000080"></i>남색 = 제목·주요 값</span><span><i class="sunk" style="background:#fff"></i>흰 우물</span><span><i class="sunk" style="background:#008000"></i>초록 = OK</span><span><i class="sunk" style="background:#800000"></i>빨강 = 오류</span><span><i class="sunk" style="background:#808000"></i>겨자 = 보통</span><span><i class="sunk" style="background:#008080"></i>청록 = 3순위</span></div></div>
      <div class="gbox g6"><span class="gt">글꼴</span><p class="li">본문·제목 MS Sans Serif(정수 px) → 물마루 / Noto Sans KR Regular</p><p class="li">스플래시 Press Start 2P · 안내 VT323(영문만)</p></div>
      <div class="gbox g6"><span class="gt">이렇게 쓰면 좋아요</span><p class="li">'프로그램을 실행한다'는 느낌 — 실험 절차, 체크리스트 수업</p><p class="li">상태색은 뜻이 정해져 있어요: 초록 = 맞음, 빨강 = 틀림</p><p class="li">장마다 창 이름(FILE.TXT)을 붙이면 주제가 또렷해져요</p></div>
    </div>
  </div>
  <div class="win w6b"><div class="tb"><span class="ic">S</span><span class="fn">SIGNATURE.EXE</span><span class="wb"><i>_</i><i>□</i><i>X</i></span></div>
    <div class="body sg6">
      <p class="vt">&gt; 대표 장치 — 눌러 보세요</p>
      <div class="gbox d6"><span class="gt">눌린 단추</span><p class="dd">마우스를 올려도 그대로이고, 누르면 테두리 빛이 뒤집혀 들어가 보여요.</p><div class="dr"><span class="btn demo-btn" id="rw-btn">확인</span><button class="btn sm" data-demo="#rw-btn" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div></div>
      <div class="gbox d6"><span class="gt">진행 막대</span><p class="dd">오목 우물 안 남색 채움 — 너비만 바뀌어요.</p><div class="dr"><div class="prog pg6" id="rw-prog"><i class="pf"></i></div><button class="btn sm" data-demo="#rw-prog">다시 보기</button></div></div>
      <div class="gbox d6"><span class="gt">마키(흐르는 글)</span><p class="dd">흰 우물 안 글이 14초에 한 바퀴 옆으로 흘러가요.</p><div class="dr"><div class="marq mq6" id="rw-mq"><span>하루 동안 태양 고도, 그림자 길이, 기온의 관계 ★ 00초등학교</span></div><button class="btn sm" data-demo="#rw-mq" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div></div>
      <div class="gbox d6"><span class="gt">CRT 주사선</span><p class="dd">모든 장 위에 3px 간격 가로줄이 3%로 깔려요(시연은 진하게).</p><div class="dr"><div class="sunk crt6" id="rw-crt"><b>SCANLINES</b></div><button class="btn sm" data-demo="#rw-crt" data-mode="toggle" aria-pressed="false">켜기 / 끄기</button></div></div>
    </div>
  </div>
</section>
<nav class="dk-nav"><span class="hint">&lt;-- ARROW KEYS to navigate --&gt;</span><span class="dk-dots"><button class="dk-dot" aria-label="1장"></button><button class="dk-dot" aria-label="2장"></button><button class="dk-dot" aria-label="3장"></button><button class="dk-dot" aria-label="4장"></button><button class="dk-dot" aria-label="5장"></button><button class="dk-dot" aria-label="6장"></button></span><span class="ctr"><button class="dk-prev" aria-label="이전">◀</button><span class="dk-count"></span><button class="dk-next" aria-label="다음">▶</button></span></nav>
  </main>
</div>

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

---

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

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

```css
/* retro-windows — k-slide 공통 CSS v1 (채팅 AI용 받기 .md가 불러옴, 고치지 말 것) */
/* === KOREAN FONTS === */
@font-face{font-family:'kp-35';font-display:swap;src:url("https://maker-ssam.github.io/korean-ofl-fonts/fonts/mulmaru/Mulmaru.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:#808080;--slide-bg:#808080;
  --kt:'kp-35';--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 === */

/* --- 윈도우 9x 시스템 색 · 입체 테두리 --- */
:root{--face:#d4d0c8;--gray:#c0c0c0;--dark:#808080;--navy:#000080;--blue:#0000a0;--lblue:#1084d0;--txt:#222;--tg:#555;--ok:#008000;--err:#800000;--mod:#808000;--cyan:#008080;
  --sys:'MS Sans Serif','Segoe UI',Tahoma,Geneva,Verdana}
.slide{font-family:var(--sys),var(--kb),sans-serif;color:var(--txt)}
.desk{background:var(--dark)}
.slide::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:99;background-image:repeating-linear-gradient(0deg,rgba(0,0,0,.03) 0px,rgba(0,0,0,.03) 1px,transparent 1px,transparent 3px)}
.slide>*{position:absolute}
.win,.raised,.btn,.wb i{background:var(--face);border-top:2px solid #fff;border-left:2px solid #fff;border-right:2px solid #000;border-bottom:2px solid #000;box-shadow:inset 1px 1px 0 #fff,inset -1px -1px 0 #404040}
.sunk,.prog,.cb{background:#fff;border-top:2px solid #404040;border-left:2px solid #404040;border-right:2px solid #fff;border-bottom:2px solid #fff}
.win{display:flex;flex-direction:column}
.tb{display:flex;align-items:center;gap:12px;padding:6px 8px 6px 10px;background:linear-gradient(90deg,var(--navy) 0%,var(--blue) 100%);color:#fff;font:700 26px/1 var(--sys),var(--kb),sans-serif;letter-spacing:.5px}
.tb.off{background:linear-gradient(90deg,#808080 0%,#a0a0a0 100%);color:#d4d0c8}
.ic{display:grid;place-items:center;width:30px;height:30px;background:#fff;border:1px solid #000;color:var(--navy);font:700 20px/1 var(--sys),sans-serif}
.fn{flex:1}
.wb{display:flex;gap:4px}
.wb i{display:grid;place-items:center;width:34px;height:30px;font:700 18px/1 var(--sys),sans-serif;color:#000;font-style:normal}
.wb i:last-child{margin-left:6px}
.body{flex:1;position:relative;padding:28px 34px 28px;display:flex;flex-direction:column;gap:20px;min-height:0}
.gbox{position:relative;border-top:2px solid #404040;border-left:2px solid #404040;border-right:2px solid #fff;border-bottom:2px solid #fff;box-shadow:1px 1px 0 #404040 inset;padding:34px 26px 22px}
.gt{position:absolute;left:18px;top:-17px;background:var(--face);padding:0 10px;font:700 26px/1.2 var(--sys),var(--kb),sans-serif}
.li::before{content:'> ';color:var(--navy);font-weight:700}
.raised{padding:12px 18px}
.status{display:flex;gap:16px;align-items:center;font-size:24px;color:var(--tg);margin-top:auto}
.ok{color:var(--ok);font-weight:700}
.nt{color:var(--tg)}
.prog{height:44px;padding:3px;flex:none}
.pf{display:block;height:100%;width:0;background:var(--navy)}
.btn{padding:12px 40px;font:400 30px/1 var(--sys),var(--kb),sans-serif;color:#000}
.btn:active:not(:disabled){border-top-color:#000;border-left-color:#000;border-right-color:#fff;border-bottom-color:#fff;box-shadow:inset 1px 1px 0 #404040}
.btn:disabled{color:#808080;text-shadow:1px 1px 0 #fff}
.cb{display:inline-grid;place-items:center;width:34px;height:34px;flex:none;border-top-color:#000;border-left-color:#000;font:700 28px/1 var(--sys),sans-serif;font-style:normal;color:#000}
.hd{font-family:var(--sys),var(--kt),sans-serif;font-weight:700;font-size:52px;line-height:1.15;color:var(--navy)}
.sh{font-family:var(--sys),var(--kt),sans-serif;font-weight:700;font-size:40px;line-height:1.2;color:var(--navy);margin-bottom:6px}
.nr{left:32px;top:12px;font-size:20px;color:#e0e0e0}

/* --- 1. 스플래시 창: 오목 로고 우물(모래시계 + 픽셀 단원 제목) + 정보 그룹 박스 + 학습 목표 흰 우물(가장 큰 글자, 핵심 낱말 = 굵게 + 남색) + 진행 막대 + 마키 + 상태 바 --- */
.w1{left:120px;right:120px;top:50px;bottom:110px}
.splash{display:grid;grid-template-columns:1fr 520px;grid-template-rows:auto auto auto auto 1fr;gap:24px 30px}
.logo{grid-column:1;grid-row:1;display:flex;align-items:center;gap:32px;padding:22px 36px}
.hg{font-size:80px;line-height:1}
.px{font:400 24px/1.8 'Press Start 2P',monospace;color:var(--navy)}
.t1{margin-top:6px;font-family:var(--kt),'Press Start 2P',monospace;font-weight:var(--wt);font-size:72px;line-height:1.05;color:var(--navy);white-space:nowrap}
.info{grid-column:2;grid-row:1;display:flex;flex-direction:column;justify-content:center;gap:12px;font-size:32px}
.goal{grid-column:1/-1;padding:20px 36px 26px}
.gt2{display:block;font:700 26px/1.2 var(--sys),var(--kb),sans-serif;color:var(--tg)}
.gtx{margin-top:8px;font-family:var(--sys),var(--kt),sans-serif;font-weight:400;font-size:96px;line-height:1.2;color:var(--txt);white-space:nowrap}
.gtx .gk{font-style:normal;font-weight:700;color:var(--navy)}
.load{grid-column:1/-1;display:flex;flex-direction:column;gap:12px}
.lt{font-size:30px}
.load .pf{transition:width 3s steps(16)}
.visible .load .pf{width:100%}
.marq{background:#fff;border:2px inset var(--gray);padding:6px 0;overflow:hidden;white-space:nowrap}
.splash .marq{grid-column:1/-1;align-self:start}
.marq span{display:inline-block;padding-left:100%;font:400 40px/1.1 'VT323',var(--kb),monospace;animation:mq 14s linear infinite}
@keyframes mq{to{transform:translateX(-100%)}}
.splash .status{grid-column:1/-1}

/* --- 2. 측정기 창: 제목 + 정의 우물 / 흰 우물 속 측정기 그림(아직 안 만든 부품 = 비활성 회색) + 안내 우물 | 체크 상자 순서(단계마다 x) + 진행 막대(너비 전환) + 단추 / 상태 바 --- */
.w2{left:100px;right:100px;top:40px;bottom:100px}
.hrow{display:flex;align-items:center;gap:30px}
.def{padding:12px 20px;font-size:30px}
.def b{color:var(--navy)}
.main2{flex:1;min-height:0;display:grid;grid-template-columns:900px 1fr;gap:26px}
.figc{display:flex;flex-direction:column;gap:16px;min-height:0}
.fig{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;padding:10px 26px;
  --g-ink:#000;--g-acc:var(--navy);--g-stick:#808000;--g-board:var(--gray);--g-ruler:#fff;--g-prot:#fff;--g-shadow:#404040;--g-font:var(--sys),var(--kb),sans-serif;--g-dim:1;--g-sw:2}
.fig .gauge{height:100%;width:auto;max-width:100%}
.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{--g-ink:#808080;--g-acc:#808080;--g-stick:var(--face);--g-board:var(--face);--g-shadow:var(--face)}
.gauge .g-part.now .g-lb{fill:var(--navy)}
.side2{display:flex;flex-direction:column;gap:20px;min-height:0}
.chk{flex:1;display:flex;flex-direction:column;justify-content:space-around;gap:10px}
.cr{display:grid;grid-template-columns:34px 1fr auto;align-items:center;gap:6px 16px;font-size:32px;color:var(--tg)}
.cr .sd{grid-column:2/-1;font-size:28px;line-height:1.35}
.sn{font-weight:700}
.cr.on{color:var(--txt)}
.cr.on .sn{color:var(--navy)}
.cr.on .cb::after{content:'x'}
.tag{font-size:24px;color:var(--tg)}
.cr.now .tag{color:var(--ok)}
.p2 .pf{transition:width .5s steps(8)}
.slide[data-step="1"] .p2 .pf{width:25%}.slide[data-step="2"] .p2 .pf{width:50%}.slide[data-step="3"] .p2 .pf{width:75%}.slide[data-step="4"] .p2 .pf{width:100%}
.btns{display:flex;gap:16px;align-items:center}
.btns.r{justify-content:flex-end;margin-top:auto}
.capw{padding:12px 18px;display:flex;align-items:center}
.cap{font-size:30px}

/* --- 3. 데이터 창: KPI 타일 4개(그룹 박스 · 남색 큰 값) + 볼록 패널 차트(남색 막대 + 청록·밝은 파랑 꺾은선) + 상태 바(출처) --- */
.w3{left:120px;right:120px;top:50px;bottom:110px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;margin-top:10px}
.kpi{display:flex;flex-direction:column}
.mx{font-family:var(--sys),var(--kt),sans-serif;font-weight:700;font-size:64px;line-height:1.05;color:var(--navy)}
.ctx{margin-top:8px;font-size:28px;line-height:1.35}
.dl{margin-top:4px;font-size:24px;color:var(--tg)}
.chartp{flex:1;display:flex;flex-direction:column;gap:6px;min-height:0;padding:12px 18px}
.lg{display:flex;gap:28px;align-items:center;font-size:24px}
.lgt{font-weight:700;color:var(--navy);margin-right:auto}
.k{display:inline-block;width:22px;height:16px;margin-right:8px;vertical-align:middle}
.k.bn{background:var(--navy)}.k.ls{background:var(--cyan)}.k.lt{background:var(--lblue)}
.cv{flex:1;width:100%;min-height:0}
.cv .gl{stroke:var(--gray);stroke-width:2}
.cv .base{stroke:#404040;stroke-width:2}
.cv .ax{font:400 22px var(--sys),sans-serif;fill:var(--txt)}
.cv .bn{fill:var(--navy)}
.cv .bvl{font:700 24px var(--sys),sans-serif;fill:#fff}
.cv .ls{fill:none;stroke:var(--cyan);stroke-width:4}.cv .lsp{fill:var(--cyan)}.cv .lst{fill:var(--cyan)}
.cv .lt{fill:none;stroke:var(--lblue);stroke-width:4}.cv .ltp{fill:var(--lblue)}.cv .ltt{fill:var(--lblue)}
.cv .pv{font:700 22px var(--sys),sans-serif;paint-order:stroke;stroke:var(--face);stroke-width:6px}
.w3 .status{font-size:22px}

/* --- 4. 창 여러 개: 비교(높을 때 · 낮을 때) + 남중 목록 — 비활성 회색 / 관계 표 창만 활성 남색 --- */
.wa{left:60px;width:580px;top:50px;height:330px}
.wb2{left:670px;width:580px;top:50px;height:330px}
.wn{left:1280px;right:60px;top:50px;height:330px}
.wa .li,.wb2 .li,.wn .li{font-size:32px;line-height:1.5}
.wn .li{font-size:28px}
.wt{left:60px;right:60px;top:410px;bottom:110px}
.row4{display:grid;grid-template-columns:1.6fr 1fr;gap:26px;flex:1;min-height:0}
.tbx{padding:30px 20px 18px}
.rt{width:100%;border-collapse:collapse;font-size:28px}
.rt th{background:var(--gray);border:1px solid #404040;padding:10px 14px;text-align:left;font-weight:700}
.rt td{background:#fff;border:1px solid var(--gray);padding:10px 14px}
.rt tr:nth-child(odd) td{background:#f0f0f0}
.qt{padding:24px 26px;display:flex;flex-direction:column;justify-content:center}
.qt p{font-family:var(--sys),var(--kt),sans-serif;font-weight:700;font-size:36px;line-height:1.4;color:var(--navy)}
.qt span{margin-top:14px;font-size:24px;color:var(--tg)}

/* --- 5. 대화상자 둘: 퀴즈(활성 · 체크 상자 x · 다시 풀기) | 빈칸(비활성 · 오목 입력칸) + 낱말 목록 + 마키 --- */
.w5a{left:80px;width:900px;top:60px;bottom:110px}
.w5b{left:1010px;right:80px;top:60px;bottom:110px}
.qrow{display:flex;gap:22px;align-items:flex-start}
.qi{flex:none;display:grid;place-items:center;width:64px;height:64px;border-radius:50%;background:var(--navy);color:#fff;font:700 42px/1 var(--sys),sans-serif}
.q{font-family:var(--sys),var(--kt),sans-serif;font-weight:700;font-size:44px;line-height:1.25;color:var(--navy)}
.opts{display:flex;flex-direction:column;gap:14px}
.opt{display:flex;align-items:center;gap:18px;text-align:left;font-size:36px;color:#000;padding:4px}
.opt:focus-visible span{outline:1px dotted #000}
.opt.right .cb::after{content:'x'}
.opt.right span{color:var(--ok);font-weight:700}
.opt.wrong span{color:var(--err);font-weight:700}
.opt:disabled:not(.right){color:#808080}
.fbw{padding:12px 16px;min-height:100px}
.fb{font-size:28px;line-height:1.45}
.w5a.solved .fb{color:var(--ok);font-weight:700}
.w5a.tried .fb{color:var(--err);font-weight:700}
.bl{display:flex;align-items:center;gap:14px;font-size:32px}
.blank{min-width:220px;padding:8px 16px;font:700 32px/1.2 var(--sys),var(--kb),sans-serif;color:var(--navy);text-align:left;position:relative}
.blank span{visibility:hidden}
.blank::after{content:'_';position:absolute;left:16px;top:6px}
.blank.open span{visibility:visible}
.blank.open::after{content:none}
.wd{display:grid;grid-template-columns:1fr 1fr;gap:10px 20px;font-size:30px;margin-top:6px}
.w5b .marq{margin-top:auto}

/* --- 크롬: 왼쪽 VT323 안내 · 가운데 입체 사각 점 · 오른쪽 오목 번호 칩 --- */
.dk-nav{position:absolute;left:0;right:0;bottom:24px;height:48px;pointer-events:none}
.hint{position:absolute;left:40px;bottom:6px;font:400 32px/1 'VT323',monospace;color:#e0e0e0}
.dk-dots{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);display:flex;gap:14px;pointer-events:auto}
.dk-dot{width:26px;height:26px;background:var(--gray);border-top:2px solid #fff;border-left:2px solid #fff;border-right:2px solid #000;border-bottom:2px solid #000;position:relative}
.dk-dot.on{background:var(--navy)}
.dk-dot.on::after{content:'';position:absolute;left:50%;top:50%;width:8px;height:8px;margin:-4px 0 0 -4px;background:#fff}
.ctr{position:absolute;right:40px;bottom:0;display:flex;gap:8px;align-items:center;pointer-events:auto}
.ctr button{width:48px;height:44px;background:var(--face);border-top:2px solid #fff;border-left:2px solid #fff;border-right:2px solid #000;border-bottom:2px solid #000;font:700 18px/1 var(--sys),sans-serif}
.ctr button:active:not(:disabled){border-top-color:#000;border-left-color:#000;border-right-color:#fff;border-bottom-color:#fff}
.ctr button:disabled{color:#808080}
.dk-count{background:#fff;border-top:2px solid #404040;border-left:2px solid #404040;border-right:2px solid #fff;border-bottom:2px solid #fff;padding:10px 18px;font:400 24px/1 var(--sys),sans-serif}
/* --- 6. 디자인 안내: README 창(그룹 박스 넷) | SIGNATURE 창(시연 넷 — 눌린 단추 · 진행 막대 · 마키 · CRT 주사선) --- */
.w6a{left:60px;width:1000px;top:40px;bottom:100px}
.w6b{left:1100px;right:60px;top:40px;bottom:100px}
.w6a .body{gap:28px}
.g6{padding:30px 24px 16px}
.ab6{font-size:28px;line-height:1.5}
.ab6 b{color:var(--navy)}
.sw6{display:flex;flex-wrap:wrap;gap:10px 22px;font-size:24px}
.sw6 i{display:inline-block;width:30px;height:30px;margin-right:8px;vertical-align:-8px}
.g6 .li{font-size:25px;line-height:1.5}
.sg6{gap:26px}
.vt{font:400 36px/1 'VT323',var(--kb),monospace;color:var(--navy)}
.d6{padding:30px 22px 16px}
.dd{font-size:23px;line-height:1.4;color:var(--tg)}
.dr{display:flex;align-items:center;gap:18px;margin-top:12px}
.btn.sm{padding:8px 18px;font-size:22px;flex:none}
.btn.sm[aria-pressed="true"],.demo-btn.play{border-top-color:#000;border-left-color:#000;border-right-color:#fff;border-bottom-color:#fff;box-shadow:inset 1px 1px 0 #404040}
.demo-btn{display:inline-block;padding:12px 40px;font-size:28px}
.demo-btn.play{padding:13px 39px 11px 41px}
.pg6{flex:1;height:40px}
.pg6 .pf{width:100%}
.pg6.play .pf{animation:rw-pf 2.4s linear both}
@keyframes rw-pf{from{width:0}to{width:100%}}
.mq6{flex:1}
.mq6 span{font-size:32px;animation-play-state:paused}
.mq6.play span{animation-play-state:running}
.crt6{flex:1;height:60px;display:grid;place-items:center;font:400 22px/1 'Press Start 2P',monospace;color:var(--navy);position:relative}
.crt6.play::after{content:'';position:absolute;inset:0;background:repeating-linear-gradient(0deg,rgba(0,0,0,.28) 0px,rgba(0,0,0,.28) 1px,transparent 1px,transparent 3px)}

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